|
@@ -49,20 +49,23 @@ rt_hw_context_switch PROC
|
|
|
STMFD sp!, {lr} ; push pc (lr should be pushed in place of PC)
|
|
|
STMFD sp!, {r0-r12, lr} ; push lr & register file
|
|
|
|
|
|
- MRS r4, cpsr
|
|
|
+ MRS r4, cpsr
|
|
|
+ TST lr, #0x01
|
|
|
+ BEQ _ARM_MODE
|
|
|
+ ORR r4, r4, #0x20 ; it's thumb code
|
|
|
+
|
|
|
+_ARM_MODE
|
|
|
STMFD sp!, {r4} ; push cpsr
|
|
|
- MRS r4, spsr
|
|
|
- STMFD sp!, {r4} ; push spsr
|
|
|
|
|
|
- STR sp, [r0] ; store sp in preempted tasks TCB
|
|
|
- LDR sp, [r1] ; get new task stack pointer
|
|
|
+ STR sp, [r0] ; store sp in preempted tasks TCB
|
|
|
+ LDR sp, [r1] ; get new task stack pointer
|
|
|
|
|
|
- LDMFD sp!, {r4} ; pop new task spsr
|
|
|
- MSR spsr_cxsf, r4
|
|
|
- LDMFD sp!, {r4} ; pop new task cpsr
|
|
|
- MSR cpsr_cxsf, r4
|
|
|
+ LDMFD sp!, {r4} ; pop new task cpsr to spsr
|
|
|
+ MSR spsr_cxsf, r4
|
|
|
+ BIC r4, r4, #0x20 ; must be ARM mode
|
|
|
+ MSR cpsr_cxsf, r4
|
|
|
|
|
|
- LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
|
|
|
+ LDMFD sp!, {r0-r12, lr, pc}^ ; pop new task r0-r12, lr & pc, copy spsr to cpsr
|
|
|
ENDP
|
|
|
|
|
|
;/*
|
|
@@ -73,12 +76,12 @@ rt_hw_context_switch_to PROC
|
|
|
EXPORT rt_hw_context_switch_to
|
|
|
LDR sp, [r0] ; get new task stack pointer
|
|
|
|
|
|
- LDMFD sp!, {r4} ; pop new task spsr
|
|
|
- MSR spsr_cxsf, r4
|
|
|
- LDMFD sp!, {r4} ; pop new task cpsr
|
|
|
- MSR cpsr_cxsf, r4
|
|
|
+ LDMFD sp!, {r4} ; pop new task cpsr to spsr
|
|
|
+ MSR spsr_cxsf, r4
|
|
|
+ BIC r4, r4, #0x20 ; must be ARM mode
|
|
|
+ MSR cpsr_cxsf, r4
|
|
|
|
|
|
- LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
|
|
|
+ LDMFD sp!, {r0-r12, lr, pc}^ ; pop new task r0-r12, lr & pc, copy spsr to cpsr
|
|
|
ENDP
|
|
|
|
|
|
;/*
|