From 2590c48d40de8684609436c28b080a693ef56b09 Mon Sep 17 00:00:00 2001 From: Hessel van der Molen Date: Tue, 20 Aug 2024 13:15:56 +0200 Subject: [PATCH] arch: arm: cortex_m: pm_s2ram: save system_off before s2ram marking The r0 register holds the system_off function pointer. As r0 is a scratch register, the pointer needs to moved to a preserved register before branching to a (custom) marker function. Furthermore, in accordance to rule 6.2.1.2 of aapcs32, the stack pointer needs to align on 8 bytes. Hence r0 is pushed to the stack in addition to the lr register, before calling the public interface of checking the s2ram marker. Signed-off-by: Hessel van der Molen --- arch/arm/core/cortex_m/pm_s2ram.S | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/arch/arm/core/cortex_m/pm_s2ram.S b/arch/arm/core/cortex_m/pm_s2ram.S index 1e5bca04fe2..f9c82b4069b 100644 --- a/arch/arm/core/cortex_m/pm_s2ram.S +++ b/arch/arm/core/cortex_m/pm_s2ram.S @@ -27,6 +27,11 @@ SECTION_FUNC(TEXT, arch_pm_s2ram_suspend) * r0: address of the system_off function */ push {r4-r12, lr} + + /* Move system_off to protected register. */ + mov r4, r0 + + /* Store CPU context */ ldr r1, =_cpu_context mrs r2, msp @@ -71,7 +76,7 @@ SECTION_FUNC(TEXT, arch_pm_s2ram_suspend) * Call the system_off function passed as parameter. This should never * return. */ - blx r0 + blx r4 /* * The system_off function returns here only when the powering off was @@ -81,9 +86,10 @@ SECTION_FUNC(TEXT, arch_pm_s2ram_suspend) /* * Reset the marking of suspend to RAM, return is ignored. */ - push {r0} bl pm_s2ram_mark_check_and_clear - pop {r0} + + /* Move system_off back to r0 as return value */ + mov r0, r4 pop {r4-r12, lr} bx lr @@ -93,11 +99,14 @@ GTEXT(arch_pm_s2ram_resume) SECTION_FUNC(TEXT, arch_pm_s2ram_resume) /* * Check if reset occurred after suspending to RAM. + * Store LR to ensure we can continue boot when we are not suspended + * to RAM. In addition to LR, R0 is pushed too, to ensure "SP mod 8 = 0", + * as stated by ARM rule 6.2.1.2 for AAPCS32. */ - push {lr} + push {r0, lr} bl pm_s2ram_mark_check_and_clear cmp r0, #0x1 - pop {lr} + pop {r0, lr} beq resume bx lr