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/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 diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index 3da4079d757e..835bc6ea86ee 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -59,17 +59,38 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv, #endif static struct vregion *module_adapter_dp_heap_new(const struct comp_ipc_config *config, - size_t *heap_size) + 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; @@ -84,11 +105,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, ext_init); if (!mod_vreg) { comp_cl_err(drv, "Failed to allocate DP module heap / vregion"); return NULL; @@ -101,7 +121,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; } @@ -230,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; @@ -244,6 +269,18 @@ 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 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; +#endif + #if CONFIG_ZEPHYR_DP_SCHEDULER /* create a task for DP processing */ if (config->proc_domain == COMP_PROCESSING_DOMAIN_DP) { @@ -256,16 +293,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", 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/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/Kconfig b/zephyr/Kconfig index 27f37d829b4e..603e52aafebd 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 @@ -232,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 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;