exception_vector.S revision 1.24
11.24Suwe/*	$NetBSD: exception_vector.S,v 1.24 2007/03/15 23:13:59 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/locore.h>
421.8Such#include <sh3/exception.h>
431.2Such#include <sh3/ubcreg.h>
441.3Such#include <sh3/mmu_sh3.h>
451.3Such#include <sh3/mmu_sh4.h>
461.12Suwe
471.23Suwe/*
481.23Suwe * Align vectors more strictly here (where we don't really care) so
491.23Suwe * that .align 5 (i.e. 32B cache line) before data block does the
501.23Suwe * right thing w.r.t. final destinations after vectors are copied.
511.23Suwe */
521.23Suwe#define _ALIGN_TEXT	.align 5
531.23Suwe#include <sh3/asm.h>
541.23Suwe
551.24Suwe__KERNEL_RCSID(0, "$NetBSD: exception_vector.S,v 1.24 2007/03/15 23:13:59 uwe Exp $")
561.12Suwe
571.1Such
581.1Such/*
591.22Suwe * Exception vectors.
601.22Suwe * The following routines are copied to vector addresses.
611.8Such *	sh_vector_generic:	VBR + 0x100
621.9Such *	sh_vector_tlbmiss:	VBR + 0x400
631.1Such *	sh_vector_interrupt:	VBR + 0x600
641.8Such */
651.8Such
661.15Suwe#define VECTOR_END_MARKER(sym)			\
671.15Suwe		.globl	_C_LABEL(sym);		\
681.15Suwe	_C_LABEL(sym):
691.15Suwe
701.15Suwe
711.1Such/*
721.15Suwe * LINTSTUB: Var: char sh_vector_generic[1];
731.15Suwe *
741.22Suwe * void sh_vector_generic(void);
751.15Suwe *	Copied to VBR+0x100.  This code should be position independent
761.22Suwe *	and maximum 786 bytes long (== 0x400 - 0x100).
771.8Such */
781.15SuweNENTRY(sh_vector_generic)
791.5Such	__EXCEPTION_ENTRY
801.9Such	__INTR_MASK(r0, r1)
811.1Such	/* Identify exception cause */
821.1Such	MOV	(EXPEVT, r0)
831.21Suwe	mov.l	@r0, r0
841.22Suwe	mov.l	r0, @(TF_EXPEVT, r14)	/* tf->tf_expevt = EXPEVT */
851.10Sthorpej	/* Get curlwp */
861.22Suwe	mov.l	.Lg_curlwp, r1
871.21Suwe	mov.l	@r1, r4			/* 1st arg */
881.11Suwe	/* Get TEA */
891.21Suwe	MOV	(TEA, r1)
901.21Suwe	mov.l	@r1, r6			/* 3rd arg */
911.9Such	/* Check TLB exception or not */
921.22Suwe	mov.l	.Lg_TLB_PROT_ST, r1
931.21Suwe	cmp/hi	r1, r0
941.9Such	bt	1f
951.11Suwe
961.22Suwe	/* tlb_exception(curlwp, tf, TEA); */
971.2Such	__EXCEPTION_UNBLOCK(r0, r1)
981.22Suwe	mov.l	.Lg_tlb_exception, r0
991.1Such	jsr	@r0
1001.21Suwe	 mov	r14, r5			/* 2nd arg */
1011.9Such	bra	2f
1021.1Such	 nop
1031.11Suwe
1041.22Suwe	/* general_exception(curlwp, tf, TEA); */
1051.21Suwe1:	mov	r4, r8
1061.1Such#ifdef DDB
1071.21Suwe	mov	#0, r2
1081.1Such	MOV	(BBRA, r1)
1091.21Suwe	mov.w	r2, @r1			/* disable UBC */
1101.22Suwe	mov.l	r2, @(TF_UBC, r14)	/* clear tf->tf_ubc */
1111.1Such#endif /* DDB */
1121.2Such	__EXCEPTION_UNBLOCK(r0, r1)
1131.22Suwe	mov.l	.Lg_general_exception, r0
1141.1Such	jsr	@r0
1151.21Suwe	 mov	r14, r5			/* 2nd arg */
1161.1Such
1171.1Such	/* Check for ASTs on exit to user mode. */
1181.21Suwe	mov	r8, r4
1191.22Suwe	mov.l	.Lg_ast, r0
1201.1Such	jsr	@r0
1211.21Suwe	 mov	r14, r5
1221.22Suwe#ifdef DDB	/* BBRA = tf->tf_ubc */
1231.2Such	__EXCEPTION_BLOCK(r0, r1)
1241.3Such	mov.l	@(TF_UBC, r14), r0
1251.1Such	MOV	(BBRA, r1)
1261.21Suwe	mov.w	r0, @r1
1271.1Such#endif /* DDB */
1281.9Such2:	__EXCEPTION_RETURN
1291.22Suwe
1301.23Suwe	.align	5
1311.22Suwe.Lg_curlwp:		.long	_C_LABEL(curlwp)
1321.1SuchREG_SYMBOL(EXPEVT)
1331.1SuchREG_SYMBOL(BBRA)
1341.9SuchREG_SYMBOL(TEA)
1351.22Suwe.Lg_tlb_exception:	.long	_C_LABEL(tlb_exception)
1361.22Suwe.Lg_general_exception:	.long	_C_LABEL(general_exception)
1371.22Suwe.Lg_ast:		.long	_C_LABEL(ast)
1381.22Suwe.Lg_TLB_PROT_ST:	.long	EXPEVT_TLB_PROT_ST
1391.15Suwe
1401.15Suwe/* LINTSTUB: Var: char sh_vector_generic_end[1]; */
1411.15SuweVECTOR_END_MARKER(sh_vector_generic_end)
1421.15Suwe	SET_ENTRY_SIZE(sh_vector_generic)
1431.15Suwe
1441.8Such
1451.3Such#ifdef SH3
1461.8Such/*
1471.15Suwe * LINTSTUB: Var: char sh3_vector_tlbmiss[1];
1481.15Suwe *
1491.22Suwe * void sh3_vector_tlbmiss(void);
1501.15Suwe *	Copied to VBR+0x400.  This code should be position independent
1511.22Suwe *	and maximum 512 bytes long (== 0x600 - 0x400).
1521.1Such */
1531.15SuweNENTRY(sh3_vector_tlbmiss)
1541.8Such	__EXCEPTION_ENTRY
1551.17Suwe	mov	#(SH3_TEA & 0xff), r0
1561.24Suwe	mov.l	@r0, r6		! 3rd arg: va = TEA
1571.24Suwe
1581.24Suwe	!! if kernel stack is in P3, handle it here fast
1591.3Such#if !defined(P1_STACK)
1601.22Suwe	mov.l	.L3_VPN_MASK, r0
1611.24Suwe	and	r6, r0		! vpn
1621.24Suwe	tst	r0, r0
1631.24Suwe	bt	6f		! punt if vpn is 0
1641.24Suwe
1651.22Suwe	mov.l	.L3_CURUPTE, r1
1661.24Suwe	mov.l	@r1, r1		! upte = &l->l_md.md_upte[0]
1671.24Suwe	mov	#UPAGES, r3	! loop limit
1681.24Suwe	mov	#1, r2		! loop count
1691.24Suwe
1701.24Suwe	!! for each page of u-area
1711.24Suwe4:	mov.l	@r1+, r7	! upte->addr: u-area VPN
1721.24Suwe	cmp/eq	r7, r0		! if (vpn == upte->addr)
1731.24Suwe	bt	5f		!     goto found;
1741.24Suwe	add	#4, r1		! skip, upte->data; point to next md_upte[i]
1751.21Suwe	cmp/eq	r2, r3
1761.3Such	bf/s	4b
1771.21Suwe	 add	#1, r2
1781.24Suwe
1791.24Suwe	!! not a page of u-area, proceed to handler
1801.24Suwe	bra	7f		! pull insn at 6f into delay slot
1811.18Suwe	 mov	#(SH3_EXPEVT & 0xff), r0
1821.24Suwe
1831.24Suwe	!! load entry for this uarea page into tlb
1841.24Suwe5:	mov.l	@r1, r2		! upte->data: u-area PTE
1851.17Suwe	mov	#(SH3_PTEL & 0xff), r1
1861.21Suwe	mov.l	r2, @r1
1871.24Suwe
1881.17Suwe	mov	#(SH3_PTEH & 0xff), r1
1891.21Suwe	mov.l	@r1, r2
1901.22Suwe	mov.l	.L3_VPN_MASK, r0
1911.21Suwe	and	r2, r0
1921.24Suwe	mov.l	r0, @r1		! ASID 0
1931.24Suwe
1941.3Such	ldtlb
1951.24Suwe
1961.24Suwe	bra	99f		! return
1971.24Suwe	 mov.l	r2, @r1		!  restore ASID
1981.3Such#endif /* !P1_STACK */
1991.24Suwe
2001.24Suwe	!! tlb_exception(curlwp, trapframe, tea)
2011.17Suwe6:	mov	#(SH3_EXPEVT & 0xff), r0
2021.21Suwe7:	mov.l	@r0, r0
2031.24Suwe	mov.l	r0, @(TF_EXPEVT, r14)	! tf->tf_expevt = EXPEVT
2041.22Suwe	mov.l	.L3_curlwp, r0
2051.24Suwe	mov.l	@r0, r4			! 1st arg: curlwp
2061.9Such	__INTR_MASK(r0, r1)
2071.9Such	__EXCEPTION_UNBLOCK(r0, r1)
2081.22Suwe	mov.l	.L3_tlb_exception, r0
2091.1Such	jsr	@r0
2101.24Suwe	 mov	r14, r5			! 2nd arg: trap frame
2111.24Suwe99:	__EXCEPTION_RETURN
2121.22Suwe
2131.23Suwe	.align	5
2141.22Suwe.L3_curlwp:		.long	_C_LABEL(curlwp)
2151.22Suwe.L3_tlb_exception:	.long	_C_LABEL(tlb_exception)
2161.22Suwe.L3_VPN_MASK:		.long	0xfffff000
2171.22Suwe.L3_CURUPTE:		.long	_C_LABEL(curupte)
2181.15Suwe
2191.15Suwe/* LINTSTUB: Var: char sh3_vector_tlbmiss_end[1]; */
2201.15SuweVECTOR_END_MARKER(sh3_vector_tlbmiss_end)
2211.15Suwe	SET_ENTRY_SIZE(sh3_vector_tlbmiss)
2221.3Such#endif /* SH3 */
2231.3Such
2241.15Suwe
2251.3Such#ifdef SH4
2261.8Such/*
2271.15Suwe * LINTSTUB: Var: char sh4_vector_tlbmiss[1];
2281.15Suwe *
2291.22Suwe * void sh4_vector_tlbmiss(void);
2301.15Suwe *	Copied to VBR+0x400.  This code should be position independent
2311.22Suwe *	and maximum 512 bytes long (== 0x600 - 0x400).
2321.3Such */
2331.15SuweNENTRY(sh4_vector_tlbmiss)
2341.8Such	__EXCEPTION_ENTRY
2351.22Suwe	mov.l	.L4_TEA4, r0
2361.21Suwe	mov.l	@r0, r6
2371.22Suwe	mov.l	.L4_EXPEVT4, r0
2381.21Suwe	mov.l	@r0, r0
2391.22Suwe	mov.l	r0, @(TF_EXPEVT, r14)	/* tf->tf_expevt = EXPEVT */
2401.22Suwe	mov.l	.L4_curlwp, r0
2411.21Suwe	mov.l	@r0, r4			/* 1st arg */
2421.3Such	__INTR_MASK(r0, r1)
2431.3Such	__EXCEPTION_UNBLOCK(r0, r1)
2441.22Suwe	mov.l	.L4_tlb_exception, r0
2451.3Such	jsr	@r0
2461.21Suwe	 mov	r14, r5			/* 2nd arg */
2471.5Such	__EXCEPTION_RETURN
2481.22Suwe
2491.23Suwe	.align	5
2501.22Suwe.L4_tlb_exception:	.long	_C_LABEL(tlb_exception)
2511.22Suwe.L4_curlwp:		.long	_C_LABEL(curlwp)
2521.22Suwe.L4_EXPEVT4:		.long	SH4_EXPEVT
2531.22Suwe.L4_TEA4:		.long	SH4_TEA
2541.15Suwe
2551.15Suwe/* LINTSTUB: Var: char sh4_vector_tlbmiss_end[1]; */
2561.15SuweVECTOR_END_MARKER(sh4_vector_tlbmiss_end)
2571.15Suwe	SET_ENTRY_SIZE(sh4_vector_tlbmiss)
2581.3Such#endif /* SH4 */
2591.1Such
2601.15Suwe
2611.1Such/*
2621.15Suwe * LINTSTUB: Var: char sh_vector_interrupt[1];
2631.15Suwe *
2641.22Suwe * void sh_vector_interrupt(void);
2651.22Suwe *	Copied to VBR+0x600.  This code should be position independent.
2661.8Such */
2671.15SuweNENTRY(sh_vector_interrupt)
2681.5Such	__EXCEPTION_ENTRY
2691.21Suwe	xor	r0, r0
2701.21Suwe	mov.l	r0, @(TF_EXPEVT, r14)	/* (for debug) */
2711.21Suwe	stc	r0_bank, r6		/* ssp */
2721.22Suwe	/* Enable exceptions for P3 access */
2731.5Such	__INTR_MASK(r0, r1)
2741.5Such	__EXCEPTION_UNBLOCK(r0, r1)
2751.22Suwe	/* ++uvmexp.intrs */
2761.22Suwe	mov.l	.Li_uvmexp_intrs, r0
2771.21Suwe	mov.l	@r0, r1
2781.21Suwe	add	#1 r1
2791.21Suwe	mov.l	r1, @r0
2801.5Such	/* Dispatch interrupt handler */
2811.22Suwe	mov.l	.Li_intc_intr, r0
2821.5Such	jsr	@r0		/* intc_intr(ssr, spc, ssp) */
2831.1Such	 nop
2841.5Such	/* Check for ASTs on exit to user mode. */
2851.22Suwe	mov.l	.Li_curlwp, r0
2861.21Suwe	mov.l	@r0, r4		/* 1st arg */
2871.22Suwe	mov.l	.Li_ast, r0
2881.5Such	jsr	@r0
2891.21Suwe	 mov	r14, r5		/* 2nd arg */
2901.5Such	__EXCEPTION_RETURN
2911.22Suwe
2921.23Suwe	.align	5
2931.22Suwe.Li_curlwp:		.long	_C_LABEL(curlwp)
2941.22Suwe.Li_intc_intr:		.long	_C_LABEL(intc_intr)
2951.22Suwe.Li_ast:		.long	_C_LABEL(ast)
2961.22Suwe.Li_uvmexp_intrs:	.long	_C_LABEL(uvmexp) + UVMEXP_INTRS
2971.15Suwe
2981.15Suwe/* LINTSTUB: Var: char sh_vector_interrupt_end[1]; */
2991.15SuweVECTOR_END_MARKER(sh_vector_interrupt_end)
3001.15Suwe	SET_ENTRY_SIZE(sh_vector_interrupt)
301