soc: intel_adsp_cavs: store PS when power gating secondary core

When non-primary core is powered down and restart with sequence of:
 - PM state set to SOFT_OFF
 - once target core is idle, cut power with soc_adsp_halt_cpu()
 - power up core again with k_smp_cpu_resume()

The execution will continue from stored DSP core context, but
will hit an assert in z_smp_cpu_mobile() as the PS.INTLEVEL
is zero.

Fix this issue by storing and restoring PS register in this flow.

Link: https://github.com/zephyrproject-rtos/zephyr/issues/70181
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
This commit is contained in:
Kai Vehmanen 2024-03-13 21:59:35 +02:00 committed by Anas Nashif
parent d1029da089
commit 010f39a409

View file

@ -58,6 +58,7 @@ struct core_state {
uint32_t a1;
uint32_t excsave2;
uint32_t intenable;
uint32_t ps;
};
static struct core_state core_desc[CONFIG_MP_MAX_NUM_CPUS] = {{0}};
@ -83,6 +84,7 @@ static ALWAYS_INLINE void _save_core_context(void)
{
uint32_t core_id = arch_proc_id();
core_desc[core_id].ps = XTENSA_RSR("PS");
core_desc[core_id].excsave2 = XTENSA_RSR(ZSR_CPU_STR);
__asm__ volatile("mov %0, a0" : "=r"(core_desc[core_id].a0));
__asm__ volatile("mov %0, a1" : "=r"(core_desc[core_id].a1));
@ -93,6 +95,7 @@ static ALWAYS_INLINE void _restore_core_context(void)
{
uint32_t core_id = arch_proc_id();
XTENSA_WSR("PS", core_desc[core_id].ps);
XTENSA_WSR(ZSR_CPU_STR, core_desc[core_id].excsave2);
__asm__ volatile("mov a0, %0" :: "r"(core_desc[core_id].a0));
__asm__ volatile("mov a1, %0" :: "r"(core_desc[core_id].a1));