diff --git a/src/audio/asrc/asrc.c b/src/audio/asrc/asrc.c index 055fdab8dfa1..8d00d1002b80 100644 --- a/src/audio/asrc/asrc.c +++ b/src/audio/asrc/asrc.c @@ -860,8 +860,35 @@ static int asrc_reset(struct processing_module *mod) return 0; } +#if CONFIG_IPC_MAJOR_3 +static int asrc_init_shim(struct processing_module *mod) +{ + struct ipc_config_asrc *ipc_asrc; + struct module_data *mod_data = &mod->priv; + const struct sof_ipc_comp_asrc *asrc = + (const struct sof_ipc_comp_asrc *)mod_data->cfg.init_data; + + if (IPC_TAIL_IS_SIZE_INVALID(*asrc)) + return -EBADMSG; + + ipc_asrc = rballoc(0, SOF_MEM_CAPS_RAM, sizeof(*ipc_asrc)); + if (!ipc_asrc) + return -ENOMEM; + + ipc_asrc->source_rate = asrc->source_rate; + ipc_asrc->sink_rate = asrc->sink_rate; + ipc_asrc->asynchronous_mode = asrc->asynchronous_mode; + ipc_asrc->operation_mode = asrc->operation_mode; + + rfree(mod_data->cfg.data); + mod_data->cfg.init_data = ipc_asrc; + mod_data->cfg.data = ipc_asrc; + return asrc_init(mod); +} +#endif + static const struct module_interface asrc_interface = { - .init = asrc_init, + .init = IPC3_SHIM(asrc_init), .prepare = asrc_prepare, .process_audio_stream = asrc_process, .trigger = asrc_trigger, diff --git a/src/audio/dai-legacy.c b/src/audio/dai-legacy.c index 5430992d2c50..e6d8b91ea383 100644 --- a/src/audio/dai-legacy.c +++ b/src/audio/dai-legacy.c @@ -217,6 +217,25 @@ static struct comp_dev *dai_new(const struct comp_driver *drv, return NULL; } +#if CONFIG_IPC_MAJOR_3 +static struct comp_dev *dai_new_shim(const struct comp_driver *drv, + const struct comp_ipc_config *config, + const void *spec) +{ + struct sof_ipc_comp_dai *comp = spec; + struct ipc_config_dai dai; + + if (IPC_TAIL_IS_SIZE_INVALID(*comp)) + return NULL; + + dai.dai_index = comp->dai_index; + dai.direction = comp->direction; + dai.type = comp->type; + + return dai_new(drv, config, &dai); +} +#endif + void dai_common_free(struct dai_data *dd) { if (dd->group) @@ -1109,7 +1128,7 @@ static const struct comp_driver comp_dai = { .uid = SOF_RT_UUID(dai_uuid), .tctx = &dai_comp_tr, .ops = { - .create = dai_new, + .create = IPC3_SHIM(dai_new), .free = dai_free, .params = dai_params, .dai_get_hw_params = dai_comp_get_hw_params, diff --git a/src/audio/dai-zephyr.c b/src/audio/dai-zephyr.c index ff378be8cd9d..e07ede250ada 100644 --- a/src/audio/dai-zephyr.c +++ b/src/audio/dai-zephyr.c @@ -577,6 +577,25 @@ static struct comp_dev *dai_new(const struct comp_driver *drv, return NULL; } +#if CONFIG_IPC_MAJOR_3 +static struct comp_dev *dai_new_shim(const struct comp_driver *drv, + const struct comp_ipc_config *config, + const void *spec) +{ + const struct sof_ipc_comp_dai *comp = spec; + struct ipc_config_dai dai; + + if (IPC_TAIL_IS_SIZE_INVALID(*comp)) + return NULL; + + dai.dai_index = comp->dai_index; + dai.direction = comp->direction; + dai.type = comp->type; + + return dai_new(drv, config, &dai); +} +#endif + void dai_common_free(struct dai_data *dd) { #ifdef CONFIG_SOF_TELEMETRY_IO_PERFORMANCE_MEASUREMENTS @@ -1919,7 +1938,7 @@ static const struct comp_driver comp_dai = { .uid = SOF_RT_UUID(dai_uuid), .tctx = &dai_comp_tr, .ops = { - .create = dai_new, + .create = IPC3_SHIM(dai_new), .free = dai_free, .params = dai_params, .dai_get_hw_params = dai_comp_get_hw_params, diff --git a/src/audio/host-legacy.c b/src/audio/host-legacy.c index 50a2884990cd..12cbe6c3039f 100644 --- a/src/audio/host-legacy.c +++ b/src/audio/host-legacy.c @@ -599,6 +599,25 @@ static struct comp_dev *host_new(const struct comp_driver *drv, return NULL; } +#if CONFIG_IPC_MAJOR_3 +static struct comp_dev *host_new_shim(const struct comp_driver *drv, + const struct comp_ipc_config *config, + const void *spec) +{ + struct sof_ipc_comp_host *comp = spec; + struct ipc_config_host host; + + if (IPC_TAIL_IS_SIZE_INVALID(*comp)) + return NULL; + + host.direction = comp->direction; + host.no_irq = comp->no_irq; + host.dmac_config = comp->dmac_config; + + return host_new(drv, config, &host); +} +#endif + void host_common_free(struct host_data *hd) { dma_put(hd->dma); @@ -1004,7 +1023,7 @@ static const struct comp_driver comp_host = { .uid = SOF_RT_UUID(host_uuid), .tctx = &host_tr, .ops = { - .create = host_new, + .create = IPC3_SHIM(host_new), .free = host_free, .params = host_params, .reset = host_reset, diff --git a/src/audio/module_adapter/module_adapter_ipc3.c b/src/audio/module_adapter/module_adapter_ipc3.c index 765c3e2b82fe..b2acbe0035c7 100644 --- a/src/audio/module_adapter/module_adapter_ipc3.c +++ b/src/audio/module_adapter/module_adapter_ipc3.c @@ -39,65 +39,9 @@ int module_adapter_init_data(struct comp_dev *dev, const void *spec) { int ret; - - const unsigned char *data = NULL; - uint32_t size = 0; - - switch (config->type) { - case SOF_COMP_VOLUME: - { - const struct ipc_config_volume *ipc_volume = spec; - - size = sizeof(*ipc_volume); - data = spec; - break; - } - case SOF_COMP_SRC: - { - const struct ipc_config_src *ipc_src = spec; - - size = sizeof(*ipc_src); - data = spec; - break; - } - case SOF_COMP_ASRC: - { - const struct ipc_config_asrc *ipc_asrc = spec; - - size = sizeof(*ipc_asrc); - data = spec; - break; - } - case SOF_COMP_MIXER: - break; - case SOF_COMP_EQ_IIR: - case SOF_COMP_EQ_FIR: - case SOF_COMP_KEYWORD_DETECT: - case SOF_COMP_KPB: - case SOF_COMP_SELECTOR: - case SOF_COMP_DEMUX: - case SOF_COMP_MUX: - case SOF_COMP_DCBLOCK: - case SOF_COMP_SMART_AMP: - case SOF_COMP_MODULE_ADAPTER: - case SOF_COMP_FILEREAD: - case SOF_COMP_FILEWRITE: - case SOF_COMP_NONE: - { - const struct ipc_config_process *ipc_module_adapter = spec; - - size = ipc_module_adapter->size; - data = ipc_module_adapter->data; - break; - } - default: - comp_err(dev, "module_adapter_init_data() unsupported comp type %d", config->type); - return -EINVAL; - } - /* Copy initial config */ - if (size) { - ret = module_load_config(dev, data, size); + if (config->ipc_config_size) { + ret = module_load_config(dev, spec, config->ipc_config_size); if (ret < 0) { comp_err(dev, "module_adapter_init_data() error %d: config loading has failed.", ret); diff --git a/src/audio/smart_amp/smart_amp.c b/src/audio/smart_amp/smart_amp.c index 1b72ef4a65f8..d61601ed2317 100644 --- a/src/audio/smart_amp/smart_amp.c +++ b/src/audio/smart_amp/smart_amp.c @@ -264,6 +264,20 @@ static struct comp_dev *smart_amp_new(const struct comp_driver *drv, return NULL; } +#if CONFIG_IPC_MAJOR_3 +static struct comp_dev *smart_amp_new_shim(const struct comp_driver *drv, + const struct comp_ipc_config *config, + const void *spec) +{ + struct ipc_config_process proc; + + if (comp_sof_process_to_ipc_process(config->ipc_config_size, spec, &proc) < 0) + return NULL; + + return smart_amp_new(drv, config, &proc); +} +#endif + static int smart_amp_set_config(struct comp_dev *dev, struct sof_ipc_ctrl_data *cdata) { @@ -813,7 +827,7 @@ static const struct comp_driver comp_smart_amp = { .uid = SOF_RT_UUID(UUID_SYM), .tctx = &smart_amp_comp_tr, .ops = { - .create = smart_amp_new, + .create = IPC3_SHIM(smart_amp_new), .free = smart_amp_free, .params = smart_amp_params, .prepare = smart_amp_prepare, diff --git a/src/audio/src/src.c b/src/audio/src/src.c index d75b1eb53822..3b5135b86f7c 100644 --- a/src/audio/src/src.c +++ b/src/audio/src/src.c @@ -68,8 +68,34 @@ static int src_prepare(struct processing_module *mod, return src_prepare_general(mod, sources[0], sinks[0]); } +#if CONFIG_IPC_MAJOR_3 +static int src_init_shim(struct processing_module *mod) +{ + struct ipc_config_src *ipc_src; + struct module_data *mod_data = &mod->priv; + const struct sof_ipc_comp_src *src = + (const struct sof_ipc_comp_src *)mod_data->cfg.init_data; + + if (IPC_TAIL_IS_SIZE_INVALID(*src)) + return -EBADMSG; + + ipc_src = rballoc(0, SOF_MEM_CAPS_RAM, sizeof(*ipc_src)); + if (!ipc_src) + return -ENOMEM; + + ipc_src->source_rate = src->source_rate; + ipc_src->sink_rate = src->sink_rate; + ipc_src->rate_mask = src->rate_mask; + + rfree(mod_data->cfg.data); + mod_data->cfg.init_data = ipc_src; + mod_data->cfg.data = ipc_src; + return src_init(mod); +} +#endif + static const struct module_interface src_interface = { - .init = src_init, + .init = IPC3_SHIM(src_init), .prepare = src_prepare, .process = src_process, .is_ready_to_process = src_is_ready_to_process, diff --git a/src/audio/tone.c b/src/audio/tone.c index d289c12d5f57..340a6712d8f1 100644 --- a/src/audio/tone.c +++ b/src/audio/tone.c @@ -706,12 +706,37 @@ static int tone_reset(struct comp_dev *dev) return 0; } +#if CONFIG_IPC_MAJOR_3 +static struct comp_dev *tone_new_shim(const struct comp_driver *drv, + const struct comp_ipc_config *config, + const void *spec) +{ + struct sof_ipc_comp_tone *comp = spec; + struct ipc_config_tone tone; + + if (IPC_TAIL_IS_SIZE_INVALID(*comp)) + return NULL; + + tone.ampl_mult = comp->ampl_mult; + tone.amplitude = comp->amplitude; + tone.freq_mult = comp->freq_mult; + tone.frequency = comp->frequency; + tone.length = comp->length; + tone.period = comp->period; + tone.ramp_step = comp->ramp_step; + tone.repeats = comp->repeats; + tone.sample_rate = comp->sample_rate; + + return tone_new(drv, config, &tone); +} +#endif + static const struct comp_driver comp_tone = { .type = SOF_COMP_TONE, .uid = SOF_RT_UUID(tone_uuid), .tctx = &tone_tr, .ops = { - .create = tone_new, + .create = IPC3_SHIM(tone_new), .free = tone_free, .params = tone_params, #if CONFIG_IPC_MAJOR_3 diff --git a/src/audio/volume/volume.c b/src/audio/volume/volume.c index 9d5ad6d43e4c..590f83ba8a65 100644 --- a/src/audio/volume/volume.c +++ b/src/audio/volume/volume.c @@ -775,8 +775,36 @@ static int volume_reset(struct processing_module *mod) return 0; } +#if CONFIG_IPC_MAJOR_3 +static int volume_init_shim(struct processing_module *mod) +{ + struct ipc_config_volume *ipc_volume; + struct module_data *mod_data = &mod->priv; + const struct sof_ipc_comp_volume *volume = + (const struct sof_ipc_comp_volume *)mod_data->cfg.init_data; + + if (IPC_TAIL_IS_SIZE_INVALID(*volume)) + return -EBADMSG; + + ipc_volume = rballoc(0, SOF_MEM_CAPS_RAM, sizeof(*ipc_volume)); + if (!ipc_volume) + return -ENOMEM; + + ipc_volume->channels = volume->channels; + ipc_volume->initial_ramp = volume->initial_ramp; + ipc_volume->max_value = volume->max_value; + ipc_volume->min_value = volume->min_value; + ipc_volume->ramp = volume->ramp; + + rfree(mod_data->cfg.data); + mod_data->cfg.init_data = ipc_volume; + mod_data->cfg.data = ipc_volume; + return volume_init(mod); +} +#endif + static const struct module_interface volume_interface = { - .init = volume_init, + .init = IPC3_SHIM(volume_init), .prepare = volume_prepare, .process_audio_stream = volume_process, .set_configuration = volume_set_config, @@ -790,7 +818,7 @@ SOF_MODULE_INIT(volume, sys_comp_module_volume_interface_init); #if CONFIG_COMP_GAIN static const struct module_interface gain_interface = { - .init = volume_init, + .init = IPC3_SHIM(volume_init), .prepare = volume_prepare, .process_audio_stream = volume_process, .set_configuration = volume_set_config, diff --git a/src/include/sof/audio/component.h b/src/include/sof/audio/component.h index eff6cea7859e..e28853f014b3 100644 --- a/src/include/sof/audio/component.h +++ b/src/include/sof/audio/component.h @@ -254,6 +254,23 @@ enum { #define IPC3_SHIM(init) init #endif +/** \brief Helper to convert sof_ipc_comp_process to ipc_config_process */ +static inline int comp_sof_process_to_ipc_process(size_t size, + const struct sof_ipc_comp_process *comp, + struct ipc_config_process *proc) +{ + if (size < sizeof(*comp) + comp->size || size + comp->size > SOF_IPC_MSG_MAX_SIZE) + return -EBADMSG; + proc->type = comp->type; + proc->size = comp->size; +#if CONFIG_LIBRARY || UNIT_TEST + proc->data = comp->data + comp->ext_data_length; +#else + proc->data = comp->data; +#endif + return 0; +} + /** \brief Type of endpoint this component is connected to in a pipeline */ enum comp_endpoint_type { COMP_ENDPOINT_HOST, /**< Connected to host dma */ diff --git a/src/ipc/ipc3/helper.c b/src/ipc/ipc3/helper.c index 678d3306e4b1..8bf565f0de14 100644 --- a/src/ipc/ipc3/helper.c +++ b/src/ipc/ipc3/helper.c @@ -171,6 +171,7 @@ static void comp_common_builder(struct sof_ipc_comp *comp, config->pipeline_id = comp->pipeline_id; config->proc_domain = COMP_PROCESSING_DOMAIN_LL; config->type = comp->type; + config->ipc_config_size = comp->hdr.size; /* buffers dont have the following data */ if (comp->type != SOF_COMP_BUFFER) { @@ -182,144 +183,6 @@ static void comp_common_builder(struct sof_ipc_comp *comp, config->xrun_action = ipc_config->xrun_action; } } -/* - * Stores all the "legacy" init IPC data locally. - */ -union ipc_config_specific { - struct ipc_config_host host; - struct ipc_config_dai dai; - struct ipc_config_volume volume; - struct ipc_config_src src; - struct ipc_config_asrc asrc; - struct ipc_config_tone tone; - struct ipc_config_process process; - struct ipc_comp_file file; -} __attribute__((packed, aligned(4))); - -/* build component specific data */ -static int comp_specific_builder(struct sof_ipc_comp *comp, - union ipc_config_specific *config) -{ -#if CONFIG_LIBRARY - struct sof_ipc_comp_file *file = (struct sof_ipc_comp_file *)comp; -#endif - struct sof_ipc_comp_host *host = (struct sof_ipc_comp_host *)comp; - struct sof_ipc_comp_dai *dai = (struct sof_ipc_comp_dai *)comp; - struct sof_ipc_comp_volume *vol = (struct sof_ipc_comp_volume *)comp; - struct sof_ipc_comp_process *proc = (struct sof_ipc_comp_process *)comp; - struct sof_ipc_comp_src *src = (struct sof_ipc_comp_src *)comp; - struct sof_ipc_comp_asrc *asrc = (struct sof_ipc_comp_asrc *)comp; - struct sof_ipc_comp_tone *tone = (struct sof_ipc_comp_tone *)comp; - - memset(config, 0, sizeof(*config)); - - switch (comp->type) { -#if CONFIG_LIBRARY - /* test bench maps host and DAIs to a file */ - case SOF_COMP_FILEREAD: - case SOF_COMP_FILEWRITE: - if (IPC_TAIL_IS_SIZE_INVALID(*file)) - return -EBADMSG; - - config->file.channels = file->channels; - config->file.fn = file->fn; - config->file.frame_fmt = file->frame_fmt; - config->file.mode = file->mode; - config->file.rate = file->rate; - config->file.direction = file->direction; - - /* For module_adapter_init_data() ipc_module_adapter compatibility */ - config->file.module_header.type = proc->type; - config->file.module_header.size = proc->size; - config->file.module_header.data = (uint8_t *)proc->data - - sizeof(struct ipc_config_process); - break; -#endif - case SOF_COMP_HOST: - case SOF_COMP_SG_HOST: - if (IPC_TAIL_IS_SIZE_INVALID(*host)) - return -EBADMSG; - config->host.direction = host->direction; - config->host.no_irq = host->no_irq; - config->host.dmac_config = host->dmac_config; - break; - case SOF_COMP_DAI: - case SOF_COMP_SG_DAI: - if (IPC_TAIL_IS_SIZE_INVALID(*dai)) - return -EBADMSG; - config->dai.dai_index = dai->dai_index; - config->dai.direction = dai->direction; - config->dai.type = dai->type; - break; - case SOF_COMP_VOLUME: - if (IPC_TAIL_IS_SIZE_INVALID(*vol)) - return -EBADMSG; - config->volume.channels = vol->channels; - config->volume.initial_ramp = vol->initial_ramp; - config->volume.max_value = vol->max_value; - config->volume.min_value = vol->min_value; - config->volume.ramp = vol->ramp; - break; - case SOF_COMP_SRC: - if (IPC_TAIL_IS_SIZE_INVALID(*src)) - return -EBADMSG; - config->src.rate_mask = src->rate_mask; - config->src.sink_rate = src->sink_rate; - config->src.source_rate = src->source_rate; - break; - case SOF_COMP_TONE: - if (IPC_TAIL_IS_SIZE_INVALID(*tone)) - return -EBADMSG; - config->tone.ampl_mult = tone->ampl_mult; - config->tone.amplitude = tone->amplitude; - config->tone.freq_mult = tone->freq_mult; - config->tone.frequency = tone->frequency; - config->tone.length = tone->length; - config->tone.period = tone->period; - config->tone.ramp_step = tone->ramp_step; - config->tone.repeats = tone->repeats; - config->tone.sample_rate = tone->sample_rate; - break; - case SOF_COMP_ASRC: - if (IPC_TAIL_IS_SIZE_INVALID(*asrc)) - return -EBADMSG; - config->asrc.source_rate = asrc->source_rate; - config->asrc.sink_rate = asrc->sink_rate; - config->asrc.asynchronous_mode = asrc->asynchronous_mode; - config->asrc.operation_mode = asrc->operation_mode; - break; - case SOF_COMP_EQ_IIR: - case SOF_COMP_EQ_FIR: - case SOF_COMP_KEYWORD_DETECT: - case SOF_COMP_KPB: - case SOF_COMP_SELECTOR: - case SOF_COMP_DEMUX: - case SOF_COMP_MUX: - case SOF_COMP_DCBLOCK: - case SOF_COMP_SMART_AMP: - case SOF_COMP_MODULE_ADAPTER: - case SOF_COMP_NONE: - if (IPC_TAIL_IS_SIZE_INVALID(*proc)) - return -EBADMSG; - - if (proc->comp.hdr.size + proc->size > SOF_IPC_MSG_MAX_SIZE) - return -EBADMSG; - - config->process.type = proc->type; - config->process.size = proc->size; -#if CONFIG_LIBRARY || UNIT_TEST - config->process.data = proc->data + comp->ext_data_length; -#else - config->process.data = proc->data; -#endif - break; - case SOF_COMP_MIXER: - break; - default: - return -EINVAL; - } - return 0; -} struct ipc_comp_dev *ipc_get_comp_by_ppl_id(struct ipc *ipc, uint16_t type, uint32_t ppl_id, @@ -343,7 +206,6 @@ struct ipc_comp_dev *ipc_get_comp_by_ppl_id(struct ipc *ipc, struct comp_dev *comp_new(struct sof_ipc_comp *comp) { struct comp_ipc_config config; - union ipc_config_specific spec; struct comp_dev *cdev; const struct comp_driver *drv; @@ -361,13 +223,8 @@ struct comp_dev *comp_new(struct sof_ipc_comp *comp) tr_info(&comp_tr, "comp new %pU type %d id %d.%d", drv->tctx->uuid_p, comp->type, comp->pipeline_id, comp->id); - /* build the component */ - if (comp_specific_builder(comp, &spec) < 0) { - comp_cl_err(drv, "comp_new(): component type not recognized"); - return NULL; - } comp_common_builder(comp, &config); - cdev = drv->ops.create(drv, &config, &spec); + cdev = drv->ops.create(drv, &config, comp); if (!cdev) { comp_cl_err(drv, "comp_new(): unable to create the new component"); return NULL; diff --git a/tools/testbench/file.c b/tools/testbench/file.c index 21243f8629b0..a627530bfe29 100644 --- a/tools/testbench/file.c +++ b/tools/testbench/file.c @@ -701,6 +701,33 @@ static int file_init(struct processing_module *mod) return -EINVAL; } +#if CONFIG_IPC_MAJOR_3 +static int file_init_shim(struct processing_module *mod) +{ + struct ipc_config_file *ipc_file; + struct module_data *mod_data = &mod->priv; + const struct sof_ipc_comp_file *file = + (const struct sof_ipc_comp_file *)mod_data->cfg.init_data; + + if (IPC_TAIL_IS_SIZE_INVALID(*file)) + return -EBADMSG; + + ipc_file = rballoc(0, SOF_MEM_CAPS_RAM, sizeof(*ipc_file)); + if (!ipc_file) + return -ENOMEM; + + ipc_file->channels = file->channels; + ipc_asrc->sink_rate = asrc->sink_rate; + ipc_asrc->asrc_get_asynchronous_mode = asrc->asrc_verify_params; + ipc_asrc->operation_mode = asrc->operation_mode; + + rfree(mod_data->cfg.init_data); + mod_data->cfg.init_data = ipc_asrc; + mod_data->cfg.data = ipc_asrc; + return asrc_init(mod); +} +#endif + static int file_free(struct processing_module *mod) { struct copier_data *ccd = module_get_private_data(mod); @@ -873,7 +900,7 @@ static struct module_endpoint_ops file_endpoint_ops = { }; static const struct module_interface file_interface = { - .init = file_init, + .init = IPC3_SHIM(file_init), .prepare = file_prepare, .process_audio_stream = file_process, .reset = file_reset,