From c6e666acf108783676fd6a9f4f66c8781c9f2919 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Tue, 10 Feb 2026 13:10:02 +0100 Subject: [PATCH 1/4] west: Changes from pull request in review This commit will be replaced with actual zephyr update after necessary changes are merged. Signed-off-by: Tomasz Leman --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 572114fd905d..3de633b7349e 100644 --- a/west.yml +++ b/west.yml @@ -43,7 +43,7 @@ manifest: - name: zephyr repo-path: zephyr - revision: f6a32b27dc17bdb4e1ba4ad84de0c56ca71e257d + revision: pull/103820/head remote: zephyrproject # Import some projects listed in zephyr/west.yml@revision From 2be7c0c56ae259940e2b44b23cce4b103ff4953c Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Tue, 10 Feb 2026 14:41:33 +0100 Subject: [PATCH 2/4] ipc4: logging: Add dynamic log level control via logs_mask Implement dynamic log level selection based on the logs_mask field from the IPC4_ENABLE_LOGS command, allowing the host to control firmware logging verbosity at runtime. Previously, logging was enabled with a fixed compile-time level (CONFIG_SOF_LOG_LEVEL), preventing dynamic control. This change parses the logs_mask[0] bits 0-4 to determine the requested log level and passes it to the backend. Mask bit mapping to Zephyr log levels: - bit 0 (critical/error) -> LOG_LEVEL_ERR (1) - bit 1 (high/warning) -> LOG_LEVEL_WRN (2) - bit 2 (medium) -> LOG_LEVEL_INF (3) - bit 3 (low/info) -> LOG_LEVEL_INF (3) - bit 4 (verbose/debug) -> LOG_LEVEL_DBG (4) The highest set bit determines the maximum log level. This allows the host to request ERROR-only logging for quiet operation, or DEBUG for verbose troubleshooting, without firmware recompilation. Additionally, log_backend_enable() is now always called (it is idempotent and safe for reconfiguration), removing the previous check that prevented level changes on already-active backends. A TODO comment documents that the mask handling should be improved with proper macros or structs in the future for better code maintainability, but the current implementation is sufficient. Signed-off-by: Tomasz Leman --- src/ipc/ipc4/logging.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/ipc/ipc4/logging.c b/src/ipc/ipc4/logging.c index feb0863f64b7..bebb345224f3 100644 --- a/src/ipc/ipc4/logging.c +++ b/src/ipc/ipc4/logging.c @@ -140,14 +140,42 @@ int ipc4_logging_enable_logs(bool first_block, log_state = (const struct ipc4_log_state_info *)data; if (log_state->enable) { + uint32_t log_level = LOG_LEVEL_NONE; /* Default if no bits set */ + uint32_t mask = log_state->logs_mask[0]; + + /* TODO: Improve mask handling for better code maintainability + * The logs_mask bits should be defined using proper macros or a struct + * to improve readability and maintainability. Current hardcoded bit + * positions are sufficient for now but should be refactored in the future. + * Possible improvements: + * - Define IPC4_LOG_MASK_* macros for each bit position + * - Create a struct with bitfields for each priority level + * - Add proper documentation in IPC4 specification headers + */ + + /* Determine log level from mask bits 0-4 (priority levels) + * bit 0: critical & error -> LOG_LEVEL_ERR + * bit 1: high & warning -> LOG_LEVEL_WRN + * bit 2: medium -> LOG_LEVEL_INF + * bit 3: low & info -> LOG_LEVEL_INF + * bit 4: verbose & debug -> LOG_LEVEL_DBG + * Check highest bit set to determine maximum log level + */ + if (mask & BIT(4)) + log_level = LOG_LEVEL_DBG; + else if (mask & (BIT(3) | BIT(2))) + log_level = LOG_LEVEL_INF; + else if (mask & BIT(1)) + log_level = LOG_LEVEL_WRN; + else if (mask & BIT(0)) + log_level = LOG_LEVEL_ERR; + adsp_mtrace_log_init(mtrace_log_hook); /* Initialize work queue if not already initialized */ if (!log_work.work.handler) k_work_init_delayable(&log_work, log_work_handler); - /* Enable backend if not already active */ - if (!log_backend_is_active(log_backend)) - log_backend_enable(log_backend, mtrace_log_hook, CONFIG_SOF_LOG_LEVEL); + log_backend_enable(log_backend, mtrace_log_hook, log_level); mtrace_aging_timer = log_state->aging_timer_period; if (mtrace_aging_timer < IPC4_MTRACE_AGING_TIMER_MIN_MS) { From 2aacdb1546eb1417d6fd7c3b623ed5e0bd2bd59c Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Tue, 10 Feb 2026 21:30:40 +0100 Subject: [PATCH 3/4] boards: ace: Enable runtime log filtering with ERROR default level Enable CONFIG_LOG_RUNTIME_FILTERING and set CONFIG_LOG_RUNTIME_DEFAULT_LEVEL to 1 (ERROR) for all Intel ADSP ACE platforms. This provides quiet firmware boot with minimal logging overhead while maintaining full DEBUG compile-time capability for dynamic log level control via IPC. Platforms configured: - intel_adsp_ace15_mtpm - intel_adsp_ace20_lnl - intel_adsp_ace30_ptl - intel_adsp_ace30_wcl - intel_adsp_ace40_nvl - intel_adsp_ace40_nvls With these settings: - Firmware boots showing only ERROR level logs (quiet startup) - Host can dynamically increase verbosity to INFO or DEBUG via IPC4_ENABLE_LOGS without recompilation - All log macros (LOG_ERR, LOG_INF, etc.) remain compiled in Runtime filtering is explicitly disabled in debug_overlay.conf to maintain current debug build behavior where logs are not filtered at runtime. This works in conjunction with the IPC4 logging handler changes that parse logs_mask to set the appropriate runtime filter level. Signed-off-by: Tomasz Leman --- app/boards/intel_adsp_ace15_mtpm.conf | 2 ++ app/boards/intel_adsp_ace20_lnl.conf | 2 ++ app/boards/intel_adsp_ace30_ptl.conf | 2 ++ app/boards/intel_adsp_ace30_wcl.conf | 2 ++ app/boards/intel_adsp_ace40_nvl.conf | 2 ++ app/boards/intel_adsp_ace40_nvls.conf | 2 ++ app/debug_overlay.conf | 4 ++++ 7 files changed, 16 insertions(+) diff --git a/app/boards/intel_adsp_ace15_mtpm.conf b/app/boards/intel_adsp_ace15_mtpm.conf index e95b18d97169..8cbaf5e96bba 100644 --- a/app/boards/intel_adsp_ace15_mtpm.conf +++ b/app/boards/intel_adsp_ace15_mtpm.conf @@ -86,3 +86,5 @@ CONFIG_LOG_BACKEND_ADSP=n CONFIG_LOG_BACKEND_SOF_PROBE=n CONFIG_WINSTREAM_CONSOLE=n CONFIG_LOG_FLUSH_SLEEP_US=5000 +CONFIG_LOG_RUNTIME_FILTERING=y +CONFIG_LOG_RUNTIME_DEFAULT_LEVEL=1 diff --git a/app/boards/intel_adsp_ace20_lnl.conf b/app/boards/intel_adsp_ace20_lnl.conf index beb441d6e6c6..f9a0fdb05e02 100644 --- a/app/boards/intel_adsp_ace20_lnl.conf +++ b/app/boards/intel_adsp_ace20_lnl.conf @@ -63,3 +63,5 @@ CONFIG_PM_DEVICE_RUNTIME_ASYNC=n CONFIG_LOG_BACKEND_ADSP=n CONFIG_WINSTREAM_CONSOLE=n CONFIG_LOG_FLUSH_SLEEP_US=5000 +CONFIG_LOG_RUNTIME_FILTERING=y +CONFIG_LOG_RUNTIME_DEFAULT_LEVEL=1 diff --git a/app/boards/intel_adsp_ace30_ptl.conf b/app/boards/intel_adsp_ace30_ptl.conf index 12aa78162c06..96765f46d7fe 100644 --- a/app/boards/intel_adsp_ace30_ptl.conf +++ b/app/boards/intel_adsp_ace30_ptl.conf @@ -66,6 +66,8 @@ CONFIG_PM_DEVICE_RUNTIME_ASYNC=n CONFIG_LOG_BACKEND_ADSP=n CONFIG_LOG_FLUSH_SLEEP_US=5000 CONFIG_WINSTREAM_CONSOLE=n +CONFIG_LOG_RUNTIME_FILTERING=y +CONFIG_LOG_RUNTIME_DEFAULT_LEVEL=1 # Userspace options CONFIG_USERSPACE=y diff --git a/app/boards/intel_adsp_ace30_wcl.conf b/app/boards/intel_adsp_ace30_wcl.conf index 621eb719de9f..b4796985426c 100644 --- a/app/boards/intel_adsp_ace30_wcl.conf +++ b/app/boards/intel_adsp_ace30_wcl.conf @@ -62,3 +62,5 @@ CONFIG_PM_DEVICE_RUNTIME_ASYNC=n CONFIG_LOG_BACKEND_ADSP=n CONFIG_LOG_FLUSH_SLEEP_US=5000 CONFIG_WINSTREAM_CONSOLE=n +CONFIG_LOG_RUNTIME_FILTERING=y +CONFIG_LOG_RUNTIME_DEFAULT_LEVEL=1 diff --git a/app/boards/intel_adsp_ace40_nvl.conf b/app/boards/intel_adsp_ace40_nvl.conf index 75652f508d53..0f60dc5569b1 100644 --- a/app/boards/intel_adsp_ace40_nvl.conf +++ b/app/boards/intel_adsp_ace40_nvl.conf @@ -55,6 +55,8 @@ CONFIG_PM_DEVICE_RUNTIME_ASYNC=n # Zephyr / logging CONFIG_LOG_BACKEND_ADSP=n CONFIG_WINSTREAM_CONSOLE=n +CONFIG_LOG_RUNTIME_FILTERING=y +CONFIG_LOG_RUNTIME_DEFAULT_LEVEL=1 # Zephyr / debug: temporary, until fixed CONFIG_GDBSTUB=n diff --git a/app/boards/intel_adsp_ace40_nvls.conf b/app/boards/intel_adsp_ace40_nvls.conf index 75652f508d53..0f60dc5569b1 100644 --- a/app/boards/intel_adsp_ace40_nvls.conf +++ b/app/boards/intel_adsp_ace40_nvls.conf @@ -55,6 +55,8 @@ CONFIG_PM_DEVICE_RUNTIME_ASYNC=n # Zephyr / logging CONFIG_LOG_BACKEND_ADSP=n CONFIG_WINSTREAM_CONSOLE=n +CONFIG_LOG_RUNTIME_FILTERING=y +CONFIG_LOG_RUNTIME_DEFAULT_LEVEL=1 # Zephyr / debug: temporary, until fixed CONFIG_GDBSTUB=n diff --git a/app/debug_overlay.conf b/app/debug_overlay.conf index 914210d4184d..8b91a757d89d 100644 --- a/app/debug_overlay.conf +++ b/app/debug_overlay.conf @@ -23,3 +23,7 @@ CONFIG_COLD_STORE_EXECUTE_DEBUG=y CONFIG_GDBSTUB=y CONFIG_GDBSTUB_ENTER_IMMEDIATELY=n + +# Logging options +# Disable runtime filtering to maintain expected behavior in SOF CI. +CONFIG_LOG_RUNTIME_FILTERING=n From 4ac31197249c42874aa9c77defe5d57e5a4b72cd Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Wed, 11 Feb 2026 12:34:49 +0100 Subject: [PATCH 4/4] drc: Export log_dynamic symbol for LLEXT with runtime filtering Export log_dynamic_drc symbol when CONFIG_LOG_RUNTIME_FILTERING is enabled to fix LLEXT module linking failure. When runtime filtering is enabled, LOG_MODULE_REGISTER() creates both log_const_ and log_dynamic_ structures. LLEXT modules need to link against these symbols at load time. Previously, only log_const_drc was exported, causing the LLEXT linker to fail with: llext: llext_link_plt: PLT: cannot find idx 46 name log_dynamic_drc llext: do_llext_load: Failed to link, ret -2 lib_manager: llext_manager_link_single: linking failed: -2 This prevented the DRC module from loading when built as LLEXT with runtime log filtering enabled. The fix conditionally exports log_dynamic_drc when runtime filtering is configured, allowing the LLEXT module to resolve all required logging symbols. Signed-off-by: Tomasz Leman --- src/audio/drc/drc_log.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/audio/drc/drc_log.c b/src/audio/drc/drc_log.c index f16feaabcedd..d2e0f1efe7ea 100644 --- a/src/audio/drc/drc_log.c +++ b/src/audio/drc/drc_log.c @@ -11,3 +11,6 @@ SOF_DEFINE_REG_UUID(drc); LOG_MODULE_REGISTER(drc, CONFIG_SOF_LOG_LEVEL); DECLARE_TR_CTX(drc_tr, SOF_UUID(drc_uuid), LOG_LEVEL_INFO); EXPORT_SYMBOL(log_const_drc); +#ifdef CONFIG_LOG_RUNTIME_FILTERING +EXPORT_SYMBOL(log_dynamic_drc); +#endif