Skip to content

Commit

Permalink
soc: intel_adsp_cavs: store PS when power gating secondary core
Browse files Browse the repository at this point in the history
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: zephyrproject-rtos/zephyr#70181
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
  • Loading branch information
kv2019i authored and nashif committed Mar 15, 2024
1 parent d1029da commit 010f39a
Showing 1 changed file with 3 additions and 0 deletions.
3 changes: 3 additions & 0 deletions soc/intel/intel_adsp/cavs/power.c
Original file line number Diff line number Diff line change
Expand Up @@ -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}};
Expand All @@ -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));
Expand All @@ -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));
Expand Down

0 comments on commit 010f39a

Please sign in to comment.