OpenOCD
rtos_standard_stackings.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2011 by Broadcom Corporation *
5  * Evan Hunter - ehunter@broadcom.com *
6  ***************************************************************************/
7 
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11 
12 #include "rtos.h"
13 #include "target/armv7m.h"
14 
16  { ARMV7M_R0, 0x20, 32 }, /* r0 */
17  { ARMV7M_R1, 0x24, 32 }, /* r1 */
18  { ARMV7M_R2, 0x28, 32 }, /* r2 */
19  { ARMV7M_R3, 0x2c, 32 }, /* r3 */
20  { ARMV7M_R4, 0x00, 32 }, /* r4 */
21  { ARMV7M_R5, 0x04, 32 }, /* r5 */
22  { ARMV7M_R6, 0x08, 32 }, /* r6 */
23  { ARMV7M_R7, 0x0c, 32 }, /* r7 */
24  { ARMV7M_R8, 0x10, 32 }, /* r8 */
25  { ARMV7M_R9, 0x14, 32 }, /* r9 */
26  { ARMV7M_R10, 0x18, 32 }, /* r10 */
27  { ARMV7M_R11, 0x1c, 32 }, /* r11 */
28  { ARMV7M_R12, 0x30, 32 }, /* r12 */
29  { ARMV7M_R13, -2, 32 }, /* sp */
30  { ARMV7M_R14, 0x34, 32 }, /* lr */
31  { ARMV7M_PC, 0x38, 32 }, /* pc */
32  { ARMV7M_XPSR, 0x3c, 32 }, /* xPSR */
33 };
34 
36  { ARMV7M_R0, 0x24, 32 }, /* r0 */
37  { ARMV7M_R1, 0x28, 32 }, /* r1 */
38  { ARMV7M_R2, 0x2c, 32 }, /* r2 */
39  { ARMV7M_R3, 0x30, 32 }, /* r3 */
40  { ARMV7M_R4, 0x00, 32 }, /* r4 */
41  { ARMV7M_R5, 0x04, 32 }, /* r5 */
42  { ARMV7M_R6, 0x08, 32 }, /* r6 */
43  { ARMV7M_R7, 0x0c, 32 }, /* r7 */
44  { ARMV7M_R8, 0x10, 32 }, /* r8 */
45  { ARMV7M_R9, 0x14, 32 }, /* r9 */
46  { ARMV7M_R10, 0x18, 32 }, /* r10 */
47  { ARMV7M_R11, 0x1c, 32 }, /* r11 */
48  { ARMV7M_R12, 0x34, 32 }, /* r12 */
49  { ARMV7M_R13, -2, 32 }, /* sp */
50  { ARMV7M_R14, 0x38, 32 }, /* lr */
51  { ARMV7M_PC, 0x3c, 32 }, /* pc */
52  { ARMV7M_XPSR, 0x40, 32 }, /* xPSR */
53 };
54 
56  { ARMV7M_R0, 0x64, 32 }, /* r0 */
57  { ARMV7M_R1, 0x68, 32 }, /* r1 */
58  { ARMV7M_R2, 0x6c, 32 }, /* r2 */
59  { ARMV7M_R3, 0x70, 32 }, /* r3 */
60  { ARMV7M_R4, 0x00, 32 }, /* r4 */
61  { ARMV7M_R5, 0x04, 32 }, /* r5 */
62  { ARMV7M_R6, 0x08, 32 }, /* r6 */
63  { ARMV7M_R7, 0x0c, 32 }, /* r7 */
64  { ARMV7M_R8, 0x10, 32 }, /* r8 */
65  { ARMV7M_R9, 0x14, 32 }, /* r9 */
66  { ARMV7M_R10, 0x18, 32 }, /* r10 */
67  { ARMV7M_R11, 0x1c, 32 }, /* r11 */
68  { ARMV7M_R12, 0x74, 32 }, /* r12 */
69  { ARMV7M_R13, -2, 32 }, /* sp */
70  { ARMV7M_R14, 0x78, 32 }, /* lr */
71  { ARMV7M_PC, 0x7c, 32 }, /* pc */
72  { ARMV7M_XPSR, 0x80, 32 }, /* xPSR */
73 };
74 
75 
77  { 0, 0x08, 32 }, /* r0 (a1) */
78  { 1, 0x0c, 32 }, /* r1 (a2) */
79  { 2, 0x10, 32 }, /* r2 (a3) */
80  { 3, 0x14, 32 }, /* r3 (a4) */
81  { 4, 0x18, 32 }, /* r4 (v1) */
82  { 5, 0x1c, 32 }, /* r5 (v2) */
83  { 6, 0x20, 32 }, /* r6 (v3) */
84  { 7, 0x24, 32 }, /* r7 (v4) */
85  { 8, 0x28, 32 }, /* r8 (a1) */
86  { 10, 0x2c, 32 }, /* r9 (sb) */
87  { 11, 0x30, 32 }, /* r10 (sl) */
88  { 12, 0x34, 32 }, /* r11 (fp) */
89  { 13, 0x38, 32 }, /* r12 (ip) */
90  { 14, -2, 32 }, /* sp */
91  { 15, 0x3c, 32 }, /* lr */
92  { 16, 0x40, 32 }, /* pc */
93  { 17, -1, 96 }, /* FPA1 */
94  { 18, -1, 96 }, /* FPA2 */
95  { 19, -1, 96 }, /* FPA3 */
96  { 20, -1, 96 }, /* FPA4 */
97  { 21, -1, 96 }, /* FPA5 */
98  { 22, -1, 96 }, /* FPA6 */
99  { 23, -1, 96 }, /* FPA7 */
100  { 24, -1, 96 }, /* FPA8 */
101  { 25, -1, 32 }, /* FPS */
102  { 26, 0x04, 32 }, /* CSPR */
103 };
104 
106  { 0, 0x88, 32 }, /* R0 */
107  { 1, 0x8C, 32 }, /* R1 */
108  { 2, 0x14, 32 }, /* R2 */
109  { 3, 0x18, 32 }, /* R3 */
110  { 4, 0x1C, 32 }, /* R4 */
111  { 5, 0x20, 32 }, /* R5 */
112  { 6, 0x24, 32 }, /* R6 */
113  { 7, 0x28, 32 }, /* R7 */
114  { 8, 0x2C, 32 }, /* R8 */
115  { 9, 0x30, 32 }, /* R9 */
116  { 10, 0x34, 32 }, /* R10 */
117  { 11, 0x38, 32 }, /* R11 */
118  { 12, 0x3C, 32 }, /* R12 */
119  { 13, 0x40, 32 }, /* R13 */
120  { 14, 0x44, 32 }, /* R14 */
121  { 15, 0x48, 32 }, /* R15 */
122  { 16, 0x4C, 32 }, /* R16 */
123  { 17, 0x50, 32 }, /* R17 */
124  { 18, 0x54, 32 }, /* R18 */
125  { 19, 0x58, 32 }, /* R19 */
126  { 20, 0x5C, 32 }, /* R20 */
127  { 21, 0x60, 32 }, /* R21 */
128  { 22, 0x64, 32 }, /* R22 */
129  { 23, 0x68, 32 }, /* R23 */
130  { 24, 0x6C, 32 }, /* R24 */
131  { 25, 0x70, 32 }, /* R25 */
132  { 26, 0x74, 32 }, /* R26 */
133  { 27, 0x78, 32 }, /* R27 */
134  { 28, 0x7C, 32 }, /* R28 */
135  { 29, 0x80, 32 }, /* R29 */
136  { 30, 0x84, 32 }, /* R30 (LP) */
137  { 31, 0x00, 32 }, /* R31 (SP) */
138  { 32, 0x04, 32 }, /* PSW */
139  { 33, 0x08, 32 }, /* IPC */
140  { 34, 0x0C, 32 }, /* IPSW */
141  { 35, 0x10, 32 }, /* IFC_LP */
142 };
143 
145  const uint8_t *stack_data, const struct rtos_register_stacking *stacking,
146  target_addr_t stack_ptr, int align)
147 {
148  target_addr_t new_stack_ptr;
149  target_addr_t aligned_stack_ptr;
150  new_stack_ptr = stack_ptr - stacking->stack_growth_direction *
151  stacking->stack_registers_size;
152  aligned_stack_ptr = new_stack_ptr & ~((target_addr_t)align - 1);
153  if (aligned_stack_ptr != new_stack_ptr &&
154  stacking->stack_growth_direction == -1) {
155  /* If we have a downward growing stack, the simple alignment code
156  * above results in a wrong result (since it rounds down to nearest
157  * alignment). We want to round up so add an extra align.
158  */
159  aligned_stack_ptr += (target_addr_t)align;
160  }
161  return aligned_stack_ptr;
162 }
163 
165  const uint8_t *stack_data, const struct rtos_register_stacking *stacking,
166  target_addr_t stack_ptr)
167 {
168  return rtos_generic_stack_align(target, stack_data,
169  stacking, stack_ptr, 8);
170 }
171 
172 /* The Cortex-M3 will indicate that an alignment adjustment
173  * has been done on the stack by setting bit 9 of the stacked xPSR
174  * register. In this case, we can just add an extra 4 bytes to get
175  * to the program stack. Note that some places in the ARM documentation
176  * make this a little unclear but the padding takes place before the
177  * normal exception stacking - so xPSR is always available at a fixed
178  * location.
179  *
180  * Relevant documentation:
181  * Cortex-M series processors -> Cortex-M3 -> Revision: xxx ->
182  * Cortex-M3 Devices Generic User Guide -> The Cortex-M3 Processor ->
183  * Exception Model -> Exception entry and return -> Exception entry
184  * Cortex-M series processors -> Cortex-M3 -> Revision: xxx ->
185  * Cortex-M3 Devices Generic User Guide -> Cortex-M3 Peripherals ->
186  * System control block -> Configuration and Control Register (STKALIGN)
187  *
188  * This is just a helper function for use in the calculate_process_stack
189  * function for a given architecture/rtos.
190  */
192  const uint8_t *stack_data, const struct rtos_register_stacking *stacking,
193  target_addr_t stack_ptr, size_t xpsr_offset)
194 {
195  const uint32_t ALIGN_NEEDED = (1 << 9);
196  uint32_t xpsr;
197  target_addr_t new_stack_ptr;
198 
199  new_stack_ptr = stack_ptr - stacking->stack_growth_direction *
200  stacking->stack_registers_size;
201  xpsr = (target->endianness == TARGET_LITTLE_ENDIAN) ?
202  le_to_h_u32(&stack_data[xpsr_offset]) :
203  be_to_h_u32(&stack_data[xpsr_offset]);
204  if ((xpsr & ALIGN_NEEDED) != 0) {
205  LOG_DEBUG("XPSR(0x%08" PRIx32 ") indicated stack alignment was necessary\r\n",
206  xpsr);
207  new_stack_ptr -= (stacking->stack_growth_direction * 4);
208  }
209  return new_stack_ptr;
210 }
211 
213  const uint8_t *stack_data, const struct rtos_register_stacking *stacking,
214  target_addr_t stack_ptr)
215 {
216  const int XPSR_OFFSET = 0x3c;
217  return rtos_cortex_m_stack_align(target, stack_data, stacking,
218  stack_ptr, XPSR_OFFSET);
219 }
220 
222  const uint8_t *stack_data, const struct rtos_register_stacking *stacking,
223  target_addr_t stack_ptr)
224 {
225  const int XPSR_OFFSET = 0x40;
226  return rtos_cortex_m_stack_align(target, stack_data, stacking,
227  stack_ptr, XPSR_OFFSET);
228 }
229 
231  const uint8_t *stack_data, const struct rtos_register_stacking *stacking,
232  target_addr_t stack_ptr)
233 {
234  const int XPSR_OFFSET = 0x80;
235  return rtos_cortex_m_stack_align(target, stack_data, stacking,
236  stack_ptr, XPSR_OFFSET);
237 }
238 
239 
241  .stack_registers_size = 0x40,
242  .stack_growth_direction = -1,
243  .num_output_registers = ARMV7M_NUM_CORE_REGS,
244  .calculate_process_stack = rtos_standard_cortex_m3_stack_align,
245  .register_offsets = rtos_standard_cortex_m3_stack_offsets
246 };
247 
249  .stack_registers_size = 0x44,
250  .stack_growth_direction = -1,
251  .num_output_registers = ARMV7M_NUM_CORE_REGS,
252  .calculate_process_stack = rtos_standard_cortex_m4f_stack_align,
253  .register_offsets = rtos_standard_cortex_m4f_stack_offsets
254 };
255 
257  .stack_registers_size = 0xcc,
258  .stack_growth_direction = -1,
259  .num_output_registers = ARMV7M_NUM_CORE_REGS,
260  .calculate_process_stack = rtos_standard_cortex_m4f_fpu_stack_align,
262 };
263 
265  .stack_registers_size = 0x48,
266  .stack_growth_direction = -1,
267  .num_output_registers = 26,
268  .calculate_process_stack = rtos_generic_stack_align8,
269  .register_offsets = rtos_standard_cortex_r4_stack_offsets
270 };
271 
273  .stack_registers_size = 0x90,
274  .stack_growth_direction = -1,
275  .num_output_registers = 32,
276  .calculate_process_stack = rtos_generic_stack_align8,
277  .register_offsets = rtos_standard_nds32_n1068_stack_offsets
278 };
@ ARMV7M_R1
Definition: armv7m.h:108
@ ARMV7M_R6
Definition: armv7m.h:114
@ ARMV7M_R2
Definition: armv7m.h:109
@ ARMV7M_R3
Definition: armv7m.h:110
@ ARMV7M_R14
Definition: armv7m.h:124
@ ARMV7M_R9
Definition: armv7m.h:118
@ ARMV7M_R12
Definition: armv7m.h:122
@ ARMV7M_R0
Definition: armv7m.h:107
@ ARMV7M_R13
Definition: armv7m.h:123
@ ARMV7M_PC
Definition: armv7m.h:125
@ ARMV7M_R7
Definition: armv7m.h:115
@ ARMV7M_R4
Definition: armv7m.h:112
@ ARMV7M_XPSR
Definition: armv7m.h:127
@ ARMV7M_R8
Definition: armv7m.h:117
@ ARMV7M_R11
Definition: armv7m.h:120
@ ARMV7M_R10
Definition: armv7m.h:119
@ ARMV7M_R5
Definition: armv7m.h:113
#define ARMV7M_NUM_CORE_REGS
Definition: armv7m.h:216
#define LOG_DEBUG(expr ...)
Definition: log.h:109
static target_addr_t rtos_standard_cortex_m4f_stack_align(struct target *target, const uint8_t *stack_data, const struct rtos_register_stacking *stacking, target_addr_t stack_ptr)
static target_addr_t rtos_generic_stack_align(struct target *target, const uint8_t *stack_data, const struct rtos_register_stacking *stacking, target_addr_t stack_ptr, int align)
static const struct stack_register_offset rtos_standard_cortex_m4f_stack_offsets[]
static const struct stack_register_offset rtos_standard_cortex_m3_stack_offsets[ARMV7M_NUM_CORE_REGS]
const struct rtos_register_stacking rtos_standard_cortex_m3_stacking
static const struct stack_register_offset rtos_standard_cortex_m4f_fpu_stack_offsets[]
const struct rtos_register_stacking rtos_standard_cortex_m4f_fpu_stacking
static const struct stack_register_offset rtos_standard_nds32_n1068_stack_offsets[]
const struct rtos_register_stacking rtos_standard_cortex_m4f_stacking
static target_addr_t rtos_standard_cortex_m4f_fpu_stack_align(struct target *target, const uint8_t *stack_data, const struct rtos_register_stacking *stacking, target_addr_t stack_ptr)
const struct rtos_register_stacking rtos_standard_cortex_r4_stacking
static target_addr_t rtos_standard_cortex_m3_stack_align(struct target *target, const uint8_t *stack_data, const struct rtos_register_stacking *stacking, target_addr_t stack_ptr)
const struct rtos_register_stacking rtos_standard_nds32_n1068_stacking
static const struct stack_register_offset rtos_standard_cortex_r4_stack_offsets[]
target_addr_t rtos_cortex_m_stack_align(struct target *target, const uint8_t *stack_data, const struct rtos_register_stacking *stacking, target_addr_t stack_ptr, size_t xpsr_offset)
target_addr_t rtos_generic_stack_align8(struct target *target, const uint8_t *stack_data, const struct rtos_register_stacking *stacking, target_addr_t stack_ptr)
unsigned char stack_registers_size
Definition: rtos.h:92
signed char stack_growth_direction
Definition: rtos.h:93
Definition: target.h:120
enum target_endianness endianness
Definition: target.h:160
@ TARGET_LITTLE_ENDIAN
Definition: target.h:86
static uint32_t be_to_h_u32(const uint8_t *buf)
Definition: types.h:139
uint64_t target_addr_t
Definition: types.h:335
static uint32_t le_to_h_u32(const uint8_t *buf)
Definition: types.h:112