From 6f7b0f964df3f9423a6491ce45543eb4fecf4270 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 5 Jun 2025 20:53:12 +0300 Subject: [PATCH 1/6] ipc4: Extend struct ipc4_module_init_ext_init with object array Adds definition, enums, and bits for adding array of struct ipc4_module_init_ext_object:s with associated data to struct ipc4_module_init_ext_init payload. Also adds struct ipc4_module_init_ext_obj_dp_data as an object to be sent as an object in the array. Signed-off-by: Jyri Sarha --- src/include/ipc4/module.h | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/include/ipc4/module.h b/src/include/ipc4/module.h index f38621ead52c..a73ede0b0bd5 100644 --- a/src/include/ipc4/module.h +++ b/src/include/ipc4/module.h @@ -73,6 +73,28 @@ struct ipc4_vendor_error { uint32_t err_code; }; +/* IDs for all global object types in struct ipc4_module_init_ext_object */ +enum ipc4_mod_init_data_glb_id { + IPC4_MOD_INIT_DATA_ID_INVALID = 0, + IPC4_MOD_INIT_DATA_ID_DP_DATA = 1, + IPC4_MOD_INIT_DATA_ID_MAX = IPC4_MOD_INIT_DATA_ID_DP_DATA, +}; + +/* data object for vendor bespoke data with ABI growth and backwards compat */ +struct ipc4_module_init_ext_object { + uint32_t last_object : 1; /* object is last in array if 1 else object follows. */ + uint32_t object_id : 15; /* unique ID for this object or globally */ + uint32_t object_words : 16; /* size in dwords (excluding this structure) */ +} __attribute__((packed, aligned(4))); +/* the object data will be placed in memory here and will have size "object_words" */ + +/* Ext init array data object for Data Processing module memory requirements */ +struct ipc4_module_init_ext_obj_dp_data { + uint32_t domain_id; /* userspace domain ID */ + uint32_t stack_bytes; /* required stack size in bytes, 0 means default size */ + uint32_t heap_bytes; /* required heap size in bytes, 0 means default size */ +} __attribute__((packed, aligned(4))); + /* * Host Driver sends this message to create a new module instance. */ @@ -83,7 +105,8 @@ struct ipc4_module_init_ext_init { /**< Indicates that GNA is used by a module and additional information */ /* (gna_config) is passed after ExtendedData. */ uint32_t gna_used : 1; - uint32_t rsvd_0 : 30; + uint32_t data_obj_array : 1; /* struct ipc4_module_init_ext_object data */ + uint32_t rsvd_0 : 29; uint32_t rsvd_1[2]; } __attribute__((packed, aligned(4))); From 1adb3a33b97f5094b7b1e6d3df180fc235b3d7e8 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 5 Jun 2025 21:25:56 +0300 Subject: [PATCH 2/6] comp: Add bool ipc_extended_init to struct comp_ipc_config Add ipc_extended_init to struct comp_ipc_config to let component know that a struct ipc4_module_init_ext_init and possible friends are added into the struct ipc4_module_init_instance payload. The value of the boolean is set according to extension bit 29 of struct ipc4_module_init_instance message. Signed-off-by: Jyri Sarha --- src/include/sof/audio/component.h | 1 + src/ipc/ipc4/helper.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/include/sof/audio/component.h b/src/include/sof/audio/component.h index 337730ccae7d..f8fb0bbdf928 100644 --- a/src/include/sof/audio/component.h +++ b/src/include/sof/audio/component.h @@ -617,6 +617,7 @@ struct comp_ipc_config { uint32_t frame_fmt; /**< SOF_IPC_FRAME_ */ uint32_t xrun_action; /**< action we should take on XRUN */ #if CONFIG_IPC_MAJOR_4 + bool ipc_extended_init; /**< true if extended init is included in ipc payload */ uint32_t ipc_config_size; /**< size of a config received by ipc */ #endif }; diff --git a/src/ipc/ipc4/helper.c b/src/ipc/ipc4/helper.c index 4ff7d3a378d1..2211c5009f97 100644 --- a/src/ipc/ipc4/helper.c +++ b/src/ipc/ipc4/helper.c @@ -137,6 +137,7 @@ __cold struct comp_dev *comp_new_ipc4(struct ipc4_module_init_instance *module_i ipc_config.pipeline_id = module_init->extension.r.ppl_instance_id; ipc_config.core = module_init->extension.r.core_id; ipc_config.ipc_config_size = module_init->extension.r.param_block_size * sizeof(uint32_t); + ipc_config.ipc_extended_init = module_init->extension.r.extended_init; dcache_invalidate_region((__sparse_force void __sparse_cache *)MAILBOX_HOSTBOX_BASE, MAILBOX_HOSTBOX_SIZE); From 355dcf0463d192c0e219a3cfe89fe5e05237c7d3 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 12 Jun 2025 22:40:24 +0300 Subject: [PATCH 3/6] module/base: Add domain id, stack- and heap bytes members to module_config Add domain_id, stack_bytes and heap_bytes members to module_config. These may be be filled from ext_init payload. Signed-off-by: Jyri Sarha --- src/include/module/module/base.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/include/module/module/base.h b/src/include/module/module/base.h index f4da3252f4e3..ce5ca363ba73 100644 --- a/src/include/module/module/base.h +++ b/src/include/module/module/base.h @@ -34,6 +34,9 @@ struct module_config { uint8_t nb_output_pins; struct ipc4_input_pin_format *input_pins; struct ipc4_output_pin_format *output_pins; + uint32_t domain_id; /* userspace domain ID */ + uint32_t stack_bytes; /* stack size in bytes, 0 means default value */ + uint32_t heap_bytes; /* max heap size in bytes, 0 means default value */ #endif }; From f3a90946330a9ab9846ef634d327830b0f5cf351 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 12 Jun 2025 22:56:32 +0300 Subject: [PATCH 4/6] component: module_adapter: Add module_ext_init_decode() and call it Add module_ext_init_decode() for struct ipc4_module_init_ext_init payload decoding. The function goes decodes ext_init and following object array payload. The only recognized object so far is struct sof_ipc4_mod_init_ext_dp_memory_data. The possibly found stack and heap size requirements are copied to struct module_config, but no other functionality is added. This first version ignores rtos_domain and gna_used flags, and fails if their associated data is found in the message payload. Signed-off-by: Jyri Sarha --- .../module_adapter/module_adapter_ipc4.c | 79 ++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/src/audio/module_adapter/module_adapter_ipc4.c b/src/audio/module_adapter/module_adapter_ipc4.c index a50b78ff7714..f41ed7f6556c 100644 --- a/src/audio/module_adapter/module_adapter_ipc4.c +++ b/src/audio/module_adapter/module_adapter_ipc4.c @@ -25,6 +25,76 @@ LOG_MODULE_DECLARE(module_adapter, CONFIG_SOF_LOG_LEVEL); +static const struct ipc4_base_module_extended_cfg * +module_ext_init_decode(struct comp_dev *dev, struct module_config *dst, + const unsigned char *data, size_t *size) +{ + const struct ipc4_module_init_ext_init *ext_init = + (const struct ipc4_module_init_ext_init *)data; + bool last_object = !ext_init->data_obj_array; + const struct ipc4_module_init_ext_object *obj; + + if (*size < sizeof(ext_init)) { + comp_err(dev, "Size too small for ext init %u < %u", + *size, sizeof(ext_init)); + return NULL; + } + /* TODO: Handle ext_init->gna_used and ext_init->rtos_domain here */ + /* Get the first obj struct right after ext_init struct */ + obj = (const struct ipc4_module_init_ext_object *)(ext_init + 1); + while (!last_object) { + const struct ipc4_module_init_ext_object *next_obj; + + /* Check if there is space for the object header */ + if ((unsigned char *)(obj + 1) - data > *size) { + comp_err(dev, "ext init obj overflow, %u > %u", + (unsigned char *)(obj + 1) - data, *size); + return NULL; + } + /* Calculate would be next object position and check if current object fits */ + next_obj = (const struct ipc4_module_init_ext_object *) + (((uint32_t *) (obj + 1)) + obj->object_words); + if ((unsigned char *)next_obj - data > *size) { + comp_err(dev, "ext init object array overflow, %u > %u", + (unsigned char *)obj - data, *size); + return NULL; + } + switch (obj->object_id) { + case IPC4_MOD_INIT_DATA_ID_DP_DATA: + { + /* Get dp_data struct that follows the obj struct */ + const struct ipc4_module_init_ext_obj_dp_data *dp_data = + (const struct ipc4_module_init_ext_obj_dp_data *)(obj + 1); + + if (obj->object_words * sizeof(uint32_t) < sizeof(*dp_data)) { + comp_err(dev, "dp_data object too small %u < %u", + obj->object_words * sizeof(uint32_t), sizeof(*dp_data)); + return NULL; + } + dst->domain_id = dp_data->domain_id; + dst->stack_bytes = dp_data->stack_bytes; + dst->heap_bytes = dp_data->heap_bytes; + comp_info(dev, "init_ext_obj_dp_data domain %u stack %u heap %u", + dp_data->domain_id, dp_data->stack_bytes, dp_data->heap_bytes); + break; + } + default: + comp_info(dev, "Unknown ext init object id %u of %u words", + obj->object_id, obj->object_words); + } + /* Read the last object flag from obj header */ + last_object = obj->last_object; + /* Move to next object */ + obj = next_obj; + } + + /* Remove decoded ext_init payload from the size */ + *size -= (unsigned char *) obj - data; + + /* return remaining payload */ + return (const struct ipc4_base_module_extended_cfg *)obj; +} + /* * \module adapter data initialize. * \param[in] dev - device. @@ -39,11 +109,18 @@ int module_adapter_init_data(struct comp_dev *dev, const struct comp_ipc_config *config, const void *spec) { + const struct ipc4_base_module_extended_cfg *cfg; const struct ipc_config_process *args = spec; - const struct ipc4_base_module_extended_cfg *cfg = (void *)args->data; size_t cfgsz = args->size; assert(dev->drv->type == SOF_COMP_MODULE_ADAPTER); + if (config->ipc_extended_init) + cfg = module_ext_init_decode(dev, dst, args->data, &cfgsz); + else + cfg = (const struct ipc4_base_module_extended_cfg *)args->data; + + if (cfg == NULL) + return -EINVAL; if (cfgsz < sizeof(cfg->base_cfg)) return -EINVAL; From aeb63bbf0670bc865959ff52a07535f1bf68b5c6 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 12 Jun 2025 18:04:00 +0300 Subject: [PATCH 5/6] topology2: domain_id stack- and heap_bytes_requirements widget attributes Define domain_id, stack_bytes_requirement and heap_bytes_requirement widget attributes. Signed-off-by: Jyri Sarha --- .../topology2/include/common/tokens.conf | 3 +++ .../include/components/widget-common.conf | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/tools/topology/topology2/include/common/tokens.conf b/tools/topology/topology2/include/common/tokens.conf index 4f00ad79a73f..d1b986ab01d4 100644 --- a/tools/topology/topology2/include/common/tokens.conf +++ b/tools/topology/topology2/include/common/tokens.conf @@ -26,6 +26,9 @@ Object.Base.VendorToken { num_output_audio_formats 416 no_wname_in_kcontrol_name 417 scheduler_domain 418 + domain_id 419 + stack_bytes_requirement 420 + heap_bytes_requirement 421 } "2" { diff --git a/tools/topology/topology2/include/components/widget-common.conf b/tools/topology/topology2/include/components/widget-common.conf index a0e816a0f22e..851e78ae1721 100644 --- a/tools/topology/topology2/include/components/widget-common.conf +++ b/tools/topology/topology2/include/components/widget-common.conf @@ -136,3 +136,22 @@ DefineAttribute."scheduler_domain" { ] } } + +## Userspace domain id +DefineAttribute."domain_id" { + # Token set reference name and type + token_ref "comp.word" +} + +## Stack size requirement in bytes for this component. Zero indicates default stack size. +DefineAttribute."stack_bytes_requirement" { + # Token set reference name and type + token_ref "comp.word" +} + +## Heap size requirement in bytes for this component. Zero indicates default heap size. +DefineAttribute."heap_bytes_requirement" { + # Token set reference name and type + token_ref "comp.word" +} + From 3b67e6ae4fa2f8aa3b648b01a1075487e8c2800f Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 12 Jun 2025 22:49:40 +0300 Subject: [PATCH 6/6] topology2: cavs-nocodec.conf: Add domain_id, stack and heap_size to DP SRC Adds domain_id, stack and heap_size_requirements values to SRCs widgets if SRC's scheduling domain is DP. At this phase the values are there only for testing purposes and they do not represent SRC modules actual requirements. The values are sent to FW using ipc4 module init message's ext_init payload and its object array. Signed-off-by: Jyri Sarha --- tools/topology/topology2/cavs-nocodec.conf | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tools/topology/topology2/cavs-nocodec.conf b/tools/topology/topology2/cavs-nocodec.conf index 3970778de1f3..398b0f86abb9 100644 --- a/tools/topology/topology2/cavs-nocodec.conf +++ b/tools/topology/topology2/cavs-nocodec.conf @@ -693,7 +693,14 @@ IncludeByKey.PASSTHROUGH { } Object.Widget.src.1 { scheduler_domain "$SRC_DOMAIN" - core_id $DP_SRC_CORE_ID + IncludeByKey.SRC_DOMAIN { + "DP" { + core_id $DP_SRC_CORE_ID + domain_id 123 + stack_bytes_requirement 4096 + heap_bytes_requirement 8192 + } + } } Object.Widget.pipeline.1 { core $SSP2_PCM_CORE_ID @@ -1370,7 +1377,14 @@ IncludeByKey.PASSTHROUGH { index 11 rate_in 48000 scheduler_domain "$SRC_DOMAIN" - core_id $DP_SRC_CORE_ID + IncludeByKey.SRC_DOMAIN { + "DP" { + core_id $DP_SRC_CORE_ID + domain_id 123 + stack_bytes_requirement 4096 + heap_bytes_requirement 8192 + } + } }