exception_vector.S revision 1.11
1/*	$NetBSD: exception_vector.S,v 1.11 2003/11/24 03:06:01 uwe Exp $	*/
2
3/*-
4 * Copyright (c) 2002 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *        This product includes software developed by the NetBSD
18 *        Foundation, Inc. and its contributors.
19 * 4. Neither the name of The NetBSD Foundation nor the names of its
20 *    contributors may be used to endorse or promote products derived
21 *    from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
24 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
27 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#include "opt_cputype.h"
37#include "opt_ddb.h"
38#include "assym.h"
39
40#include <sh3/param.h>
41#include <sh3/asm.h>
42#include <sh3/locore.h>
43#include <sh3/exception.h>
44#include <sh3/ubcreg.h>
45#include <sh3/mmu_sh3.h>
46#include <sh3/mmu_sh4.h>
47
48/*
49 * Exception vectors. following routines are copied to vector addreses.
50 *	sh_vector_generic:	VBR + 0x100
51 *	sh_vector_tlbmiss:	VBR + 0x400
52 *	sh_vector_interrupt:	VBR + 0x600
53 */
54
55/*
56 * void sh_vector_generic(void) __attribute__((__noreturn__)):
57 *	copied to VBR+0x100. This code should be relocatable and max 384
58 *	instructions.
59 */
60	.globl	_C_LABEL(sh_vector_generic), _C_LABEL(sh_vector_generic_end)
61	.text
62	.align	2
63_C_LABEL(sh_vector_generic):
64	__EXCEPTION_ENTRY
65	__INTR_MASK(r0, r1)
66	/* Identify exception cause */
67	MOV	(EXPEVT, r0)
68	mov.l	@r0,	r0
69	mov.l	r0,	@(TF_EXPEVT, r14) /* trapframe->tf_expevt = EXPEVT */
70	/* Get curlwp */
71	mov.l	3f,	r1
72	mov.l	@r1,	r4	/* 1st arg */
73	/* Get TEA */
74	MOV	(TEA,	r1)
75	mov.l	@r1,	r6	/* 3rd arg */
76	/* Check TLB exception or not */
77	mov.l	_L.TLB_PROT_ST, r1
78	cmp/hi	r1,	r0
79	bt	1f
80
81	/* tlb_exception(curlwp, trapframe, trunc_page(TEA)); */
82	mov.l	_L.VPN_MASK, r1
83	and	r1,	r6	/* va = trunc_page(va) */
84	__EXCEPTION_UNBLOCK(r0, r1)
85	mov.l	_L.tlb, r0
86	jsr	@r0
87	 mov	r14,	r5	/* 2nd arg */
88	bra	2f
89	 nop
90
91	/* general_exception(curlwp, trapframe, TEA); */
921:	mov	r4,	r8
93#ifdef DDB
94	mov	#0,	r2
95	MOV	(BBRA, r1)
96	mov.w	r2,	@r1	/* disable UBC */
97	mov.l	r2,	@(TF_UBC, r14)	/* clear trapframe->tf_ubc */
98#endif /* DDB */
99	__EXCEPTION_UNBLOCK(r0, r1)
100	mov.l	_L.general, r0
101	jsr	@r0
102	 mov	r14,	r5	/* 2nd arg */
103
104	/* Check for ASTs on exit to user mode. */
105	mov	r8,	r4
106	mov.l	_L.ast,	r0
107	jsr	@r0
108	 mov	r14,	r5
109#ifdef DDB	/* BBRA = trapframe->tf_ubc */
110	__EXCEPTION_BLOCK(r0, r1)
111	mov.l	@(TF_UBC, r14), r0
112	MOV	(BBRA, r1)
113	mov.w	r0,	@r1
114#endif /* DDB */
1152:	__EXCEPTION_RETURN
116	/* NOTREACHED */
117	.align	2
1183:		.long	_C_LABEL(curlwp)
119REG_SYMBOL(EXPEVT)
120REG_SYMBOL(BBRA)
121REG_SYMBOL(TEA)
122_L.tlb:		.long	_C_LABEL(tlb_exception)
123_L.general:	.long	_C_LABEL(general_exception)
124_L.ast:		.long	_C_LABEL(ast)
125_L.TLB_PROT_ST:	.long	0xc0
126_L.VPN_MASK:	.long	0xfffff000
127_C_LABEL(sh_vector_generic_end):	.long	0
128
129#ifdef SH3
130/*
131 * void sh3_vector_tlbmiss(void) __attribute__((__noreturn__)):
132 *	copied to VBR+0x400. This code should be relocatable and max 256
133 *	instructions.
134 */
135	.globl	_C_LABEL(sh3_vector_tlbmiss), _C_LABEL(sh3_vector_tlbmiss_end)
136	.text
137	.align	2
138_C_LABEL(sh3_vector_tlbmiss):
139	__EXCEPTION_ENTRY
140	mov.l	_L.TEA3, r0
141	mov.l	@r0,	r6
142	mov.l	__L.VPN_MASK, r1
143	and	r1,	r6	/* 3rd arg */
144#if !defined(P1_STACK)
145	/* Load kernel stack */
146	tst	r6,	r6	/* check VPN == 0 */
147	bt	6f
148	mov.l	_L.CURUPTE, r1
149	mov.l	@r1,	r1
150	mov	#UPAGES,r3
151	mov	#1,	r2
1524:	mov.l	@r1+,	r7
153	cmp/eq	r7,	r6	/* md_upte.addr: u-area VPN */
154	bt	5f
155	add	#4,	r1	/* skip md_upte.data */
156	cmp/eq	r2,	r3
157	bf/s	4b
158	 add	#1,	r2
159	bra	6f
160	 nop
1615:	mov.l	@r1,	r2	/* md_upte.data: u-area PTE */
162	mov.l	_L.PTEL, r1
163	mov.l	r2,	@r1
164	mov.l	_L.PTEH, r1
165	mov.l	@r1,	r2
166	mov.l	__L.VPN_MASK, r0
167	and	r2,	r0
168	mov.l	r0,	@r1	/* ASID 0 */
169	ldtlb
170	mov.l	r2,	@r1	/* restore ASID */
171	bra	3f
172	 nop
173#endif /* !P1_STACK */
1746:	mov.l	_L.EXPEVT3, r0
175	mov.l	@r0,	r0
176	mov.l	r0,	@(TF_EXPEVT, r14) /* trapframe->tf_expevt = EXPEVT */
177	mov.l	2f,	r0
178	mov.l	@r0,	r4	/* 1st arg */
179	__INTR_MASK(r0, r1)
180	__EXCEPTION_UNBLOCK(r0, r1)
181	mov.l	1f,	r0
182	jsr	@r0
183	 mov	r14,	r5	/* 2nd arg */
1843:	__EXCEPTION_RETURN
185	.align	2
1862:		.long	_C_LABEL(curlwp)
1871:		.long	_C_LABEL(tlb_exception)
188_L.EXPEVT3:	.long	SH3_EXPEVT
189_L.TEA3:	.long	SH3_TEA
190_L.PTEL:	.long	SH3_PTEL
191_L.PTEH:	.long	SH3_PTEH
192__L.VPN_MASK:	.long	0xfffff000
193_L.CURUPTE:	.long	_C_LABEL(curupte)
194	.align	2
195_C_LABEL(sh3_vector_tlbmiss_end):	.long	0
196#endif /* SH3 */
197
198#ifdef SH4
199/*
200 * void sh4_vector_tlbmiss(void) __attribute__((__noreturn__)):
201 *	copied to VBR+0x400. This code should be relocatable and max 256
202 *	instructions.
203 */
204	.globl	_C_LABEL(sh4_vector_tlbmiss), _C_LABEL(sh4_vector_tlbmiss_end)
205	.text
206	.align	2
207_C_LABEL(sh4_vector_tlbmiss):
208	__EXCEPTION_ENTRY
209	mov.l	_L.TEA4, r0
210	mov.l	@r0,	r6
211	mov.l	___L.VPN_MASK, r1
212	and	r1,	r6	/* va = trunc_page(va) */
213	mov.l	_L.EXPEVT4, r0
214	mov.l	@r0,	r0
215	mov.l	r0,	@(TF_EXPEVT, r14) /* trapframe->tf_expevt = EXPEVT */
216	mov.l	2f,	r0
217	mov.l	@r0,	r4	/* 1st arg */
218	__INTR_MASK(r0, r1)
219	__EXCEPTION_UNBLOCK(r0, r1)
220	mov.l	1f,	r0
221	jsr	@r0
222	 mov	r14,	r5	/* 2nd arg */
223	__EXCEPTION_RETURN
224	.align	2
2251:		.long	_C_LABEL(tlb_exception)
2262:		.long	_C_LABEL(curlwp)
227_L.EXPEVT4:	.long	SH4_EXPEVT
228_L.TEA4:	.long	SH4_TEA
229___L.VPN_MASK:	.long	0xfffff000
230_C_LABEL(sh4_vector_tlbmiss_end):	.long	0
231#endif /* SH4 */
232
233/*
234 * void sh_vector_interrupt(void) __attribute__((__noreturn__)):
235 *	copied to VBR+0x600. This code should be relocatable.
236 */
237	.globl	_C_LABEL(sh_vector_interrupt), _C_LABEL(sh_vector_interrupt_end)
238	.align	2
239	.text
240_C_LABEL(sh_vector_interrupt):
241	__EXCEPTION_ENTRY
242	xor	r0,	r0
243	mov.l	r0,	@(TF_EXPEVT, r14) /* (for debug) */
244	stc	r0_bank,r6	/* ssp */
245	/* Enable exception for P3 access */
246	__INTR_MASK(r0, r1)
247	__EXCEPTION_UNBLOCK(r0, r1)
248	/* uvmexp.intrs++ */
249	mov.l	__L.uvmexp.intrs, r0
250	mov.l	@r0,	r1
251	add	#1	r1
252	mov.l	r1,	@r0
253	/* Dispatch interrupt handler */
254	mov.l	__L.intc_intr, r0
255	jsr	@r0		/* intc_intr(ssr, spc, ssp) */
256	 nop
257	/* Check for ASTs on exit to user mode. */
258	mov.l	1f,	r0
259	mov.l	@r0,	r4	/* 1st arg */
260	mov.l	__L.ast, r0
261	jsr	@r0
262	 mov	r14,	r5	/* 2nd arg */
263	__EXCEPTION_RETURN
264	.align	2
2651:			.long	_C_LABEL(curlwp)
266__L.intc_intr:		.long	_C_LABEL(intc_intr)
267__L.ast:		.long	_C_LABEL(ast)
268__L.uvmexp.intrs:	.long	_C_LABEL(uvmexp) + UVMEXP_INTRS
269_C_LABEL(sh_vector_interrupt_end):	.long	0
270