From b016c9b11ac2f5fc0f6e577068dcb8e5a5fe61dc Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Thu, 3 Oct 2024 15:37:07 -0700 Subject: [PATCH] WIP: Example code for downstream type conversion ONLY COMPILE/FUZZ TESTED Given we cannot trust our enum field in the IPC as communicator may lie about the component on the other side and the module adapter is obscuring the nature of many of the components we need to move the type casting into the components directly. Here is a breakdown of the general steps to achieve this. 1. report ipc config size for all versions 2. remove type casting in the IPC3 layer 3. on non module adapter components cast the config in a compile time selected shim 4. in the module adapter ipc3 layer, remove type casting again 5. in module adapter components realloc init data and cast over in a compile time enabled shim Signed-off-by: Curtis Malainey --- src/audio/asrc/asrc.c | 29 +++- src/audio/dai-legacy.c | 21 ++- src/audio/dai-zephyr.c | 21 ++- src/audio/host-legacy.c | 21 ++- .../module_adapter/module_adapter_ipc3.c | 69 +------- src/audio/smart_amp/smart_amp.c | 16 +- src/audio/src/src.c | 28 +++- src/audio/tone.c | 27 +++- src/audio/volume/volume.c | 31 +++- src/include/module/module/base.h | 26 ++++ src/include/sof/audio/component.h | 17 ++ src/ipc/ipc3/helper.c | 147 +----------------- tools/testbench/file.c | 32 +++- 13 files changed, 263 insertions(+), 222 deletions(-) diff --git a/src/audio/asrc/asrc.c b/src/audio/asrc/asrc.c index 055fdab8dfa1..934b21271288 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..54d481ae6a8b 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) +{ + 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) { 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..9a2fc66aff93 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..54eb5fa70987 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) +{ + const 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..acf31a99f7cb 100644 --- a/src/audio/module_adapter/module_adapter_ipc3.c +++ b/src/audio/module_adapter/module_adapter_ipc3.c @@ -38,73 +38,8 @@ int module_adapter_init_data(struct comp_dev *dev, const struct comp_ipc_config *config, 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 (ret < 0) { - comp_err(dev, "module_adapter_init_data() error %d: config loading has failed.", - ret); - return ret; - } - dst->init_data = dst->data; - } + // Downstream shim will copy and alloc the correct data + dst->init_data = dst->data; return 0; } diff --git a/src/audio/smart_amp/smart_amp.c b/src/audio/smart_amp/smart_amp.c index 1b72ef4a65f8..e74fe0fc0d72 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(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..1be74b53e2bb 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..0ca70091a001 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) +{ + const 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..866a1d7b1627 100644 --- a/src/audio/volume/volume.c +++ b/src/audio/volume/volume.c @@ -775,8 +775,35 @@ 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; + + 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 +817,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/module/module/base.h b/src/include/module/module/base.h index d3f912957791..d6c42d2856dd 100644 --- a/src/include/module/module/base.h +++ b/src/include/module/module/base.h @@ -180,4 +180,30 @@ struct processing_module { #endif /* SOF_MODULE_PRIVATE */ }; +/** \brief Helper to convert sof_ipc_comp_process to ipc_config_process in modules */ +static inline int mod_sof_process_to_ipc_process(struct processing_module *mod) +{ + struct ipc_config_process *proc; + struct module_data *mod_data = &mod->priv; + const struct sof_ipc_comp_process *comp = + (const struct sof_ipc_comp_process *)mod_data->cfg.init_data; + + if (comp->comp.hdr.size < sizeof(*comp) || + comp->comp.hdr.size + comp->size > SOF_IPC_MSG_MAX_SIZE) + return -EBADMSG; + + proc = rballoc(0, SOF_MEM_CAPS_RAM, sizeof(*proc) + comp->size); + if (!proc) + return -ENOMEM; + + memcpy_s(proc + 1, comp->size, comp->data, comp->size); + + proc->type = comp->type; + proc->size = comp->size; + proc->data = (uint8_t *)(proc + 1); + mod_data->cfg.init_data = proc; + mod_data->cfg.data = proc; + return 0; +} + #endif /* __MODULE_MODULE_BASE__ */ diff --git a/src/include/sof/audio/component.h b/src/include/sof/audio/component.h index eff6cea7859e..9febf339f570 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 in components */ +static inline int comp_sof_process_to_ipc_process(const struct sof_ipc_comp_process *comp, + struct ipc_config_process *proc) +{ + if (comp->comp.hdr.size < sizeof(*comp) || + comp->comp.hdr.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->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..66b3b4886ed4 100644 --- a/tools/testbench/file.c +++ b/tools/testbench/file.c @@ -701,6 +701,36 @@ 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_comp_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; + + // TODO fix for bespoke data + ipc_file = rballoc(0, SOF_MEM_CAPS_RAM, sizeof(*ipc_file)); + if (!ipc_file) + return -ENOMEM; + + ipc_file->channels = file->channels; + ipc_file->fn = file->fn; + ipc_file->frame_fmt = file->frame_fmt; + ipc_file->mode = file->mode; + ipc_file->rate = file->rate; + ipc_file->direction = file->direction; + + rfree(mod_data->cfg.init_data); + mod_data->cfg.init_data = ipc_file; + mod_data->cfg.data = ipc_file; + return file_init(mod); +} +#endif + static int file_free(struct processing_module *mod) { struct copier_data *ccd = module_get_private_data(mod); @@ -873,7 +903,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,