Skip to content

Commit 5b0ee9d

Browse files
author
Mathieu Choplain
committed
arch: arm: cortex_m: pm_s2ram: add support for all architectures
Extend the ARM M-profile suspend-to-RAM implementation to be compatible with all versions of the M-profile supported by Zephyr: ARMv6-M, ARMv7-M, and ARMv8-M Baseline. Signed-off-by: Mathieu Choplain <[email protected]>
1 parent e57d10f commit 5b0ee9d

File tree

3 files changed

+89
-16
lines changed

3 files changed

+89
-16
lines changed

arch/arm/core/cortex_m/pm_s2ram.S

Lines changed: 67 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,77 @@
4747
* Pushes registers r4~r12 and lr on the stack.
4848
* r0 is unmodified but other GPRs may be overwritten.
4949
*/
50+
#if !defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
51+
/* `push` on ARMv6-M / ARMv8-M Baseline:
52+
* only r0~r7 and lr may be pushed
53+
*/
54+
#define PUSH_GPRS \
55+
push {r4-r7}; \
56+
mov r1, r8; \
57+
mov r2, r9; \
58+
mov r3, r10; \
59+
mov r4, r11; \
60+
mov r5, r12; \
61+
push {r1-r5, lr}
62+
#else
63+
/* `push` on ARMv7-M and ARMv8-M Mainline: no limitation */
5064
#define PUSH_GPRS \
5165
push {r4-r12, lr}
66+
#endif /* !CONFIG_ARMV7_M_ARMV8_M_MAINLINE */
5267

5368
/*
5469
* Pops registers r4~r12 and lr from the stack
5570
* r0 is unmodified but other GPRs may be overwritten.
5671
*/
72+
#if !defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
73+
/* `pop` on ARMv6-M / ARMv8-M Baseline:
74+
* can only pop to r0~r7 and pc (not lr!)
75+
*/
76+
#define POP_GPRS \
77+
pop {r1-r6}; \
78+
mov lr, r6; \
79+
mov r12, r5; \
80+
mov r11, r4; \
81+
mov r10, r3; \
82+
mov r9, r2; \
83+
mov r8, r1; \
84+
pop {r4-r7}
85+
#else
86+
/* `pop` on ARMv7-M and ARMv8-M Mainline: no limitation */
5787
#define POP_GPRS \
5888
pop {r4-r12, lr}
89+
#endif /* !CONFIG_ARMV7_M_ARMV8_M_MAINLINE */
90+
91+
92+
#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
93+
/* Registers present only on ARMv7-M and ARMv8-M Mainline */
94+
#define SAVE_FM_BP_REGS(cpu_ctx, tmp_reg) \
95+
SAVE_SPECIAL_REG(faultmask, cpu_ctx, tmp_reg) \
96+
SAVE_SPECIAL_REG(basepri, cpu_ctx, tmp_reg)
97+
98+
#define RESTORE_FM_BP_REGS(cpu_ctx, tmp_reg) \
99+
RESTORE_SPECIAL_REG(faultmask, cpu_ctx, tmp_reg) \
100+
RESTORE_SPECIAL_REG(basepri, cpu_ctx, tmp_reg)
101+
#else
102+
/* Registers not present: do nothing */
103+
#define SAVE_FM_BP_REGS(cpu_ctx, tmp_reg)
104+
#define RESTORE_FM_BP_REGS(cpu_ctx, tmp_reg)
105+
#endif /* CONFIG_ARMV7_M_ARMV8_M_MAINLINE */
106+
107+
#if defined(CONFIG_CPU_CORTEX_M_HAS_SPLIM)
108+
/* Registers present only on certain ARMv8-M implementations */
109+
#define SAVE_SPLIM_REGS(cpu_ctx, tmp_reg) \
110+
SAVE_SPECIAL_REG(msplim, cpu_ctx, tmp_reg) \
111+
SAVE_SPECIAL_REG(psplim, cpu_ctx, tmp_reg)
112+
113+
#define RESTORE_SPLIM_REGS(cpu_ctx, tmp_reg) \
114+
RESTORE_SPECIAL_REG(msplim, cpu_ctx, tmp_reg) \
115+
RESTORE_SPECIAL_REG(psplim, cpu_ctx, tmp_reg)
116+
#else
117+
/* Registers not present: do nothing */
118+
#define SAVE_SPLIM_REGS(cpu_ctx, tmp_reg)
119+
#define RESTORE_SPLIM_REGS(cpu_ctx, tmp_reg)
120+
#endif /* CONFIG_CPU_CORTEX_M_HAS_SPLIM */
59121

60122
/*
61123
* Saves the CPU's special registers in the `struct __cpu_context`
@@ -64,12 +126,10 @@
64126
*/
65127
#define SAVE_SPECIAL_REGISTERS(cpu_ctx, tmp_reg) \
66128
SAVE_SPECIAL_REG(msp, cpu_ctx, tmp_reg) \
67-
SAVE_SPECIAL_REG(msplim, cpu_ctx, tmp_reg) \
68129
SAVE_SPECIAL_REG(psp, cpu_ctx, tmp_reg) \
69-
SAVE_SPECIAL_REG(psplim, cpu_ctx, tmp_reg) \
70130
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) \
131+
SAVE_SPLIM_REGS( cpu_ctx, tmp_reg) \
132+
SAVE_FM_BP_REGS( cpu_ctx, tmp_reg) \
73133
SAVE_SPECIAL_REG(control, cpu_ctx, tmp_reg)
74134

75135
/*
@@ -86,12 +146,10 @@
86146
*/
87147
#define RESTORE_SPECIAL_REGISTERS(cpu_ctx, tmp_reg) \
88148
RESTORE_SPECIAL_REG(msp, cpu_ctx, tmp_reg) \
89-
RESTORE_SPECIAL_REG(msplim, cpu_ctx, tmp_reg) \
90149
RESTORE_SPECIAL_REG(psp, cpu_ctx, tmp_reg) \
91-
RESTORE_SPECIAL_REG(psplim, cpu_ctx, tmp_reg) \
92150
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) \
151+
RESTORE_SPLIM_REGS( cpu_ctx, tmp_reg) \
152+
RESTORE_FM_BP_REGS( cpu_ctx, tmp_reg) \
95153
RESTORE_SPECIAL_REG(control, cpu_ctx, tmp_reg) \
96154
isb
97155

@@ -174,5 +232,5 @@ resume:
174232
/*
175233
* Set the return value and return
176234
*/
177-
mov r0, #0
235+
movs r0, #0
178236
bx lr

arch/arm/core/offsets/offsets_aarch32.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,21 @@ GEN_OFFSET_SYM(_thread_stack_info_t, start);
8383
*/
8484
#if defined(CONFIG_PM_S2RAM)
8585
GEN_OFFSET_SYM(_cpu_context_t, msp);
86-
GEN_OFFSET_SYM(_cpu_context_t, msplim);
8786
GEN_OFFSET_SYM(_cpu_context_t, psp);
88-
GEN_OFFSET_SYM(_cpu_context_t, psplim);
89-
9087
GEN_OFFSET_SYM(_cpu_context_t, primask);
88+
GEN_OFFSET_SYM(_cpu_context_t, control);
89+
90+
#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
91+
/* Registers present only on ARMv7-M and ARMv8-M Mainline */
9192
GEN_OFFSET_SYM(_cpu_context_t, faultmask);
9293
GEN_OFFSET_SYM(_cpu_context_t, basepri);
93-
GEN_OFFSET_SYM(_cpu_context_t, control);
94+
#endif /* CONFIG_ARMV7_M_ARMV8_M_MAINLINE */
95+
96+
#if defined(CONFIG_CPU_CORTEX_M_HAS_SPLIM)
97+
/* Registers present only on certain ARMv8-M implementations */
98+
GEN_OFFSET_SYM(_cpu_context_t, msplim);
99+
GEN_OFFSET_SYM(_cpu_context_t, psplim);
100+
#endif /* CONFIG_CPU_CORTEX_M_HAS_SPLIM */
94101
#endif /* CONFIG_PM_S2RAM */
95102

96103
#endif /* _ARM_OFFSETS_INC_ */

include/zephyr/arch/arm/cortex_m/cpu.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,21 @@ extern "C" {
5454
struct __cpu_context {
5555
/* GPRs are saved onto the stack */
5656
uint32_t msp;
57-
uint32_t msplim;
5857
uint32_t psp;
59-
uint32_t psplim;
6058
uint32_t primask;
59+
uint32_t control;
60+
61+
#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
62+
/* Registers present only on ARMv7-M and ARMv8-M Mainline */
6163
uint32_t faultmask;
6264
uint32_t basepri;
63-
uint32_t control;
65+
#endif /* CONFIG_ARMV7_M_ARMV8_M_MAINLINE */
66+
67+
#if defined(CONFIG_CPU_CORTEX_M_HAS_SPLIM)
68+
/* Registers present only on certain ARMv8-M implementations */
69+
uint32_t msplim;
70+
uint32_t psplim;
71+
#endif /* CONFIG_CPU_CORTEX_M_HAS_SPLIM */
6472
};
6573

6674
typedef struct __cpu_context _cpu_context_t;

0 commit comments

Comments
 (0)