diff --git a/src/ipc/ipc4/handler.c b/src/ipc/ipc4/handler.c index 3e9b5d1b4472..96ddd1eca235 100644 --- a/src/ipc/ipc4/handler.c +++ b/src/ipc/ipc4/handler.c @@ -1064,13 +1064,6 @@ static int ipc4_get_large_config_module_instance(struct ipc4_message_request *ip tr_dbg(&ipc_tr, "ipc4_get_large_config_module_instance %x : %x", (uint32_t)config.primary.r.module_id, (uint32_t)config.primary.r.instance_id); - drv = ipc4_get_comp_drv(config.primary.r.module_id); - if (!drv) - return IPC4_MOD_INVALID_ID; - - if (!drv->ops.get_large_config) - return IPC4_INVALID_REQUEST; - /* get component dev for non-basefw since there is no * component dev for basefw */ @@ -1083,11 +1076,21 @@ static int ipc4_get_large_config_module_instance(struct ipc4_message_request *ip if (!dev) return IPC4_MOD_INVALID_ID; + drv = dev->drv; + /* Pass IPC to target core */ if (!cpu_is_me(dev->ipc_config.core)) return ipc4_process_on_core(dev->ipc_config.core, false); + } else { + drv = ipc4_get_comp_drv(config.primary.r.module_id); } + if (!drv) + return IPC4_MOD_INVALID_ID; + + if (!drv->ops.get_large_config) + return IPC4_INVALID_REQUEST; + data_offset = config.extension.r.data_off_size; /* check for vendor param first */ @@ -1222,13 +1225,6 @@ static int ipc4_set_large_config_module_instance(struct ipc4_message_request *ip tr_dbg(&ipc_tr, "ipc4_set_large_config_module_instance %x : %x", (uint32_t)config.primary.r.module_id, (uint32_t)config.primary.r.instance_id); - drv = ipc4_get_comp_drv(config.primary.r.module_id); - if (!drv) - return IPC4_MOD_INVALID_ID; - - if (!drv->ops.set_large_config) - return IPC4_INVALID_REQUEST; - if (config.primary.r.module_id) { uint32_t comp_id; @@ -1237,11 +1233,21 @@ static int ipc4_set_large_config_module_instance(struct ipc4_message_request *ip if (!dev) return IPC4_MOD_INVALID_ID; + drv = dev->drv; + /* Pass IPC to target core */ if (!cpu_is_me(dev->ipc_config.core)) return ipc4_process_on_core(dev->ipc_config.core, false); + } else { + drv = ipc4_get_comp_drv(config.primary.r.module_id); } + if (!drv) + return IPC4_MOD_INVALID_ID; + + if (!drv->ops.set_large_config) + return IPC4_INVALID_REQUEST; + /* check for vendor param first */ if (config.extension.r.large_param_id == VENDOR_CONFIG_PARAM) { ret = ipc4_set_vendor_config_module_instance(dev, drv, diff --git a/src/ipc/ipc4/helper.c b/src/ipc/ipc4/helper.c index 609d9abc1022..e2932bfef774 100644 --- a/src/ipc/ipc4/helper.c +++ b/src/ipc/ipc4/helper.c @@ -90,6 +90,11 @@ static inline char *ipc4_get_comp_new_data(void) return data; } + +static const struct comp_driver *ipc4_library_get_comp_drv(char *data) +{ + return ipc4_get_drv((const uint8_t *)data); +} #else static inline char *ipc4_get_comp_new_data(void) { @@ -107,9 +112,6 @@ struct comp_dev *comp_new_ipc4(struct ipc4_module_init_instance *module_init) comp_id = IPC4_COMP_ID(module_init->primary.r.module_id, module_init->primary.r.instance_id); - drv = ipc4_get_comp_drv(IPC4_MOD_ID(comp_id)); - if (!drv) - return NULL; if (ipc4_get_comp_dev(comp_id)) { tr_err(&ipc_tr, "comp 0x%x exists", comp_id); @@ -127,6 +129,20 @@ struct comp_dev *comp_new_ipc4(struct ipc4_module_init_instance *module_init) ipc_config.core = module_init->extension.r.core_id; ipc_config.ipc_config_size = module_init->extension.r.param_block_size * sizeof(uint32_t); + dcache_invalidate_region((__sparse_force void __sparse_cache *)MAILBOX_HOSTBOX_BASE, + MAILBOX_HOSTBOX_SIZE); + + data = ipc4_get_comp_new_data(); + +#if CONFIG_LIBRARY + ipc_config.ipc_config_size -= sizeof(struct sof_uuid); + drv = ipc4_library_get_comp_drv(data + ipc_config.ipc_config_size); +#else + drv = ipc4_get_comp_drv(IPC4_MOD_ID(comp_id)); +#endif + if (!drv) + return NULL; + #if CONFIG_ZEPHYR_DP_SCHEDULER if (module_init->extension.r.proc_domain) ipc_config.proc_domain = COMP_PROCESSING_DOMAIN_DP; @@ -140,15 +156,10 @@ struct comp_dev *comp_new_ipc4(struct ipc4_module_init_instance *module_init) ipc_config.proc_domain = COMP_PROCESSING_DOMAIN_LL; #endif /* CONFIG_ZEPHYR_DP_SCHEDULER */ - dcache_invalidate_region((__sparse_force void __sparse_cache *)MAILBOX_HOSTBOX_BASE, - MAILBOX_HOSTBOX_SIZE); - - data = ipc4_get_comp_new_data(); if (drv->type == SOF_COMP_MODULE_ADAPTER) { const struct ipc_config_process spec = { .data = (const unsigned char *)data, - /* spec_size in IPC4 is in DW. Convert to bytes. */ - .size = module_init->extension.r.param_block_size * sizeof(uint32_t), + .size = ipc_config.ipc_config_size, }; dev = drv->ops.create(drv, &ipc_config, (const void *)&spec); @@ -936,59 +947,6 @@ const struct comp_driver *ipc4_get_drv(const uint8_t *uuid) return drv; } -#if CONFIG_LIBRARY -struct ipc4_module_uuid { - int module_id; - struct sof_uuid uuid; -}; - -/* Hardcoded table mapping UUIDs with module ID's. TODO: replace this with a scalable solution */ -static const struct ipc4_module_uuid uuid_map[] = { - {0x6, {.a = 0x61bca9a8, .b = 0x18d0, .c = 0x4a18, - .d = { 0x8e, 0x7b, 0x26, 0x39, 0x21, 0x98, 0x04, 0xb7 }}}, /* gain */ - {0x2, {.a = 0x39656eb2, .b = 0x3b71, .c = 0x4049, - .d = { 0x8d, 0x3f, 0xf9, 0x2c, 0xd5, 0xc4, 0x3c, 0x09 }}}, /* mixin */ - {0x3, {.a = 0x3c56505a, .b = 0x24d7, .c = 0x418f, - .d = { 0xbd, 0xdc, 0xc1, 0xf5, 0xa3, 0xac, 0x2a, 0xe0 }}}, /* mixout */ - {0x95, {.a = 0x7ae671a7, .b = 0x4617, .c = 0x4a09, - .d = { 0xbf, 0x6d, 0x9d, 0x29, 0xc9, 0x98, 0xdb, 0xc1 }}}, /* noise suppresion */ - {0x96, {.a = 0xe2b6031c, .b = 0x47e8, .c = 0x11ed, - .d = { 0x07, 0xa9, 0x7f, 0x80, 0x1b, 0x6e, 0xfa, 0x6c }}}, /* host SHM write */ - {0x98, {.a = 0xdabe8814, .b = 0x47e8, .c = 0x11ed, - .d = { 0xa5, 0x8b, 0xb3, 0x09, 0x97, 0x4f, 0xec, 0xce }}}, /* host SHM read */ - {0x97, {.a = 0x72cee996, .b = 0x39f2, .c = 0x11ed, - .d = { 0xa0, 0x8f, 0x97, 0xfc, 0xc4, 0x2e, 0xaa, 0xeb }}}, /* ALSA aplay */ - {0x99, {.a = 0x66def9f0, .b = 0x39f2, .c = 0x11ed, - .d = { 0xf7, 0x89, 0xaf, 0x98, 0xa6, 0x44, 0x0c, 0xc4 }}}, /* ALSA arecord */ - {0x9a, {.a = 0xbfc7488c, .b = 0x75aa, .c = 0x4ce8, - .d = { 0x9d, 0xbe, 0xd8, 0xda, 0x08, 0xa6, 0x98, 0xc2 }}}, /* file read aif */ - {0x9b, {.a = 0xbfc7488c, .b = 0x75aa, .c = 0x4ce8, - .d = { 0x9d, 0xbe, 0xd8, 0xda, 0x08, 0xa6, 0x98, 0xc2 }}}, /* file write aif */ - {0x9c, {.a = 0xbfc7488c, .b = 0x75aa, .c = 0x4ce8, - .d = { 0x9d, 0xbe, 0xd8, 0xda, 0x08, 0xa6, 0x98, 0xc2 }}}, /* file read dai */ - {0x9d, {.a = 0xbfc7488c, .b = 0x75aa, .c = 0x4ce8, - .d = { 0x9d, 0xbe, 0xd8, 0xda, 0x08, 0xa6, 0x98, 0xc2 }}}, /* file write dai */ - {0x9e, {.a = 0xb809efaf, .b = 0x5681, .c = 0x42b1, - .d = { 0x9e, 0xd6, 0x04, 0xbb, 0x01, 0x2d, 0xd3, 0x84 }}}, /* process: dcblock */ -}; - -static const struct comp_driver *ipc4_library_get_drv(int module_id) -{ - const struct ipc4_module_uuid *mod_uuid; - int i; - - for (i = 0; i < ARRAY_SIZE(uuid_map); i++) { - mod_uuid = &uuid_map[i]; - - if (mod_uuid->module_id == module_id) - return ipc4_get_drv((const uint8_t *)&mod_uuid->uuid); - } - - tr_err(&comp_tr, "ipc4_library_get_drv(): Unsupported module ID %#x\n", module_id); - return NULL; -} -#endif - const struct comp_driver *ipc4_get_comp_drv(uint32_t module_id) { const struct sof_man_fw_desc *desc = NULL; @@ -996,10 +954,6 @@ const struct comp_driver *ipc4_get_comp_drv(uint32_t module_id) const struct sof_man_module *mod; uint32_t entry_index; -#if CONFIG_LIBRARY - return ipc4_library_get_drv(module_id); -#endif - #ifdef RIMAGE_MANIFEST desc = (const struct sof_man_fw_desc *)IMR_BOOT_LDR_MANIFEST_BASE; #else diff --git a/tools/plugin/alsaplug/tplg.c b/tools/plugin/alsaplug/tplg.c index f8f229f563d3..cbd8ba0cddf1 100644 --- a/tools/plugin/alsaplug/tplg.c +++ b/tools/plugin/alsaplug/tplg.c @@ -101,20 +101,30 @@ static int plug_aif_in_out(snd_sof_plug_t *plug, int dir) if (ret < 0) return ret; - comp_info->ipc_payload = calloc(sizeof(struct ipc4_base_module_cfg), 1); + comp_info->ipc_size = sizeof(struct ipc4_base_module_cfg) + sizeof(struct sof_uuid); + comp_info->ipc_payload = calloc(comp_info->ipc_size, 1); if (!comp_info->ipc_payload) return -ENOMEM; - comp_info->ipc_size = sizeof(struct ipc4_base_module_cfg); - + /* overwrite the topology UUIDs with the SHM module UUID for the host components */ if (dir == SOF_IPC_STREAM_PLAYBACK) { + struct sof_uuid uuid = {.a = 0xe2b6031c, .b = 0x47e8, .c = 0x11ed, + .d = { 0x07, 0xa9, 0x7f, 0x80, 0x1b, 0x6e, 0xfa, 0x6c }}; comp_info->module_id = 0x96; plug_setup_widget_ipc_msg(comp_info); + comp_info->uuid = uuid; } else { + struct sof_uuid uuid = {.a = 0xdabe8814, .b = 0x47e8, .c = 0x11ed, + .d = { 0xa5, 0x8b, 0xb3, 0x09, 0x97, 0x4f, 0xec, 0xce }}; comp_info->module_id = 0x98; plug_setup_widget_ipc_msg(comp_info); + comp_info->uuid = uuid; } + /* copy uuid to the end of the payload */ + memcpy(comp_info->ipc_payload + sizeof(struct ipc4_base_module_cfg), &comp_info->uuid, + sizeof(struct sof_uuid)); + return 0; } @@ -128,20 +138,32 @@ static int plug_dai_in_out(snd_sof_plug_t *plug, int dir) if (ret < 0) return ret; - comp_info->ipc_payload = calloc(sizeof(struct ipc4_base_module_cfg), 1); + comp_info->ipc_size = sizeof(struct ipc4_base_module_cfg) + sizeof(struct sof_uuid); + comp_info->ipc_payload = calloc(comp_info->ipc_size, 1); if (!comp_info->ipc_payload) return -ENOMEM; - comp_info->ipc_size = sizeof(struct ipc4_base_module_cfg); - + /* overwrite the topology UUIDs with the ALSA module UUID for the DAI components */ if (dir == SOF_IPC_STREAM_PLAYBACK) { + struct sof_uuid uuid = {.a = 0x72cee996, .b = 0x39f2, .c = 0x11ed, + .d = { 0xa0, 0x8f, 0x97, 0xfc, 0xc4, 0x2e, 0xaa, 0xeb }}; + comp_info->module_id = 0x97; plug_setup_widget_ipc_msg(comp_info); + comp_info->uuid = uuid; } else { + struct sof_uuid uuid = {.a = 0x66def9f0, .b = 0x39f2, .c = 0x11ed, + .d = { 0xf7, 0x89, 0xaf, 0x98, 0xa6, 0x44, 0x0c, 0xc4 }}; + comp_info->module_id = 0x99; plug_setup_widget_ipc_msg(comp_info); + comp_info->uuid = uuid; } + /* copy uuid to the end of the payload */ + memcpy(comp_info->ipc_payload + sizeof(struct ipc4_base_module_cfg), &comp_info->uuid, + sizeof(struct sof_uuid)); + return 0; } @@ -210,7 +232,7 @@ static int plug_new_mixer(snd_sof_plug_t *plug) return -ENOMEM; comp_info->instance_id = plug->instance_ids[SND_SOC_TPLG_DAPM_MIXER]++; - comp_info->ipc_size = sizeof(struct ipc4_base_module_cfg); + comp_info->ipc_size = sizeof(struct ipc4_base_module_cfg) + sizeof(struct sof_uuid); comp_info->ipc_payload = calloc(comp_info->ipc_size, 1); if (!comp_info->ipc_payload) return -ENOMEM; @@ -229,6 +251,10 @@ static int plug_new_mixer(snd_sof_plug_t *plug) comp_info->module_id = 0x3; plug_setup_widget_ipc_msg(comp_info); } + + /* copy uuid to the end of the payload */ + memcpy(comp_info->ipc_payload + sizeof(struct ipc4_base_module_cfg), &comp_info->uuid, + sizeof(struct sof_uuid)); out: free(tplg_ctl); return ret; @@ -240,10 +266,13 @@ static int plug_new_pga(snd_sof_plug_t *plug) struct tplg_comp_info *comp_info = ctx->current_comp_info; struct ipc4_peak_volume_config volume; struct snd_soc_tplg_ctl_hdr *tplg_ctl; + uint32_t uuid_offset; int ret; - comp_info->ipc_size = - sizeof(struct ipc4_peak_volume_config) + sizeof(struct ipc4_base_module_cfg); + comp_info->ipc_size = sizeof(struct ipc4_peak_volume_config); + comp_info->ipc_size += sizeof(struct ipc4_base_module_cfg); + uuid_offset = comp_info->ipc_size; + comp_info->ipc_size += sizeof(struct sof_uuid); comp_info->ipc_payload = calloc(comp_info->ipc_size, 1); if (!comp_info->ipc_payload) return -ENOMEM; @@ -269,6 +298,9 @@ static int plug_new_pga(snd_sof_plug_t *plug) memcpy(comp_info->ipc_payload + sizeof(struct ipc4_base_module_cfg), &volume, sizeof(struct ipc4_peak_volume_config)); + /* copy uuid to the end of the payload */ + memcpy(comp_info->ipc_payload + uuid_offset, &comp_info->uuid, sizeof(struct sof_uuid)); + /* skip kcontrols for now */ if (tplg_create_controls(ctx, ctx->widget->num_kcontrols, tplg_ctl, ctx->hdr->payload_size, comp_info) < 0) { @@ -302,7 +334,7 @@ static int plug_new_process(snd_sof_plug_t *plug) return ret; /* only base config supported for now. extn support will be added later */ - comp_info->ipc_size = sizeof(struct ipc4_base_module_cfg); + comp_info->ipc_size = sizeof(struct ipc4_base_module_cfg) + sizeof(struct sof_uuid); comp_info->ipc_payload = calloc(comp_info->ipc_size, 1); if (!comp_info->ipc_payload) return -ENOMEM; @@ -319,6 +351,10 @@ static int plug_new_process(snd_sof_plug_t *plug) return -ENOMEM; } + /* copy uuid to the end of the payload */ + memcpy(comp_info->ipc_payload + sizeof(struct ipc4_base_module_cfg), &comp_info->uuid, + sizeof(struct sof_uuid)); + /* set up kcontrols */ ret = tplg_create_controls(ctx, ctx->widget->num_kcontrols, tplg_ctl, ctx->hdr->payload_size, comp_info);