From a7b30818957ecdde6709e3efd412f9bef971f6da Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 5 Mar 2026 21:49:22 +0200 Subject: [PATCH 1/6] module-adapter: Move pipeline_comp_dp_task_init() after mod struct inits Move pipeline_comp_dp_task_init() call after module private data initializations so that the struct module_config is available already at pipeline_comp_dp_task_init() init time. Signed-off-by: Jyri Sarha --- src/audio/module_adapter/module_adapter.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index 3da4079d757e..d62b8736e015 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -244,6 +244,17 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv, struct comp_dev *dev = mod->dev; + dst = &mod->priv.cfg; + /* + * NOTE: dst->ext_data points to stack variable and contains + * pointers to IPC payload mailbox, so its only valid in + * functions that called from this function. This why + * the pointer is set NULL before this function exits. + */ +#if CONFIG_IPC_MAJOR_4 + dst->ext_data = &ext_data; +#endif + #if CONFIG_ZEPHYR_DP_SCHEDULER /* create a task for DP processing */ if (config->proc_domain == COMP_PROCESSING_DOMAIN_DP) { @@ -256,16 +267,6 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv, } #endif /* CONFIG_ZEPHYR_DP_SCHEDULER */ - dst = &mod->priv.cfg; - /* - * NOTE: dst->ext_data points to stack variable and contains - * pointers to IPC payload mailbox, so its only valid in - * functions that called from this function. This why - * the pointer is set NULL before this function exits. - */ -#if CONFIG_IPC_MAJOR_4 - dst->ext_data = &ext_data; -#endif ret = module_adapter_init_data(dev, dst, config, &spec); if (ret) { comp_err(dev, "%d: module init data failed", From 30e2ec5f0b8576d816b7e0177dc99af82f4b1e3d Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 25 Jun 2026 15:40:32 +0300 Subject: [PATCH 2/6] module-adapter: module_adapter_dp_heap_new() remove heap_size parameter Remove unused heap_size parameter from module_adapter_dp_heap_new() function. Signed-off-by: Jyri Sarha --- src/audio/module_adapter/module_adapter.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index d62b8736e015..8c5c1783f291 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -58,8 +58,7 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv, #define PAGE_SZ HOST_PAGE_SIZE #endif -static struct vregion *module_adapter_dp_heap_new(const struct comp_ipc_config *config, - size_t *heap_size) +static struct vregion *module_adapter_dp_heap_new(const struct comp_ipc_config *config) { /* src-lite with 8 channels has been seen allocating 14k in one go */ /* FIXME: the size will be derived from configuration */ @@ -84,11 +83,10 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv */ uint32_t flags = config->proc_domain == COMP_PROCESSING_DOMAIN_DP ? SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT : SOF_MEM_FLAG_USER; - size_t heap_size; if (config->proc_domain == COMP_PROCESSING_DOMAIN_DP && IS_ENABLED(CONFIG_SOF_VREGIONS) && IS_ENABLED(CONFIG_USERSPACE) && !IS_ENABLED(CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP)) { - mod_vreg = module_adapter_dp_heap_new(config, &heap_size); + mod_vreg = module_adapter_dp_heap_new(config); if (!mod_vreg) { comp_cl_err(drv, "Failed to allocate DP module heap / vregion"); return NULL; @@ -101,7 +99,6 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv #else mod_heap = drv->user_heap; #endif - heap_size = 0; mod_vreg = NULL; } From bef5f96516111712822c4a625126b84f8ef859bd Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 5 Mar 2026 19:53:46 +0200 Subject: [PATCH 3/6] module-adapter: Size DP heap from IPC ext init data Use IPC module init extended data (the dp_data) to determine DP module heap size when available. Add Kconfig option SOF_USERSPACE_DP_DEFAULT_HEAP_SIZE (default 20480) as fallback when extended init data is not present or does not provide heap sizes. Sanity-check the requested sizes (reject values above 64 MB) and log the allocated heap size. Also pass ext_init through module_adapter_mem_alloc() to module_adapter_dp_heap_new() and fix a minor comment typo. Signed-off-by: Jyri Sarha --- src/audio/module_adapter/module_adapter.c | 47 ++++++++++++++++++----- zephyr/Kconfig | 9 +++++ 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index 8c5c1783f291..835bc6ea86ee 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -58,17 +58,39 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv, #define PAGE_SZ HOST_PAGE_SIZE #endif -static struct vregion *module_adapter_dp_heap_new(const struct comp_ipc_config *config) +static struct vregion *module_adapter_dp_heap_new(const struct comp_ipc_config *config, + const struct module_ext_init_data *ext_init) { /* src-lite with 8 channels has been seen allocating 14k in one go */ - /* FIXME: the size will be derived from configuration */ - const size_t buf_size = 28 * 1024; + size_t buf_size = CONFIG_SOF_USERSPACE_DP_DEFAULT_HEAP_SIZE; +#if CONFIG_IPC_MAJOR_4 + if (config->ipc_extended_init && ext_init && ext_init->dp_data && + ext_init->dp_data->heap_bytes > 0) { + if (ext_init->dp_data->heap_bytes > MB(64)) { + LOG_ERR("Bad heap size %u bytes for %#x", + ext_init->dp_data->heap_bytes, config->id); + return NULL; + } + + buf_size = ext_init->dp_data->heap_bytes; + + LOG_INF("%zu byte heap size requested in IPC for %#x", buf_size, config->id); + } +#endif + /* + * A 1-to-1 replacement of the original heap implementation would be to + * have "lifetime size" equal to 0. But (1) this is invalid for + * vregion_create() and (2) we gradually move objects, that are simple + * to move to the lifetime buffer. Make it 4k for the beginning. + */ return vregion_create(buf_size); } -static struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv, - const struct comp_ipc_config *config) +static +struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv, + const struct comp_ipc_config *config, + const struct module_ext_init_data *ext_init) { struct k_heap *mod_heap; struct vregion *mod_vreg; @@ -86,7 +108,7 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv if (config->proc_domain == COMP_PROCESSING_DOMAIN_DP && IS_ENABLED(CONFIG_SOF_VREGIONS) && IS_ENABLED(CONFIG_USERSPACE) && !IS_ENABLED(CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP)) { - mod_vreg = module_adapter_dp_heap_new(config); + mod_vreg = module_adapter_dp_heap_new(config, ext_init); if (!mod_vreg) { comp_cl_err(drv, "Failed to allocate DP module heap / vregion"); return NULL; @@ -227,8 +249,14 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv, return NULL; } #endif + const struct module_ext_init_data *ext_init = +#if CONFIG_IPC_MAJOR_4 + &ext_data; +#else + NULL; +#endif - struct processing_module *mod = module_adapter_mem_alloc(drv, config); + struct processing_module *mod = module_adapter_mem_alloc(drv, config, ext_init); if (!mod) return NULL; @@ -245,8 +273,9 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv, /* * NOTE: dst->ext_data points to stack variable and contains * pointers to IPC payload mailbox, so its only valid in - * functions that called from this function. This why - * the pointer is set NULL before this function exits. + * functions that are called from this function. This is + * why the pointer is set to NULL before this function + * exits. */ #if CONFIG_IPC_MAJOR_4 dst->ext_data = &ext_data; diff --git a/zephyr/Kconfig b/zephyr/Kconfig index 27f37d829b4e..5d2743fe56ae 100644 --- a/zephyr/Kconfig +++ b/zephyr/Kconfig @@ -69,6 +69,15 @@ config SOF_ZEPHYR_HEAP_SIZE NOTE: Keep in mind that the heap size should not be greater than the physical memory size of the system defined in DT (and this includes baseFW text/data). +config SOF_USERSPACE_DP_DEFAULT_HEAP_SIZE + int "Default heap size for DP userspace threads" + default 20480 + help + Defines the default heap size for userspace DP processing + threads. The value can be overridden with IPC module init + ext_init module payload. The default is derived from what is + required for SRC module to produce all supported conversions. + config SOF_USERSPACE_USE_SHARED_HEAP bool "Use shared heap for SOF userspace modules" depends on USERSPACE From 5e259b990904042fe6305b38e44179cfd8b12eb6 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 5 Mar 2026 21:35:41 +0200 Subject: [PATCH 4/6] pipeline: Use dp_data stack size for DP task Use IPC module init extended data (dp_data stack_bytes) to set the DP processing thread stack size when available. Fall back to TASK_DP_STACK_SIZE when ext init data is not present or does not provide a stack size. Add Kconfig option ZEPHYR_DP_SCHEDULER_MIN_STACK_SIZE (default 2048) to enforce a minimum stack size regardless of what the IPC payload requests. Signed-off-by: Jyri Sarha --- src/audio/pipeline/pipeline-schedule.c | 12 +++++++++++- zephyr/Kconfig | 9 +++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/audio/pipeline/pipeline-schedule.c b/src/audio/pipeline/pipeline-schedule.c index cb4ec8fd3c62..70ae1186b2a2 100644 --- a/src/audio/pipeline/pipeline-schedule.c +++ b/src/audio/pipeline/pipeline-schedule.c @@ -398,6 +398,7 @@ int pipeline_comp_dp_task_init(struct comp_dev *comp) { /* DP tasks are guaranteed to have a module_adapter */ struct processing_module *mod = comp_mod(comp); + size_t stack_size = TASK_DP_STACK_SIZE; struct task_ops ops = { .run = dp_task_run, .get_deadline = NULL, @@ -413,8 +414,17 @@ int pipeline_comp_dp_task_init(struct comp_dev *comp) unsigned int flags = IS_ENABLED(CONFIG_USERSPACE) ? K_USER : 0; #endif + if (mod->priv.cfg.ext_data && mod->priv.cfg.ext_data->dp_data && + mod->priv.cfg.ext_data->dp_data->stack_bytes > 0) { + stack_size = MAX(mod->priv.cfg.ext_data->dp_data->stack_bytes, + CONFIG_ZEPHYR_DP_SCHEDULER_MIN_STACK_SIZE); + comp_info(comp, "stack size set to %zu, %zu requested, min allowed %zu", + stack_size, mod->priv.cfg.ext_data->dp_data->stack_bytes, + CONFIG_ZEPHYR_DP_SCHEDULER_MIN_STACK_SIZE); + } + return scheduler_dp_task_init(&comp->task, SOF_UUID(dp_task_uuid), &ops, mod, - comp->ipc_config.core, TASK_DP_STACK_SIZE, flags); + comp->ipc_config.core, stack_size, flags); } #endif /* CONFIG_ZEPHYR_DP_SCHEDULER */ diff --git a/zephyr/Kconfig b/zephyr/Kconfig index 5d2743fe56ae..603e52aafebd 100644 --- a/zephyr/Kconfig +++ b/zephyr/Kconfig @@ -241,6 +241,15 @@ config ZEPHYR_DP_SCHEDULER DP modules can be located in dieffrent cores than LL pipeline modules, may have different tick (i.e. 300ms for speech reccognition, etc.) +config ZEPHYR_DP_SCHEDULER_MIN_STACK_SIZE + int "Minimum stack size for DP processing thread" + default 512 + help + Defines the minimum stack size allowed for DP processing + threads despite what is requested in the module init IPC + ext_init payload. If the stack size requested in the IPC is + smaller than this, then the value defined here takes over. + config CROSS_CORE_STREAM bool "Enable cross-core connected pipelines" default y if IPC_MAJOR_4 From 6ff55af2ddf90ecd53ac2b9f336058ec078ede98 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 30 Jun 2026 19:19:01 +0300 Subject: [PATCH 5/6] module: Kconfig: add SOF_USERSPACE_DP_DEFAULT_HEAP_SIZE stub Add a dummy Kconfig definition for SOF_USERSPACE_DP_DEFAULT_HEAP_SIZE so the testbench build can resolve the symbol. The testbench does not use Zephyr, where this option is normally defined, so it needs a local fallback. Signed-off-by: Jyri Sarha --- src/audio/module_adapter/Kconfig | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/audio/module_adapter/Kconfig b/src/audio/module_adapter/Kconfig index a9f88dd1f2ad..9e722c00a0d4 100644 --- a/src/audio/module_adapter/Kconfig +++ b/src/audio/module_adapter/Kconfig @@ -24,6 +24,16 @@ menu "Processing modules" assert to make sure no other thread makes such operations. + config SOF_USERSPACE_DP_DEFAULT_HEAP_SIZE + int "Default heap size for DP userspace threads" + default 20480 + help + Defines the default heap size for userspace DP processing + threads. The value can be overridden with IPC module init + ext_init module payload. The default is derived from what is + required for SRC module to produce all supported conversions. + (This is a dummy Kconfig option to help testbench to build.) + config CADENCE_CODEC bool "Cadence codec" help From 2a53dfeac8f1456adc30a0ff4432623cedd493a0 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 30 Jun 2026 20:05:59 +0300 Subject: [PATCH 6/6] posix: add Zephyr logging and util stubs for testbench build Add posix stub headers for and so that firmware source files using LOG_ERR, LOG_INF, LOG_WRN, LOG_DBG, KB, or MB can compile in the testbench / posix build without modification. Remove the #ifdef __ZEPHYR__ guard around the include in sof/trace/trace.h and the include in sof/common.h so the posix stubs are picked up automatically. The redundant LOG_MODULE_REGISTER / LOG_MODULE_DECLARE definitions in trace.h are removed since the posix stub now provides them. Remove the macros and fix couple of format string issues. Also the tools/logger CMakeList.txt requires some tuning to find the now unconditionally included zephyr/sys/util.h. Signed-off-by: Jyri Sarha --- posix/include/zephyr/logging/log.h | 33 ++++++++++++++++++++++++++++++ posix/include/zephyr/sys/util.h | 21 +++++++++++++++++++ src/include/sof/common.h | 2 -- src/include/sof/trace/trace.h | 10 +-------- tools/logger/CMakeLists.txt | 1 + zephyr/lib/fast-get.c | 9 +------- 6 files changed, 57 insertions(+), 19 deletions(-) create mode 100644 posix/include/zephyr/logging/log.h create mode 100644 posix/include/zephyr/sys/util.h diff --git a/posix/include/zephyr/logging/log.h b/posix/include/zephyr/logging/log.h new file mode 100644 index 000000000000..20ca6371bd63 --- /dev/null +++ b/posix/include/zephyr/logging/log.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright(c) 2026 Intel Corporation. All rights reserved. + * + * Stub for used by testbench / posix builds. + */ + +#ifndef __POSIX_ZEPHYR_LOGGING_LOG_H__ +#define __POSIX_ZEPHYR_LOGGING_LOG_H__ + +#include + +#ifndef LOG_ERR +#define LOG_ERR(fmt, ...) fprintf(stderr, "ERR: " fmt "\n", ##__VA_ARGS__) +#endif +#ifndef LOG_WRN +#define LOG_WRN(fmt, ...) fprintf(stderr, "WRN: " fmt "\n", ##__VA_ARGS__) +#endif +#ifndef LOG_INF +#define LOG_INF(fmt, ...) printf("INF: " fmt "\n", ##__VA_ARGS__) +#endif +#ifndef LOG_DBG +#define LOG_DBG(fmt, ...) do { } while (0) +#endif + +#ifndef LOG_MODULE_REGISTER +#define LOG_MODULE_REGISTER(ctx, level) +#endif +#ifndef LOG_MODULE_DECLARE +#define LOG_MODULE_DECLARE(ctx, level) +#endif + +#endif /* __POSIX_ZEPHYR_LOGGING_LOG_H__ */ diff --git a/posix/include/zephyr/sys/util.h b/posix/include/zephyr/sys/util.h new file mode 100644 index 000000000000..027b2ef15a6d --- /dev/null +++ b/posix/include/zephyr/sys/util.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright(c) 2026 Intel Corporation. All rights reserved. + * + * Stub for used by testbench / posix builds. + */ + +#ifndef __POSIX_ZEPHYR_SYS_UTIL_H__ +#define __POSIX_ZEPHYR_SYS_UTIL_H__ + +#include + +#ifndef KB +#define KB(x) (((size_t)(x)) << 10) +#endif + +#ifndef MB +#define MB(x) (KB(x) << 10) +#endif + +#endif /* __POSIX_ZEPHYR_SYS_UTIL_H__ */ diff --git a/src/include/sof/common.h b/src/include/sof/common.h index d7aa9a7989cb..bb193310e97f 100644 --- a/src/include/sof/common.h +++ b/src/include/sof/common.h @@ -14,9 +14,7 @@ /* callers must check/use the return value */ #define __must_check __attribute__((warn_unused_result)) -#ifdef __ZEPHYR__ #include -#endif /* Align the number to the nearest alignment value */ #ifndef IS_ALIGNED diff --git a/src/include/sof/trace/trace.h b/src/include/sof/trace/trace.h index fc3aa324f847..bd6a56d87da0 100644 --- a/src/include/sof/trace/trace.h +++ b/src/include/sof/trace/trace.h @@ -23,8 +23,8 @@ #ifdef __ZEPHYR__ #include -#include #endif +#include #if !CONFIG_LIBRARY #include @@ -155,12 +155,4 @@ struct tr_ctx { .level = default_log_level, \ } -/* Only define these two macros for XTOS to avoid the collision with - * zephyr/include/zephyr/logging/log.h - */ -#ifndef __ZEPHYR__ -#define LOG_MODULE_REGISTER(ctx, level) -#define LOG_MODULE_DECLARE(ctx, level) -#endif - #endif /* __SOF_TRACE_TRACE_H__ */ diff --git a/tools/logger/CMakeLists.txt b/tools/logger/CMakeLists.txt index ac83f5687454..8c15dd125739 100644 --- a/tools/logger/CMakeLists.txt +++ b/tools/logger/CMakeLists.txt @@ -38,6 +38,7 @@ target_compile_options(sof-logger PRIVATE target_include_directories(sof-logger PRIVATE "${SOF_ROOT_SOURCE_DIRECTORY}/src/include" + "${SOF_ROOT_SOURCE_DIRECTORY}/posix/include" "${SOF_ROOT_SOURCE_DIRECTORY}/tools/rimage/src/include" "${SOF_ROOT_SOURCE_DIRECTORY}" ) diff --git a/zephyr/lib/fast-get.c b/zephyr/lib/fast-get.c index cb0a2cfb07c7..f60efe48120c 100644 --- a/zephyr/lib/fast-get.c +++ b/zephyr/lib/fast-get.c @@ -19,14 +19,7 @@ #include #include -#ifdef __ZEPHYR__ #include -#else -#define LOG_DBG(...) do {} while (0) -#define LOG_INF(...) do {} while (0) -#define LOG_WRN(...) do {} while (0) -#define LOG_ERR(...) do {} while (0) -#endif struct sof_fast_get_entry { const void *dram_ptr; @@ -154,7 +147,7 @@ const void *fast_get(struct mod_alloc_ctx *alloc, const void *dram_ptr, size_t s if (entry->sram_ptr) { if (entry->size != size || entry->dram_ptr != dram_ptr) { - LOG_ERR("size %u != %u or ptr %p != %p mismatch", + LOG_ERR("size %zu != %zu or ptr %p != %p mismatch", entry->size, size, entry->dram_ptr, dram_ptr); ret = NULL; goto out;