exception.S revision 266277
1219820Sjeff/*	$NetBSD: exception.S,v 1.13 2003/10/31 16:30:15 scw Exp $	*/
2219820Sjeff
3219820Sjeff/*-
4219820Sjeff * Copyright (c) 1994-1997 Mark Brinicombe.
5219820Sjeff * Copyright (c) 1994 Brini.
6219820Sjeff * All rights reserved.
7219820Sjeff *
8219820Sjeff * This code is derived from software written for Brini by Mark Brinicombe
9219820Sjeff *
10219820Sjeff * Redistribution and use in source and binary forms, with or without
11219820Sjeff * modification, are permitted provided that the following conditions
12219820Sjeff * are met:
13219820Sjeff * 1. Redistributions of source code must retain the above copyright
14219820Sjeff *    notice, this list of conditions and the following disclaimer.
15219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright
16219820Sjeff *    notice, this list of conditions and the following disclaimer in the
17219820Sjeff *    documentation and/or other materials provided with the distribution.
18219820Sjeff * 3. All advertising materials mentioning features or use of this software
19219820Sjeff *    must display the following acknowledgement:
20219820Sjeff *	This product includes software developed by Brini.
21219820Sjeff * 4. The name of the company nor the name of the author may be used to
22219820Sjeff *    endorse or promote products derived from this software without specific
23219820Sjeff *    prior written permission.
24219820Sjeff *
25219820Sjeff * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
26219820Sjeff * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
27219820Sjeff * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28219820Sjeff * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29219820Sjeff * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30219820Sjeff * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31219820Sjeff * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32219820Sjeff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33219820Sjeff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34219820Sjeff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35219820Sjeff * SUCH DAMAGE.
36219820Sjeff *
37219820Sjeff * RiscBSD kernel project
38219820Sjeff *
39219820Sjeff * exception.S
40219820Sjeff *
41219820Sjeff * Low level handlers for exception vectors
42219820Sjeff *
43219820Sjeff * Created      : 24/09/94
44219820Sjeff *
45219820Sjeff * Based on kate/display/abort.s
46219820Sjeff *
47219820Sjeff */
48219820Sjeff
49219820Sjeff#include "assym.s"
50219820Sjeff
51219820Sjeff#include <machine/asm.h>
52219820Sjeff#include <machine/armreg.h>
53219820Sjeff#include <machine/asmacros.h>
54219820Sjeff__FBSDID("$FreeBSD: stable/10/sys/arm/arm/exception.S 266277 2014-05-17 00:53:12Z ian $");
55219820Sjeff
56219820Sjeff	.text
57219820Sjeff	.align	0
58219820Sjeff
59219820SjeffAST_LOCALS
60219820Sjeff
61219820Sjeff/*
62219820Sjeff * reset_entry:
63219820Sjeff *
64219820Sjeff *	Handler for Reset exception.
65219820Sjeff */
66219820SjeffASENTRY_NP(reset_entry)
67219820Sjeff	adr	r0, Lreset_panicmsg
68219820Sjeff	bl	_C_LABEL(panic)
69219820Sjeff	/* NOTREACHED */
70219820SjeffLreset_panicmsg:
71219820Sjeff	.asciz	"Reset vector called, LR = 0x%08x"
72219820Sjeff	.balign	4
73219820SjeffEND(reset_entry)
74219820Sjeff
75219820Sjeff/*
76219820Sjeff * swi_entry
77219820Sjeff *
78219820Sjeff *	Handler for the Software Interrupt exception.
79219820Sjeff */
80219820SjeffASENTRY_NP(swi_entry)
81219820Sjeff	STOP_UNWINDING			/* Don't unwind past here */
82219820Sjeff
83219820Sjeff	PUSHFRAME
84219820Sjeff
85219820Sjeff	mov	r0, sp			/* Pass the frame to any function */
86219820Sjeff	bl	_C_LABEL(swi_handler)	/* It's a SWI ! */
87219820Sjeff
88219820Sjeff	DO_AST
89219820Sjeff	PULLFRAME
90219820Sjeff	movs	pc, lr			/* Exit */
91219820SjeffEND(swi_entry)
92219820Sjeff
93219820Sjeff/*
94219820Sjeff * prefetch_abort_entry:
95219820Sjeff *
96219820Sjeff *	Handler for the Prefetch Abort exception.
97219820Sjeff */
98219820SjeffASENTRY_NP(prefetch_abort_entry)
99219820Sjeff#ifdef __XSCALE__
100219820Sjeff	nop				/* Make absolutely sure any pending */
101219820Sjeff	nop				/* imprecise aborts have occurred. */
102219820Sjeff#endif
103219820Sjeff        sub     lr, lr, #0x00000004     /* Adjust the lr */
104219820Sjeff
105219820Sjeff	PUSHFRAMEINSVC
106219820Sjeff	ldr	r1, Lprefetch_abort_handler_address
107219820Sjeff	adr	lr, exception_exit
108219820Sjeff 	mov	r0, sp			/* pass the stack pointer as r0 */
109219820Sjeff	ldr	pc, [r1]
110219820Sjeff
111219820SjeffLprefetch_abort_handler_address:
112219820Sjeff	.word	_C_LABEL(prefetch_abort_handler_address)
113219820Sjeff
114219820Sjeff	.data
115219820Sjeff	.global	_C_LABEL(prefetch_abort_handler_address)
116219820Sjeff
117219820Sjeff_C_LABEL(prefetch_abort_handler_address):
118219820Sjeff	.word	abortprefetch
119219820Sjeff
120219820Sjeff	.text
121219820Sjeffabortprefetch:
122219820Sjeff        adr     r0, abortprefetchmsg
123219820Sjeff	b	_C_LABEL(panic)
124219820Sjeff
125219820Sjeffabortprefetchmsg:
126219820Sjeff        .asciz  "abortprefetch"
127219820Sjeff        .align  0
128219820SjeffEND(prefetch_abort_entry)
129219820Sjeff
130219820Sjeff/*
131219820Sjeff * data_abort_entry:
132219820Sjeff *
133219820Sjeff *	Handler for the Data Abort exception.
134219820Sjeff */
135219820SjeffASENTRY_NP(data_abort_entry)
136219820Sjeff#ifdef __XSCALE__
137219820Sjeff	nop				/* Make absolutely sure any pending */
138219820Sjeff	nop				/* imprecise aborts have occurred. */
139219820Sjeff#endif
140219820Sjeff
141219820Sjeff        sub     lr, lr, #0x00000008     /* Adjust the lr */
142219820Sjeff	PUSHFRAMEINSVC			/* Push trap frame and switch */
143219820Sjeff					/* to SVC32 mode */
144219820Sjeff	ldr	r1, Ldata_abort_handler_address
145219820Sjeff	adr	lr, exception_exit
146219820Sjeff	mov	r0, sp			/* pass the stack pointer as r0 */
147219820Sjeff	ldr	pc, [r1]
148219820SjeffLdata_abort_handler_address:
149219820Sjeff	.word	_C_LABEL(data_abort_handler_address)
150219820Sjeff
151	.data
152	.global	_C_LABEL(data_abort_handler_address)
153_C_LABEL(data_abort_handler_address):
154	.word	abortdata
155
156	.text
157abortdata:
158        adr     r0, abortdatamsg
159	b	_C_LABEL(panic)
160
161abortdatamsg:
162        .asciz  "abortdata"
163        .align  0
164END(data_abort_entry)
165
166/*
167 * address_exception_entry:
168 *
169 *	Handler for the Address Exception exception.
170 *
171 *	NOTE: This exception isn't really used on arm32.  We
172 *	print a warning message to the console and then treat
173 *	it like a Data Abort.
174 */
175ASENTRY_NP(address_exception_entry)
176	mrs	r1, cpsr
177	mrs	r2, spsr
178	mov	r3, lr
179	adr	r0, Laddress_exception_msg
180	bl	_C_LABEL(printf)	/* XXX CLOBBERS LR!! */
181	b	data_abort_entry
182Laddress_exception_msg:
183	.asciz	"Address Exception CPSR=0x%08x SPSR=0x%08x LR=0x%08x\n"
184	.balign	4
185END(address_exception_entry)
186
187/*
188 * General exception exit handler
189 * (Placed here to be within range of all the references to it)
190 *
191 * It exits straight away if not returning to USR mode.
192 * This loops around delivering any pending ASTs.
193 * Interrupts are disabled at suitable points to avoid ASTs
194 * being posted between testing and exit to user mode.
195 *
196 * This function uses PULLFRAMEFROMSVCANDEXIT and DO_AST and can
197 * only be called if the exception handler used PUSHFRAMEINSVC.
198 *
199 * For EABI, don't try to unwind any further than this.  This is a
200 * stopgap measure to avoid getting stuck in a loop in the unwinder,
201 * which happens because we don't yet provide the proper unwind info
202 * here that describes which registers are being restored.
203 */
204
205ASENTRY_NP(exception_exit)
206	UNWINDSVCFRAME
207	DO_AST
208	PULLFRAMEFROMSVCANDEXIT
209END(exception_exit)
210
211/*
212 * undefined_entry:
213 *
214 *	Handler for the Undefined Instruction exception.
215 *
216 *	We indirect the undefined vector via the handler address
217 *	in the data area.  Entry to the undefined handler must
218 *	look like direct entry from the vector.
219 */
220ASENTRY_NP(undefined_entry)
221
222        sub     lr, lr, #0x00000004     /* Adjust the lr */
223	PUSHFRAMEINSVC			/* Push trap frame and switch */
224					/* to SVC32 mode */
225	ldr	r1, Lundefined_handler_address
226	adr	lr, exception_exit
227	mov	r0, sp			/* pass the stack pointer as r0 */
228	ldr	pc, [r1]
229END(undefined_entry)
230
231ASENTRY_NP(undefinedinstruction_bounce)
232	b	undefinedinstruction
233END(undefinedinstruction_bounce)
234
235Lundefined_handler_address:
236	.word	_C_LABEL(undefined_handler_address)
237
238	.data
239	.global	_C_LABEL(undefined_handler_address)
240_C_LABEL(undefined_handler_address):
241	.word	undefinedinstruction_bounce
242
243