From f9183465a8f72403e411527a9f02cb64db1a9371 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 3 Nov 2023 11:57:30 -0700 Subject: [PATCH 1/4] zephyr: use k_smp_cpu_start/_resume for secondary core power up This changes the secondary core power up routine to use the newly introduced k_smp_cpu_start() and k_smp_cpu_resume(). This removes the need to mirror part of the SMP start up code from Zephyr, and no longer need to call into Zephyr private kernel code. West update includes : eefaeee061c8 kernel: smp: introduce k_smp_cpu_resume 042cb6ac4e00 soc: intel_adsp: enable DfTTS-based time stamping on ACE platforms 6a0b1da158a4 soc: intel_adsp: call framework callback function for restore e7217925c93e ace: use a 'switch' statement in pm_state_set() c99a604bbf2c ace: remove superfluous variable initialisation a0ac2faf9bde intel_adsp: ace: enable power domain 4204ca9bcb3f ace: fix DSP panic during startup (fixes c3a6274bf5e4) d4b0273ab0c4 cmake: sparse.template: add COMMAND_ERROR_IS_FATAL ca12fd13c6d3 xtensa: intel_adsp: fix a cache handling error 0ee1e28a2f5f xtensa: polish doxygen and add to missing doc 035c8d8ceb4b xtensa: remove sys_define_gpr_with_alias() a64eec6aaeec xtensa: remove XTENSA_ERR_NORET Signed-off-by: Daniel Leung Signed-off-by: Rander Wang --- west.yml | 2 +- zephyr/lib/cpu.c | 80 ++++++++++-------------------------------------- 2 files changed, 18 insertions(+), 64 deletions(-) diff --git a/west.yml b/west.yml index 37418754dda6..b615055fc3f7 100644 --- a/west.yml +++ b/west.yml @@ -43,7 +43,7 @@ manifest: - name: zephyr repo-path: zephyr - revision: 9852e8e15bc8536aa1a49cc2697c1e8f802e331f + revision: 6a0b1da158a4f8bc5f2ca5058637dce26a38660e remote: zephyrproject # Import some projects listed in zephyr/west.yml@revision diff --git a/zephyr/lib/cpu.c b/zephyr/lib/cpu.c index 3dde19dc38bc..6a896255795a 100644 --- a/zephyr/lib/cpu.c +++ b/zephyr/lib/cpu.c @@ -19,6 +19,7 @@ /* Zephyr includes */ #include #include +#include #include #include @@ -27,37 +28,9 @@ extern K_KERNEL_STACK_ARRAY_DEFINE(z_interrupt_stacks, CONFIG_MP_MAX_NUM_CPUS, CONFIG_ISR_STACK_SIZE); -static atomic_t start_flag; -static atomic_t ready_flag; - -/* Zephyr kernel_internal.h interface */ -extern void smp_timer_init(void); - -static FUNC_NORETURN void secondary_init(void *arg) +static void secondary_init(void *arg) { - struct k_thread dummy_thread; - - /* - * This is an open-coded version of zephyr/kernel/smp.c - * smp_init_top(). We do this so that we can call SOF - * secondary_core_init() for each core. - */ - - atomic_set(&ready_flag, 1); - z_smp_thread_init(arg, &dummy_thread); - smp_timer_init(); - secondary_core_init(sof_get()); - -#ifdef CONFIG_THREAD_STACK_INFO - dummy_thread.stack_info.start = (uintptr_t)z_interrupt_stacks + - arch_curr_cpu()->id * Z_KERNEL_STACK_LEN(CONFIG_ISR_STACK_SIZE); - dummy_thread.stack_info.size = Z_KERNEL_STACK_LEN(CONFIG_ISR_STACK_SIZE); -#endif - - z_smp_thread_swap(); - - CODE_UNREACHABLE; /* LCOV_EXCL_LINE */ } #if CONFIG_ZEPHYR_NATIVE_DRIVERS @@ -113,7 +86,6 @@ void cpu_notify_state_exit(enum pm_state state) /* Notifying primary core that secondary core successfully exit the D3 * state and is back in the Idle thread. */ - atomic_set(&ready_flag, 1); return; } #endif @@ -142,26 +114,17 @@ int cpu_enable_core(int id) if (arch_cpu_active(id)) return 0; -#if ZEPHYR_VERSION(3, 0, 99) <= ZEPHYR_VERSION_CODE /* During kernel initialization, the next pm state is set to ACTIVE. By checking this * value, we determine if this is the first core boot, if not, we need to skip idle thread * initialization. By reinitializing the idle thread, we would overwrite the kernel structs * and the idle thread stack. */ - if (pm_state_next_get(id)->state == PM_STATE_ACTIVE) - z_init_cpu(id); -#endif - - atomic_clear(&start_flag); - atomic_clear(&ready_flag); - - arch_start_cpu(id, z_interrupt_stacks[id], CONFIG_ISR_STACK_SIZE, - secondary_init, &start_flag); - - while (!atomic_get(&ready_flag)) - k_busy_wait(100); + if (pm_state_next_get(id)->state == PM_STATE_ACTIVE) { + k_smp_cpu_start(id, secondary_init, NULL); + return 0; + } - atomic_set(&start_flag, 1); + k_smp_cpu_resume(id, secondary_init, NULL, true, false); return 0; } @@ -239,29 +202,20 @@ int cpu_enable_core(int id) int cpu_enable_secondary_core(int id) { - /* - * This is an open-coded version of zephyr/kernel/smp.c - * z_smp_start_cpu(). We do this, so we can use a customized - * secondary_init() for SOF. - */ - if (arch_cpu_active(id)) return 0; -#if ZEPHYR_VERSION(3, 0, 99) <= ZEPHYR_VERSION_CODE - z_init_cpu(id); -#endif - - atomic_clear(&start_flag); - atomic_clear(&ready_flag); - - arch_start_cpu(id, z_interrupt_stacks[id], CONFIG_ISR_STACK_SIZE, - secondary_init, &start_flag); - - while (!atomic_get(&ready_flag)) - k_busy_wait(100); + /* During kernel initialization, the next pm state is set to ACTIVE. By checking this + * value, we determine if this is the first core boot, if not, we need to skip idle thread + * initialization. By reinitializing the idle thread, we would overwrite the kernel structs + * and the idle thread stack. + */ + if (pm_state_next_get(id)->state == PM_STATE_ACTIVE) { + k_smp_cpu_start(id, secondary_init, NULL); + return 0; + } - atomic_set(&start_flag, 1); + k_smp_cpu_resume(id, secondary_init, NULL, true, false); return 0; } From 0ff4f000f42753b9aa2b542831bc051683b94662 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 31 Jan 2024 17:14:14 +0100 Subject: [PATCH 2/4] [TEST] Check Zephyr fix for secondary core resume https://github.com/zephyrproject-rtos/zephyr/pull/68366 fixes an SOF use case when a pipeline, using a secondary core is stopped, the secondary core is powered down, but the DSP stays powered on, after which the same secondary core is powered on again. The bug prevents correct context restoration. Signed-off-by: Guennadi Liakhovetski --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index b615055fc3f7..799c9af438c2 100644 --- a/west.yml +++ b/west.yml @@ -43,7 +43,7 @@ manifest: - name: zephyr repo-path: zephyr - revision: 6a0b1da158a4f8bc5f2ca5058637dce26a38660e + revision: pull/68366/head remote: zephyrproject # Import some projects listed in zephyr/west.yml@revision From b11b536d3a27fdfc6e294008b2e101376d481a76 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Fri, 26 Jan 2024 19:03:35 +0200 Subject: [PATCH 3/4] chain_dma: workaround for failed DMA stop on pause/stop Starting with Zephyr commit e021ccfc745221c6 ("drivers: dma: intel-adsp-hda: add delay to stop host dma"), the pause-resume sof-test cases started failing on Intel cAVS2.5 platforms. Add a delay loop around DMA stop code in chain DMA to workaround the issue while a proper fix is under investigation. This allows to resume integration of newer Zephyr versions to SOF and ensure we detect any new regressions in time. Link: https://github.com/thesofproject/sof/issues/8792 Signed-off-by: Kai Vehmanen --- src/audio/chain_dma.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/audio/chain_dma.c b/src/audio/chain_dma.c index 696973146404..99e8502f8bd5 100644 --- a/src/audio/chain_dma.c +++ b/src/audio/chain_dma.c @@ -121,9 +121,28 @@ static int chain_host_stop(struct comp_dev *dev) int err; err = dma_stop(cd->chan_host->dma->z_dev, cd->chan_host->index); - if (err < 0) + if (err < 0) { + if (err == -EBUSY) { + int retries = 100; + + comp_warn(dev, "dma_stop() fail chan_index = %u, retrying...", + cd->chan_link->index); + + /* + * FIXME: ugly workaround for + * https://github.com/thesofproject/sof/issues/8686 + */ + while (err == -EBUSY && --retries) { + k_busy_wait(10); + err = dma_stop(cd->chan_link->dma->z_dev, cd->chan_link->index); + if (!err) + goto out; + } + } return err; +} +out: comp_info(dev, "chain_host_stop(): dma_stop() host chan_index = %u", cd->chan_host->index); From cb24cf37027699572c3f169ddc20deb9ae6315e0 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 1 Feb 2024 08:20:21 +0100 Subject: [PATCH 4/4] [MERGE INTO OFFENDER] remove a callback when resuming cores Resuming secondary cores doesn't need a callback, remove it. Signed-off-by: Guennadi Liakhovetski --- zephyr/lib/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zephyr/lib/cpu.c b/zephyr/lib/cpu.c index 6a896255795a..3c6becd79bce 100644 --- a/zephyr/lib/cpu.c +++ b/zephyr/lib/cpu.c @@ -124,7 +124,7 @@ int cpu_enable_core(int id) return 0; } - k_smp_cpu_resume(id, secondary_init, NULL, true, false); + k_smp_cpu_resume(id, NULL, NULL, true, false); return 0; } @@ -215,7 +215,7 @@ int cpu_enable_secondary_core(int id) return 0; } - k_smp_cpu_resume(id, secondary_init, NULL, true, false); + k_smp_cpu_resume(id, NULL, NULL, true, false); return 0; }