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 th at 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
43100GTEXT(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