From f9f71a93685b587c32ac2a60666fdc0ceaabed95 Mon Sep 17 00:00:00 2001 From: Adrian Bonislawski Date: Mon, 3 Nov 2025 12:19:35 +0100 Subject: [PATCH 1/2] audio: mux: use IPC4_SINK_QUEUE_ID macro for buffer queue ID extraction Use IPC4_SINK_QUEUE_ID() macro to properly extract the queue ID from buffer ID in IPC4 mux implementation. This ensures correct indexing into the streams[] array when mapping source buffers to their corresponding stream configurations. Signed-off-by: Adrian Bonislawski --- src/audio/mux/mux_ipc4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/mux/mux_ipc4.c b/src/audio/mux/mux_ipc4.c index 9d844ac15efa..10669424d4ce 100644 --- a/src/audio/mux/mux_ipc4.c +++ b/src/audio/mux/mux_ipc4.c @@ -105,7 +105,7 @@ static void set_mux_params(struct processing_module *mod) struct ipc4_audio_format *audio_fmt; comp_dev_for_each_producer(dev, source) { - j = buf_get_id(source); + j = IPC4_SINK_QUEUE_ID(buf_get_id(source)); cd->config.streams[j].pipeline_id = buffer_pipeline_id(source); if (j == BASE_CFG_QUEUED_ID) audio_fmt = &cd->md.base_cfg.audio_fmt; From ca200ed49b2eaadafef7216512f417dfdc116e27 Mon Sep 17 00:00:00 2001 From: Adrian Bonislawski Date: Mon, 3 Nov 2025 12:15:15 +0100 Subject: [PATCH 2/2] audio: mux: fix IPC4 configuration handling for IPC3/IPC4 separation This patch will fix IPC4 configuration. Move configuration blob handling from common mux_prepare() to IPC-specific mux_params() implementations to better separate IPC3 and IPC4 code paths. Changes: - Remove config blob retrieval and validation from mux_prepare() in mux.c - Move blob handling to mux_params() in mux_ipc3.c for IPC3 path - Update mux_ipc4.c to use blob handler for config blob instead of storing in comp_data->md - Define MUX_BLOB_MAX_SIZE conditionally based on IPC version: * IPC4: sizeof(struct mux_data) * IPC3: sizeof(struct sof_mux_config) + MUX_BLOB_STREAMS_SIZE Signed-off-by: Adrian Bonislawski --- src/audio/mux/mux.c | 10 ---------- src/audio/mux/mux.h | 4 ++++ src/audio/mux/mux_ipc3.c | 13 +++++++++++++ src/audio/mux/mux_ipc4.c | 40 +++++++++++++++++++++++++--------------- 4 files changed, 42 insertions(+), 25 deletions(-) diff --git a/src/audio/mux/mux.c b/src/audio/mux/mux.c index d23a734e28fe..1e4b0138e5ec 100644 --- a/src/audio/mux/mux.c +++ b/src/audio/mux/mux.c @@ -390,20 +390,10 @@ static int mux_prepare(struct processing_module *mod, { struct comp_dev *dev = mod->dev; struct comp_data *cd = module_get_private_data(mod); - struct sof_mux_config *config; - size_t blob_size; int ret; comp_dbg(dev, "mux_prepare()"); - config = comp_get_data_blob(cd->model_handler, &blob_size, NULL); - if (blob_size > MUX_BLOB_MAX_SIZE) { - comp_err(dev, "illegal blob size %zu", blob_size); - return -EINVAL; - } - - memcpy_s(&cd->config, MUX_BLOB_MAX_SIZE, config, blob_size); - ret = mux_params(mod); if (ret < 0) return ret; diff --git a/src/audio/mux/mux.h b/src/audio/mux/mux.h index 526d70ecb870..0fb11d8300b5 100644 --- a/src/audio/mux/mux.h +++ b/src/audio/mux/mux.h @@ -213,7 +213,11 @@ void sys_comp_module_demux_interface_init(void); #endif /* UNIT_TEST */ #define MUX_BLOB_STREAMS_SIZE (MUX_MAX_STREAMS * sizeof(struct mux_stream_data)) +#ifdef CONFIG_IPC_MAJOR_4 +#define MUX_BLOB_MAX_SIZE (sizeof(struct mux_data)) +#else #define MUX_BLOB_MAX_SIZE (sizeof(struct sof_mux_config) + MUX_BLOB_STREAMS_SIZE) +#endif extern const struct sof_uuid demux_uuid; extern struct tr_ctx mux_tr; diff --git a/src/audio/mux/mux_ipc3.c b/src/audio/mux/mux_ipc3.c index 4a39dd277012..16a2eeecf90d 100644 --- a/src/audio/mux/mux_ipc3.c +++ b/src/audio/mux/mux_ipc3.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -98,6 +99,18 @@ static int mux_set_values(struct processing_module *mod) int mux_params(struct processing_module *mod) { + struct comp_data *cd = module_get_private_data(mod); + struct sof_mux_config *config; + size_t blob_size; + + config = comp_get_data_blob(cd->model_handler, &blob_size, NULL); + if (blob_size > MUX_BLOB_MAX_SIZE) { + comp_err(mod->dev, "illegal blob size %zu", blob_size); + return -EINVAL; + } + + memcpy_s(&cd->config, MUX_BLOB_MAX_SIZE, config, blob_size); + return mux_set_values(mod); } #endif /* CONFIG_COMP_MUX */ diff --git a/src/audio/mux/mux_ipc4.c b/src/audio/mux/mux_ipc4.c index 10669424d4ce..dc6877059f57 100644 --- a/src/audio/mux/mux_ipc4.c +++ b/src/audio/mux/mux_ipc4.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -31,7 +32,7 @@ SOF_DEFINE_REG_UUID(demux); DECLARE_TR_CTX(demux_tr, SOF_UUID(demux_uuid), LOG_LEVEL_INFO); -static int build_config(struct processing_module *mod) +static int build_config(struct processing_module *mod, struct mux_data *cfg) { struct comp_dev *dev = mod->dev; struct comp_data *cd = module_get_private_data(mod); @@ -45,12 +46,12 @@ static int build_config(struct processing_module *mod) memset(cd->config.streams[i].mask, 0, sizeof(cd->config.streams[i].mask)); /* Setting masks for streams */ - for (i = 0; i < cd->md.base_cfg.audio_fmt.channels_count; i++) { + for (i = 0; i < cfg->base_cfg.audio_fmt.channels_count; i++) { cd->config.streams[0].mask[i] = mask; mask <<= 1; } - for (i = 0; i < cd->md.reference_format.channels_count; i++) { + for (i = 0; i < cfg->reference_format.channels_count; i++) { cd->config.streams[1].mask[i] = mask; mask <<= 1; } @@ -67,7 +68,7 @@ static int build_config(struct processing_module *mod) * set up param then verify param. BTW for IPC3 path, the param is sent by * host driver. */ -static void set_mux_params(struct processing_module *mod) +static void set_mux_params(struct processing_module *mod, struct mux_data *cfg) { struct sof_ipc_stream_params *params = mod->stream_params; struct comp_data *cd = module_get_private_data(mod); @@ -76,12 +77,12 @@ static void set_mux_params(struct processing_module *mod) int j; params->direction = dev->direction; - params->channels = cd->md.base_cfg.audio_fmt.channels_count; - params->rate = cd->md.base_cfg.audio_fmt.sampling_frequency; - params->sample_container_bytes = cd->md.base_cfg.audio_fmt.depth / 8; - params->sample_valid_bytes = cd->md.base_cfg.audio_fmt.valid_bit_depth / 8; - params->buffer_fmt = cd->md.base_cfg.audio_fmt.interleaving_style; - params->buffer.size = cd->md.base_cfg.ibs; + params->channels = cfg->base_cfg.audio_fmt.channels_count; + params->rate = cfg->base_cfg.audio_fmt.sampling_frequency; + params->sample_container_bytes = cfg->base_cfg.audio_fmt.depth / 8; + params->sample_valid_bytes = cfg->base_cfg.audio_fmt.valid_bit_depth / 8; + params->buffer_fmt = cfg->base_cfg.audio_fmt.interleaving_style; + params->buffer.size = cfg->base_cfg.ibs; params->no_stream_position = 1; /* There are two input pins and one output pin in the mux. @@ -95,7 +96,7 @@ static void set_mux_params(struct processing_module *mod) sink = comp_dev_get_first_data_consumer(dev); if (!audio_buffer_hw_params_configured(&sink->audio_buffer)) { - ipc4_update_buffer_format(sink, &cd->md.output_format); + ipc4_update_buffer_format(sink, &cfg->output_format); params->frame_fmt = audio_stream_get_frm_fmt(&sink->stream); } } @@ -108,9 +109,9 @@ static void set_mux_params(struct processing_module *mod) j = IPC4_SINK_QUEUE_ID(buf_get_id(source)); cd->config.streams[j].pipeline_id = buffer_pipeline_id(source); if (j == BASE_CFG_QUEUED_ID) - audio_fmt = &cd->md.base_cfg.audio_fmt; + audio_fmt = &cfg->base_cfg.audio_fmt; else - audio_fmt = &cd->md.reference_format; + audio_fmt = &cfg->reference_format; ipc4_update_buffer_format(source, audio_fmt); } @@ -121,13 +122,22 @@ static void set_mux_params(struct processing_module *mod) int mux_params(struct processing_module *mod) { + struct comp_data *cd = module_get_private_data(mod); + struct mux_data *cfg; + size_t blob_size; int ret; - ret = build_config(mod); + cfg = comp_get_data_blob(cd->model_handler, &blob_size, NULL); + if (!cfg || blob_size > MUX_BLOB_MAX_SIZE) { + comp_err(mod->dev, "illegal blob size %zu", blob_size); + return -EINVAL; + } + + ret = build_config(mod, cfg); if (ret < 0) return ret; - set_mux_params(mod); + set_mux_params(mod, cfg); return ret; }