exception_vector.S revision 1.15
1/* $NetBSD: exception_vector.S,v 1.15 2006/01/22 05:56:58 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.15 2006/01/22 05:56:58 uwe Exp $") 49 50 51/* 52 * Exception vectors. The following routines are copied to vector addreses. 53 * sh_vector_generic: VBR + 0x100 54 * sh_vector_tlbmiss: VBR + 0x400 55 * sh_vector_interrupt: VBR + 0x600 56 */ 57 58#define VECTOR_END_MARKER(sym) \ 59 .globl _C_LABEL(sym); \ 60 _C_LABEL(sym): 61 62 63/* 64 * LINTSTUB: Var: char sh_vector_generic[1]; 65 * 66 * void sh_vector_generic(void) __attribute__((__noreturn__)) 67 * Copied to VBR+0x100. This code should be position independent 68 * and no more than 786 bytes long (== 0x400 - 0x100). 69 */ 70NENTRY(sh_vector_generic) 71 __EXCEPTION_ENTRY 72 __INTR_MASK(r0, r1) 73 /* Identify exception cause */ 74 MOV (EXPEVT, r0) 75 mov.l @r0, r0 76 mov.l r0, @(TF_EXPEVT, r14) /* trapframe->tf_expevt = EXPEVT */ 77 /* Get curlwp */ 78 mov.l _L.curlwp, r1 79 mov.l @r1, r4 /* 1st arg */ 80 /* Get TEA */ 81 MOV (TEA, r1) 82 mov.l @r1, r6 /* 3rd arg */ 83 /* Check TLB exception or not */ 84 mov.l _L.TLB_PROT_ST, r1 85 cmp/hi r1, r0 86 bt 1f 87 88 /* tlb_exception(curlwp, trapframe, trunc_page(TEA)); */ 89 mov.l _L.VPN_MASK, r1 90 and r1, r6 /* va = trunc_page(va) */ 91 __EXCEPTION_UNBLOCK(r0, r1) 92 mov.l _L.tlb, r0 93 jsr @r0 94 mov r14, r5 /* 2nd arg */ 95 bra 2f 96 nop 97 98 /* general_exception(curlwp, trapframe, TEA); */ 991: mov r4, r8 100#ifdef DDB 101 mov #0, r2 102 MOV (BBRA, r1) 103 mov.w r2, @r1 /* disable UBC */ 104 mov.l r2, @(TF_UBC, r14) /* clear trapframe->tf_ubc */ 105#endif /* DDB */ 106 __EXCEPTION_UNBLOCK(r0, r1) 107 mov.l _L.general, r0 108 jsr @r0 109 mov r14, r5 /* 2nd arg */ 110 111 /* Check for ASTs on exit to user mode. */ 112 mov r8, r4 113 mov.l _L.ast, r0 114 jsr @r0 115 mov r14, r5 116#ifdef DDB /* BBRA = trapframe->tf_ubc */ 117 __EXCEPTION_BLOCK(r0, r1) 118 mov.l @(TF_UBC, r14), r0 119 MOV (BBRA, r1) 120 mov.w r0, @r1 121#endif /* DDB */ 1222: __EXCEPTION_RETURN 123 /* NOTREACHED */ 124 .align 2 125_L.curlwp: .long _C_LABEL(curlwp) 126REG_SYMBOL(EXPEVT) 127REG_SYMBOL(BBRA) 128REG_SYMBOL(TEA) 129_L.tlb: .long _C_LABEL(tlb_exception) 130_L.general: .long _C_LABEL(general_exception) 131_L.ast: .long _C_LABEL(ast) 132_L.TLB_PROT_ST: .long 0xc0 133_L.VPN_MASK: .long 0xfffff000 134 135/* LINTSTUB: Var: char sh_vector_generic_end[1]; */ 136VECTOR_END_MARKER(sh_vector_generic_end) 137 SET_ENTRY_SIZE(sh_vector_generic) 138 139 140#ifdef SH3 141/* 142 * LINTSTUB: Var: char sh3_vector_tlbmiss[1]; 143 * 144 * void sh3_vector_tlbmiss(void) __attribute__((__noreturn__)) 145 * Copied to VBR+0x400. This code should be position independent 146 * and no more than 512 bytes long (== 0x600 - 0x400). 147 */ 148NENTRY(sh3_vector_tlbmiss) 149 __EXCEPTION_ENTRY 150 mov.l _L.TEA3, r0 151 mov.l @r0, r6 152 mov.l __L.VPN_MASK, r1 153 and r1, r6 /* 3rd arg */ 154#if !defined(P1_STACK) 155 /* Load kernel stack */ 156 tst r6, r6 /* check VPN == 0 */ 157 bt 6f 158 mov.l _L.CURUPTE, r1 159 mov.l @r1, r1 160 mov #UPAGES,r3 161 mov #1, r2 1624: mov.l @r1+, r7 163 cmp/eq r7, r6 /* md_upte.addr: u-area VPN */ 164 bt 5f 165 add #4, r1 /* skip md_upte.data */ 166 cmp/eq r2, r3 167 bf/s 4b 168 add #1, r2 169 bra 6f 170 nop 1715: mov.l @r1, r2 /* md_upte.data: u-area PTE */ 172 mov.l _L.PTEL, r1 173 mov.l r2, @r1 174 mov.l _L.PTEH, r1 175 mov.l @r1, r2 176 mov.l __L.VPN_MASK, r0 177 and r2, r0 178 mov.l r0, @r1 /* ASID 0 */ 179 ldtlb 180 mov.l r2, @r1 /* restore ASID */ 181 bra 3f 182 nop 183#endif /* !P1_STACK */ 1846: mov.l _L.EXPEVT3, r0 185 mov.l @r0, r0 186 mov.l r0, @(TF_EXPEVT, r14) /* trapframe->tf_expevt = EXPEVT */ 187 mov.l 2f, r0 188 mov.l @r0, r4 /* 1st arg */ 189 __INTR_MASK(r0, r1) 190 __EXCEPTION_UNBLOCK(r0, r1) 191 mov.l 1f, r0 192 jsr @r0 193 mov r14, r5 /* 2nd arg */ 1943: __EXCEPTION_RETURN 195 .align 2 1962: .long _C_LABEL(curlwp) 1971: .long _C_LABEL(tlb_exception) 198_L.EXPEVT3: .long SH3_EXPEVT 199_L.TEA3: .long SH3_TEA 200_L.PTEL: .long SH3_PTEL 201_L.PTEH: .long SH3_PTEH 202__L.VPN_MASK: .long 0xfffff000 203_L.CURUPTE: .long _C_LABEL(curupte) 204 205/* LINTSTUB: Var: char sh3_vector_tlbmiss_end[1]; */ 206VECTOR_END_MARKER(sh3_vector_tlbmiss_end) 207 SET_ENTRY_SIZE(sh3_vector_tlbmiss) 208#endif /* SH3 */ 209 210 211#ifdef SH4 212/* 213 * LINTSTUB: Var: char sh4_vector_tlbmiss[1]; 214 * 215 * void sh4_vector_tlbmiss(void) __attribute__((__noreturn__)) 216 * Copied to VBR+0x400. This code should be position independent 217 * and no more than 512 bytes long (== 0x600 - 0x400). 218 */ 219NENTRY(sh4_vector_tlbmiss) 220 __EXCEPTION_ENTRY 221 mov.l _L.TEA4, r0 222 mov.l @r0, r6 223 mov.l ___L.VPN_MASK, r1 224 and r1, r6 /* va = trunc_page(va) */ 225 mov.l _L.EXPEVT4, r0 226 mov.l @r0, r0 227 mov.l r0, @(TF_EXPEVT, r14) /* trapframe->tf_expevt = EXPEVT */ 228 mov.l 2f, r0 229 mov.l @r0, r4 /* 1st arg */ 230 __INTR_MASK(r0, r1) 231 __EXCEPTION_UNBLOCK(r0, r1) 232 mov.l 1f, r0 233 jsr @r0 234 mov r14, r5 /* 2nd arg */ 235 __EXCEPTION_RETURN 236 .align 2 2371: .long _C_LABEL(tlb_exception) 2382: .long _C_LABEL(curlwp) 239_L.EXPEVT4: .long SH4_EXPEVT 240_L.TEA4: .long SH4_TEA 241___L.VPN_MASK: .long 0xfffff000 242 243/* LINTSTUB: Var: char sh4_vector_tlbmiss_end[1]; */ 244VECTOR_END_MARKER(sh4_vector_tlbmiss_end) 245 SET_ENTRY_SIZE(sh4_vector_tlbmiss) 246#endif /* SH4 */ 247 248 249/* 250 * LINTSTUB: Var: char sh_vector_interrupt[1]; 251 * 252 * void sh_vector_interrupt(void) __attribute__((__noreturn__)): 253 * copied to VBR+0x600. This code should be relocatable. 254 */ 255NENTRY(sh_vector_interrupt) 256 __EXCEPTION_ENTRY 257 xor r0, r0 258 mov.l r0, @(TF_EXPEVT, r14) /* (for debug) */ 259 stc r0_bank,r6 /* ssp */ 260 /* Enable exception for P3 access */ 261 __INTR_MASK(r0, r1) 262 __EXCEPTION_UNBLOCK(r0, r1) 263 /* uvmexp.intrs++ */ 264 mov.l __L.uvmexp.intrs, r0 265 mov.l @r0, r1 266 add #1 r1 267 mov.l r1, @r0 268 /* Dispatch interrupt handler */ 269 mov.l __L.intc_intr, r0 270 jsr @r0 /* intc_intr(ssr, spc, ssp) */ 271 nop 272 /* Check for ASTs on exit to user mode. */ 273 mov.l 1f, r0 274 mov.l @r0, r4 /* 1st arg */ 275 mov.l __L.ast, r0 276 jsr @r0 277 mov r14, r5 /* 2nd arg */ 278 __EXCEPTION_RETURN 279 .align 2 2801: .long _C_LABEL(curlwp) 281__L.intc_intr: .long _C_LABEL(intc_intr) 282__L.ast: .long _C_LABEL(ast) 283__L.uvmexp.intrs: .long _C_LABEL(uvmexp) + UVMEXP_INTRS 284 285/* LINTSTUB: Var: char sh_vector_interrupt_end[1]; */ 286VECTOR_END_MARKER(sh_vector_interrupt_end) 287 SET_ENTRY_SIZE(sh_vector_interrupt) 288