From 0eb04fe2a3d833b1c1122757ec187042a03f8cf5 Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Wed, 2 Oct 2024 16:34:34 -0700 Subject: [PATCH 1/4] component: add macro to toggle shims by IPC type Add helper to switch out init calls to shim in conversion functions if needed. Signed-off-by: Curtis Malainey --- src/include/sof/audio/component.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/include/sof/audio/component.h b/src/include/sof/audio/component.h index 483a32439e56..654608ded32a 100644 --- a/src/include/sof/audio/component.h +++ b/src/include/sof/audio/component.h @@ -247,6 +247,13 @@ enum { /** @}*/ +/** \brief Helper macro for IPC3 init shims */ +#ifdef CONFIG_IPC_MAJOR_3 + #define IPC3_SHIM(init) init##_shim +#else + #define IPC3_SHIM(init) init +#endif + /** \brief Type of endpoint this component is connected to in a pipeline */ enum comp_endpoint_type { COMP_ENDPOINT_HOST, /**< Connected to host dma */ From 1905971eba29fc2c0a436e63417881cd47cd7e03 Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Thu, 10 Oct 2024 14:22:02 -0700 Subject: [PATCH 2/4] cmocka: update create to use standard alloc flow gotta test all the standard flows Signed-off-by: Curtis Malainey --- test/cmocka/src/audio/mixer/comp_mock.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/cmocka/src/audio/mixer/comp_mock.c b/test/cmocka/src/audio/mixer/comp_mock.c index 5a3f22d6131e..3016c6b86afc 100644 --- a/test/cmocka/src/audio/mixer/comp_mock.c +++ b/test/cmocka/src/audio/mixer/comp_mock.c @@ -22,9 +22,8 @@ static struct comp_dev *mock_comp_new(const struct comp_driver *drv, const struct comp_ipc_config *config, const void *spec) { - struct comp_dev *dev = calloc(1, sizeof(struct comp_dev)); + struct comp_dev *dev = comp_alloc(drv, sizeof(*dev)); - dev->drv = drv; return dev; } From cae1175f4b04e8c6a5c21a4ad1a0d6510ed32a40 Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Thu, 10 Oct 2024 14:35:40 -0700 Subject: [PATCH 3/4] audio: google: constify ops drivers Never gonna give you up Never gonna let you down Never gonna run around and modify you Signed-off-by: Curtis Malainey --- src/audio/google/google_ctc_audio_processing.c | 2 +- src/audio/google/google_rtc_audio_processing.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/audio/google/google_ctc_audio_processing.c b/src/audio/google/google_ctc_audio_processing.c index e746d14480cd..12ecac66f8a7 100644 --- a/src/audio/google/google_ctc_audio_processing.c +++ b/src/audio/google/google_ctc_audio_processing.c @@ -444,7 +444,7 @@ static int ctc_process(struct processing_module *mod, return 0; } -static struct module_interface google_ctc_audio_processing_interface = { +static const struct module_interface google_ctc_audio_processing_interface = { .init = ctc_init, .free = ctc_free, .process_audio_stream = ctc_process, diff --git a/src/audio/google/google_rtc_audio_processing.c b/src/audio/google/google_rtc_audio_processing.c index 78354123b1ec..c84cadb4c5c8 100644 --- a/src/audio/google/google_rtc_audio_processing.c +++ b/src/audio/google/google_rtc_audio_processing.c @@ -838,7 +838,7 @@ static int mod_process(struct processing_module *mod, struct sof_source **source return 0; } -static struct module_interface google_rtc_audio_processing_interface = { +static const struct module_interface google_rtc_audio_processing_interface = { .init = google_rtc_audio_processing_init, .free = google_rtc_audio_processing_free, .process = mod_process, From 2566518b346373a5193816a9f3cbe2f77f9ac196 Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Thu, 3 Oct 2024 15:37:07 -0700 Subject: [PATCH 4/4] 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 ++- src/audio/host-zephyr.c | 18 ++- src/audio/kpb.c | 16 +- .../module_adapter/module_adapter_ipc3.c | 69 +-------- src/audio/selector/selector.c | 14 ++ 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 | 146 +----------------- src/samples/audio/detect_test.c | 16 +- src/samples/audio/smart_amp_test_ipc3.c | 16 +- tools/plugin/modules/shm.c | 18 ++- tools/testbench/file.c | 32 +++- 19 files changed, 354 insertions(+), 228 deletions(-) diff --git a/src/audio/asrc/asrc.c b/src/audio/asrc/asrc.c index 45a0acc81bfb..24112a2b3ff0 100644 --- a/src/audio/asrc/asrc.c +++ b/src/audio/asrc/asrc.c @@ -859,8 +859,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 5065c3f21ca1..dc561b71fcc1 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 58499b8a699f..45c3307b12db 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 e8d62e17301d..c65448885d68 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/host-zephyr.c b/src/audio/host-zephyr.c index 6addb947f7c0..6dc514a6f5b7 100644 --- a/src/audio/host-zephyr.c +++ b/src/audio/host-zephyr.c @@ -676,6 +676,22 @@ 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; + + 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); @@ -1150,7 +1166,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/kpb.c b/src/audio/kpb.c index 2141cc8ac1d5..8e1d3ff6eb22 100644 --- a/src/audio/kpb.c +++ b/src/audio/kpb.c @@ -525,6 +525,20 @@ static struct comp_dev *kpb_new(const struct comp_driver *drv, return dev; } +#if CONFIG_IPC_MAJOR_3 +static struct comp_dev *kpb_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 kpb_new(drv, config, &proc); +} +#endif + /** * \brief Allocate history buffer. * \param[in] kpb - KPB component data pointer. @@ -2591,7 +2605,7 @@ static const struct comp_driver comp_kpb = { .uid = SOF_RT_UUID(KPB_UUID), .tctx = &kpb_tr, .ops = { - .create = kpb_new, + .create = IPC3_SHIM(kpb_new), .free = kpb_free, .trigger = kpb_trigger, .copy = kpb_copy, 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/selector/selector.c b/src/audio/selector/selector.c index 8032a3d7dea9..714039f62cf4 100644 --- a/src/audio/selector/selector.c +++ b/src/audio/selector/selector.c @@ -181,6 +181,20 @@ static struct comp_dev *selector_new(const struct comp_driver *drv, return dev; } +#if CONFIG_IPC_MAJOR_3 +static struct comp_dev *selector_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 selector_new(drv, config, &proc); +} +#endif + /** * \brief Frees selector component. * \param[in,out] dev Selector base component device. 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 c07be0302b8c..fac8c2aba3a3 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 ed0bbc99dec1..e1f33fe3f83e 100644 --- a/src/audio/volume/volume.c +++ b/src/audio/volume/volume.c @@ -774,8 +774,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, @@ -789,7 +816,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 654608ded32a..de25e507073f 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..2d209a1ce910 100644 --- a/src/ipc/ipc3/helper.c +++ b/src/ipc/ipc3/helper.c @@ -182,144 +182,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 +205,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 +222,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/src/samples/audio/detect_test.c b/src/samples/audio/detect_test.c index 0b7d12d8914c..625c80ba48e1 100644 --- a/src/samples/audio/detect_test.c +++ b/src/samples/audio/detect_test.c @@ -780,6 +780,20 @@ static void test_keyword_free(struct comp_dev *dev) rfree(dev); } +#if CONFIG_IPC_MAJOR_3 +static struct comp_dev *test_keyword_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 test_keyword_new(drv, config, &proc) +} +#endif + static int test_keyword_verify_params(struct comp_dev *dev, struct sof_ipc_stream_params *params) { @@ -1066,7 +1080,7 @@ static const struct comp_driver comp_keyword = { .uid = SOF_RT_UUID(keyword_uuid), .tctx = &keyword_tr, .ops = { - .create = test_keyword_new, + .create = IPC3_SHIM(test_keyword_new), .free = test_keyword_free, .params = test_keyword_params, #if CONFIG_IPC_MAJOR_4 diff --git a/src/samples/audio/smart_amp_test_ipc3.c b/src/samples/audio/smart_amp_test_ipc3.c index 289b8a36e126..3b0ed7488bba 100644 --- a/src/samples/audio/smart_amp_test_ipc3.c +++ b/src/samples/audio/smart_amp_test_ipc3.c @@ -92,6 +92,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 void smart_amp_set_params(struct comp_dev *dev, struct sof_ipc_stream_params *params) { @@ -534,7 +548,7 @@ static const struct comp_driver comp_smart_amp = { .uid = SOF_RT_UUID(smart_amp_test_uuid), .tctx = &smart_amp_test_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/tools/plugin/modules/shm.c b/tools/plugin/modules/shm.c index 63f9e002e0d2..c7d4f2be4303 100644 --- a/tools/plugin/modules/shm.c +++ b/tools/plugin/modules/shm.c @@ -137,18 +137,32 @@ static struct comp_dev *shm_new(const struct comp_driver *drv, return NULL; } +#if CONFIG_IPC_MAJOR_3 +static struct comp_dev *shm_new_shim(const struct comp_driver *drv, + const struct comp_ipc_config *config, + const void *spec, int direction) +{ + struct ipc_config_process proc; + + if (comp_sof_process_to_ipc_process(spec, &proc) < 0) + return NULL; + + return shm_new(drv, config, &proc); +} +#endif + static struct comp_dev *shmwrite_new(const struct comp_driver *drv, const struct comp_ipc_config *config, const void *spec) { - return shm_new(drv, config, spec, SOF_IPC_STREAM_PLAYBACK); + return IPC3_SHIM(shm_new)(drv, config, spec, SOF_IPC_STREAM_PLAYBACK); } static struct comp_dev *shmread_new(const struct comp_driver *drv, const struct comp_ipc_config *config, const void *spec) { - return shm_new(drv, config, spec, SOF_IPC_STREAM_CAPTURE); + return IPC3_SHIM(shm_new)(drv, config, spec, SOF_IPC_STREAM_CAPTURE); } /** 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,