exception_vector.S revision 1.22
1/* $NetBSD: exception_vector.S,v 1.22 2007/03/15 00:00:38 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.22 2007/03/15 00:00:38 uwe Exp $") 49 50 51/* 52 * Exception vectors. 53 * The following routines are copied to vector addresses. 54 * sh_vector_generic: VBR + 0x100 55 * sh_vector_tlbmiss: VBR + 0x400 56 * sh_vector_interrupt: VBR + 0x600 57 */ 58 59#define VECTOR_END_MARKER(sym) \ 60 .globl _C_LABEL(sym); \ 61 _C_LABEL(sym): 62 63 64/* 65 * LINTSTUB: Var: char sh_vector_generic[1]; 66 * 67 * void sh_vector_generic(void); 68 * Copied to VBR+0x100. This code should be position independent 69 * and maximum 786 bytes long (== 0x400 - 0x100). 70 */ 71NENTRY(sh_vector_generic) 72 __EXCEPTION_ENTRY 73 __INTR_MASK(r0, r1) 74 /* Identify exception cause */ 75 MOV (EXPEVT, r0) 76 mov.l @r0, r0 77 mov.l r0, @(TF_EXPEVT, r14) /* tf->tf_expevt = EXPEVT */ 78 /* Get curlwp */ 79 mov.l .Lg_curlwp, r1 80 mov.l @r1, r4 /* 1st arg */ 81 /* Get TEA */ 82 MOV (TEA, r1) 83 mov.l @r1, r6 /* 3rd arg */ 84 /* Check TLB exception or not */ 85 mov.l .Lg_TLB_PROT_ST, r1 86 cmp/hi r1, r0 87 bt 1f 88 89 /* tlb_exception(curlwp, tf, TEA); */ 90 __EXCEPTION_UNBLOCK(r0, r1) 91 mov.l .Lg_tlb_exception, r0 92 jsr @r0 93 mov r14, r5 /* 2nd arg */ 94 bra 2f 95 nop 96 97 /* general_exception(curlwp, tf, TEA); */ 981: mov r4, r8 99#ifdef DDB 100 mov #0, r2 101 MOV (BBRA, r1) 102 mov.w r2, @r1 /* disable UBC */ 103 mov.l r2, @(TF_UBC, r14) /* clear tf->tf_ubc */ 104#endif /* DDB */ 105 __EXCEPTION_UNBLOCK(r0, r1) 106 mov.l .Lg_general_exception, r0 107 jsr @r0 108 mov r14, r5 /* 2nd arg */ 109 110 /* Check for ASTs on exit to user mode. */ 111 mov r8, r4 112 mov.l .Lg_ast, r0 113 jsr @r0 114 mov r14, r5 115#ifdef DDB /* BBRA = tf->tf_ubc */ 116 __EXCEPTION_BLOCK(r0, r1) 117 mov.l @(TF_UBC, r14), r0 118 MOV (BBRA, r1) 119 mov.w r0, @r1 120#endif /* DDB */ 1212: __EXCEPTION_RETURN 122 123 .align 2 124.Lg_curlwp: .long _C_LABEL(curlwp) 125REG_SYMBOL(EXPEVT) 126REG_SYMBOL(BBRA) 127REG_SYMBOL(TEA) 128.Lg_tlb_exception: .long _C_LABEL(tlb_exception) 129.Lg_general_exception: .long _C_LABEL(general_exception) 130.Lg_ast: .long _C_LABEL(ast) 131.Lg_TLB_PROT_ST: .long EXPEVT_TLB_PROT_ST 132 133/* LINTSTUB: Var: char sh_vector_generic_end[1]; */ 134VECTOR_END_MARKER(sh_vector_generic_end) 135 SET_ENTRY_SIZE(sh_vector_generic) 136 137 138#ifdef SH3 139/* 140 * LINTSTUB: Var: char sh3_vector_tlbmiss[1]; 141 * 142 * void sh3_vector_tlbmiss(void); 143 * Copied to VBR+0x400. This code should be position independent 144 * and maximum 512 bytes long (== 0x600 - 0x400). 145 */ 146NENTRY(sh3_vector_tlbmiss) 147 __EXCEPTION_ENTRY 148 mov #(SH3_TEA & 0xff), r0 149 mov.l @r0, r6 /* 3rd arg: va = TEA */ 150#if !defined(P1_STACK) 151 /* Load kernel stack */ 152 mov.l .L3_VPN_MASK, r0 153 and r6, r0 154 tst r0, r0 /* check VPN == 0 */ 155 bt 6f 156 mov.l .L3_CURUPTE, r1 157 mov.l @r1, r1 158 mov #UPAGES, r3 159 mov #1, r2 1604: mov.l @r1+, r7 161 cmp/eq r7, r0 /* md_upte.addr: u-area VPN */ 162 bt 5f 163 add #4, r1 /* skip md_upte.data */ 164 cmp/eq r2, r3 165 bf/s 4b 166 add #1, r2 167 bra 7f /* pull insn at 6f into delay slot */ 168 mov #(SH3_EXPEVT & 0xff), r0 1695: mov.l @r1, r2 /* md_upte.data: u-area PTE */ 170 mov #(SH3_PTEL & 0xff), r1 171 mov.l r2, @r1 172 mov #(SH3_PTEH & 0xff), r1 173 mov.l @r1, r2 174 mov.l .L3_VPN_MASK, r0 175 and r2, r0 176 mov.l r0, @r1 /* ASID 0 */ 177 ldtlb 178 bra 3f 179 mov.l r2, @r1 /* restore ASID */ 180#endif /* !P1_STACK */ 1816: mov #(SH3_EXPEVT & 0xff), r0 1827: mov.l @r0, r0 183 mov.l r0, @(TF_EXPEVT, r14) /* tf->tf_expevt = EXPEVT */ 184 mov.l .L3_curlwp, r0 185 mov.l @r0, r4 /* 1st arg */ 186 __INTR_MASK(r0, r1) 187 __EXCEPTION_UNBLOCK(r0, r1) 188 mov.l .L3_tlb_exception, r0 189 jsr @r0 190 mov r14, r5 /* 2nd arg */ 1913: __EXCEPTION_RETURN 192 193 .align 2 194.L3_curlwp: .long _C_LABEL(curlwp) 195.L3_tlb_exception: .long _C_LABEL(tlb_exception) 196.L3_VPN_MASK: .long 0xfffff000 197.L3_CURUPTE: .long _C_LABEL(curupte) 198 199/* LINTSTUB: Var: char sh3_vector_tlbmiss_end[1]; */ 200VECTOR_END_MARKER(sh3_vector_tlbmiss_end) 201 SET_ENTRY_SIZE(sh3_vector_tlbmiss) 202#endif /* SH3 */ 203 204 205#ifdef SH4 206/* 207 * LINTSTUB: Var: char sh4_vector_tlbmiss[1]; 208 * 209 * void sh4_vector_tlbmiss(void); 210 * Copied to VBR+0x400. This code should be position independent 211 * and maximum 512 bytes long (== 0x600 - 0x400). 212 */ 213NENTRY(sh4_vector_tlbmiss) 214 __EXCEPTION_ENTRY 215 mov.l .L4_TEA4, r0 216 mov.l @r0, r6 217 mov.l .L4_EXPEVT4, r0 218 mov.l @r0, r0 219 mov.l r0, @(TF_EXPEVT, r14) /* tf->tf_expevt = EXPEVT */ 220 mov.l .L4_curlwp, r0 221 mov.l @r0, r4 /* 1st arg */ 222 __INTR_MASK(r0, r1) 223 __EXCEPTION_UNBLOCK(r0, r1) 224 mov.l .L4_tlb_exception, r0 225 jsr @r0 226 mov r14, r5 /* 2nd arg */ 227 __EXCEPTION_RETURN 228 229 .align 2 230.L4_tlb_exception: .long _C_LABEL(tlb_exception) 231.L4_curlwp: .long _C_LABEL(curlwp) 232.L4_EXPEVT4: .long SH4_EXPEVT 233.L4_TEA4: .long SH4_TEA 234 235/* LINTSTUB: Var: char sh4_vector_tlbmiss_end[1]; */ 236VECTOR_END_MARKER(sh4_vector_tlbmiss_end) 237 SET_ENTRY_SIZE(sh4_vector_tlbmiss) 238#endif /* SH4 */ 239 240 241/* 242 * LINTSTUB: Var: char sh_vector_interrupt[1]; 243 * 244 * void sh_vector_interrupt(void); 245 * Copied to VBR+0x600. This code should be position independent. 246 */ 247NENTRY(sh_vector_interrupt) 248 __EXCEPTION_ENTRY 249 xor r0, r0 250 mov.l r0, @(TF_EXPEVT, r14) /* (for debug) */ 251 stc r0_bank, r6 /* ssp */ 252 /* Enable exceptions for P3 access */ 253 __INTR_MASK(r0, r1) 254 __EXCEPTION_UNBLOCK(r0, r1) 255 /* ++uvmexp.intrs */ 256 mov.l .Li_uvmexp_intrs, r0 257 mov.l @r0, r1 258 add #1 r1 259 mov.l r1, @r0 260 /* Dispatch interrupt handler */ 261 mov.l .Li_intc_intr, r0 262 jsr @r0 /* intc_intr(ssr, spc, ssp) */ 263 nop 264 /* Check for ASTs on exit to user mode. */ 265 mov.l .Li_curlwp, r0 266 mov.l @r0, r4 /* 1st arg */ 267 mov.l .Li_ast, r0 268 jsr @r0 269 mov r14, r5 /* 2nd arg */ 270 __EXCEPTION_RETURN 271 272 .align 2 273.Li_curlwp: .long _C_LABEL(curlwp) 274.Li_intc_intr: .long _C_LABEL(intc_intr) 275.Li_ast: .long _C_LABEL(ast) 276.Li_uvmexp_intrs: .long _C_LABEL(uvmexp) + UVMEXP_INTRS 277 278/* LINTSTUB: Var: char sh_vector_interrupt_end[1]; */ 279VECTOR_END_MARKER(sh_vector_interrupt_end) 280 SET_ENTRY_SIZE(sh_vector_interrupt) 281