Skip to content

Commit 9413a7a

Browse files
Andrew RuderFreddieChopin
Andrew Ruder
authored andcommitted
rtos: turn stack alignment into a function pointer
Some targets (Cortex M) require more complicated calculations for turning the stored stack pointer back into a process stack pointer. For example, the Cortex M stores a bit in the auto-stacked xPSR indicating that alignment had to be performed and an additional 4 byte padding is present before the exception stacking. This change only sets up the framework for Cortex-M unstacking and does not add Cortex-M support. Note: this also fixes the alignment calculation nearly addressed by change #2301 entitled rtos/rtos.c: fix stack alignment calculation. Updated calculation is in rtos_generic_stack_align. Change-Id: I0f662cad0df81cbe5866219ad0fef980dcb3e44f Signed-off-by: Andrew Ruder <[email protected]> Cc: Paul Fertser <[email protected]> Cc: Andreas Fritiofson <[email protected]> Cc: Evan Hunter <[email protected]> Cc: Jon Burgess <[email protected]> Reviewed-on: http://openocd.zylin.com/3002 Reviewed-by: Andreas Fritiofson <[email protected]> Tested-by: jenkins
1 parent ddc3317 commit 9413a7a

9 files changed

+58
-18
lines changed

src/rtos/ThreadX.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,14 @@ const struct rtos_register_stacking rtos_threadx_arm926ejs_stacking[] = {
117117
ARM926EJS_REGISTERS_SIZE_SOLICITED, /* stack_registers_size */
118118
-1, /* stack_growth_direction */
119119
17, /* num_output_registers */
120-
0, /* stack_alignment */
120+
NULL, /* stack_alignment */
121121
rtos_threadx_arm926ejs_stack_offsets_solicited /* register_offsets */
122122
},
123123
{
124124
ARM926EJS_REGISTERS_SIZE_INTERRUPT, /* stack_registers_size */
125125
-1, /* stack_growth_direction */
126126
17, /* num_output_registers */
127-
0, /* stack_alignment */
127+
NULL, /* stack_alignment */
128128
rtos_threadx_arm926ejs_stack_offsets_interrupt /* register_offsets */
129129
},
130130
};

src/rtos/rtos.c

+6-7
Original file line numberDiff line numberDiff line change
@@ -485,13 +485,12 @@ int rtos_generic_stack_read(struct target *target,
485485
list_size += stacking->register_offsets[i].width_bits/8;
486486
*hex_reg_list = malloc(list_size*2 + 1);
487487
tmp_str_ptr = *hex_reg_list;
488-
new_stack_ptr = stack_ptr - stacking->stack_growth_direction *
489-
stacking->stack_registers_size;
490-
if (stacking->stack_alignment != 0) {
491-
/* Align new stack pointer to x byte boundary */
492-
new_stack_ptr =
493-
(new_stack_ptr & (~((int64_t) stacking->stack_alignment - 1))) +
494-
((stacking->stack_growth_direction == -1) ? stacking->stack_alignment : 0);
488+
if (stacking->calculate_process_stack != NULL) {
489+
new_stack_ptr = stacking->calculate_process_stack(target,
490+
stack_data, stacking, stack_ptr);
491+
} else {
492+
new_stack_ptr = stack_ptr - stacking->stack_growth_direction *
493+
stacking->stack_registers_size;
495494
}
496495
for (i = 0; i < stacking->num_output_registers; i++) {
497496
int j;

src/rtos/rtos.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,15 @@ struct rtos_register_stacking {
8383
unsigned char stack_registers_size;
8484
signed char stack_growth_direction;
8585
unsigned char num_output_registers;
86-
unsigned char stack_alignment;
86+
/* Some targets require evaluating the stack to determine the
87+
* actual stack pointer for a process. If this field is NULL,
88+
* just use stacking->stack_registers_size * stack_growth_direction
89+
* to calculate adjustment.
90+
*/
91+
int64_t (*calculate_process_stack)(struct target *target,
92+
const uint8_t *stack_data,
93+
const struct rtos_register_stacking *stacking,
94+
int64_t stack_ptr);
8795
const struct stack_register_offset *register_offsets;
8896
};
8997

src/rtos/rtos_chibios_stackings.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking = {
5252
0x24, /* stack_registers_size */
5353
-1, /* stack_growth_direction */
5454
ARMV7M_NUM_CORE_REGS, /* num_output_registers */
55-
0, /* stack_alignment */
55+
NULL, /* stack_alignment */
5656
rtos_chibios_arm_v7m_stack_offsets /* register_offsets */
5757
};
5858

@@ -80,6 +80,6 @@ const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking_w_fpu = {
8080
0x64, /* stack_registers_size */
8181
-1, /* stack_growth_direction */
8282
ARMV7M_NUM_CORE_REGS, /* num_output_registers */
83-
0, /* stack_alignment */
83+
NULL, /* stack_alignment */
8484
rtos_chibios_arm_v7m_stack_offsets_w_fpu /* register_offsets */
8585
};

src/rtos/rtos_ecos_stackings.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#endif
2222

2323
#include "rtos.h"
24+
#include "rtos_standard_stackings.h"
2425
#include "target/armv7m.h"
2526

2627
static const struct stack_register_offset rtos_eCos_Cortex_M3_stack_offsets[ARMV7M_NUM_CORE_REGS] = {
@@ -47,6 +48,6 @@ const struct rtos_register_stacking rtos_eCos_Cortex_M3_stacking = {
4748
0x44, /* stack_registers_size */
4849
-1, /* stack_growth_direction */
4950
ARMV7M_NUM_CORE_REGS, /* num_output_registers */
50-
8, /* stack_alignment */
51+
rtos_generic_stack_align8, /* stack_alignment */
5152
rtos_eCos_Cortex_M3_stack_offsets /* register_offsets */
5253
};

src/rtos/rtos_embkernel_stackings.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include "rtos.h"
2626
#include "target/armv7m.h"
27+
#include "rtos_standard_stackings.h"
2728

2829
static const struct stack_register_offset rtos_embkernel_Cortex_M_stack_offsets[ARMV7M_NUM_CORE_REGS] = {
2930
{ 0x24, 32 }, /* r0 */
@@ -49,7 +50,7 @@ const struct rtos_register_stacking rtos_embkernel_Cortex_M_stacking = {
4950
0x40, /* stack_registers_size */
5051
-1, /* stack_growth_direction */
5152
ARMV7M_NUM_CORE_REGS, /* num_output_registers */
52-
8, /* stack_alignment */
53+
rtos_generic_stack_align8, /* stack_alignment */
5354
rtos_embkernel_Cortex_M_stack_offsets /* register_offsets */
5455
};
5556

src/rtos/rtos_mqx_stackings.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ const struct rtos_register_stacking rtos_mqx_arm_v7m_stacking = {
7575
0x4C, /* stack_registers_size, calculate offset base address */
7676
-1, /* stack_growth_direction */
7777
ARMV7M_NUM_CORE_REGS, /* num_output_registers */
78-
0, /* stack_alignment */
78+
NULL, /* stack_alignment */
7979
rtos_mqx_arm_v7m_stack_offsets /* register_offsets */
8080
};
8181

src/rtos/rtos_standard_stackings.c

+31-3
Original file line numberDiff line numberDiff line change
@@ -113,26 +113,54 @@ static const struct stack_register_offset rtos_standard_NDS32_N1068_stack_offset
113113
{ 0x10, 32 }, /* IFC_LP */
114114
};
115115

116+
static int64_t rtos_generic_stack_align(struct target *target,
117+
const uint8_t *stack_data, const struct rtos_register_stacking *stacking,
118+
int64_t stack_ptr, int align)
119+
{
120+
int64_t new_stack_ptr;
121+
int64_t aligned_stack_ptr;
122+
new_stack_ptr = stack_ptr - stacking->stack_growth_direction *
123+
stacking->stack_registers_size;
124+
aligned_stack_ptr = new_stack_ptr & ~((int64_t)align - 1);
125+
if (aligned_stack_ptr != new_stack_ptr &&
126+
stacking->stack_growth_direction == -1) {
127+
/* If we have a downward growing stack, the simple alignment code
128+
* above results in a wrong result (since it rounds down to nearest
129+
* alignment). We want to round up so add an extra align.
130+
*/
131+
aligned_stack_ptr += (int64_t)align;
132+
}
133+
return aligned_stack_ptr;
134+
}
135+
136+
int64_t rtos_generic_stack_align8(struct target *target,
137+
const uint8_t *stack_data, const struct rtos_register_stacking *stacking,
138+
int64_t stack_ptr)
139+
{
140+
return rtos_generic_stack_align(target, stack_data,
141+
stacking, stack_ptr, 8);
142+
}
143+
116144
const struct rtos_register_stacking rtos_standard_Cortex_M3_stacking = {
117145
0x40, /* stack_registers_size */
118146
-1, /* stack_growth_direction */
119147
ARMV7M_NUM_CORE_REGS, /* num_output_registers */
120-
8, /* stack_alignment */
148+
rtos_generic_stack_align8, /* stack_alignment */
121149
rtos_standard_Cortex_M3_stack_offsets /* register_offsets */
122150
};
123151

124152
const struct rtos_register_stacking rtos_standard_Cortex_R4_stacking = {
125153
0x48, /* stack_registers_size */
126154
-1, /* stack_growth_direction */
127155
26, /* num_output_registers */
128-
8, /* stack_alignment */
156+
rtos_generic_stack_align8, /* stack_alignment */
129157
rtos_standard_Cortex_R4_stack_offsets /* register_offsets */
130158
};
131159

132160
const struct rtos_register_stacking rtos_standard_NDS32_N1068_stacking = {
133161
0x90, /* stack_registers_size */
134162
-1, /* stack_growth_direction */
135163
32, /* num_output_registers */
136-
8, /* stack_alignment */
164+
rtos_generic_stack_align8, /* stack_alignment */
137165
rtos_standard_NDS32_N1068_stack_offsets /* register_offsets */
138166
};

src/rtos/rtos_standard_stackings.h

+3
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,8 @@
3030
extern const struct rtos_register_stacking rtos_standard_Cortex_M3_stacking;
3131
extern const struct rtos_register_stacking rtos_standard_Cortex_R4_stacking;
3232
extern const struct rtos_register_stacking rtos_standard_NDS32_N1068_stacking;
33+
int64_t rtos_generic_stack_align8(struct target *target,
34+
const uint8_t *stack_data, const struct rtos_register_stacking *stacking,
35+
int64_t stack_ptr);
3336

3437
#endif /* ifndef INCLUDED_RTOS_STANDARD_STACKINGS_H_ */

0 commit comments

Comments
 (0)