exception_vector.S revision 1.5
11.5Such/*	$NetBSD: exception_vector.S,v 1.5 2002/03/24 18:04:41 uch Exp $	*/
21.1Such
31.1Such/*-
41.1Such * Copyright (c) 2002 The NetBSD Foundation, Inc.
51.1Such * All rights reserved.
61.1Such *
71.1Such * Redistribution and use in source and binary forms, with or without
81.1Such * modification, are permitted provided that the following conditions
91.1Such * are met:
101.1Such * 1. Redistributions of source code must retain the above copyright
111.1Such *    notice, this list of conditions and the following disclaimer.
121.1Such * 2. Redistributions in binary form must reproduce the above copyright
131.1Such *    notice, this list of conditions and the following disclaimer in the
141.1Such *    documentation and/or other materials provided with the distribution.
151.1Such * 3. All advertising materials mentioning features or use of this software
161.1Such *    must display the following acknowledgement:
171.1Such *        This product includes software developed by the NetBSD
181.1Such *        Foundation, Inc. and its contributors.
191.1Such * 4. Neither the name of The NetBSD Foundation nor the names of its
201.1Such *    contributors may be used to endorse or promote products derived
211.1Such *    from this software without specific prior written permission.
221.1Such *
231.1Such * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
241.1Such * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
251.1Such * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
261.1Such * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
271.1Such * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
281.1Such * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
291.1Such * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
301.1Such * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
311.1Such * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
321.1Such * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
331.1Such * POSSIBILITY OF SUCH DAMAGE.
341.1Such */
351.1Such
361.1Such#include "assym.h"
371.1Such
381.3Such#include <sh3/param.h>
391.1Such#include <sh3/asm.h>
401.1Such#include <sh3/locore.h>
411.5Such#include <sh3/exception.h>
421.2Such#include <sh3/ubcreg.h>
431.3Such#include <sh3/mmu_sh3.h>
441.3Such#include <sh3/mmu_sh4.h>
451.1Such
461.1Such/*
471.1Such * Exception vectors. following routines are copied to vector addreses.
481.1Such *	sh_vector_generic:	VBR + 0x100
491.1Such *	sh_vector_tlbmiss:	VBR + 0x400
501.1Such *	sh_vector_interrupt:	VBR + 0x600
511.1Such */
521.3Such
531.1Such/*
541.1Such * void sh_vector_generic(void) __attribute__((__noreturn__)):
551.1Such *	copied to VBR+0x100. This code should be relocatable and max 384
561.1Such *	instructions.
571.1Such *		0x40 TLB miss (load)
581.1Such *		0x60 TLB miss (store)
591.1Such *		0xc0	TLB protection (store)
601.1Such *		  -> tlbmiss_exp()
611.1Such *		0xa0 TLB protection (load)
621.1Such *		0x80 Initial page write.
631.1Such *		 and other...
641.1Such *		  -> trap()
651.1Such */
661.1Such	.globl	_C_LABEL(sh_vector_generic), _C_LABEL(sh_vector_generic_end)
671.3Such	.text
681.1Such	.align	2
691.1Such_C_LABEL(sh_vector_generic):
701.5Such	__EXCEPTION_ENTRY
711.1Such	/* Identify exception cause */
721.1Such	MOV	(EXPEVT, r0)
731.1Such	mov.l	@r0,	r0
741.1Such	/*
751.1Such	 * TLB exception.
761.1Such	 */
771.1Such	cmp/eq	#0x40,	r0		/* T_TLBINVALIDR */
781.1Such	bf	1f
791.1Such3:
801.2Such	__INTR_MASK(r0, r1)
811.2Such	__EXCEPTION_UNBLOCK(r0, r1)
821.1Such	mov.l	_L.tlb_handler, r0
831.1Such	jsr	@r0
841.3Such	 mov	r14,	r6
851.1Such	bra	4f
861.1Such	 nop
871.1Such1:
881.1Such	cmp/eq	#0x60,	r0		/* T_TLBINVALIDW */
891.1Such	bt	3b
901.1Such
911.1Such	mov.l	_L.TLBPROTWR, r1	/* T_TLBPRIVW */
921.1Such	cmp/eq	r0,	r1
931.1Such	bt	3b
941.1Such
951.1Such	/*
961.1Such	 * General exception.
971.1Such	 */
981.1Such#ifdef DDB
991.1Such	mov	#0,	r2
1001.1Such	MOV	(BBRA, r1)
1011.1Such	mov.w	r2,	@r1	/* disable UBC */
1021.3Such	mov.l	r2,	@(TF_UBC, r14)	/* clear trapframe->tf_ubc */
1031.1Such#endif /* DDB */
1041.3Such
1051.3Such	mov.l	r0,	@(TF_TRAPNO, r14) /* trapframe->tf_trapno = EXPEVT */
1061.2Such	__INTR_UNMASK(r0, r1)
1071.2Such	__EXCEPTION_UNBLOCK(r0, r1)
1081.1Such	mov.l	_L.trap, r0
1091.1Such	jsr	@r0
1101.3Such	 mov	r14,	r6
1111.1Such
1121.1Such	/* Check for ASTs on exit to user mode. */
1131.1Such	mov.l	_L.ast,	r0
1141.1Such	jsr	@r0
1151.3Such	 mov	r14,	r4
1161.1Such
1171.1Such#ifdef DDB	/* BBRA = trapframe->tf_ubc */
1181.2Such	__EXCEPTION_BLOCK(r0, r1)
1191.3Such	mov.l	@(TF_UBC, r14), r0
1201.1Such	MOV	(BBRA, r1)
1211.1Such	mov.w	r0,	@r1
1221.1Such#endif /* DDB */
1231.1Such4:
1241.5Such	__EXCEPTION_RETURN
1251.1Such	/* NOTREACHED */
1261.1Such	.align	2
1271.1SuchREG_SYMBOL(EXPEVT)
1281.1SuchREG_SYMBOL(BBRA)
1291.1Such_L.TLBPROTWR:	.long	0x000000c0
1301.1Such_L.trap:	.long	_C_LABEL(trap)
1311.1Such_L.ast:		.long	_C_LABEL(ast)
1321.1Such_L.tlb_handler:	.long	_C_LABEL(tlb_handler)
1331.3Such_C_LABEL(sh_vector_generic_end):	.long	0
1341.1Such
1351.3Such#ifdef SH3
1361.1Such/*
1371.3Such * void sh3_vector_tlbmiss(void) __attribute__((__noreturn__)):
1381.1Such *	copied to VBR+0x400. This code should be relocatable and max 256
1391.1Such *	instructions.
1401.1Such */
1411.3Such	.globl	_C_LABEL(sh3_vector_tlbmiss), _C_LABEL(sh3_vector_tlbmiss_end)
1421.3Such	.text
1431.3Such	.align	2
1441.3Such_C_LABEL(sh3_vector_tlbmiss):
1451.5Such	__EXCEPTION_ENTRY
1461.2Such	__INTR_MASK(r0, r1)
1471.2Such	__EXCEPTION_UNBLOCK(r0, r1)
1481.3Such#if !defined(P1_STACK)
1491.4Such	/* Load kernel stack */
1501.3Such	mov.l	_L.TEA, r1
1511.3Such	mov.l	@r1,	r0	/* r0 = va */
1521.3Such	mov.l	_L.VPN_MASK, r1
1531.3Such	and	r1,	r0	/* va = trunc_page(va) */
1541.3Such	mov.l	_L.CURUPTE, r1
1551.3Such	mov	#UPAGES,r3
1561.3Such	mov	#1,	r2
1571.3Such4:	mov.l	@r1+,	r6
1581.3Such	cmp/eq	r6,	r0	/* md_upte.addr: u-area VPN */
1591.3Such	bt	5f
1601.3Such	add	#4,	r1	/* skip md_upte.data */
1611.3Such	cmp/eq	r2,	r3
1621.3Such	bf/s	4b
1631.3Such	 add	#1,	r2
1641.3Such	bra	6f
1651.3Such	 nop
1661.3Such5:	mov.l	@r1,	r2	/* md_upte.data: u-area PTE */
1671.3Such	mov.l	_L.PTEL, r1
1681.3Such	mov.l	r2,	@r1
1691.3Such	ldtlb
1701.3Such	bra	3f
1711.3Such	 nop
1721.3Such#endif /* !P1_STACK */
1731.3Such6:	mov	r0,	r2
1741.3Such	mov	#-22,	r1
1751.3Such	shld	r1,	r2	/* r2 = va >> 22 */
1761.3Such	shll2	r2		/* r2 *= sizeof(pt_entry_t) */
1771.3Such	mov.l	_L.TTB, r1
1781.3Such	mov.l	@r1,	r1
1791.3Such	add	r1,	r2	/* r2 = page directory entry address */
1801.3Such	mov	#1	r1
1811.3Such	swap.b	r1,	r1	/* 0x100 (PG_V) */
1821.3Such	mov.l	@r2,	r2	/* r2 = pde */
1831.3Such	and	r2,	r1
1841.3Such	tst	r1,	r1
1851.3Such	bt	2f		/* (pde & PG_V) == 0 -> tlb_handler */
1861.3Such	mov.l	_L.VPN_MASK, r1
1871.3Such	and	r1,	r2	/* zero attribute bits */
1881.3Such	mov.l	_L.PT_MASK, r1
1891.3Such	mov	r0,	r3
1901.3Such	and	r1,	r3	/* r3 = va & 0x003ff000 */
1911.3Such	mov	#-12	r1
1921.3Such	shld	r1,	r3	/* r3 = (va & 0x003ff000) >> 12 */
1931.3Such	shll2	r3		/* r3 *= sizeof(pt_entry_t) */
1941.3Such	add	r2,	r3	/* r3 = page table entry address */
1951.3Such	mov.l	@r3,	r3	/* r3 = page table entry */
1961.3Such	mov	#1,	r1
1971.3Such	swap.b	r1,	r1	/* r1 = PG_V */
1981.3Such	and	r3,	r1
1991.3Such	tst	r1,	r1
2001.3Such	bt	2f		/* (pte & PG_V) == 0 -> tlb_handler */
2011.3Such	mov.l	_L.PTE_HW_BITS, r2
2021.3Such	and	r2,	r3
2031.3Such	mov.l	_L.PTEL, r1
2041.3Such	mov.l	r3,	@r1	/* PTEL = (pte & PG_HW_BITS) */
2051.3Such	ldtlb
2061.3Such	bra	3f
2071.3Such	 nop
2081.3Such2:
2091.1Such	mov.l	1f,	r0
2101.1Such	jsr	@r0
2111.3Such	 mov	r14,	r6
2121.3Such3:
2131.5Such	__EXCEPTION_RETURN
2141.3Such	.align	2
2151.3Such1:		.long	_C_LABEL(tlb_handler)
2161.3Such_L.TEA:		.long	SH3_TEA
2171.3Such_L.TTB:		.long	SH3_TTB
2181.3Such_L.PTEL:	.long	SH3_PTEL
2191.3Such_L.PTE_HW_BITS:	.long	0x1ffff17e
2201.3Such_L.PT_MASK:	.long	0x003ff000
2211.3Such_L.VPN_MASK:	.long	0xfffff000
2221.3Such_L.CURUPTE:	.long	_C_LABEL(curupte)
2231.3Such	.align	2
2241.3Such_C_LABEL(sh3_vector_tlbmiss_end):	.long	0
2251.3Such#endif /* SH3 */
2261.3Such
2271.3Such#ifdef SH4
2281.3Such/*
2291.3Such * void sh4_vector_tlbmiss(void) __attribute__((__noreturn__)):
2301.3Such *	copied to VBR+0x400. This code should be relocatable and max 256
2311.3Such *	instructions.
2321.3Such */
2331.3Such	.globl	_C_LABEL(sh4_vector_tlbmiss), _C_LABEL(sh4_vector_tlbmiss_end)
2341.3Such	.text
2351.3Such	.align	2
2361.3Such_C_LABEL(sh4_vector_tlbmiss):
2371.5Such	__EXCEPTION_ENTRY
2381.3Such	__INTR_MASK(r0, r1)
2391.3Such	__EXCEPTION_UNBLOCK(r0, r1)
2401.3Such	mov	#0x20,	r7
2411.3Such	swap.b	r7,	r7
2421.3Such	swap.w	r7,	r7	/* r7 = 0x20000000 */
2431.3Such	mov.l	__L.TEA, r1
2441.3Such	mov.l	@r1,	r0	/* r0 = va */
2451.3Such	mov	r0,	r2
2461.3Such	mov	#-22,	r1
2471.3Such	shld	r1,	r2	/* r2 = va >> 22 */
2481.3Such	shll2	r2		/* r2 *= sizeof(pt_entry_t) */
2491.3Such	mov.l	__L.TTB, r1
2501.3Such	mov.l	@r1,	r1
2511.3Such	or	r7,	r1	/* XXX P2 access */
2521.3Such	add	r1,	r2	/* r2 = page directory entry address */
2531.3Such	mov	#1	r1
2541.3Such	swap.b	r1,	r1	/* 0x100 (PG_V) */
2551.3Such	mov.l	@r2,	r2	/* r2 = pde */
2561.3Such	and	r2,	r1
2571.3Such	tst	r1,	r1
2581.3Such	bt	2f		/* (pde & PG_V) == 0 -> tlb_handler */
2591.3Such	mov.l	__L.VPN_MASK, r1
2601.3Such	and	r1,	r2	/* zero attribute bits */
2611.3Such	mov.l	__L.PT_MASK, r1
2621.3Such	mov	r0,	r3
2631.3Such	and	r1,	r3	/* r3 = va & 0x003ff000 */
2641.3Such	mov	#-12	r1
2651.3Such	shld	r1,	r3	/* r3 = (va & 0x003ff000) >> 12 */
2661.3Such	shll2	r3		/* r3 *= sizeof(pt_entry_t) */
2671.3Such	add	r2,	r3	/* r3 = page table entry address */
2681.3Such	or	r7,	r3	/* XXX P2 access */
2691.3Such	mov.l	@r3,	r3	/* r3 = page table entry */
2701.3Such	mov	#1,	r1
2711.3Such	swap.b	r1,	r1	/* r1 = PG_V */
2721.3Such	and	r3,	r1
2731.3Such	tst	r1,	r1
2741.3Such	bt	2f		/* (pte & PG_V) == 0 -> tlb_handler */
2751.3Such	mov	#0xe,	r1
2761.3Such	swap.b	r1,	r1	/* r1 = _PG_PCMCIA (0x0e00) */
2771.3Such	and	r3,	r1
2781.3Such	tst	r1,	r1
2791.3Such	bt	4f
2801.3Such	mov	r3,	r2
2811.3Such	mov	#-9	r1
2821.3Such	shld	r1,	r2
2831.3Such	mov	#7,	r1
2841.3Such	and	r1,	r2	/* r2 = (pte >> 9) & 0x7 */
2851.3Such	mov.l	__L.PTEA, r1
2861.3Such	mov.l	r2,	@r1
2871.3Such	mov.l	__L.PTE_HW_BITS, r1
2881.3Such	and	r3,	r1
2891.3Such	mov	#-9,	r2
2901.3Such	and	r2,	r3	/* pte &= ~PG_N XXX */
2911.3Such	mov.l	__L.PTEL, r1
2921.3Such	mov.l	r3,	@r1
2931.3Such	bra	6f
2941.3Such	 nop
2951.3Such4:
2961.3Such	mov.l	__L.PTE_HW_BITS, r1
2971.3Such	and	r1,	r3
2981.3Such	mov.l	__L.P3SEGBASE, r1
2991.3Such	cmp/hs	r1,	r0	/* va >= 0xc0000000 ? T = 1 */
3001.3Such	bf	5f
3011.3Such	mov	#1,	r1
3021.3Such	or	r1,	r3	/* PG_WT  P3 write-through XXX */
3031.3Such5:
3041.3Such	mov.l	__L.PTEA, r1
3051.3Such	xor	r0,	r0
3061.3Such	mov.l	r0,	@r1
3071.3Such	mov.l	__L.PTEL, r1
3081.3Such	mov.l	r3,	@r1
3091.3Such	nop
3101.3Such6:	ldtlb
3111.3Such	bra	3f
3121.1Such	 nop
3131.3Such2:
3141.3Such	mov.l	1f,	r0
3151.3Such	jsr	@r0
3161.3Such	 mov	r14,	r6
3171.3Such3:
3181.5Such	__EXCEPTION_RETURN
3191.1Such	.align	2
3201.3Such1:		.long	_C_LABEL(tlb_handler)
3211.3Such__L.TEA:	.long	SH4_TEA
3221.3Such__L.TTB:	.long	SH4_TTB
3231.3Such__L.PTEL:	.long	SH4_PTEL
3241.3Such__L.PTEA:	.long	SH4_PTEA
3251.3Such__L.P3SEGBASE:	.long	0xc0000000
3261.3Such__L.PTE_HW_BITS:.long	0x1ffff17e
3271.3Such__L.PT_MASK:	.long	0x003ff000
3281.3Such__L.VPN_MASK:	.long	0xfffff000
3291.3Such_C_LABEL(sh4_vector_tlbmiss_end):	.long	0
3301.3Such#endif /* SH4 */
3311.1Such
3321.1Such/*
3331.1Such * void sh_vector_interrupt(void) __attribute__((__noreturn__)):
3341.1Such *	copied to VBR+0x600. This code should be relocatable.
3351.1Such */
3361.1Such	.globl	_C_LABEL(sh_vector_interrupt), _C_LABEL(sh_vector_interrupt_end)
3371.1Such	.align	2
3381.3Such	.text
3391.1Such_C_LABEL(sh_vector_interrupt):
3401.5Such	__EXCEPTION_ENTRY
3411.5Such	stc	r0_bank,r6	/* ssp */
3421.5Such	/* Enable exception for P3 access */
3431.5Such	__INTR_MASK(r0, r1)
3441.5Such	__EXCEPTION_UNBLOCK(r0, r1)
3451.5Such	/* Dispatch interrupt handler */
3461.1Such	mov.l	1f,	r0
3471.5Such	jsr	@r0		/* intc_intr(ssr, spc, ssp) */
3481.1Such	 nop
3491.5Such	/* Check for ASTs on exit to user mode. */
3501.5Such	mov.l	2f,	r0
3511.5Such	jsr	@r0
3521.5Such	 mov	r14,	r4
3531.5Such	__EXCEPTION_RETURN
3541.1Such	.align	2
3551.5Such1:	.long	_C_LABEL(intc_intr)
3561.5Such2:	.long	_C_LABEL(ast)
3571.3Such_C_LABEL(sh_vector_interrupt_end):	.long	0
358