Skip to content

Commit

Permalink
module_adapter_ipc4: Save and pre-parse base_cfg_ext data
Browse files Browse the repository at this point in the history
The kernel-provided "base_cfg_ext" data wasn't being handled correctly
by the module adapter layer.  These structs (packed wire formats) only
ever lived in the IPC memory.  The module would set them on an
"init_data" before calling into driver init, and then clear that
poitner afterwards.  That's a critical problem, because the values in
that struct need to be used at pipeline setup time to configure buffer
formats!

Save the data correctly.  Also pre-parse it so users don't need to do
byte math on raw buffers and can just use "in/output_pins[]" arrays on
the module_config struct.

Signed-off-by: Andy Ross <andyross@google.com>
  • Loading branch information
andyross committed Jan 3, 2024
1 parent 9315ada commit 2f6c804
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 9 deletions.
4 changes: 4 additions & 0 deletions src/audio/module_adapter/module_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1333,6 +1333,10 @@ int module_adapter_reset(struct comp_dev *dev)
rfree(mod->stream_params);
mod->stream_params = NULL;

#if CONFIG_IPC_MAJOR_4
rfree(mod->priv.cfg.input_pins);
#endif

comp_dbg(dev, "module_adapter_reset(): done");

return comp_set_state(dev, COMP_TRIGGER_RESET);
Expand Down
38 changes: 29 additions & 9 deletions src/audio/module_adapter/module_adapter_ipc4.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,39 @@ int module_adapter_init_data(struct comp_dev *dev,
const struct comp_ipc_config *config,
const void *spec)
{
if (dev->drv->type == SOF_COMP_MODULE_ADAPTER) {
const struct ipc_config_process *ipc_module_adapter = spec;
const struct ipc_config_process *cp = spec;
const struct ipc4_base_module_extended_cfg *cfg = (void *)cp->data;
size_t cfgsz = cp->size;

dst->init_data = ipc_module_adapter->data;
dst->size = ipc_module_adapter->size;
dst->avail = true;
assert(dev->drv->type == SOF_COMP_MODULE_ADAPTER);
if (cp->size < sizeof(cfg->base_cfg))
return -EINVAL;

memcpy_s(&dst->base_cfg, sizeof(dst->base_cfg), ipc_module_adapter->data,
sizeof(dst->base_cfg));
} else {
dst->init_data = spec;
dst->base_cfg = cfg->base_cfg;
dst->size = cp->size;

if (cp->size >= sizeof(*cfg)) {
int ni = cfg->base_cfg_ext.nb_input_pins;
int no = cfg->base_cfg_ext.nb_output_pins;
size_t pinsz = (ni * sizeof(*dst->input_pins))
+ (no * sizeof(*dst->output_pins));

if (cp->size == (sizeof(*cfg) + pinsz)) {
dst->nb_input_pins = ni;
dst->nb_output_pins = no;
dst->input_pins = rmalloc(SOF_MEM_ZONE_RUNTIME_SHARED,
0, SOF_MEM_CAPS_RAM, pinsz);
if (!dst->input_pins)
return -ENOMEM;

dst->output_pins = (void *) &dst->input_pins[ni];
memcpy_s(dst->input_pins, pinsz,
&cfg->base_cfg_ext.pin_formats[0], pinsz);
}
}

dst->init_data = cp->data; /* legacy API */
dst->avail = true;
return 0;
}

Expand Down
4 changes: 4 additions & 0 deletions src/include/module/module/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ struct module_config {
const void *init_data; /**< Initial IPC configuration. */
#if CONFIG_IPC_MAJOR_4
struct ipc4_base_module_cfg base_cfg;
uint8_t nb_input_pins;
uint8_t nb_output_pins;
struct ipc4_input_pin_format *input_pins;
struct ipc4_output_pin_format *output_pins;
#endif
};

Expand Down

0 comments on commit 2f6c804

Please sign in to comment.