exception_vector.S revision 1.21
11.21Suwe/*	$NetBSD: exception_vector.S,v 1.21 2007/03/14 22:38:00 uwe 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.9Such#include "opt_cputype.h"
371.9Such#include "opt_ddb.h"
381.1Such#include "assym.h"
391.7Such
401.3Such#include <sh3/param.h>
411.1Such#include <sh3/asm.h>
421.1Such#include <sh3/locore.h>
431.8Such#include <sh3/exception.h>
441.2Such#include <sh3/ubcreg.h>
451.3Such#include <sh3/mmu_sh3.h>
461.3Such#include <sh3/mmu_sh4.h>
471.12Suwe
481.21Suwe__KERNEL_RCSID(0, "$NetBSD: exception_vector.S,v 1.21 2007/03/14 22:38:00 uwe Exp $")
491.12Suwe
501.1Such
511.1Such/*
521.15Suwe * Exception vectors. The following routines are copied to vector addreses.
531.8Such *	sh_vector_generic:	VBR + 0x100
541.9Such *	sh_vector_tlbmiss:	VBR + 0x400
551.1Such *	sh_vector_interrupt:	VBR + 0x600
561.8Such */
571.8Such
581.15Suwe#define VECTOR_END_MARKER(sym)			\
591.15Suwe		.globl	_C_LABEL(sym);		\
601.15Suwe	_C_LABEL(sym):
611.15Suwe
621.15Suwe
631.1Such/*
641.15Suwe * LINTSTUB: Var: char sh_vector_generic[1];
651.15Suwe *
661.15Suwe * void sh_vector_generic(void) __attribute__((__noreturn__))
671.15Suwe *	Copied to VBR+0x100.  This code should be position independent
681.15Suwe *	and no more than 786 bytes long (== 0x400 - 0x100).
691.8Such */
701.15SuweNENTRY(sh_vector_generic)
711.5Such	__EXCEPTION_ENTRY
721.9Such	__INTR_MASK(r0, r1)
731.1Such	/* Identify exception cause */
741.1Such	MOV	(EXPEVT, r0)
751.21Suwe	mov.l	@r0, r0
761.21Suwe	mov.l	r0, @(TF_EXPEVT, r14)	/* trapframe->tf_expevt = EXPEVT */
771.10Sthorpej	/* Get curlwp */
781.13Suwe	mov.l	_L.curlwp, r1
791.21Suwe	mov.l	@r1, r4			/* 1st arg */
801.11Suwe	/* Get TEA */
811.21Suwe	MOV	(TEA, r1)
821.21Suwe	mov.l	@r1, r6			/* 3rd arg */
831.9Such	/* Check TLB exception or not */
841.9Such	mov.l	_L.TLB_PROT_ST, r1
851.21Suwe	cmp/hi	r1, r0
861.9Such	bt	1f
871.11Suwe
881.20Suwe	/* tlb_exception(curlwp, trapframe, TEA); */
891.2Such	__EXCEPTION_UNBLOCK(r0, r1)
901.9Such	mov.l	_L.tlb, r0
911.1Such	jsr	@r0
921.21Suwe	 mov	r14, r5			/* 2nd arg */
931.9Such	bra	2f
941.1Such	 nop
951.11Suwe
961.11Suwe	/* general_exception(curlwp, trapframe, TEA); */
971.21Suwe1:	mov	r4, r8
981.1Such#ifdef DDB
991.21Suwe	mov	#0, r2
1001.1Such	MOV	(BBRA, r1)
1011.21Suwe	mov.w	r2, @r1			/* disable UBC */
1021.21Suwe	mov.l	r2, @(TF_UBC, r14)	/* clear trapframe->tf_ubc */
1031.1Such#endif /* DDB */
1041.2Such	__EXCEPTION_UNBLOCK(r0, r1)
1051.9Such	mov.l	_L.general, r0
1061.1Such	jsr	@r0
1071.21Suwe	 mov	r14, r5			/* 2nd arg */
1081.1Such
1091.1Such	/* Check for ASTs on exit to user mode. */
1101.21Suwe	mov	r8, r4
1111.21Suwe	mov.l	_L.ast, r0
1121.1Such	jsr	@r0
1131.21Suwe	 mov	r14, r5
1141.8Such#ifdef DDB	/* BBRA = trapframe->tf_ubc */
1151.2Such	__EXCEPTION_BLOCK(r0, r1)
1161.3Such	mov.l	@(TF_UBC, r14), r0
1171.1Such	MOV	(BBRA, r1)
1181.21Suwe	mov.w	r0, @r1
1191.1Such#endif /* DDB */
1201.9Such2:	__EXCEPTION_RETURN
1211.1Such	/* NOTREACHED */
1221.1Such	.align	2
1231.13Suwe_L.curlwp:	.long	_C_LABEL(curlwp)
1241.1SuchREG_SYMBOL(EXPEVT)
1251.1SuchREG_SYMBOL(BBRA)
1261.9SuchREG_SYMBOL(TEA)
1271.9Such_L.tlb:		.long	_C_LABEL(tlb_exception)
1281.9Such_L.general:	.long	_C_LABEL(general_exception)
1291.1Such_L.ast:		.long	_C_LABEL(ast)
1301.9Such_L.TLB_PROT_ST:	.long	0xc0
1311.15Suwe
1321.15Suwe/* LINTSTUB: Var: char sh_vector_generic_end[1]; */
1331.15SuweVECTOR_END_MARKER(sh_vector_generic_end)
1341.15Suwe	SET_ENTRY_SIZE(sh_vector_generic)
1351.15Suwe
1361.8Such
1371.3Such#ifdef SH3
1381.8Such/*
1391.15Suwe * LINTSTUB: Var: char sh3_vector_tlbmiss[1];
1401.15Suwe *
1411.15Suwe * void sh3_vector_tlbmiss(void) __attribute__((__noreturn__))
1421.15Suwe *	Copied to VBR+0x400.  This code should be position independent
1431.15Suwe *	and no more than 512 bytes long (== 0x600 - 0x400).
1441.1Such */
1451.15SuweNENTRY(sh3_vector_tlbmiss)
1461.8Such	__EXCEPTION_ENTRY
1471.17Suwe	mov	#(SH3_TEA & 0xff), r0
1481.21Suwe	mov.l	@r0, r6		/* 3rd arg: va = TEA */
1491.3Such#if !defined(P1_STACK)
1501.4Such	/* Load kernel stack */
1511.16Suwe	mov.l	__L.VPN_MASK, r0
1521.21Suwe	and	r6, r0
1531.21Suwe	tst	r0, r0		/* check VPN == 0 */
1541.9Such	bt	6f
1551.3Such	mov.l	_L.CURUPTE, r1
1561.21Suwe	mov.l	@r1, r1
1571.21Suwe	mov	#UPAGES, r3
1581.21Suwe	mov	#1, r2
1591.21Suwe4:	mov.l	@r1+, r7
1601.21Suwe	cmp/eq	r7, r0		/* md_upte.addr: u-area VPN */
1611.3Such	bt	5f
1621.21Suwe	add	#4, r1		/* skip md_upte.data */
1631.21Suwe	cmp/eq	r2, r3
1641.3Such	bf/s	4b
1651.21Suwe	 add	#1, r2
1661.18Suwe	bra	7f		/* pull insn at 6f into delay slot */
1671.18Suwe	 mov	#(SH3_EXPEVT & 0xff), r0
1681.21Suwe5:	mov.l	@r1, r2		/* md_upte.data: u-area PTE */
1691.17Suwe	mov	#(SH3_PTEL & 0xff), r1
1701.21Suwe	mov.l	r2, @r1
1711.17Suwe	mov	#(SH3_PTEH & 0xff), r1
1721.21Suwe	mov.l	@r1, r2
1731.9Such	mov.l	__L.VPN_MASK, r0
1741.21Suwe	and	r2, r0
1751.21Suwe	mov.l	r0, @r1		/* ASID 0 */
1761.3Such	ldtlb
1771.3Such	bra	3f
1781.21Suwe	 mov.l	r2, @r1		/* restore ASID */
1791.3Such#endif /* !P1_STACK */
1801.17Suwe6:	mov	#(SH3_EXPEVT & 0xff), r0
1811.21Suwe7:	mov.l	@r0, r0
1821.21Suwe	mov.l	r0, @(TF_EXPEVT, r14)	/* trapframe->tf_expevt = EXPEVT */
1831.21Suwe	mov.l	2f, r0
1841.21Suwe	mov.l	@r0, r4		/* 1st arg */
1851.9Such	__INTR_MASK(r0, r1)
1861.9Such	__EXCEPTION_UNBLOCK(r0, r1)
1871.21Suwe	mov.l	1f, r0
1881.1Such	jsr	@r0
1891.21Suwe	 mov	r14, r5		/* 2nd arg */
1901.9Such3:	__EXCEPTION_RETURN
1911.3Such	.align	2
1921.10Sthorpej2:		.long	_C_LABEL(curlwp)
1931.9Such1:		.long	_C_LABEL(tlb_exception)
1941.9Such__L.VPN_MASK:	.long	0xfffff000
1951.3Such_L.CURUPTE:	.long	_C_LABEL(curupte)
1961.15Suwe
1971.15Suwe/* LINTSTUB: Var: char sh3_vector_tlbmiss_end[1]; */
1981.15SuweVECTOR_END_MARKER(sh3_vector_tlbmiss_end)
1991.15Suwe	SET_ENTRY_SIZE(sh3_vector_tlbmiss)
2001.3Such#endif /* SH3 */
2011.3Such
2021.15Suwe
2031.3Such#ifdef SH4
2041.8Such/*
2051.15Suwe * LINTSTUB: Var: char sh4_vector_tlbmiss[1];
2061.15Suwe *
2071.15Suwe * void sh4_vector_tlbmiss(void) __attribute__((__noreturn__))
2081.15Suwe *	Copied to VBR+0x400.  This code should be position independent
2091.15Suwe *	and no more than 512 bytes long (== 0x600 - 0x400).
2101.3Such */
2111.15SuweNENTRY(sh4_vector_tlbmiss)
2121.8Such	__EXCEPTION_ENTRY
2131.9Such	mov.l	_L.TEA4, r0
2141.21Suwe	mov.l	@r0, r6
2151.9Such	mov.l	_L.EXPEVT4, r0
2161.21Suwe	mov.l	@r0, r0
2171.21Suwe	mov.l	r0, @(TF_EXPEVT, r14)	/* trapframe->tf_expevt = EXPEVT */
2181.21Suwe	mov.l	2f, r0
2191.21Suwe	mov.l	@r0, r4			/* 1st arg */
2201.3Such	__INTR_MASK(r0, r1)
2211.3Such	__EXCEPTION_UNBLOCK(r0, r1)
2221.21Suwe	mov.l	1f, r0
2231.3Such	jsr	@r0
2241.21Suwe	 mov	r14, r5			/* 2nd arg */
2251.5Such	__EXCEPTION_RETURN
2261.1Such	.align	2
2271.9Such1:		.long	_C_LABEL(tlb_exception)
2281.10Sthorpej2:		.long	_C_LABEL(curlwp)
2291.9Such_L.EXPEVT4:	.long	SH4_EXPEVT
2301.9Such_L.TEA4:	.long	SH4_TEA
2311.15Suwe
2321.15Suwe/* LINTSTUB: Var: char sh4_vector_tlbmiss_end[1]; */
2331.15SuweVECTOR_END_MARKER(sh4_vector_tlbmiss_end)
2341.15Suwe	SET_ENTRY_SIZE(sh4_vector_tlbmiss)
2351.3Such#endif /* SH4 */
2361.1Such
2371.15Suwe
2381.1Such/*
2391.15Suwe * LINTSTUB: Var: char sh_vector_interrupt[1];
2401.15Suwe *
2411.8Such * void sh_vector_interrupt(void) __attribute__((__noreturn__)):
2421.1Such *	copied to VBR+0x600. This code should be relocatable.
2431.8Such */
2441.15SuweNENTRY(sh_vector_interrupt)
2451.5Such	__EXCEPTION_ENTRY
2461.21Suwe	xor	r0, r0
2471.21Suwe	mov.l	r0, @(TF_EXPEVT, r14)	/* (for debug) */
2481.21Suwe	stc	r0_bank, r6		/* ssp */
2491.5Such	/* Enable exception for P3 access */
2501.5Such	__INTR_MASK(r0, r1)
2511.5Such	__EXCEPTION_UNBLOCK(r0, r1)
2521.6Such	/* uvmexp.intrs++ */
2531.6Such	mov.l	__L.uvmexp.intrs, r0
2541.21Suwe	mov.l	@r0, r1
2551.21Suwe	add	#1 r1
2561.21Suwe	mov.l	r1, @r0
2571.5Such	/* Dispatch interrupt handler */
2581.6Such	mov.l	__L.intc_intr, r0
2591.5Such	jsr	@r0		/* intc_intr(ssr, spc, ssp) */
2601.1Such	 nop
2611.5Such	/* Check for ASTs on exit to user mode. */
2621.21Suwe	mov.l	1f, r0
2631.21Suwe	mov.l	@r0, r4		/* 1st arg */
2641.6Such	mov.l	__L.ast, r0
2651.5Such	jsr	@r0
2661.21Suwe	 mov	r14, r5		/* 2nd arg */
2671.5Such	__EXCEPTION_RETURN
2681.1Such	.align	2
2691.10Sthorpej1:			.long	_C_LABEL(curlwp)
2701.8Such__L.intc_intr:		.long	_C_LABEL(intc_intr)
2711.8Such__L.ast:		.long	_C_LABEL(ast)
2721.6Such__L.uvmexp.intrs:	.long	_C_LABEL(uvmexp) + UVMEXP_INTRS
2731.15Suwe
2741.15Suwe/* LINTSTUB: Var: char sh_vector_interrupt_end[1]; */
2751.15SuweVECTOR_END_MARKER(sh_vector_interrupt_end)
2761.15Suwe	SET_ENTRY_SIZE(sh_vector_interrupt)
277