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