Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 78 additions & 1 deletion src/audio/module_adapter/module_adapter_ipc4.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as to kernel PR. We already have a concept of "extended init". E.g. we have:

» struct sof_ipc4_base_module_cfg base_config;
» struct sof_ipc4_base_module_cfg_ext *base_config_ext;

All modules have base_config, but some have base_config_ext additionally. This new PR (and the bit29) seems to add a way to extend the module init data, but still keeps the old "base_config_ext" around as well. Having two "extended" module configs is highly confusing. Can we call this new variant (ipc_extended_init) something clearly different?

Copy link
Contributor Author

@jsarha jsarha Jul 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I address all the other comments first and push a new version. I take on this tomorrow, when I am certain we have an agreement on what to do.

So @kv2019i , should I go and rename struct ipc4_module_init_ext_init that has been there since 6c29004 ? Or would something less be enough?

What I find most annoying is that the both payload extesions are described in completely different places in the source tree without any cross reference or comment that the both entities may exist in the same payload. The comments here

give an idea that this is all that should be in module init payload.

Would it be enough if I would document in the above place that struct ipc4_base_module_cfg_ext may follow the already mentioned structs structs, and document the situation the same way on the Linux side?

BTW it currently does not mention here

struct ipc4_base_module_cfg_ext {
at all how, when, or where this struct is used. Is the payload of module init message the only place or is there some other uses too? I could add some comments there too, but I am not certain what they should be.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack @jsarha . I got (again) confused we extended the module init message both at 1) TOP level (t ipc4_module_init_ext_init) and at 2) BASEFW level (sof_ipc4_base_module_cfg). Given the naming predates your PR, no need to rename now.


if (cfg == NULL)
return -EINVAL;
if (cfgsz < sizeof(cfg->base_cfg))
return -EINVAL;

Expand Down
25 changes: 24 additions & 1 deletion src/include/ipc4/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand All @@ -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)));

Expand Down
3 changes: 3 additions & 0 deletions src/include/module/module/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

Expand Down
1 change: 1 addition & 0 deletions src/include/sof/audio/component.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
};
Expand Down
1 change: 1 addition & 0 deletions src/ipc/ipc4/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
18 changes: 16 additions & 2 deletions tools/topology/topology2/cavs-nocodec.conf
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}
}

<include/components/src_format_s32_convert_from_48k.conf>
}
Expand Down
3 changes: 3 additions & 0 deletions tools/topology/topology2/include/common/tokens.conf
Original file line number Diff line number Diff line change
Expand Up @@ -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" {
Expand Down
19 changes: 19 additions & 0 deletions tools/topology/topology2/include/components/widget-common.conf
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}

Loading