exception_vector.S revision 1.15
1/*	$NetBSD: exception_vector.S,v 1.15 2006/01/22 05:56:58 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__KERNEL_RCSID(0, "$NetBSD: exception_vector.S,v 1.15 2006/01/22 05:56:58 uwe Exp $")
49
50
51/*
52 * Exception vectors. The following routines are copied to vector addreses.
53 *	sh_vector_generic:	VBR + 0x100
54 *	sh_vector_tlbmiss:	VBR + 0x400
55 *	sh_vector_interrupt:	VBR + 0x600
56 */
57
58#define VECTOR_END_MARKER(sym)			\
59		.globl	_C_LABEL(sym);		\
60	_C_LABEL(sym):
61
62
63/*
64 * LINTSTUB: Var: char sh_vector_generic[1];
65 *
66 * void sh_vector_generic(void) __attribute__((__noreturn__))
67 *	Copied to VBR+0x100.  This code should be position independent
68 *	and no more than 786 bytes long (== 0x400 - 0x100).
69 */
70NENTRY(sh_vector_generic)
71	__EXCEPTION_ENTRY
72	__INTR_MASK(r0, r1)
73	/* Identify exception cause */
74	MOV	(EXPEVT, r0)
75	mov.l	@r0,	r0
76	mov.l	r0,	@(TF_EXPEVT, r14) /* trapframe->tf_expevt = EXPEVT */
77	/* Get curlwp */
78	mov.l	_L.curlwp, r1
79	mov.l	@r1,	r4	/* 1st arg */
80	/* Get TEA */
81	MOV	(TEA,	r1)
82	mov.l	@r1,	r6	/* 3rd arg */
83	/* Check TLB exception or not */
84	mov.l	_L.TLB_PROT_ST, r1
85	cmp/hi	r1,	r0
86	bt	1f
87
88	/* tlb_exception(curlwp, trapframe, trunc_page(TEA)); */
89	mov.l	_L.VPN_MASK, r1
90	and	r1,	r6	/* va = trunc_page(va) */
91	__EXCEPTION_UNBLOCK(r0, r1)
92	mov.l	_L.tlb, r0
93	jsr	@r0
94	 mov	r14,	r5	/* 2nd arg */
95	bra	2f
96	 nop
97
98	/* general_exception(curlwp, trapframe, TEA); */
991:	mov	r4,	r8
100#ifdef DDB
101	mov	#0,	r2
102	MOV	(BBRA, r1)
103	mov.w	r2,	@r1	/* disable UBC */
104	mov.l	r2,	@(TF_UBC, r14)	/* clear trapframe->tf_ubc */
105#endif /* DDB */
106	__EXCEPTION_UNBLOCK(r0, r1)
107	mov.l	_L.general, r0
108	jsr	@r0
109	 mov	r14,	r5	/* 2nd arg */
110
111	/* Check for ASTs on exit to user mode. */
112	mov	r8,	r4
113	mov.l	_L.ast,	r0
114	jsr	@r0
115	 mov	r14,	r5
116#ifdef DDB	/* BBRA = trapframe->tf_ubc */
117	__EXCEPTION_BLOCK(r0, r1)
118	mov.l	@(TF_UBC, r14), r0
119	MOV	(BBRA, r1)
120	mov.w	r0,	@r1
121#endif /* DDB */
1222:	__EXCEPTION_RETURN
123	/* NOTREACHED */
124	.align	2
125_L.curlwp:	.long	_C_LABEL(curlwp)
126REG_SYMBOL(EXPEVT)
127REG_SYMBOL(BBRA)
128REG_SYMBOL(TEA)
129_L.tlb:		.long	_C_LABEL(tlb_exception)
130_L.general:	.long	_C_LABEL(general_exception)
131_L.ast:		.long	_C_LABEL(ast)
132_L.TLB_PROT_ST:	.long	0xc0
133_L.VPN_MASK:	.long	0xfffff000
134
135/* LINTSTUB: Var: char sh_vector_generic_end[1]; */
136VECTOR_END_MARKER(sh_vector_generic_end)
137	SET_ENTRY_SIZE(sh_vector_generic)
138
139
140#ifdef SH3
141/*
142 * LINTSTUB: Var: char sh3_vector_tlbmiss[1];
143 *
144 * void sh3_vector_tlbmiss(void) __attribute__((__noreturn__))
145 *	Copied to VBR+0x400.  This code should be position independent
146 *	and no more than 512 bytes long (== 0x600 - 0x400).
147 */
148NENTRY(sh3_vector_tlbmiss)
149	__EXCEPTION_ENTRY
150	mov.l	_L.TEA3, r0
151	mov.l	@r0,	r6
152	mov.l	__L.VPN_MASK, r1
153	and	r1,	r6	/* 3rd arg */
154#if !defined(P1_STACK)
155	/* Load kernel stack */
156	tst	r6,	r6	/* check VPN == 0 */
157	bt	6f
158	mov.l	_L.CURUPTE, r1
159	mov.l	@r1,	r1
160	mov	#UPAGES,r3
161	mov	#1,	r2
1624:	mov.l	@r1+,	r7
163	cmp/eq	r7,	r6	/* md_upte.addr: u-area VPN */
164	bt	5f
165	add	#4,	r1	/* skip md_upte.data */
166	cmp/eq	r2,	r3
167	bf/s	4b
168	 add	#1,	r2
169	bra	6f
170	 nop
1715:	mov.l	@r1,	r2	/* md_upte.data: u-area PTE */
172	mov.l	_L.PTEL, r1
173	mov.l	r2,	@r1
174	mov.l	_L.PTEH, r1
175	mov.l	@r1,	r2
176	mov.l	__L.VPN_MASK, r0
177	and	r2,	r0
178	mov.l	r0,	@r1	/* ASID 0 */
179	ldtlb
180	mov.l	r2,	@r1	/* restore ASID */
181	bra	3f
182	 nop
183#endif /* !P1_STACK */
1846:	mov.l	_L.EXPEVT3, r0
185	mov.l	@r0,	r0
186	mov.l	r0,	@(TF_EXPEVT, r14) /* trapframe->tf_expevt = EXPEVT */
187	mov.l	2f,	r0
188	mov.l	@r0,	r4	/* 1st arg */
189	__INTR_MASK(r0, r1)
190	__EXCEPTION_UNBLOCK(r0, r1)
191	mov.l	1f,	r0
192	jsr	@r0
193	 mov	r14,	r5	/* 2nd arg */
1943:	__EXCEPTION_RETURN
195	.align	2
1962:		.long	_C_LABEL(curlwp)
1971:		.long	_C_LABEL(tlb_exception)
198_L.EXPEVT3:	.long	SH3_EXPEVT
199_L.TEA3:	.long	SH3_TEA
200_L.PTEL:	.long	SH3_PTEL
201_L.PTEH:	.long	SH3_PTEH
202__L.VPN_MASK:	.long	0xfffff000
203_L.CURUPTE:	.long	_C_LABEL(curupte)
204
205/* LINTSTUB: Var: char sh3_vector_tlbmiss_end[1]; */
206VECTOR_END_MARKER(sh3_vector_tlbmiss_end)
207	SET_ENTRY_SIZE(sh3_vector_tlbmiss)
208#endif /* SH3 */
209
210
211#ifdef SH4
212/*
213 * LINTSTUB: Var: char sh4_vector_tlbmiss[1];
214 *
215 * void sh4_vector_tlbmiss(void) __attribute__((__noreturn__))
216 *	Copied to VBR+0x400.  This code should be position independent
217 *	and no more than 512 bytes long (== 0x600 - 0x400).
218 */
219NENTRY(sh4_vector_tlbmiss)
220	__EXCEPTION_ENTRY
221	mov.l	_L.TEA4, r0
222	mov.l	@r0,	r6
223	mov.l	___L.VPN_MASK, r1
224	and	r1,	r6	/* va = trunc_page(va) */
225	mov.l	_L.EXPEVT4, r0
226	mov.l	@r0,	r0
227	mov.l	r0,	@(TF_EXPEVT, r14) /* trapframe->tf_expevt = EXPEVT */
228	mov.l	2f,	r0
229	mov.l	@r0,	r4	/* 1st arg */
230	__INTR_MASK(r0, r1)
231	__EXCEPTION_UNBLOCK(r0, r1)
232	mov.l	1f,	r0
233	jsr	@r0
234	 mov	r14,	r5	/* 2nd arg */
235	__EXCEPTION_RETURN
236	.align	2
2371:		.long	_C_LABEL(tlb_exception)
2382:		.long	_C_LABEL(curlwp)
239_L.EXPEVT4:	.long	SH4_EXPEVT
240_L.TEA4:	.long	SH4_TEA
241___L.VPN_MASK:	.long	0xfffff000
242
243/* LINTSTUB: Var: char sh4_vector_tlbmiss_end[1]; */
244VECTOR_END_MARKER(sh4_vector_tlbmiss_end)
245	SET_ENTRY_SIZE(sh4_vector_tlbmiss)
246#endif /* SH4 */
247
248
249/*
250 * LINTSTUB: Var: char sh_vector_interrupt[1];
251 *
252 * void sh_vector_interrupt(void) __attribute__((__noreturn__)):
253 *	copied to VBR+0x600. This code should be relocatable.
254 */
255NENTRY(sh_vector_interrupt)
256	__EXCEPTION_ENTRY
257	xor	r0,	r0
258	mov.l	r0,	@(TF_EXPEVT, r14) /* (for debug) */
259	stc	r0_bank,r6	/* ssp */
260	/* Enable exception for P3 access */
261	__INTR_MASK(r0, r1)
262	__EXCEPTION_UNBLOCK(r0, r1)
263	/* uvmexp.intrs++ */
264	mov.l	__L.uvmexp.intrs, r0
265	mov.l	@r0,	r1
266	add	#1	r1
267	mov.l	r1,	@r0
268	/* Dispatch interrupt handler */
269	mov.l	__L.intc_intr, r0
270	jsr	@r0		/* intc_intr(ssr, spc, ssp) */
271	 nop
272	/* Check for ASTs on exit to user mode. */
273	mov.l	1f,	r0
274	mov.l	@r0,	r4	/* 1st arg */
275	mov.l	__L.ast, r0
276	jsr	@r0
277	 mov	r14,	r5	/* 2nd arg */
278	__EXCEPTION_RETURN
279	.align	2
2801:			.long	_C_LABEL(curlwp)
281__L.intc_intr:		.long	_C_LABEL(intc_intr)
282__L.ast:		.long	_C_LABEL(ast)
283__L.uvmexp.intrs:	.long	_C_LABEL(uvmexp) + UVMEXP_INTRS
284
285/* LINTSTUB: Var: char sh_vector_interrupt_end[1]; */
286VECTOR_END_MARKER(sh_vector_interrupt_end)
287	SET_ENTRY_SIZE(sh_vector_interrupt)
288