Skip to content

Commit e57d10f

Browse files
author
Mathieu Choplain
committed
arch: arm: cortex_m: pm_s2ram: wrap context save/restore in macros
Wrap the CPU register save/restore operations (GPR and special registers) in macros to make core logic simpler to follow. This is also a preparatory step to introduce ARMv6-M and ARMv7-M support. Signed-off-by: Mathieu Choplain <[email protected]>
1 parent 78bff68 commit e57d10f

File tree

1 file changed

+62
-34
lines changed

1 file changed

+62
-34
lines changed

arch/arm/core/cortex_m/pm_s2ram.S

Lines changed: 62 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,63 @@
3838
ldr tmp_reg, [cpu_ctx_reg, # CPU_CTX_SR_OFFSET(sr_name)]; \
3939
msr sr_name, tmp_reg;
4040

41+
/*
42+
* The following macros could be written as assembler macros, but C is used
43+
* for portability (assembler macro syntax may differ between toolchains).
44+
*/
45+
46+
/*
47+
* Pushes registers r4~r12 and lr on the stack.
48+
* r0 is unmodified but other GPRs may be overwritten.
49+
*/
50+
#define PUSH_GPRS \
51+
push {r4-r12, lr}
52+
53+
/*
54+
* Pops registers r4~r12 and lr from the stack
55+
* r0 is unmodified but other GPRs may be overwritten.
56+
*/
57+
#define POP_GPRS \
58+
pop {r4-r12, lr}
59+
60+
/*
61+
* Saves the CPU's special registers in the `struct __cpu_context`
62+
* pointed to by the `cpu_ctx` register.
63+
* The `tmp_reg` register is overwritten as part of this process.
64+
*/
65+
#define SAVE_SPECIAL_REGISTERS(cpu_ctx, tmp_reg) \
66+
SAVE_SPECIAL_REG(msp, cpu_ctx, tmp_reg) \
67+
SAVE_SPECIAL_REG(msplim, cpu_ctx, tmp_reg) \
68+
SAVE_SPECIAL_REG(psp, cpu_ctx, tmp_reg) \
69+
SAVE_SPECIAL_REG(psplim, cpu_ctx, tmp_reg) \
70+
SAVE_SPECIAL_REG(primask, cpu_ctx, tmp_reg) \
71+
SAVE_SPECIAL_REG(faultmask, cpu_ctx, tmp_reg) \
72+
SAVE_SPECIAL_REG(basepri, cpu_ctx, tmp_reg) \
73+
SAVE_SPECIAL_REG(control, cpu_ctx, tmp_reg)
74+
75+
/*
76+
* Restores the CPU's special registers from the `struct __cpu_context`
77+
* pointed to by the `cpu_ctx` register.
78+
* The `tmp_reg` register is overwritten as part of this process.
79+
*
80+
* N.B.: ISB at the end is required because "Software must use an ISB
81+
* barrier instruction to ensure a write to the CONTROL register takes
82+
* effect before the next instruction is executed."
83+
*
84+
* If this macro is modified, make sure CONTROL is always the last
85+
* restored register, and that an ISB follows the MSR instruction.
86+
*/
87+
#define RESTORE_SPECIAL_REGISTERS(cpu_ctx, tmp_reg) \
88+
RESTORE_SPECIAL_REG(msp, cpu_ctx, tmp_reg) \
89+
RESTORE_SPECIAL_REG(msplim, cpu_ctx, tmp_reg) \
90+
RESTORE_SPECIAL_REG(psp, cpu_ctx, tmp_reg) \
91+
RESTORE_SPECIAL_REG(psplim, cpu_ctx, tmp_reg) \
92+
RESTORE_SPECIAL_REG(primask, cpu_ctx, tmp_reg) \
93+
RESTORE_SPECIAL_REG(faultmask, cpu_ctx, tmp_reg) \
94+
RESTORE_SPECIAL_REG(basepri, cpu_ctx, tmp_reg) \
95+
RESTORE_SPECIAL_REG(control, cpu_ctx, tmp_reg) \
96+
isb
97+
4198
_ASM_FILE_PROLOGUE
4299

43100
GTEXT(pm_s2ram_mark_set)
@@ -50,29 +107,15 @@ SECTION_FUNC(TEXT, arch_pm_s2ram_suspend)
50107
*
51108
* r0: address of the system_off function
52109
*/
53-
push {r4-r12, lr}
110+
PUSH_GPRS
54111

55112
/* Move system_off to protected register. */
56113
mov r4, r0
57114

58115
/* Store CPU context */
59116
ldr r1, =_cpu_context
60117

61-
SAVE_SPECIAL_REG(msp, r1, r2)
62-
63-
SAVE_SPECIAL_REG(msplim, r1, r2)
64-
65-
SAVE_SPECIAL_REG(psp, r1, r2)
66-
67-
SAVE_SPECIAL_REG(psplim, r1, r2)
68-
69-
SAVE_SPECIAL_REG(primask, r1, r2)
70-
71-
SAVE_SPECIAL_REG(faultmask, r1, r2)
72-
73-
SAVE_SPECIAL_REG(basepri, r1, r2)
74-
75-
SAVE_SPECIAL_REG(control, r1, r2)
118+
SAVE_SPECIAL_REGISTERS(/* ctx: */ r1, /* tmp: */ r2)
76119

77120
/*
78121
* Mark entering suspend to RAM.
@@ -102,7 +145,7 @@ SECTION_FUNC(TEXT, arch_pm_s2ram_suspend)
102145
/* Move system_off back to r0 as return value */
103146
mov r0, r4
104147

105-
pop {r4-r12, lr}
148+
POP_GPRS
106149
bx lr
107150

108151

@@ -124,24 +167,9 @@ resume:
124167
*/
125168
ldr r0, =_cpu_context
126169

127-
RESTORE_SPECIAL_REG(msp, r0, r1)
170+
RESTORE_SPECIAL_REGISTERS(/* ctx: */ r0, /* tmp: */ r1)
128171

129-
RESTORE_SPECIAL_REG(msplim, r0, r1)
130-
131-
RESTORE_SPECIAL_REG(psp, r0, r1)
132-
133-
RESTORE_SPECIAL_REG(psplim, r0, r1)
134-
135-
RESTORE_SPECIAL_REG(primask, r0, r1)
136-
137-
RESTORE_SPECIAL_REG(faultmask, r0, r1)
138-
139-
RESTORE_SPECIAL_REG(basepri, r0, r1)
140-
141-
RESTORE_SPECIAL_REG(control, r0, r1)
142-
isb
143-
144-
pop {r4-r12, lr}
172+
POP_GPRS
145173

146174
/*
147175
* Set the return value and return

0 commit comments

Comments
 (0)