A question about the irq handler of the arm core

PowerMan powerman1st at gmail.com
Wed Sep 10 08:32:12 UTC 2008


I attach a piece of code from the file $(RTEMS-4.7.3)/c/src/lib/
libbsp/arm/shared/irq/irq_asm.S,
its the ISR handler of ARM core.

In the line 59 to 62, it judge whether the arm core is in irq mode,
if so - exit the isr handler and return to normal program
else - go on to do some more work and return

But its impossible to call this function in normal program
except an interrupt really happen.

If so, the arm core is sure to be in the irq mode,
the code from line 63 to 128 seems would never be executed.

Could the maintainer of ARM explain it?
I was so confused.
Thanks.

**********************************************************************************
24            .globl _ISR_Handler
  25    _ISR_Handler:
  26            stmdb   sp!, {r0, r1, r2, r3, r12}   /* save regs on INT
stack */
  27            stmdb   sp!, {lr}               /*    now safe to call C
funcs */
  28
  29    /* one nest level deeper */
  30            ldr     r0, =_ISR_Nest_level
  31            ldr     r1, [r0]
  32            add     r1, r1,#1
  33            str     r1, [r0]
  34
  35    /* disable multitasking */
  36            ldr     r0, =_Thread_Dispatch_disable_level
  37            ldr     r1, [r0]
  38            add     r1, r1,#1
  39            str     r1, [r0]
  40
  41    /* BSP specific function to INT handler */
  42            /* FIXME: I'm not sure why I can't save just r12. I'm also
*/
  43            /*     not sure which of r1-r3 are important.
*/
  44            bl      ExecuteITHandler
  45
  46    /* one less nest level  */
  47            ldr     r0, =_ISR_Nest_level
  48            ldr     r1, [r0]
  49            sub     r1, r1,#1
  50            str     r1, [r0]
  51
  52    /* unnest multitasking */
  53            ldr     r0, =_Thread_Dispatch_disable_level
  54            ldr     r1, [r0]
  55            sub     r1, r1,#1
  56            str     r1, [r0]
  57
  58    /* check to see if we interrupted nd INT (with FIQ?) */
  59            mrs   r0, spsr
  60            and   r0, r0, #0x1f
  61            cmp   r0, #0x12        /* is it INT mode? */
  62            beq   exitit
  63
  64    /* If thread dispatching is disabled, exit */
  65            cmp     r1, #0
  66            bne     exitit
  67
  68    /* If a task switch is necessary, call scheduler */
  69            ldr     r0, =_Context_Switch_necessary
  70            ldr     r1, [r0]
  71            cmp     r1, #0
  72
  73            /* since bframe is going to clear
_ISR_Signals_to_thread_executing, */
  74            /*    we need to load it here */
  75            ldr     r0, =_ISR_Signals_to_thread_executing
  76            ldr     r1, [r0]
  77            bne     bframe
  78
  79    /* If a signals to be sent (_ISR_Signals_to_thread_executing !=
0),        */
  80    /*  call scheduler */
  81            cmp     r1, #0
  82            beq     exitit
  83
  84    /* _ISR_Signals_to_thread_executing = FALSE */
  85            mov     r1, #0
  86            str     r1, [r0]
  87
  88    bframe:
  89
  90    /* Now we need to set up the return from this ISR to be
_ISR_Dispatch */
  91    /* To do that, we need to save the current lr_int and spsr_int on
the */
  92    /* SVC
stack                                                          */
  93            mrs     r0, spsr
  94            ldmia   sp!, {r1}       /* get lr off stack */
  95            stmdb   sp!, {r1}
  96            mrs     r2, cpsr
  97            orr     r3, r2, #0x1    /* change to SVC mode */
  98            msr     cpsr_c, r3
  99
 100            /* now in SVC mode */
 101            stmdb   sp!, {r0, r1}   /* put spsr_int and lr_int on SVC
stack */
 102            msr     cpsr_c, r2      /* change back to INT mode */
 103
 104            /* now in INT mode */
 105
 106            /* replace lr with address of _ISR_Dispatch */
 107            ldr     lr, =_ISR_Dispatch_p_4    /* On entry to an ISR, the
lr is */
 108                                              /*    the return address +
4, so */
 109                                              /*    we have to emulate
that    */
 110            ldmia   sp!, {r1}                 /* out with the
old          */
 111            stmdb   sp!, {lr}                 /*    in with the new (lr)
*/
 112
 113            orr     r0, r0, #0xc0
 114            msr     spsr, r0
 115
 116    exitit:
 117            ldmia   sp!, {lr}                     /* restore regs from
INT stack */
 118            ldmia   sp!, {r0, r1, r2, r3, r12}    /* restore regs from
INT stack */
 119            subs    pc, lr, #4                /* return */
 120
 121            /* on entry to _ISR_Dispatch, we're in SVC mode */
 122            .globl _ISR_Dispatch
 123    _ISR_Dispatch:
 124            stmdb   sp!, {r0-r3, r12,lr}      /* save regs on SVC stack
*/
 125                                              /*    (now safe to call C
funcs) */
 126                                              /*    we don't save lr,
since  */
 127                                              /*    it's just going to
get   */
 128                                              /*
overwritten              */
************************************************************************************************
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/users/attachments/20080910/0807d830/attachment.html>


More information about the users mailing list