Skip to content

Commit ebedb35

Browse files
[nrf fromtree] arch: arm: cortex_m: pm_s2ram: Rework S2RAM mark functions
The S2RAM procedure requires marker checking after reset. Such checking is performed on very early stage of the system initialization and must ensure that the stack is not used due to the TLS pointer which is not initialized yet. Signed-off-by: Adam Kondraciuk <[email protected]> (cherry picked from commit 474d4c3)
1 parent a735c24 commit ebedb35

File tree

3 files changed

+54
-19
lines changed

3 files changed

+54
-19
lines changed

arch/arm/core/cortex_m/pm_s2ram.S

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ SECTION_FUNC(TEXT, arch_pm_s2ram_suspend)
7070
/*
7171
* Mark entering suspend to RAM.
7272
*/
73-
bl pm_s2ram_mark_set
73+
mov r1, lr
74+
bl pm_s2ram_mark_set
75+
mov lr, r1
7476

7577
/*
7678
* Call the system_off function passed as parameter. This should never
@@ -86,7 +88,9 @@ SECTION_FUNC(TEXT, arch_pm_s2ram_suspend)
8688
/*
8789
* Reset the marking of suspend to RAM, return is ignored.
8890
*/
89-
bl pm_s2ram_mark_check_and_clear
91+
mov r1, lr
92+
bl pm_s2ram_mark_check_and_clear
93+
mov lr, r1
9094

9195
/* Move system_off back to r0 as return value */
9296
mov r0, r4
@@ -99,16 +103,13 @@ GTEXT(arch_pm_s2ram_resume)
99103
SECTION_FUNC(TEXT, arch_pm_s2ram_resume)
100104
/*
101105
* Check if reset occurred after suspending to RAM.
102-
* Store LR to ensure we can continue boot when we are not suspended
103-
* to RAM. In addition to LR, R0 is pushed too, to ensure "SP mod 8 = 0",
104-
* as stated by ARM rule 6.2.1.2 for AAPCS32.
105106
*/
106-
push {r0, lr}
107-
bl pm_s2ram_mark_check_and_clear
108-
cmp r0, #0x1
109-
pop {r0, lr}
110-
beq resume
111-
bx lr
107+
mov r1, lr
108+
bl pm_s2ram_mark_check_and_clear
109+
mov lr, r1
110+
cmp r0, #0x1
111+
beq resume
112+
bx lr
112113

113114
resume:
114115
/*

arch/arm/core/cortex_m/pm_s2ram.c

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,44 @@ __noinit _cpu_context_t _cpu_context;
2222
*/
2323
static __noinit uint32_t marker;
2424

25-
void pm_s2ram_mark_set(void)
25+
void __attribute__((naked)) pm_s2ram_mark_set(void)
2626
{
27-
marker = MAGIC;
27+
__asm__ volatile(
28+
/* Set the marker to MAGIC value */
29+
"str %[_magic_val], [%[_marker]]\n"
30+
31+
"bx lr\n"
32+
:
33+
: [_magic_val] "r"(MAGIC), [_marker] "r"(&marker)
34+
: "r1", "r4", "memory");
2835
}
2936

30-
bool pm_s2ram_mark_check_and_clear(void)
37+
bool __attribute__((naked)) pm_s2ram_mark_check_and_clear(void)
3138
{
32-
if (marker == MAGIC) {
33-
marker = 0;
39+
__asm__ volatile(
40+
/* Set return value to 0 */
41+
"mov r0, #0\n"
42+
43+
/* Check the marker */
44+
"ldr r3, [%[_marker]]\n"
45+
"cmp r3, %[_magic_val]\n"
46+
"bne exit\n"
47+
48+
/*
49+
* Reset the marker
50+
*/
51+
"str r0, [%[_marker]]\n"
3452

35-
return true;
36-
}
53+
/*
54+
* Set return value to 1
55+
*/
56+
"mov r0, #1\n"
3757

38-
return false;
58+
"exit:\n"
59+
"bx lr\n"
60+
:
61+
: [_magic_val] "r"(MAGIC), [_marker] "r"(&marker)
62+
: "r0", "r1", "r3", "r4", "memory");
3963
}
4064

4165
#endif /* CONFIG_PM_S2RAM_CUSTOM_MARKING */

include/zephyr/arch/common/pm_s2ram.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ int arch_pm_s2ram_suspend(pm_s2ram_system_off_fn_t system_off);
6565
*
6666
* Default implementation is setting a magic word in RAM. CONFIG_PM_S2RAM_CUSTOM_MARKING
6767
* allows custom implementation.
68+
* The following requirements must be fulfilled:
69+
* - the function cannot use stack (asm function or function with 'naked' attribute)
70+
* - the content of the R1 and R4 registers must remain unchanged
71+
* - returning from the function should be performed with the `bx lr` instruction
72+
*
6873
*/
6974
void pm_s2ram_mark_set(void);
7075

@@ -76,6 +81,11 @@ void pm_s2ram_mark_set(void);
7681
*
7782
* Default implementation is checking a magic word in RAM. CONFIG_PM_S2RAM_CUSTOM_MARKING
7883
* allows custom implementation.
84+
* The following requirements must be fulfilled:
85+
* - the function cannot use stack (most likely asm function)
86+
* - the content of the R1 and R4 registers must remain unchanged
87+
* - the function's return value is passed by R0 register
88+
* - returning from the function should be performed with the `bx lr` instruction
7989
*
8090
* @retval true if marking is found which indicates resuming after suspend-to-RAM.
8191
* @retval false if marking is not found which indicates standard boot.

0 commit comments

Comments
 (0)