exception_vector.S revision 1.3
1/*	$NetBSD: exception_vector.S,v 1.3 2002/03/17 14:02:03 uch 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 "assym.h"
37
38#include <sh3/param.h>
39#include <sh3/asm.h>
40#include <sh3/locore.h>
41#include <sh3/trapreg.h>
42#include <sh3/ubcreg.h>
43#include <sh3/mmu_sh3.h>
44#include <sh3/mmu_sh4.h>
45
46/*
47 * Exception vectors. following routines are copied to vector addreses.
48 *	sh_vector_generic:	VBR + 0x100
49 *	sh_vector_tlbmiss:	VBR + 0x400
50 *	sh_vector_interrupt:	VBR + 0x600
51 */
52
53/*
54 * void sh_vector_generic(void) __attribute__((__noreturn__)):
55 *	copied to VBR+0x100. This code should be relocatable and max 384
56 *	instructions.
57 *		0x40 TLB miss (load)
58 *		0x60 TLB miss (store)
59 *		0xc0	TLB protection (store)
60 *		  -> tlbmiss_exp()
61 *		0xa0 TLB protection (load)
62 *		0x80 Initial page write.
63 *		 and other...
64 *		  -> trap()
65 */
66	.globl	_C_LABEL(sh_vector_generic), _C_LABEL(sh_vector_generic_end)
67	.text
68	.align	2
69_C_LABEL(sh_vector_generic):
70	EXCEPTION_ENTRY
71	/* Identify exception cause */
72	MOV	(EXPEVT, r0)
73	mov.l	@r0,	r0
74	/*
75	 * TLB exception.
76	 */
77	cmp/eq	#0x40,	r0		/* T_TLBINVALIDR */
78	bf	1f
793:
80	__INTR_MASK(r0, r1)
81	__EXCEPTION_UNBLOCK(r0, r1)
82	mov.l	_L.tlb_handler, r0
83	jsr	@r0
84	 mov	r14,	r6
85	bra	4f
86	 nop
871:
88	cmp/eq	#0x60,	r0		/* T_TLBINVALIDW */
89	bt	3b
90
91	mov.l	_L.TLBPROTWR, r1	/* T_TLBPRIVW */
92	cmp/eq	r0,	r1
93	bt	3b
94
95	/*
96	 * General exception.
97	 */
98#ifdef DDB
99	mov	#0,	r2
100	MOV	(BBRA, r1)
101	mov.w	r2,	@r1	/* disable UBC */
102	mov.l	r2,	@(TF_UBC, r14)	/* clear trapframe->tf_ubc */
103#endif /* DDB */
104
105	mov.l	r0,	@(TF_TRAPNO, r14) /* trapframe->tf_trapno = EXPEVT */
106	__INTR_UNMASK(r0, r1)
107	__EXCEPTION_UNBLOCK(r0, r1)
108	mov.l	_L.trap, r0
109	jsr	@r0
110	 mov	r14,	r6
111
112	/* Check for ASTs on exit to user mode. */
113	mov.l	_L.ast,	r0
114	jsr	@r0
115	 mov	r14,	r4
116
117#ifdef DDB	/* BBRA = trapframe->tf_ubc */
118	__EXCEPTION_BLOCK(r0, r1)
119	mov.l	@(TF_UBC, r14), r0
120	MOV	(BBRA, r1)
121	mov.w	r0,	@r1
122#endif /* DDB */
1234:
124	EXCEPTION_RETURN
125	/* NOTREACHED */
126	.align	2
127REG_SYMBOL(EXPEVT)
128REG_SYMBOL(BBRA)
129_L.TLBPROTWR:	.long	0x000000c0
130_L.trap:	.long	_C_LABEL(trap)
131_L.ast:		.long	_C_LABEL(ast)
132_L.tlb_handler:	.long	_C_LABEL(tlb_handler)
133_C_LABEL(sh_vector_generic_end):	.long	0
134
135#ifdef SH3
136/*
137 * void sh3_vector_tlbmiss(void) __attribute__((__noreturn__)):
138 *	copied to VBR+0x400. This code should be relocatable and max 256
139 *	instructions.
140 */
141	.globl	_C_LABEL(sh3_vector_tlbmiss), _C_LABEL(sh3_vector_tlbmiss_end)
142	.text
143	.align	2
144_C_LABEL(sh3_vector_tlbmiss):
145	EXCEPTION_ENTRY
146	__INTR_MASK(r0, r1)
147	__EXCEPTION_UNBLOCK(r0, r1)
148#if !defined(P1_STACK)
149	/* Load kerne stack */
150	mov.l	_L.TEA, r1
151	mov.l	@r1,	r0	/* r0 = va */
152	mov.l	_L.VPN_MASK, r1
153	and	r1,	r0	/* va = trunc_page(va) */
154	mov.l	_L.CURUPTE, r1
155	mov	#UPAGES,r3
156	mov	#1,	r2
1574:	mov.l	@r1+,	r6
158	cmp/eq	r6,	r0	/* md_upte.addr: u-area VPN */
159	bt	5f
160	add	#4,	r1	/* skip md_upte.data */
161	cmp/eq	r2,	r3
162	bf/s	4b
163	 add	#1,	r2
164	bra	6f
165	 nop
1665:	mov.l	@r1,	r2	/* md_upte.data: u-area PTE */
167	mov.l	_L.PTEL, r1
168	mov.l	r2,	@r1
169	ldtlb
170	bra	3f
171	 nop
172#endif /* !P1_STACK */
1736:	mov	r0,	r2
174	mov	#-22,	r1
175	shld	r1,	r2	/* r2 = va >> 22 */
176	shll2	r2		/* r2 *= sizeof(pt_entry_t) */
177	mov.l	_L.TTB, r1
178	mov.l	@r1,	r1
179	add	r1,	r2	/* r2 = page directory entry address */
180	mov	#1	r1
181	swap.b	r1,	r1	/* 0x100 (PG_V) */
182	mov.l	@r2,	r2	/* r2 = pde */
183	and	r2,	r1
184	tst	r1,	r1
185	bt	2f		/* (pde & PG_V) == 0 -> tlb_handler */
186	mov.l	_L.VPN_MASK, r1
187	and	r1,	r2	/* zero attribute bits */
188	mov.l	_L.PT_MASK, r1
189	mov	r0,	r3
190	and	r1,	r3	/* r3 = va & 0x003ff000 */
191	mov	#-12	r1
192	shld	r1,	r3	/* r3 = (va & 0x003ff000) >> 12 */
193	shll2	r3		/* r3 *= sizeof(pt_entry_t) */
194	add	r2,	r3	/* r3 = page table entry address */
195	mov.l	@r3,	r3	/* r3 = page table entry */
196	mov	#1,	r1
197	swap.b	r1,	r1	/* r1 = PG_V */
198	and	r3,	r1
199	tst	r1,	r1
200	bt	2f		/* (pte & PG_V) == 0 -> tlb_handler */
201	mov.l	_L.PTE_HW_BITS, r2
202	and	r2,	r3
203	mov.l	_L.PTEL, r1
204	mov.l	r3,	@r1	/* PTEL = (pte & PG_HW_BITS) */
205	ldtlb
206	bra	3f
207	 nop
2082:
209	mov.l	1f,	r0
210	jsr	@r0
211	 mov	r14,	r6
2123:
213	EXCEPTION_RETURN
214	.align	2
2151:		.long	_C_LABEL(tlb_handler)
216_L.TEA:		.long	SH3_TEA
217_L.TTB:		.long	SH3_TTB
218_L.PTEL:	.long	SH3_PTEL
219_L.PTE_HW_BITS:	.long	0x1ffff17e
220_L.PT_MASK:	.long	0x003ff000
221_L.VPN_MASK:	.long	0xfffff000
222_L.CURUPTE:	.long	_C_LABEL(curupte)
223	.align	2
224_C_LABEL(sh3_vector_tlbmiss_end):	.long	0
225#endif /* SH3 */
226
227#ifdef SH4
228/*
229 * void sh4_vector_tlbmiss(void) __attribute__((__noreturn__)):
230 *	copied to VBR+0x400. This code should be relocatable and max 256
231 *	instructions.
232 */
233	.globl	_C_LABEL(sh4_vector_tlbmiss), _C_LABEL(sh4_vector_tlbmiss_end)
234	.text
235	.align	2
236_C_LABEL(sh4_vector_tlbmiss):
237	EXCEPTION_ENTRY
238	__INTR_MASK(r0, r1)
239	__EXCEPTION_UNBLOCK(r0, r1)
240	mov	#0x20,	r7
241	swap.b	r7,	r7
242	swap.w	r7,	r7	/* r7 = 0x20000000 */
243	mov.l	__L.TEA, r1
244	mov.l	@r1,	r0	/* r0 = va */
245	mov	r0,	r2
246	mov	#-22,	r1
247	shld	r1,	r2	/* r2 = va >> 22 */
248	shll2	r2		/* r2 *= sizeof(pt_entry_t) */
249	mov.l	__L.TTB, r1
250	mov.l	@r1,	r1
251	or	r7,	r1	/* XXX P2 access */
252	add	r1,	r2	/* r2 = page directory entry address */
253	mov	#1	r1
254	swap.b	r1,	r1	/* 0x100 (PG_V) */
255	mov.l	@r2,	r2	/* r2 = pde */
256	and	r2,	r1
257	tst	r1,	r1
258	bt	2f		/* (pde & PG_V) == 0 -> tlb_handler */
259	mov.l	__L.VPN_MASK, r1
260	and	r1,	r2	/* zero attribute bits */
261	mov.l	__L.PT_MASK, r1
262	mov	r0,	r3
263	and	r1,	r3	/* r3 = va & 0x003ff000 */
264	mov	#-12	r1
265	shld	r1,	r3	/* r3 = (va & 0x003ff000) >> 12 */
266	shll2	r3		/* r3 *= sizeof(pt_entry_t) */
267	add	r2,	r3	/* r3 = page table entry address */
268	or	r7,	r3	/* XXX P2 access */
269	mov.l	@r3,	r3	/* r3 = page table entry */
270	mov	#1,	r1
271	swap.b	r1,	r1	/* r1 = PG_V */
272	and	r3,	r1
273	tst	r1,	r1
274	bt	2f		/* (pte & PG_V) == 0 -> tlb_handler */
275	mov	#0xe,	r1
276	swap.b	r1,	r1	/* r1 = _PG_PCMCIA (0x0e00) */
277	and	r3,	r1
278	tst	r1,	r1
279	bt	4f
280	mov	r3,	r2
281	mov	#-9	r1
282	shld	r1,	r2
283	mov	#7,	r1
284	and	r1,	r2	/* r2 = (pte >> 9) & 0x7 */
285	mov.l	__L.PTEA, r1
286	mov.l	r2,	@r1
287	mov.l	__L.PTE_HW_BITS, r1
288	and	r3,	r1
289	mov	#-9,	r2
290	and	r2,	r3	/* pte &= ~PG_N XXX */
291	mov.l	__L.PTEL, r1
292	mov.l	r3,	@r1
293	bra	6f
294	 nop
2954:
296	mov.l	__L.PTE_HW_BITS, r1
297	and	r1,	r3
298	mov.l	__L.P3SEGBASE, r1
299	cmp/hs	r1,	r0	/* va >= 0xc0000000 ? T = 1 */
300	bf	5f
301	mov	#1,	r1
302	or	r1,	r3	/* PG_WT  P3 write-through XXX */
3035:
304	mov.l	__L.PTEA, r1
305	xor	r0,	r0
306	mov.l	r0,	@r1
307	mov.l	__L.PTEL, r1
308	mov.l	r3,	@r1
309	nop
3106:	ldtlb
311	bra	3f
312	 nop
3132:
314	mov.l	1f,	r0
315	jsr	@r0
316	 mov	r14,	r6
3173:
318	EXCEPTION_RETURN
319	.align	2
3201:		.long	_C_LABEL(tlb_handler)
321__L.TEA:	.long	SH4_TEA
322__L.TTB:	.long	SH4_TTB
323__L.PTEL:	.long	SH4_PTEL
324__L.PTEA:	.long	SH4_PTEA
325__L.P3SEGBASE:	.long	0xc0000000
326__L.PTE_HW_BITS:.long	0x1ffff17e
327__L.PT_MASK:	.long	0x003ff000
328__L.VPN_MASK:	.long	0xfffff000
329_C_LABEL(sh4_vector_tlbmiss_end):	.long	0
330#endif /* SH4 */
331
332/*
333 * void sh_vector_interrupt(void) __attribute__((__noreturn__)):
334 *	copied to VBR+0x600. This code should be relocatable.
335 */
336	.globl	_C_LABEL(sh_vector_interrupt), _C_LABEL(sh_vector_interrupt_end)
337	.align	2
338	.text
339_C_LABEL(sh_vector_interrupt):
340	EXCEPTION_ENTRY
341	mov.l	1f,	r0
342	jmp	@r0
343	 nop
344	.align	2
3451:	.long	_C_LABEL(interrupt_exp)
346_C_LABEL(sh_vector_interrupt_end):	.long	0
347