浏览代码

add thumb mode support.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1629 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong 14 年之前
父节点
当前提交
1b9e80dc70
共有 3 个文件被更改,包括 31 次插入26 次删除
  1. 18 15
      libcpu/arm/lpc24xx/context_rvds.S
  2. 8 4
      libcpu/arm/lpc24xx/stack.c
  3. 5 7
      libcpu/arm/lpc24xx/start_rvds.S

+ 18 - 15
libcpu/arm/lpc24xx/context_rvds.S

@@ -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
 
 ;/*

+ 8 - 4
libcpu/arm/lpc24xx/stack.c

@@ -12,7 +12,7 @@
  * 2008-12-11     XuXinming    first version
  */
 #include <rtthread.h>
-#include "LPC24xx.h"
+#include "LPC24xx.h"
 
 /**
  * @addtogroup LPC2478
@@ -49,9 +49,13 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
 	*(--stk) = 0;							/* r3 */
 	*(--stk) = 0;							/* r2 */
 	*(--stk) = 0;							/* r1 */
-	*(--stk) = (unsigned long)parameter;	/* r0 : argument */
-	*(--stk) = SVCMODE;						/* cpsr */
-	*(--stk) = SVCMODE;						/* spsr */
+	*(--stk) = (unsigned long)parameter;	/* r0 : argument */
+
+	/* cpsr */
+	if ((rt_uint32_t)tentry & 0x01)
+		*(--stk) = SVCMODE | 0x20;			/* thumb mode */
+	else
+		*(--stk) = SVCMODE;					/* arm mode   */
 
 	/* return task's current stack address */
 	return (rt_uint8_t *)stk;

+ 5 - 7
libcpu/arm/lpc24xx/start_rvds.S

@@ -1538,8 +1538,6 @@ rt_hw_context_switch_interrupt_do   PROC
                 LDMFD   r4!, {r0-r3}
                 STMFD   sp!, {r0-r3}    ; push old task's r3-r0
                 STMFD   sp!, {r5}       ; push old task's cpsr
-                MRS     r4,  spsr
-                STMFD   sp!, {r4}       ; push old task's spsr
 
                 LDR     r4,  =rt_interrupt_from_thread
                 LDR     r5,  [r4]
@@ -1548,13 +1546,13 @@ rt_hw_context_switch_interrupt_do   PROC
                 LDR     r6,  =rt_interrupt_to_thread
                 LDR     r6,  [r6]
                 LDR     sp,  [r6]       ; get new task's stack pointer
-            
-                LDMFD   sp!, {r4}       ; pop new task's spsr
-                MSR     spsr_cxsf, r4
-                LDMFD   sp!, {r4}       ; pop new task's psr
+
+                LDMFD   sp!, {r4}       ; pop new task's 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's r0-r12,lr & pc
+                LDMFD   sp!, {r0-r12,lr,pc}^ ; pop new task's r0-r12,lr & pc, copy spsr to cpsr
                 ENDP
 
                 IF      :DEF:__MICROLIB