Annotation of sys/arch/arm/arm/exception.S, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: exception.S,v 1.2 2004/02/01 06:10:33 drahn Exp $ */
2: /* $NetBSD: exception.S,v 1.13 2003/10/31 16:30:15 scw Exp $ */
3:
4: /*
5: * Copyright (c) 1994-1997 Mark Brinicombe.
6: * Copyright (c) 1994 Brini.
7: * All rights reserved.
8: *
9: * This code is derived from software written for Brini by Mark Brinicombe
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. All advertising materials mentioning features or use of this software
20: * must display the following acknowledgement:
21: * This product includes software developed by Brini.
22: * 4. The name of the company nor the name of the author may be used to
23: * endorse or promote products derived from this software without specific
24: * prior written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
27: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29: * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36: * SUCH DAMAGE.
37: *
38: * RiscBSD kernel project
39: *
40: * exception.S
41: *
42: * Low level handlers for exception vectors
43: *
44: * Created : 24/09/94
45: *
46: * Based on kate/display/abort.s
47: */
48:
49: #include <machine/asm.h>
50: #include <machine/cpu.h>
51: #include <machine/frame.h>
52: #include "assym.h"
53:
54: .text
55: .align 0
56:
57: AST_ALIGNMENT_FAULT_LOCALS
58:
59: /*
60: * reset_entry:
61: *
62: * Handler for Reset exception.
63: */
64: ASENTRY_NP(reset_entry)
65: adr r0, Lreset_panicmsg
66: mov r1, lr
67: bl _C_LABEL(panic)
68: /* NOTREACHED */
69: Lreset_panicmsg:
70: .asciz "Reset vector called, LR = 0x%08x"
71: .balign 4
72:
73: /*
74: * swi_entry
75: *
76: * Handler for the Software Interrupt exception.
77: */
78: ASENTRY_NP(swi_entry)
79: PUSHFRAME
80: ENABLE_ALIGNMENT_FAULTS
81:
82: mov r0, sp /* Pass the frame to any function */
83: bl _C_LABEL(swi_handler) /* It's a SWI ! */
84:
85: DO_AST_AND_RESTORE_ALIGNMENT_FAULTS
86: PULLFRAME
87: movs pc, lr /* Exit */
88:
89: /*
90: * prefetch_abort_entry:
91: *
92: * Handler for the Prefetch Abort exception.
93: */
94: ASENTRY_NP(prefetch_abort_entry)
95: #ifdef __XSCALE__
96: nop /* Make absolutely sure any pending */
97: nop /* imprecise aborts have occurred. */
98: #endif
99: sub lr, lr, #0x00000004 /* Adjust the lr */
100:
101: PUSHFRAMEINSVC
102: ENABLE_ALIGNMENT_FAULTS
103:
104: ldr r1, Lprefetch_abort_handler_address
105: adr lr, exception_exit
106: mov r0, sp /* pass the stack pointer as r0 */
107: ldr pc, [r1]
108:
109: Lprefetch_abort_handler_address:
110: .word _C_LABEL(prefetch_abort_handler_address)
111:
112: .data
113: .global _C_LABEL(prefetch_abort_handler_address)
114:
115: _C_LABEL(prefetch_abort_handler_address):
116: .word abortprefetch
117:
118: .text
119: abortprefetch:
120: adr r0, abortprefetchmsg
121: b _C_LABEL(panic)
122:
123: abortprefetchmsg:
124: .asciz "abortprefetch"
125: .align 0
126:
127: /*
128: * data_abort_entry:
129: *
130: * Handler for the Data Abort exception.
131: */
132: ASENTRY_NP(data_abort_entry)
133: #ifdef __XSCALE__
134: nop /* Make absolutely sure any pending */
135: nop /* imprecise aborts have occurred. */
136: #endif
137: sub lr, lr, #0x00000008 /* Adjust the lr */
138:
139: PUSHFRAMEINSVC /* Push trap frame and switch */
140: /* to SVC32 mode */
141: ENABLE_ALIGNMENT_FAULTS
142:
143: ldr r1, Ldata_abort_handler_address
144: adr lr, exception_exit
145: mov r0, sp /* pass the stack pointer as r0 */
146: ldr pc, [r1]
147:
148: Ldata_abort_handler_address:
149: .word _C_LABEL(data_abort_handler_address)
150:
151: .data
152: .global _C_LABEL(data_abort_handler_address)
153: _C_LABEL(data_abort_handler_address):
154: .word abortdata
155:
156: .text
157: abortdata:
158: adr r0, abortdatamsg
159: b _C_LABEL(panic)
160:
161: abortdatamsg:
162: .asciz "abortdata"
163: .align 0
164:
165: /*
166: * address_exception_entry:
167: *
168: * Handler for the Address Exception exception.
169: *
170: * NOTE: This exception isn't really used on arm32. We
171: * print a warning message to the console and then treat
172: * it like a Data Abort.
173: */
174: ASENTRY_NP(address_exception_entry)
175: mrs r1, cpsr_all
176: mrs r2, spsr_all
177: mov r3, lr
178: adr r0, Laddress_exception_msg
179: bl _C_LABEL(printf) /* XXX CLOBBERS LR!! */
180: b data_abort_entry
181: Laddress_exception_msg:
182: .asciz "Address Exception CPSR=0x%08x SPSR=0x%08x LR=0x%08x\n"
183: .balign 4
184:
185: /*
186: * General exception exit handler
187: * (Placed here to be within range of all the references to it)
188: *
189: * It exits straight away if not returning to USR mode.
190: * This loops around delivering any pending ASTs.
191: * Interrupts are disabled at suitable points to avoid ASTs
192: * being posted between testing and exit to user mode.
193: *
194: * This function uses PULLFRAMEFROMSVCANDEXIT and
195: * DO_AST_AND_RESTORE_ALIGNMENT_FAULTS thus should
196: * only be called if the exception handler used PUSHFRAMEINSVC
197: * followed by ENABLE_ALIGNMENT_FAULTS.
198: */
199:
200: exception_exit:
201: DO_AST_AND_RESTORE_ALIGNMENT_FAULTS
202: PULLFRAMEFROMSVCANDEXIT
203:
204: /*
205: * undefined_entry:
206: *
207: * Handler for the Undefined Instruction exception.
208: *
209: * We indirect the undefined vector via the handler address
210: * in the data area. Entry to the undefined handler must
211: * look like direct entry from the vector.
212: */
213: ASENTRY_NP(undefined_entry)
214: #ifdef IPKDB
215: /*
216: * IPKDB must be hooked in at the earliest possible entry point.
217: *
218: */
219: /*
220: * Make room for all registers saving real r0-r7 and r15.
221: * The remaining registers are updated later.
222: */
223: stmfd sp!, {r0,r1} /* psr & spsr */
224: stmfd sp!, {lr} /* pc */
225: stmfd sp!, {r0-r14} /* r0-r7, r8-r14 */
226: /*
227: * Get previous psr.
228: */
229: mrs r7, cpsr_all
230: mrs r0, spsr_all
231: str r0, [sp, #(16*4)]
232: /*
233: * Test for user mode.
234: */
235: tst r0, #0xf
236: bne .Lprenotuser_push
237: add r1, sp, #(8*4)
238: stmia r1,{r8-r14}^ /* store user mode r8-r14*/
239: b .Lgoipkdb
240: /*
241: * Switch to previous mode to get r8-r13.
242: */
243: .Lprenotuser_push:
244: orr r0, r0, #(I32_bit) /* disable interrupts */
245: msr cpsr_all, r0
246: mov r1, r8
247: mov r2, r9
248: mov r3, r10
249: mov r4, r11
250: mov r5, r12
251: mov r6, r13
252: msr cpsr_all, r7 /* back to undefined mode */
253: add r8, sp, #(8*4)
254: stmia r8, {r1-r6} /* r8-r13 */
255: /*
256: * Now back to previous mode to get r14 and spsr.
257: */
258: msr cpsr_all, r0
259: mov r1, r14
260: mrs r2, spsr
261: msr cpsr_all, r7 /* back to undefined mode */
262: str r1, [sp, #(14*4)] /* r14 */
263: str r2, [sp, #(17*4)] /* spsr */
264: /*
265: * Now to IPKDB.
266: */
267: .Lgoipkdb:
268: mov r0, sp
269: bl _C_LABEL(ipkdb_trap_glue)
270: ldr r1, .Lipkdb_trap_return
271: str r0,[r1]
272:
273: /*
274: * Have to load all registers from the stack.
275: *
276: * Start with spsr and pc.
277: */
278: ldr r0, [sp, #(16*4)] /* spsr */
279: ldr r1, [sp, #(15*4)] /* r15 */
280: msr spsr_all, r0
281: mov r14, r1
282: /*
283: * Test for user mode.
284: */
285: tst r0, #0xf
286: bne .Lprenotuser_pull
287: add r1, sp, #(8*4)
288: ldmia r1, {r8-r14}^ /* load user mode r8-r14 */
289: b .Lpull_r0r7
290: .Lprenotuser_pull:
291: /*
292: * Now previous mode spsr and r14.
293: */
294: ldr r1, [sp, #(17*4)] /* spsr */
295: ldr r2, [sp, #(14*4)] /* r14 */
296: orr r0, r0, #(I32_bit)
297: msr cpsr_all, r0 /* switch to previous mode */
298: msr spsr_all, r1
299: mov r14, r2
300: msr cpsr_all, r7 /* back to undefined mode */
301: /*
302: * Now r8-r13.
303: */
304: add r8, sp, #(8*4)
305: ldmia r8, {r1-r6} /* r8-r13 */
306: msr cpsr_all, r0
307: mov r8, r1
308: mov r9, r2
309: mov r10, r3
310: mov r11, r4
311: mov r12, r5
312: mov r13, r6
313: msr cpsr_all, r7
314: .Lpull_r0r7:
315: /*
316: * Now the rest of the registers.
317: */
318: ldr r1,Lipkdb_trap_return
319: ldr r0,[r1]
320: tst r0,r0
321: ldmfd sp!, {r0-r7} /* r0-r7 */
322: add sp, sp, #(10*4) /* adjust sp */
323:
324: /*
325: * Did IPKDB handle it?
326: */
327: movnes pc, lr /* return */
328:
329: #endif
330: stmfd sp!, {r0, r1}
331: ldr r0, Lundefined_handler_indirection
332: ldr r1, [sp], #0x0004
333: str r1, [r0, #0x0000]
334: ldr r1, [sp], #0x0004
335: str r1, [r0, #0x0004]
336: ldmia r0, {r0, r1, pc}
337:
338: #ifdef IPKDB
339: Lipkdb_trap_return:
340: .word Lipkdb_trap_return_data
341: #endif
342:
343: Lundefined_handler_indirection:
344: .word Lundefined_handler_indirection_data
345:
346: /*
347: * assembly bounce code for calling the kernel
348: * undefined instruction handler. This uses
349: * a standard trap frame and is called in SVC mode.
350: */
351:
352: ENTRY_NP(undefinedinstruction_bounce)
353: PUSHFRAMEINSVC
354: ENABLE_ALIGNMENT_FAULTS
355:
356: mov r0, sp
357: adr lr, exception_exit
358: b _C_LABEL(undefinedinstruction)
359:
360: .data
361: .align 0
362:
363: #ifdef IPKDB
364: Lipkdb_trap_return_data:
365: .word 0
366: #endif
367:
368: /*
369: * Indirection data
370: * 2 words use for preserving r0 and r1
371: * 3rd word contains the undefined handler address.
372: */
373:
374: Lundefined_handler_indirection_data:
375: .word 0
376: .word 0
377:
378: .global _C_LABEL(undefined_handler_address)
379: _C_LABEL(undefined_handler_address):
380: .word _C_LABEL(undefinedinstruction_bounce)
CVSweb