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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
|
/* cpu_asm.s
*
* This file contains all assembly code for the ARM implementation
* of RTEMS.
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*/
#include <asm.h>
/*
* Format of ARM Register structure
*/
.set REG_R0, 0
.set REG_R1, 4
.set REG_R2, 8
.set REG_R3, 12
.set REG_R4, 16
.set REG_R5, 20
.set REG_R6, 24
.set REG_R7, 28
.set REG_R8, 32
.set REG_R9, 36
.set REG_R10, 40
.set REG_FP, 44
.set REG_IP, 48
.set REG_SP, 52
.set REG_LR, 56
.set REG_PC, 60
.set SIZE_REGS, REG_PC + 4
/*
* void _CPU_Context_switch( run_context, heir_context )
*
* This routine performs a normal non-FP context.
*
* R0 = run_context R1 = heir_context
*
*/
.globl _CPU_Context_switch
_CPU_Context_switch:
str r2, [r0, #REG_R2]
str r3, [r0, #REG_R3]
str r4, [r0, #REG_R4]
str r5, [r0, #REG_R5]
str r6, [r0, #REG_R6]
str r7, [r0, #REG_R7]
str r8, [r0, #REG_R8]
str r9, [r0, #REG_R9]
str r10, [r0, #REG_R10]
str sp, [r0, #REG_SP]
str lr, [r0, #REG_PC]
ldr r2, [r1, #REG_R2]
ldr r3, [r1, #REG_R3]
ldr r4, [r1, #REG_R4]
ldr r5, [r1, #REG_R5]
ldr r6, [r1, #REG_R6]
ldr r7, [r1, #REG_R7]
ldr r8, [r1, #REG_R8]
ldr r9, [r1, #REG_R9]
ldr r10, [r1, #REG_R10]
ldr sp, [r1, #REG_SP]
ldr lr, [r1, #REG_PC]
mov pc, lr
/*
* NOTE: May be unnecessary to reload some registers.
*/
/*
* void _CPU_Context_restore( new_context )
*
* This routine performs a normal non-FP context.
*/
.globl _CPU_Context_restore
_CPU_Context_restore:
ldr r2, [r0, #REG_R2]
ldr r3, [r0, #REG_R3]
ldr r4, [r0, #REG_R4]
ldr r5, [r0, #REG_R5]
ldr r6, [r0, #REG_R6]
ldr r7, [r0, #REG_R7]
ldr r8, [r0, #REG_R8]
ldr r9, [r0, #REG_R9]
ldr r10, [r0, #REG_R10]
ldr sp, [r0, #REG_SP]
ldr lr, [r0, #REG_PC]
mov pc, lr
.globl _Exception_Handler_Undef_Swi
_Exception_Handler_Undef_Swi:
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 fp, [r13, #REG_FP]
str ip, [r13, #REG_IP]
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 r0 (C arg 1) */
ldr r1, =_currentExcHandler
ldr lr, =_go_back_1
ldr pc,[r1] /* call handler */
_go_back_1:
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 fp, [r13, #REG_FP]
ldr ip, [r13, #REG_IP]
ldr sp, [r13, #REG_SP]
ldr lr, [r13, #REG_LR]
add r13,r13,#SIZE_REGS
movs pc,r14 /* return */
.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 sp, [r13, #REG_FP]
str lr, [r13, #REG_IP]
str lr, [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 sp, [r13, #REG_FP]
ldr lr, [r13, #REG_IP]
ldr lr, [r13, #REG_SP]
ldr lr, [r13, #REG_LR]
add r13,r13,#SIZE_REGS
subs pc,r14,#4 /* return */
|