1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
/* irq_asm.S
*
* This file contains the implementation of the IRQ handler
*
* CopyRight (C) 2000 Canon Research France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include "asm.h"
#define __asm__
#include <registers.h>
/*
* WARNING : register r5 is important. If you need to use it,
* to forget to save it !!!!!!!!!!
*/
.globl _ISR_Handler
_ISR_Handler:
stmdb sp!, {r4,r5,lr} /* save regs on INT stack */
mrs r4, cpsr /* save current CSPR */
mov r5, r4 /* copy CSPR */
orr r4, r4, #3
msr cpsr, r4 /* switch to SVC mode */
stmdb sp!, {r0-r3,r12,r14} /* save scratch regs on SVC stack */
msr cpsr, r5 /* switch back to INT mode */
ldr r0, =_ISR_Nest_level /* one nest level deeper */
ldr r1, [r0]
add r1, r1,#1
str r1, [r0]
ldr r0, =_Thread_Dispatch_disable_level /* disable multitasking */
ldr r1, [r0]
add r1, r1,#1
str r1, [r0]
b ExecuteITHandler /* BSP specific function to INT handler */
.globl ReturnFromHandler
ReturnFromHandler :
ldr r0, =_ISR_Nest_level /* one less nest level */
ldr r1, [r0]
sub r1, r1,#1
str r1, [r0]
ldr r0, =_Thread_Dispatch_disable_level /* unnest multitasking */
ldr r1, [r0]
sub r1, r1,#1
str r1, [r0]
cmp r1, #0 /* is dispatch enabled */
bne exitit /* Yes, then exit */
ldr r0, =_Context_Switch_necessary /* task switch necessary ? */
ldr r1, [r0]
cmp r1, #0
bne schedule /* yes, call scheduler */
ldr r0, =_ISR_Signals_to_thread_executing
ldr r1, [r0] /* signals sent to Run_thread */
cmp r1, #0 /* while in interrupt handler ? */
beq exitit /* No, exit */
bframe:
mov r1, #0 /* _ISR_Signals_to_thread_executing = FALSE */
str r1, [r0]
/*
* At this point, we need a complete exception context for the
* current thread. We need to complete the interrupt exception
* with the "not-yet-saved" registers
*/
/*
* currently exception context = interrupt handler
* it needs to be optimized
*/
bl _ThreadProcessSignalsFromIrq
b exitit
schedule:
/*
* the scratch registers have already been saved and we are already
* back on the thread system stack. So we can call _Thread_Displatch
* directly
*/
bl _Thread_Dispatch
/*
* fall through exit to restore complete contex (scratch registers
* eip, CS, Flags).
*/
exitit:
b AckControler /* BSP specific function to ack PIC */
.globl ReturnFromAck
ReturnFromAck :
ldmia sp!, {r0-r3,r12,r14} /* restore regs from SVC stack */
msr cpsr, r5 /* switch back to INT mode */
ldmia sp!, {r4,r5,lr} /* restore regs from INT stack */
subs pc,r14,#4 /* return */
|