Commit 010f39a4 authored by Kai Vehmanen's avatar Kai Vehmanen Committed by Anas Nashif
Browse files

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: default avatarKai Vehmanen <kai.vehmanen@linux.intel.com>
parent d1029da0
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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));