annotate source/exception.S @ 0:ed10291ff195

first commit
author mir3636
date Sun, 06 Jan 2019 19:27:03 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
ed10291ff195 first commit
mir3636
parents:
diff changeset
1 /*****************************************************************
ed10291ff195 first commit
mir3636
parents:
diff changeset
2 * exception.s
ed10291ff195 first commit
mir3636
parents:
diff changeset
3 * by Zhiyi Huang, hzy@cs.otago.ac.nz
ed10291ff195 first commit
mir3636
parents:
diff changeset
4 * University of Otago
ed10291ff195 first commit
mir3636
parents:
diff changeset
5 *
ed10291ff195 first commit
mir3636
parents:
diff changeset
6 ********************************************************************/
ed10291ff195 first commit
mir3636
parents:
diff changeset
7
ed10291ff195 first commit
mir3636
parents:
diff changeset
8
ed10291ff195 first commit
mir3636
parents:
diff changeset
9 .align 4
ed10291ff195 first commit
mir3636
parents:
diff changeset
10 .section .text
ed10291ff195 first commit
mir3636
parents:
diff changeset
11
ed10291ff195 first commit
mir3636
parents:
diff changeset
12 .global vectors
ed10291ff195 first commit
mir3636
parents:
diff changeset
13 vectors:
ed10291ff195 first commit
mir3636
parents:
diff changeset
14 ldr pc, reset_handler
ed10291ff195 first commit
mir3636
parents:
diff changeset
15 ldr pc, undefintr_handler
ed10291ff195 first commit
mir3636
parents:
diff changeset
16 ldr pc, swi_handler
ed10291ff195 first commit
mir3636
parents:
diff changeset
17 ldr pc, prefetch_handler
ed10291ff195 first commit
mir3636
parents:
diff changeset
18 ldr pc, data_handler
ed10291ff195 first commit
mir3636
parents:
diff changeset
19 ldr pc, unused_handler
ed10291ff195 first commit
mir3636
parents:
diff changeset
20 ldr pc, irq_handler
ed10291ff195 first commit
mir3636
parents:
diff changeset
21 ldr pc, fiq_handler
ed10291ff195 first commit
mir3636
parents:
diff changeset
22 reset_handler:
ed10291ff195 first commit
mir3636
parents:
diff changeset
23 .word hang /* reset, in svc mode already */
ed10291ff195 first commit
mir3636
parents:
diff changeset
24 undefintr_handler:
ed10291ff195 first commit
mir3636
parents:
diff changeset
25 .word do_und /* undefined instruction */
ed10291ff195 first commit
mir3636
parents:
diff changeset
26 swi_handler:
ed10291ff195 first commit
mir3636
parents:
diff changeset
27 .word do_svc /* SWI & SVC */
ed10291ff195 first commit
mir3636
parents:
diff changeset
28 prefetch_handler:
ed10291ff195 first commit
mir3636
parents:
diff changeset
29 .word do_pabt /* prefetch abort */
ed10291ff195 first commit
mir3636
parents:
diff changeset
30 data_handler:
ed10291ff195 first commit
mir3636
parents:
diff changeset
31 .word do_dabt /* data abort */
ed10291ff195 first commit
mir3636
parents:
diff changeset
32 unused_handler:
ed10291ff195 first commit
mir3636
parents:
diff changeset
33 .word hang /* reserved */
ed10291ff195 first commit
mir3636
parents:
diff changeset
34 irq_handler:
ed10291ff195 first commit
mir3636
parents:
diff changeset
35 .word do_irq /* IRQ */
ed10291ff195 first commit
mir3636
parents:
diff changeset
36 fiq_handler:
ed10291ff195 first commit
mir3636
parents:
diff changeset
37 .word hang /* FIQ */
ed10291ff195 first commit
mir3636
parents:
diff changeset
38
ed10291ff195 first commit
mir3636
parents:
diff changeset
39 hang:
ed10291ff195 first commit
mir3636
parents:
diff changeset
40 bl NotOkLoop;
ed10291ff195 first commit
mir3636
parents:
diff changeset
41 b hang
ed10291ff195 first commit
mir3636
parents:
diff changeset
42 do_svc:
ed10291ff195 first commit
mir3636
parents:
diff changeset
43 push {lr}
ed10291ff195 first commit
mir3636
parents:
diff changeset
44 mrs lr, spsr
ed10291ff195 first commit
mir3636
parents:
diff changeset
45 push {lr}
ed10291ff195 first commit
mir3636
parents:
diff changeset
46 mrs lr, cpsr
ed10291ff195 first commit
mir3636
parents:
diff changeset
47 push {lr}
ed10291ff195 first commit
mir3636
parents:
diff changeset
48 mrc p15, 0, lr, c6, c0, 2 /* read Instruction Fault Address Register (IFAR) */
ed10291ff195 first commit
mir3636
parents:
diff changeset
49 push {lr}
ed10291ff195 first commit
mir3636
parents:
diff changeset
50 mov lr, #0x40
ed10291ff195 first commit
mir3636
parents:
diff changeset
51 push {lr}
ed10291ff195 first commit
mir3636
parents:
diff changeset
52 STMFD sp, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14}
ed10291ff195 first commit
mir3636
parents:
diff changeset
53 sub sp, sp, #60
ed10291ff195 first commit
mir3636
parents:
diff changeset
54 mov r0, sp /* save sp */
ed10291ff195 first commit
mir3636
parents:
diff changeset
55 STMFD r0, {r13}^ /* save user mode sp */
ed10291ff195 first commit
mir3636
parents:
diff changeset
56 mov r1, r1 /* three nops after STM with user mode banked registers */
ed10291ff195 first commit
mir3636
parents:
diff changeset
57 mov r1, r1
ed10291ff195 first commit
mir3636
parents:
diff changeset
58 mov r1, r1
ed10291ff195 first commit
mir3636
parents:
diff changeset
59 mov sp, r0 /* restore sp */
ed10291ff195 first commit
mir3636
parents:
diff changeset
60 sub sp, sp, #4
ed10291ff195 first commit
mir3636
parents:
diff changeset
61 mov r0, sp
ed10291ff195 first commit
mir3636
parents:
diff changeset
62 bl trap
ed10291ff195 first commit
mir3636
parents:
diff changeset
63
ed10291ff195 first commit
mir3636
parents:
diff changeset
64 .global trapret
ed10291ff195 first commit
mir3636
parents:
diff changeset
65 trapret:
ed10291ff195 first commit
mir3636
parents:
diff changeset
66 mov r0, sp /* save sp in case it is changed to sp_usr after the following LDMFD instruction */
ed10291ff195 first commit
mir3636
parents:
diff changeset
67 LDMFD r0, {r13}^ /* restore user mode sp */
ed10291ff195 first commit
mir3636
parents:
diff changeset
68 mov r1, r1 /* three nops after LDMFD */
ed10291ff195 first commit
mir3636
parents:
diff changeset
69 mov r1, r1
ed10291ff195 first commit
mir3636
parents:
diff changeset
70 mov r1, r1
ed10291ff195 first commit
mir3636
parents:
diff changeset
71 mov sp, r0 /* restore sp */
ed10291ff195 first commit
mir3636
parents:
diff changeset
72 add sp, sp, #4
ed10291ff195 first commit
mir3636
parents:
diff changeset
73 LDMFD sp, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12}
ed10291ff195 first commit
mir3636
parents:
diff changeset
74 add sp, sp, #72
ed10291ff195 first commit
mir3636
parents:
diff changeset
75 pop {lr}
ed10291ff195 first commit
mir3636
parents:
diff changeset
76 msr spsr, lr
ed10291ff195 first commit
mir3636
parents:
diff changeset
77 pop {lr}
ed10291ff195 first commit
mir3636
parents:
diff changeset
78 movs pc, lr /* subs pc,lr,#0 */
ed10291ff195 first commit
mir3636
parents:
diff changeset
79
ed10291ff195 first commit
mir3636
parents:
diff changeset
80 do_und:
ed10291ff195 first commit
mir3636
parents:
diff changeset
81 STMFD sp, {r0-r4}
ed10291ff195 first commit
mir3636
parents:
diff changeset
82 mov r0, #0x01
ed10291ff195 first commit
mir3636
parents:
diff changeset
83 b _switchtosvc
ed10291ff195 first commit
mir3636
parents:
diff changeset
84
ed10291ff195 first commit
mir3636
parents:
diff changeset
85 do_pabt:
ed10291ff195 first commit
mir3636
parents:
diff changeset
86 STMFD sp, {r0-r4}
ed10291ff195 first commit
mir3636
parents:
diff changeset
87 mov r0, #0x02
ed10291ff195 first commit
mir3636
parents:
diff changeset
88 b _switchtosvc
ed10291ff195 first commit
mir3636
parents:
diff changeset
89
ed10291ff195 first commit
mir3636
parents:
diff changeset
90 do_dabt:
ed10291ff195 first commit
mir3636
parents:
diff changeset
91 STMFD sp, {r0-r4}
ed10291ff195 first commit
mir3636
parents:
diff changeset
92 mov r0, #0x04
ed10291ff195 first commit
mir3636
parents:
diff changeset
93 b _switchtosvc
ed10291ff195 first commit
mir3636
parents:
diff changeset
94
ed10291ff195 first commit
mir3636
parents:
diff changeset
95 do_irq:
ed10291ff195 first commit
mir3636
parents:
diff changeset
96 STMFD sp, {r0-r4}
ed10291ff195 first commit
mir3636
parents:
diff changeset
97 mov r0, #0x80
ed10291ff195 first commit
mir3636
parents:
diff changeset
98 b _switchtosvc
ed10291ff195 first commit
mir3636
parents:
diff changeset
99 _switchtosvc:
ed10291ff195 first commit
mir3636
parents:
diff changeset
100 mrs r1, spsr
ed10291ff195 first commit
mir3636
parents:
diff changeset
101 sub r2, lr, #4
ed10291ff195 first commit
mir3636
parents:
diff changeset
102 mov r3, sp
ed10291ff195 first commit
mir3636
parents:
diff changeset
103 mrs lr, cpsr
ed10291ff195 first commit
mir3636
parents:
diff changeset
104 bic lr, #0x0000001F /* PSR_MASK */
ed10291ff195 first commit
mir3636
parents:
diff changeset
105 orr lr, #0x00000080 /* PSR_DISABLE_IRQ */
ed10291ff195 first commit
mir3636
parents:
diff changeset
106 orr lr, #0x00000013 /* PSR_MODE_SVC */
ed10291ff195 first commit
mir3636
parents:
diff changeset
107 msr cpsr, lr /* switch to svc */
ed10291ff195 first commit
mir3636
parents:
diff changeset
108 push {r2}
ed10291ff195 first commit
mir3636
parents:
diff changeset
109 push {r1}
ed10291ff195 first commit
mir3636
parents:
diff changeset
110 mrs r1, cpsr
ed10291ff195 first commit
mir3636
parents:
diff changeset
111 push {r1}
ed10291ff195 first commit
mir3636
parents:
diff changeset
112 mrc p15, 0, r1, c6, c0, 2 /* read Instruction Fault Address Register (I
ed10291ff195 first commit
mir3636
parents:
diff changeset
113 FAR) */
ed10291ff195 first commit
mir3636
parents:
diff changeset
114 push {r1}
ed10291ff195 first commit
mir3636
parents:
diff changeset
115 push {r0}
ed10291ff195 first commit
mir3636
parents:
diff changeset
116 sub r1, r3, #20
ed10291ff195 first commit
mir3636
parents:
diff changeset
117 LDMFD r1, {r0-r4}
ed10291ff195 first commit
mir3636
parents:
diff changeset
118 STMFD sp, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14}
ed10291ff195 first commit
mir3636
parents:
diff changeset
119 sub sp, sp, #60
ed10291ff195 first commit
mir3636
parents:
diff changeset
120 mov r0, sp /* save sp */
ed10291ff195 first commit
mir3636
parents:
diff changeset
121 STMFD r0, {r13}^ /* save user mode sp */
ed10291ff195 first commit
mir3636
parents:
diff changeset
122 mov r1, r1 /* three nops after STM with user mode banked registers */
ed10291ff195 first commit
mir3636
parents:
diff changeset
123 mov r1, r1
ed10291ff195 first commit
mir3636
parents:
diff changeset
124 mov r1, r1
ed10291ff195 first commit
mir3636
parents:
diff changeset
125 mov sp, r0 /* restore sp */
ed10291ff195 first commit
mir3636
parents:
diff changeset
126 sub sp, sp, #4
ed10291ff195 first commit
mir3636
parents:
diff changeset
127 mov r0, sp
ed10291ff195 first commit
mir3636
parents:
diff changeset
128
ed10291ff195 first commit
mir3636
parents:
diff changeset
129 bl trap
ed10291ff195 first commit
mir3636
parents:
diff changeset
130
ed10291ff195 first commit
mir3636
parents:
diff changeset
131 mov r0, sp
ed10291ff195 first commit
mir3636
parents:
diff changeset
132 add r0, #76
ed10291ff195 first commit
mir3636
parents:
diff changeset
133 LDMIA r0, {r1}
ed10291ff195 first commit
mir3636
parents:
diff changeset
134 mov r2, r1
ed10291ff195 first commit
mir3636
parents:
diff changeset
135 and r2, #0xf
ed10291ff195 first commit
mir3636
parents:
diff changeset
136 cmp r2, #0
ed10291ff195 first commit
mir3636
parents:
diff changeset
137 beq _backtouser
ed10291ff195 first commit
mir3636
parents:
diff changeset
138 msr cpsr, r1
ed10291ff195 first commit
mir3636
parents:
diff changeset
139 add sp, #4
ed10291ff195 first commit
mir3636
parents:
diff changeset
140 LDMFD sp, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12}
ed10291ff195 first commit
mir3636
parents:
diff changeset
141 add sp, sp, #56
ed10291ff195 first commit
mir3636
parents:
diff changeset
142 pop {r14}
ed10291ff195 first commit
mir3636
parents:
diff changeset
143 add sp, sp, #16
ed10291ff195 first commit
mir3636
parents:
diff changeset
144 pop {pc}
ed10291ff195 first commit
mir3636
parents:
diff changeset
145
ed10291ff195 first commit
mir3636
parents:
diff changeset
146 _backtouser:
ed10291ff195 first commit
mir3636
parents:
diff changeset
147 mov r0, sp /* save sp in case it is changed to sp_usr after the following LDMFD instruction */
ed10291ff195 first commit
mir3636
parents:
diff changeset
148 LDMFD r0, {r13}^ /* restore user mode sp */
ed10291ff195 first commit
mir3636
parents:
diff changeset
149 mov r1, r1 /* three nops after LDMFD */
ed10291ff195 first commit
mir3636
parents:
diff changeset
150 mov r1, r1
ed10291ff195 first commit
mir3636
parents:
diff changeset
151 mov r1, r1
ed10291ff195 first commit
mir3636
parents:
diff changeset
152 mov sp, r0 /* restore sp */
ed10291ff195 first commit
mir3636
parents:
diff changeset
153 add sp, sp, #4
ed10291ff195 first commit
mir3636
parents:
diff changeset
154 LDMIA sp, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12}
ed10291ff195 first commit
mir3636
parents:
diff changeset
155 add sp, sp, #72
ed10291ff195 first commit
mir3636
parents:
diff changeset
156 pop {lr}
ed10291ff195 first commit
mir3636
parents:
diff changeset
157 msr spsr, lr
ed10291ff195 first commit
mir3636
parents:
diff changeset
158 pop {lr}
ed10291ff195 first commit
mir3636
parents:
diff changeset
159 movs pc, lr /* subs pc,lr,#0 */
ed10291ff195 first commit
mir3636
parents:
diff changeset
160
ed10291ff195 first commit
mir3636
parents:
diff changeset
161
ed10291ff195 first commit
mir3636
parents:
diff changeset
162 .global set_mode_sp
ed10291ff195 first commit
mir3636
parents:
diff changeset
163 set_mode_sp:
ed10291ff195 first commit
mir3636
parents:
diff changeset
164 mrs r2, cpsr
ed10291ff195 first commit
mir3636
parents:
diff changeset
165 msr cpsr_c,r1
ed10291ff195 first commit
mir3636
parents:
diff changeset
166 mov sp, r0
ed10291ff195 first commit
mir3636
parents:
diff changeset
167 mrs r0, cpsr
ed10291ff195 first commit
mir3636
parents:
diff changeset
168 orr r0, #0x00000080 /* PSR_DISABLE_IRQ */
ed10291ff195 first commit
mir3636
parents:
diff changeset
169 orr r0, #0x00000040 /* PSR_DISABLE_FIQ */
ed10291ff195 first commit
mir3636
parents:
diff changeset
170 msr cpsr, r0
ed10291ff195 first commit
mir3636
parents:
diff changeset
171 msr cpsr_c, r2
ed10291ff195 first commit
mir3636
parents:
diff changeset
172 bx lr
ed10291ff195 first commit
mir3636
parents:
diff changeset
173
ed10291ff195 first commit
mir3636
parents:
diff changeset
174 .global readcpsr
ed10291ff195 first commit
mir3636
parents:
diff changeset
175 readcpsr:
ed10291ff195 first commit
mir3636
parents:
diff changeset
176 mrs r0, cpsr
ed10291ff195 first commit
mir3636
parents:
diff changeset
177 bx lr
ed10291ff195 first commit
mir3636
parents:
diff changeset
178
ed10291ff195 first commit
mir3636
parents:
diff changeset
179 .global cli
ed10291ff195 first commit
mir3636
parents:
diff changeset
180 cli:
ed10291ff195 first commit
mir3636
parents:
diff changeset
181 mrs r0, cpsr
ed10291ff195 first commit
mir3636
parents:
diff changeset
182 orr r0, #0x00000080 /* PSR_DISABLE_IRQ */
ed10291ff195 first commit
mir3636
parents:
diff changeset
183 msr cpsr, r0
ed10291ff195 first commit
mir3636
parents:
diff changeset
184 bx lr
ed10291ff195 first commit
mir3636
parents:
diff changeset
185
ed10291ff195 first commit
mir3636
parents:
diff changeset
186 .global sti
ed10291ff195 first commit
mir3636
parents:
diff changeset
187 sti:
ed10291ff195 first commit
mir3636
parents:
diff changeset
188 mrs r0, cpsr
ed10291ff195 first commit
mir3636
parents:
diff changeset
189 bic r0, r0, #0x00000080 /* PSR_DISABLE_IRQ */
ed10291ff195 first commit
mir3636
parents:
diff changeset
190 msr cpsr, r0
ed10291ff195 first commit
mir3636
parents:
diff changeset
191 bx lr
ed10291ff195 first commit
mir3636
parents:
diff changeset
192
ed10291ff195 first commit
mir3636
parents:
diff changeset
193 .global swtch
ed10291ff195 first commit
mir3636
parents:
diff changeset
194 swtch:
ed10291ff195 first commit
mir3636
parents:
diff changeset
195 push {lr} /* save the return address */
ed10291ff195 first commit
mir3636
parents:
diff changeset
196 push {lr}
ed10291ff195 first commit
mir3636
parents:
diff changeset
197 /* save old callee-save registers */
ed10291ff195 first commit
mir3636
parents:
diff changeset
198 push {r12}
ed10291ff195 first commit
mir3636
parents:
diff changeset
199 push {r11}
ed10291ff195 first commit
mir3636
parents:
diff changeset
200 push {r10}
ed10291ff195 first commit
mir3636
parents:
diff changeset
201 push {r9}
ed10291ff195 first commit
mir3636
parents:
diff changeset
202 push {r8}
ed10291ff195 first commit
mir3636
parents:
diff changeset
203 push {r7}
ed10291ff195 first commit
mir3636
parents:
diff changeset
204 push {r6}
ed10291ff195 first commit
mir3636
parents:
diff changeset
205 push {r5}
ed10291ff195 first commit
mir3636
parents:
diff changeset
206 push {r4}
ed10291ff195 first commit
mir3636
parents:
diff changeset
207
ed10291ff195 first commit
mir3636
parents:
diff changeset
208 /* switch stacks */
ed10291ff195 first commit
mir3636
parents:
diff changeset
209 str sp, [r0]
ed10291ff195 first commit
mir3636
parents:
diff changeset
210 mov sp, r1
ed10291ff195 first commit
mir3636
parents:
diff changeset
211
ed10291ff195 first commit
mir3636
parents:
diff changeset
212 /* load new callee-save registers */
ed10291ff195 first commit
mir3636
parents:
diff changeset
213 pop {r4}
ed10291ff195 first commit
mir3636
parents:
diff changeset
214 pop {r5}
ed10291ff195 first commit
mir3636
parents:
diff changeset
215 pop {r6}
ed10291ff195 first commit
mir3636
parents:
diff changeset
216 pop {r7}
ed10291ff195 first commit
mir3636
parents:
diff changeset
217 pop {r8}
ed10291ff195 first commit
mir3636
parents:
diff changeset
218 pop {r9}
ed10291ff195 first commit
mir3636
parents:
diff changeset
219 pop {r10}
ed10291ff195 first commit
mir3636
parents:
diff changeset
220 pop {r11}
ed10291ff195 first commit
mir3636
parents:
diff changeset
221 pop {r12}
ed10291ff195 first commit
mir3636
parents:
diff changeset
222
ed10291ff195 first commit
mir3636
parents:
diff changeset
223 /* return to previously saved pc */
ed10291ff195 first commit
mir3636
parents:
diff changeset
224 pop {lr}
ed10291ff195 first commit
mir3636
parents:
diff changeset
225 pop {pc}
ed10291ff195 first commit
mir3636
parents:
diff changeset
226