exception_vector.S revision 1.22
1/*	$NetBSD: exception_vector.S,v 1.22 2007/03/15 00:00:38 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.22 2007/03/15 00:00:38 uwe Exp $")
49
50
51/*
52 * Exception vectors.
53 * The following routines are copied to vector addresses.
54 *	sh_vector_generic:	VBR + 0x100
55 *	sh_vector_tlbmiss:	VBR + 0x400
56 *	sh_vector_interrupt:	VBR + 0x600
57 */
58
59#define VECTOR_END_MARKER(sym)			\
60		.globl	_C_LABEL(sym);		\
61	_C_LABEL(sym):
62
63
64/*
65 * LINTSTUB: Var: char sh_vector_generic[1];
66 *
67 * void sh_vector_generic(void);
68 *	Copied to VBR+0x100.  This code should be position independent
69 *	and maximum 786 bytes long (== 0x400 - 0x100).
70 */
71NENTRY(sh_vector_generic)
72	__EXCEPTION_ENTRY
73	__INTR_MASK(r0, r1)
74	/* Identify exception cause */
75	MOV	(EXPEVT, r0)
76	mov.l	@r0, r0
77	mov.l	r0, @(TF_EXPEVT, r14)	/* tf->tf_expevt = EXPEVT */
78	/* Get curlwp */
79	mov.l	.Lg_curlwp, r1
80	mov.l	@r1, r4			/* 1st arg */
81	/* Get TEA */
82	MOV	(TEA, r1)
83	mov.l	@r1, r6			/* 3rd arg */
84	/* Check TLB exception or not */
85	mov.l	.Lg_TLB_PROT_ST, r1
86	cmp/hi	r1, r0
87	bt	1f
88
89	/* tlb_exception(curlwp, tf, TEA); */
90	__EXCEPTION_UNBLOCK(r0, r1)
91	mov.l	.Lg_tlb_exception, r0
92	jsr	@r0
93	 mov	r14, r5			/* 2nd arg */
94	bra	2f
95	 nop
96
97	/* general_exception(curlwp, tf, TEA); */
981:	mov	r4, r8
99#ifdef DDB
100	mov	#0, r2
101	MOV	(BBRA, r1)
102	mov.w	r2, @r1			/* disable UBC */
103	mov.l	r2, @(TF_UBC, r14)	/* clear tf->tf_ubc */
104#endif /* DDB */
105	__EXCEPTION_UNBLOCK(r0, r1)
106	mov.l	.Lg_general_exception, r0
107	jsr	@r0
108	 mov	r14, r5			/* 2nd arg */
109
110	/* Check for ASTs on exit to user mode. */
111	mov	r8, r4
112	mov.l	.Lg_ast, r0
113	jsr	@r0
114	 mov	r14, r5
115#ifdef DDB	/* BBRA = tf->tf_ubc */
116	__EXCEPTION_BLOCK(r0, r1)
117	mov.l	@(TF_UBC, r14), r0
118	MOV	(BBRA, r1)
119	mov.w	r0, @r1
120#endif /* DDB */
1212:	__EXCEPTION_RETURN
122
123	.align	2
124.Lg_curlwp:		.long	_C_LABEL(curlwp)
125REG_SYMBOL(EXPEVT)
126REG_SYMBOL(BBRA)
127REG_SYMBOL(TEA)
128.Lg_tlb_exception:	.long	_C_LABEL(tlb_exception)
129.Lg_general_exception:	.long	_C_LABEL(general_exception)
130.Lg_ast:		.long	_C_LABEL(ast)
131.Lg_TLB_PROT_ST:	.long	EXPEVT_TLB_PROT_ST
132
133/* LINTSTUB: Var: char sh_vector_generic_end[1]; */
134VECTOR_END_MARKER(sh_vector_generic_end)
135	SET_ENTRY_SIZE(sh_vector_generic)
136
137
138#ifdef SH3
139/*
140 * LINTSTUB: Var: char sh3_vector_tlbmiss[1];
141 *
142 * void sh3_vector_tlbmiss(void);
143 *	Copied to VBR+0x400.  This code should be position independent
144 *	and maximum 512 bytes long (== 0x600 - 0x400).
145 */
146NENTRY(sh3_vector_tlbmiss)
147	__EXCEPTION_ENTRY
148	mov	#(SH3_TEA & 0xff), r0
149	mov.l	@r0, r6		/* 3rd arg: va = TEA */
150#if !defined(P1_STACK)
151	/* Load kernel stack */
152	mov.l	.L3_VPN_MASK, r0
153	and	r6, r0
154	tst	r0, r0		/* check VPN == 0 */
155	bt	6f
156	mov.l	.L3_CURUPTE, r1
157	mov.l	@r1, r1
158	mov	#UPAGES, r3
159	mov	#1, r2
1604:	mov.l	@r1+, r7
161	cmp/eq	r7, r0		/* md_upte.addr: u-area VPN */
162	bt	5f
163	add	#4, r1		/* skip md_upte.data */
164	cmp/eq	r2, r3
165	bf/s	4b
166	 add	#1, r2
167	bra	7f		/* pull insn at 6f into delay slot */
168	 mov	#(SH3_EXPEVT & 0xff), r0
1695:	mov.l	@r1, r2		/* md_upte.data: u-area PTE */
170	mov	#(SH3_PTEL & 0xff), r1
171	mov.l	r2, @r1
172	mov	#(SH3_PTEH & 0xff), r1
173	mov.l	@r1, r2
174	mov.l	.L3_VPN_MASK, r0
175	and	r2, r0
176	mov.l	r0, @r1		/* ASID 0 */
177	ldtlb
178	bra	3f
179	 mov.l	r2, @r1		/* restore ASID */
180#endif /* !P1_STACK */
1816:	mov	#(SH3_EXPEVT & 0xff), r0
1827:	mov.l	@r0, r0
183	mov.l	r0, @(TF_EXPEVT, r14)	/* tf->tf_expevt = EXPEVT */
184	mov.l	.L3_curlwp, r0
185	mov.l	@r0, r4		/* 1st arg */
186	__INTR_MASK(r0, r1)
187	__EXCEPTION_UNBLOCK(r0, r1)
188	mov.l	.L3_tlb_exception, r0
189	jsr	@r0
190	 mov	r14, r5		/* 2nd arg */
1913:	__EXCEPTION_RETURN
192
193	.align	2
194.L3_curlwp:		.long	_C_LABEL(curlwp)
195.L3_tlb_exception:	.long	_C_LABEL(tlb_exception)
196.L3_VPN_MASK:		.long	0xfffff000
197.L3_CURUPTE:		.long	_C_LABEL(curupte)
198
199/* LINTSTUB: Var: char sh3_vector_tlbmiss_end[1]; */
200VECTOR_END_MARKER(sh3_vector_tlbmiss_end)
201	SET_ENTRY_SIZE(sh3_vector_tlbmiss)
202#endif /* SH3 */
203
204
205#ifdef SH4
206/*
207 * LINTSTUB: Var: char sh4_vector_tlbmiss[1];
208 *
209 * void sh4_vector_tlbmiss(void);
210 *	Copied to VBR+0x400.  This code should be position independent
211 *	and maximum 512 bytes long (== 0x600 - 0x400).
212 */
213NENTRY(sh4_vector_tlbmiss)
214	__EXCEPTION_ENTRY
215	mov.l	.L4_TEA4, r0
216	mov.l	@r0, r6
217	mov.l	.L4_EXPEVT4, r0
218	mov.l	@r0, r0
219	mov.l	r0, @(TF_EXPEVT, r14)	/* tf->tf_expevt = EXPEVT */
220	mov.l	.L4_curlwp, r0
221	mov.l	@r0, r4			/* 1st arg */
222	__INTR_MASK(r0, r1)
223	__EXCEPTION_UNBLOCK(r0, r1)
224	mov.l	.L4_tlb_exception, r0
225	jsr	@r0
226	 mov	r14, r5			/* 2nd arg */
227	__EXCEPTION_RETURN
228
229	.align	2
230.L4_tlb_exception:	.long	_C_LABEL(tlb_exception)
231.L4_curlwp:		.long	_C_LABEL(curlwp)
232.L4_EXPEVT4:		.long	SH4_EXPEVT
233.L4_TEA4:		.long	SH4_TEA
234
235/* LINTSTUB: Var: char sh4_vector_tlbmiss_end[1]; */
236VECTOR_END_MARKER(sh4_vector_tlbmiss_end)
237	SET_ENTRY_SIZE(sh4_vector_tlbmiss)
238#endif /* SH4 */
239
240
241/*
242 * LINTSTUB: Var: char sh_vector_interrupt[1];
243 *
244 * void sh_vector_interrupt(void);
245 *	Copied to VBR+0x600.  This code should be position independent.
246 */
247NENTRY(sh_vector_interrupt)
248	__EXCEPTION_ENTRY
249	xor	r0, r0
250	mov.l	r0, @(TF_EXPEVT, r14)	/* (for debug) */
251	stc	r0_bank, r6		/* ssp */
252	/* Enable exceptions for P3 access */
253	__INTR_MASK(r0, r1)
254	__EXCEPTION_UNBLOCK(r0, r1)
255	/* ++uvmexp.intrs */
256	mov.l	.Li_uvmexp_intrs, r0
257	mov.l	@r0, r1
258	add	#1 r1
259	mov.l	r1, @r0
260	/* Dispatch interrupt handler */
261	mov.l	.Li_intc_intr, r0
262	jsr	@r0		/* intc_intr(ssr, spc, ssp) */
263	 nop
264	/* Check for ASTs on exit to user mode. */
265	mov.l	.Li_curlwp, r0
266	mov.l	@r0, r4		/* 1st arg */
267	mov.l	.Li_ast, r0
268	jsr	@r0
269	 mov	r14, r5		/* 2nd arg */
270	__EXCEPTION_RETURN
271
272	.align	2
273.Li_curlwp:		.long	_C_LABEL(curlwp)
274.Li_intc_intr:		.long	_C_LABEL(intc_intr)
275.Li_ast:		.long	_C_LABEL(ast)
276.Li_uvmexp_intrs:	.long	_C_LABEL(uvmexp) + UVMEXP_INTRS
277
278/* LINTSTUB: Var: char sh_vector_interrupt_end[1]; */
279VECTOR_END_MARKER(sh_vector_interrupt_end)
280	SET_ENTRY_SIZE(sh_vector_interrupt)
281