Skip to content

Commit 162e286

Browse files
committed
Fix Cortex-R5 ISR stack switching implementation
This implements missing ISR stack switching to prevent thread stack overflow. Comments described the logic but code was not implemented, causing ISRs to execute on thread stacks instead of dedicated system stack. Context Save (ISR Entry): - tx_thread_context_save.S: Add missing stack switch for IRQ - tx_thread_fiq_context_save.S: Add missing stack switch for FIQ - tx_thread_vectored_context_save.S: Add missing stack switch for vectored Context Restore (ISR Exit): - tx_thread_context_restore.S: Restore thread SP before popping registers (both __tx_thread_no_preempt_restore and __tx_thread_preempt_restore) - tx_thread_fiq_context_restore.S: Restore thread SP before popping registers (both FIQ no-preempt and preempt paths) Implementation: ISR Entry (Save): STMDB sp!, {r2, r10, r12, lr} @ Save registers on thread stack LDR r1, =_tx_thread_system_stack_ptr @ Get system stack address STR sp, [r0, eclipse-threadx#8] @ Save thread SP to TCB LDR sp, [r1] @ Switch to system stack ISR Exit (Restore): LDR sp, [r0, eclipse-threadx#8] @ Restore thread SP from TCB LDMIA sp!, {r0, r10, r12, lr} @ Pop from thread stack Rationale: - Prevents stack overflow: ISRs execute on dedicated system stack - Preserves thread stack integrity for debugging and stack checking - Matches design intent documented in inline comments - Required for nested interrupt support and stack overflow detection - Critical for lockstep mode (deterministic stack usage) Execution Flow: 1. IRQ/FIQ occurs while thread running 2. Save minimal context to thread stack 3. Save thread SP to TCB at offset eclipse-threadx#8 (tx_thread_stack_ptr field) 4. Switch SP to system stack 5. ISR executes on system stack 6. Restore thread SP from TCB before returning 7. Pop saved context from thread stack 8. Return to interrupted thread All Paths Fixed: - IRQ no-preempt restore: Thread continues without context switch - IRQ preempt restore: Higher-priority thread needs to run - FIQ no-preempt restore: FIQ returns to same thread - FIQ preempt restore: FIQ triggers thread switch - Vectored interrupts: Return through context_restore (already fixed) Impact: - Fixes stack overflow risk from nested/heavy ISRs - Enables TX_ENABLE_STACK_CHECKING to work correctly - Debugging tools can now properly inspect thread stacks - System stack usage isolated from thread stack usage
1 parent 41840f0 commit 162e286

5 files changed

Lines changed: 25 additions & 7 deletions

File tree

ports/cortex_r5/gnu/src/tx_thread_context_restore.S

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ __tx_thread_no_preempt_restore:
158158
@
159159
@ /* Pickup the saved stack pointer. */
160160
@ tmp_ptr = _tx_thread_current_ptr -> tx_thread_stack_ptr;
161+
@
162+
LDR sp, [r0, #8] @ Restore thread stack pointer
161163
@
162164
@ /* Recover the saved context and return to the point of interrupt. */
163165
@
@@ -171,6 +173,7 @@ __tx_thread_no_preempt_restore:
171173
@ {
172174
__tx_thread_preempt_restore:
173175
@
176+
LDR sp, [r0, #8] @ Restore thread stack pointer
174177
LDMIA sp!, {r3, r10, r12, lr} @ Recover temporarily saved registers
175178
MOV r1, lr @ Save lr (point of interrupt)
176179
MOV r2, #SVC_MODE @ Build SVC mode CPSR

ports/cortex_r5/gnu/src/tx_thread_context_save.S

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,20 @@ __tx_thread_not_nested_save:
140140
@ /* Save minimal context of interrupted thread. */
141141
@
142142
MRS r2, SPSR @ Pickup saved SPSR
143-
SUB lr, lr, #4 @ Adjust point of interrupt
143+
SUB lr, lr, #4 @ Adjust point of interrupt
144144
STMDB sp!, {r2, r10, r12, lr} @ Store other registers
145145
@
146146
@ /* Save the current stack pointer in the thread's control block. */
147147
@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
148+
@
149+
LDR r1, =_tx_thread_system_stack_ptr @ Pickup system stack pointer address
150+
STR sp, [r0, #8] @ Save thread stack pointer
148151
@
149152
@ /* Switch to the system stack. */
150153
@ sp = _tx_thread_system_stack_ptr@
151154
@
152-
MOV r10, #0 @ Clear stack limit
155+
LDR sp, [r1] @ Switch to system stack
156+
MOV r10, #0 @ Clear stack limit
153157

154158
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
155159
@

ports/cortex_r5/gnu/src/tx_thread_fiq_context_restore.S

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ __tx_thread_fiq_no_preempt_restore:
160160
@
161161
@ /* Pickup the saved stack pointer. */
162162
@ tmp_ptr = _tx_thread_current_ptr -> tx_thread_stack_ptr;
163+
@
164+
LDR sp, [r0, #8] @ Restore thread stack pointer
163165
@
164166
@ /* Recover the saved context and return to the point of interrupt. */
165167
@
@@ -173,6 +175,7 @@ __tx_thread_fiq_no_preempt_restore:
173175
@ {
174176
__tx_thread_fiq_preempt_restore:
175177
@
178+
LDR sp, [r0, #8] @ Restore thread stack pointer
176179
LDMIA sp!, {r3, lr} @ Recover temporarily saved registers
177180
MOV r1, lr @ Save lr (point of interrupt)
178181
MOV r2, #SVC_MODE @ Build SVC mode CPSR

ports/cortex_r5/gnu/src/tx_thread_fiq_context_save.S

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,19 +137,23 @@ __tx_thread_fiq_not_nested_save:
137137
@ /* Save minimal context of interrupted thread. */
138138
@
139139
MRS r2, SPSR @ Pickup saved SPSR
140-
SUB lr, lr, #4 @ Adjust point of interrupt
140+
SUB lr, lr, #4 @ Adjust point of interrupt
141141
STMDB sp!, {r2, lr} @ Store other registers, Note that we don't
142-
@ @ need to save sl and ip since FIQ has
143-
@ @ copies of these registers. Nested
142+
@ @ need to save sl and ip since FIQ has
143+
@ @ copies of these registers. Nested
144144
@ @ interrupt processing does need to save
145145
@ @ these registers.
146146
@
147147
@ /* Save the current stack pointer in the thread's control block. */
148-
@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
148+
@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
149+
@
150+
LDR r1, =_tx_thread_system_stack_ptr @ Pickup system stack pointer address
151+
STR sp, [r0, #8] @ Save thread stack pointer
149152
@
150153
@ /* Switch to the system stack. */
151-
@ sp = _tx_thread_system_stack_ptr;
154+
@ sp = _tx_thread_system_stack_ptr;
152155
@
156+
LDR sp, [r1] @ Switch to system stack
153157
MOV r10, #0 @ Clear stack limit
154158

155159
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY

ports/cortex_r5/gnu/src/tx_thread_vectored_context_save.S

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,14 @@ __tx_thread_not_nested_save:
135135
@
136136
@ /* Save the current stack pointer in the thread's control block. */
137137
@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
138+
@
139+
LDR r1, =_tx_thread_system_stack_ptr @ Pickup system stack pointer address
140+
STR sp, [r0, #8] @ Save thread stack pointer
138141
@
139142
@ /* Switch to the system stack. */
140143
@ sp = _tx_thread_system_stack_ptr;
141144
@
145+
LDR sp, [r1] @ Switch to system stack
142146
MOV r10, #0 @ Clear stack limit
143147

144148
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY

0 commit comments

Comments
 (0)