ARM interrupt handling

Andy Dachs iwe at fsmail.net
Thu Apr 25 09:41:57 UTC 2002


Hi Jay,

It might be because the processor state is not being saved on context switches.  Is Emmanuel Raguet still about on the mailing list as I'd like to discuss some of the changes?

In the meantime, this is what I did to cpu_asm.S:

Regards,
Andy

diff -urN /usr/local/rtems/tools/rtems-ss-20011210/c/src/exec/score/cpu/arm/cpu_asm.S ./arm/cpu_asm.S
--- /usr/local/rtems/tools/rtems-ss-20011210/c/src/exec/score/cpu/arm/cpu_asm.S	Thu Jul 27 02:04:10 2000
+++ ./arm/cpu_asm.S	Tue Dec  4 17:32:10 2001
@@ -14,6 +14,8 @@
 
 #include <asm.h>
 
+#define SAVE_CPSR
+
 /*
  * Format of ARM Register structure
  */
@@ -29,12 +31,17 @@
 .set REG_R8,  32
 .set REG_R9,  36
 .set REG_R10, 40
-.set REG_FP,  44
-.set REG_IP,  48
+.set REG_R11, 44
+.set REG_R12, 48
 .set REG_SP,  52
 .set REG_LR,  56
 .set REG_PC,  60
+#ifndef SAVE_CPSR
 .set SIZE_REGS,   REG_PC + 4
+#else
+.set REG_CPSR, 64      /* added AFD*/
+.set SIZE_REGS,   REG_CPSR + 4
+#endif
 
 /*
  *  void _CPU_Context_switch( run_context, heir_context )
@@ -57,9 +64,23 @@
 	str     r8,  [r0, #REG_R8]
 	str     r9,  [r0, #REG_R9]
 	str     r10, [r0, #REG_R10]
+	
+	str     r11, [r0, #REG_R11]
+	str     r12, [r0, #REG_R12]	
+	
 	str     sp,  [r0, #REG_SP]
 	str     lr,  [r0, #REG_PC]
 	
+#ifdef SAVE_CPSR
+	mrs	r2, cpsr
+	str	r2,  [r0, #REG_CPSR]
+#endif	
+
+#ifdef SAVE_CPSR
+	ldr	r2,  [r1, #REG_CPSR]
+	msr	cpsr_f, r2
+#endif		
+
 	ldr     r2,  [r1, #REG_R2]
 	ldr     r3,  [r1, #REG_R3]
 	ldr     r4,  [r1, #REG_R4]
@@ -68,9 +89,12 @@
 	ldr     r7,  [r1, #REG_R7]
 	ldr     r8,  [r1, #REG_R8]
 	ldr     r9,  [r1, #REG_R9]
-	ldr     r10, [r1, #REG_R10]
+	ldr     r10, [r1, #REG_R10]	
+	ldr     r11, [r1, #REG_R11]
+	ldr     r12, [r1, #REG_R12]	
+	
 	ldr     sp,  [r1, #REG_SP]
-	ldr     lr,  [r1, #REG_PC]
+	ldr     lr,  [r1, #REG_PC]	
 	mov	pc, lr
 
 /*
@@ -86,7 +110,12 @@
 
 _CPU_Context_restore:
 
-	ldr     r2,  [r0, #REG_R2]
+#ifdef SAVE_CPSR
+	ldr	r2,  [r0, #REG_CPSR]
+	msr	cpsr_f, r2
+#endif	
+
+	ldr     r2,  [r0, #REG_R2]	
 	ldr     r3,  [r0, #REG_R3]
 	ldr     r4,  [r0, #REG_R4]
 	ldr     r5,  [r0, #REG_R5]
@@ -94,7 +123,10 @@
 	ldr     r7,  [r0, #REG_R7]
 	ldr     r8,  [r0, #REG_R8]
 	ldr     r9,  [r0, #REG_R9]
-	ldr     r10, [r0, #REG_R10]
+	ldr     r10, [r0, #REG_R10]	
+	ldr     r11, [r1, #REG_R11]
+	ldr     r12, [r1, #REG_R12]	
+			
 	ldr     sp,  [r0, #REG_SP]
 	ldr     lr,  [r0, #REG_PC]
 	mov     pc,  lr	
@@ -114,8 +146,8 @@
 	str     r8,  [r13, #REG_R8]
 	str     r9,  [r13, #REG_R9]
 	str     r10, [r13, #REG_R10]
-	str     fp,  [r13, #REG_FP]
-	str     ip,  [r13, #REG_IP]
+	str     r11, [r13, #REG_R11]
+	str     r12, [r13, #REG_R12]
 	str     sp,  [r13, #REG_SP]
 	str     lr,  [r13, #REG_LR]
 	mrs	r0,  cpsr		/* read the status */
@@ -123,7 +155,7 @@
 	str	r0,  [r13, #REG_PC]     /* we store it in a free place */
 	mov	r0,  r13		/* put frame address in r0 (C arg 1) */
 
-	ldr	r1, =_currentExcHandler
+	ldr	r1, =_SWIHandler
 	ldr     lr, =_go_back_1
 	ldr	pc,[r1]				/* call handler  */
 _go_back_1:
@@ -138,13 +170,13 @@
 	ldr     r8,  [r13, #REG_R8]
 	ldr     r9,  [r13, #REG_R9]
 	ldr     r10, [r13, #REG_R10]
-	ldr     fp,  [r13, #REG_FP]
-	ldr     ip,  [r13, #REG_IP]
+	ldr     r11, [r13, #REG_R11]
+	ldr     r12, [r13, #REG_R12]
 	ldr     sp,  [r13, #REG_SP]
 	ldr     lr,  [r13, #REG_LR]
 	add     r13,r13,#SIZE_REGS
-	movs	pc,r14				/* return  */
-
+	mov	pc,r14				/* return  */ /* why was this movs???*/
+	
         .globl _Exception_Handler_Abort
 _Exception_Handler_Abort:
 	sub     r13,r13,#SIZE_REGS
@@ -159,8 +191,8 @@
 	str     r8,  [r13, #REG_R8]
 	str     r9,  [r13, #REG_R9]
 	str     r10, [r13, #REG_R10]
-	str     sp,  [r13, #REG_FP]
-	str     lr,  [r13, #REG_IP]
+	str     sp,  [r13, #REG_R11]
+	str     lr,  [r13, #REG_R12]
 	str     lr,  [r13, #REG_SP]
 	str     lr,  [r13, #REG_LR]
 	mrs	r0,  cpsr		/* read the status */
@@ -183,11 +215,57 @@
 	ldr     r8,  [r13, #REG_R8]
 	ldr     r9,  [r13, #REG_R9]
 	ldr     r10, [r13, #REG_R10]
-	ldr     sp,  [r13, #REG_FP]
-	ldr     lr,  [r13, #REG_IP]
+	ldr     sp,  [r13, #REG_R11]
+	ldr     lr,  [r13, #REG_R12]
 	ldr     lr,  [r13, #REG_SP]
 	ldr     lr,  [r13, #REG_LR]
 	add     r13,r13,#SIZE_REGS
 	subs	pc,r14,#4			/* return */
 	
-
+#if 0
+        .globl _Exception_Handler_Abort
+_Exception_Handler_Abort:
+	sub     r13,r13,#SIZE_REGS
+	str     r0,  [r13, #REG_R0]
+	str     r1,  [r13, #REG_R1]
+	str     r2,  [r13, #REG_R2]
+	str     r3,  [r13, #REG_R3]
+	str     r4,  [r13, #REG_R4]
+	str     r5,  [r13, #REG_R5]
+	str     r6,  [r13, #REG_R6]
+	str     r7,  [r13, #REG_R7]
+	str     r8,  [r13, #REG_R8]
+	str     r9,  [r13, #REG_R9]
+	str     r10, [r13, #REG_R10]
+	str     r11, [r13, #REG_R11]
+	str     r12, [r13, #REG_R12]
+	str     sp,  [r13, #REG_SP]
+	str     lr,  [r13, #REG_LR]
+	mrs	r0,  cpsr		/* read the status */
+	and	r0,  r0,#0x1f		/* we keep the mode as exception number */
+	str	r0,  [r13, #REG_PC]     /* we store it in a free place */
+	mov	r0,  r13		/* put frame address in ro (C arg 1) */
+	
+	ldr	r1, =_currentExcHandler
+	ldr     lr, =_go_back_2
+	ldr	pc,[r1]				/* call handler  */
+_go_back_2:
+	ldr     r0,  [r13, #REG_R0]
+	ldr     r1,  [r13, #REG_R1]
+	ldr     r2,  [r13, #REG_R2]
+	ldr     r3,  [r13, #REG_R3]
+	ldr     r4,  [r13, #REG_R4]
+	ldr     r5,  [r13, #REG_R5]
+	ldr     r6,  [r13, #REG_R6]
+	ldr     r7,  [r13, #REG_R7]
+	ldr     r8,  [r13, #REG_R8]
+	ldr     r9,  [r13, #REG_R9]
+	ldr     r10, [r13, #REG_R10]
+	ldr     r11, [r13, #REG_R11]
+	ldr     r12, [r13, #REG_R12]
+	ldr     sp,  [r13, #REG_SP]
+	ldr     lr,  [r13, #REG_LR]
+	add     r13,r13,#SIZE_REGS
+	subs	pc,r14,#4			/* return */
+		
+#endif

> 
> -----Original Message-----
> From: Jay Monkman [mailto:jtm at smoothsmoothie.com]
> Sent: Wednesday, April 24, 2002 7:34 PM
> To: rtems-users at oarcorp.com
> Subject: ARM interrupt handling
> 
> 
> I'm working on an arm 940T based BSP, and an having a problem
> with interrupts. It looks like the processor state changes to
> IRQ state when an interrupt occurs, but then changes back to
> supervisor state. That seems to be causing the stack pointer
> to point to the wrong address, since its using the IRQ stack
> pointer. Does anybody have any idea what I'm doing wrong that
> is preventing the CPU from going back to supervisor state?
> 
> Also, in c/src/exec/score/cpu/arm/rtems/score/cpu.h, 
> CPU_HAS_HARDWARE_INTERRUPT_STACK is set to FALSE. Is that
> correct? Since the ARM has multiple stack pointer registers 
> (R13), doesn't that count as a hardware interrupt stack?
> 
> Thanks.
> 
> 
> -- 
> Jay Monkman	    The truth knocks on the door and you say "Go away, I'm 
> monkman at jump.net    looking for the truth," and so it goes away. Puzzling.
> 		     - from _Zen_and_the_Art_of_Motorcycle_Maintenance_
> 





More information about the users mailing list