ARM interrupt handling
Joel Sherrill
joel.sherrill at OARcorp.com
Thu Apr 25 12:18:50 UTC 2002
Jay.. if you confirm this is OK, I will merge it.
--joel
Andy Dachs wrote:
>
> 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_
> >
--
Joel Sherrill, Ph.D. Director of Research & Development
joel at OARcorp.com On-Line Applications Research
Ask me about RTEMS: a free RTOS Huntsville AL 35805
Support Available (256) 722-9985
More information about the users
mailing list