exception_vector.S revision 1.8
1/* $NetBSD: exception_vector.S,v 1.8 2002/04/28 17:10:38 uch 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 "assym.h" 37#include "opt_cputype.h" 38 39#include <sh3/param.h> 40#include <sh3/asm.h> 41#include <sh3/locore.h> 42#include <sh3/exception.h> 43#include <sh3/ubcreg.h> 44#include <sh3/mmu_sh3.h> 45#include <sh3/mmu_sh4.h> 46 47/* 48 * Exception vectors. following routines are copied to vector addreses. 49 * sh_vector_generic: VBR + 0x100 50 * sh_vector_tlbmiss: VBR + 0x400 51 * sh_vector_interrupt: VBR + 0x600 52 */ 53 54/* 55 * void sh_vector_generic(void) __attribute__((__noreturn__)): 56 * copied to VBR+0x100. This code should be relocatable and max 384 57 * instructions. 58 * 0x40 TLB miss (load) 59 * 0x60 TLB miss (store) 60 * 0xc0 TLB protection (store) 61 * -> tlbmiss_exp() 62 * 0xa0 TLB protection (load) 63 * 0x80 Initial page write. 64 * and other... 65 * -> trap() 66 */ 67 .globl _C_LABEL(sh_vector_generic), _C_LABEL(sh_vector_generic_end) 68 .text 69 .align 2 70_C_LABEL(sh_vector_generic): 71 __EXCEPTION_ENTRY 72 /* Identify exception cause */ 73 MOV (EXPEVT, r0) 74 mov.l @r0, r0 75 /* 76 * TLB exception. 77 */ 78 cmp/eq #0x40, r0 /* T_TLBINVALIDR */ 79 bf 1f 803: 81 __INTR_MASK(r0, r1) 82 __EXCEPTION_UNBLOCK(r0, r1) 83 mov.l _L.tlb_handler, r0 84 jsr @r0 85 mov r14, r6 86 bra 4f 87 nop 881: 89 cmp/eq #0x60, r0 /* T_TLBINVALIDW */ 90 bt 3b 91 92 mov.l _L.TLBPROTWR, r1 /* T_TLBPRIVW */ 93 cmp/eq r0, r1 94 bt 3b 95 96 /* 97 * General exception. 98 */ 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 trapframe->tf_ubc */ 104#endif /* DDB */ 105 106 mov.l r0, @(TF_TRAPNO, r14) /* trapframe->tf_trapno = EXPEVT */ 107 __INTR_UNMASK(r0, r1) 108 __EXCEPTION_UNBLOCK(r0, r1) 109 mov.l _L.trap, r0 110 jsr @r0 111 mov r14, r6 112 113 /* Check for ASTs on exit to user mode. */ 114 mov.l _L.ast, r0 115 jsr @r0 116 mov r14, r4 117 118#ifdef DDB /* BBRA = trapframe->tf_ubc */ 119 __EXCEPTION_BLOCK(r0, r1) 120 mov.l @(TF_UBC, r14), r0 121 MOV (BBRA, r1) 122 mov.w r0, @r1 123#endif /* DDB */ 1244: 125 __EXCEPTION_RETURN 126 /* NOTREACHED */ 127 .align 2 128REG_SYMBOL(EXPEVT) 129REG_SYMBOL(BBRA) 130_L.TLBPROTWR: .long 0x000000c0 131_L.trap: .long _C_LABEL(trap) 132_L.ast: .long _C_LABEL(ast) 133_L.tlb_handler: .long _C_LABEL(tlb_handler) 134_C_LABEL(sh_vector_generic_end): .long 0 135 136#ifdef SH3 137/* 138 * void sh3_vector_tlbmiss(void) __attribute__((__noreturn__)): 139 * copied to VBR+0x400. This code should be relocatable and max 256 140 * instructions. 141 */ 142 .globl _C_LABEL(sh3_vector_tlbmiss), _C_LABEL(sh3_vector_tlbmiss_end) 143 .text 144 .align 2 145_C_LABEL(sh3_vector_tlbmiss): 146 __EXCEPTION_ENTRY 147 __INTR_MASK(r0, r1) 148 __EXCEPTION_UNBLOCK(r0, r1) 149#if !defined(P1_STACK) 150 /* Load kernel stack */ 151 mov.l _L.TEA, r1 152 mov.l @r1, r0 /* r0 = va */ 153 mov.l _L.VPN_MASK, r1 154 and r1, r0 /* va = trunc_page(va) */ 155 mov.l _L.CURUPTE, r1 156 mov #UPAGES,r3 157 mov #1, r2 1584: mov.l @r1+, r6 159 cmp/eq r6, r0 /* md_upte.addr: u-area VPN */ 160 bt 5f 161 add #4, r1 /* skip md_upte.data */ 162 cmp/eq r2, r3 163 bf/s 4b 164 add #1, r2 165 bra 6f 166 nop 1675: mov.l @r1, r2 /* md_upte.data: u-area PTE */ 168 mov.l _L.PTEL, r1 169 mov.l r2, @r1 170 ldtlb 171 bra 3f 172 nop 173#endif /* !P1_STACK */ 1746: mov r0, r2 175 mov #-22, r1 176 shld r1, r2 /* r2 = va >> 22 */ 177 shll2 r2 /* r2 *= sizeof(pt_entry_t) */ 178 mov.l _L.TTB, r1 179 mov.l @r1, r1 180 add r1, r2 /* r2 = page directory entry address */ 181 mov #1 r1 182 swap.b r1, r1 /* 0x100 (PG_V) */ 183 mov.l @r2, r2 /* r2 = pde */ 184 and r2, r1 185 tst r1, r1 186 bt 2f /* (pde & PG_V) == 0 -> tlb_handler */ 187 mov.l _L.VPN_MASK, r1 188 and r1, r2 /* zero attribute bits */ 189 mov.l _L.PT_MASK, r1 190 mov r0, r3 191 and r1, r3 /* r3 = va & 0x003ff000 */ 192 mov #-12 r1 193 shld r1, r3 /* r3 = (va & 0x003ff000) >> 12 */ 194 shll2 r3 /* r3 *= sizeof(pt_entry_t) */ 195 add r2, r3 /* r3 = page table entry address */ 196 mov.l @r3, r3 /* r3 = page table entry */ 197 mov #1, r1 198 swap.b r1, r1 /* r1 = PG_V */ 199 and r3, r1 200 tst r1, r1 201 bt 2f /* (pte & PG_V) == 0 -> tlb_handler */ 202 mov.l _L.PTE_HW_BITS, r2 203 and r2, r3 204 mov.l _L.PTEL, r1 205 mov.l r3, @r1 /* PTEL = (pte & PG_HW_BITS) */ 206 ldtlb 207 bra 3f 208 nop 2092: 210 mov.l 1f, r0 211 jsr @r0 212 mov r14, r6 2133: 214 __EXCEPTION_RETURN 215 .align 2 2161: .long _C_LABEL(tlb_handler) 217_L.TEA: .long SH3_TEA 218_L.TTB: .long SH3_TTB 219_L.PTEL: .long SH3_PTEL 220_L.PTE_HW_BITS: .long 0x1ffff17e 221_L.PT_MASK: .long 0x003ff000 222_L.VPN_MASK: .long 0xfffff000 223_L.CURUPTE: .long _C_LABEL(curupte) 224 .align 2 225_C_LABEL(sh3_vector_tlbmiss_end): .long 0 226#endif /* SH3 */ 227 228#ifdef SH4 229/* 230 * void sh4_vector_tlbmiss(void) __attribute__((__noreturn__)): 231 * copied to VBR+0x400. This code should be relocatable and max 256 232 * instructions. 233 */ 234 .globl _C_LABEL(sh4_vector_tlbmiss), _C_LABEL(sh4_vector_tlbmiss_end) 235 .text 236 .align 2 237_C_LABEL(sh4_vector_tlbmiss): 238 __EXCEPTION_ENTRY 239 __INTR_MASK(r0, r1) 240 __EXCEPTION_UNBLOCK(r0, r1) 241 mov #0x20, r7 242 swap.b r7, r7 243 swap.w r7, r7 /* r7 = 0x20000000 */ 244 mov.l __L.TEA, r1 245 mov.l @r1, r0 /* r0 = va */ 246 mov r0, r2 247 mov #-22, r1 248 shld r1, r2 /* r2 = va >> 22 */ 249 shll2 r2 /* r2 *= sizeof(pt_entry_t) */ 250 mov.l __L.TTB, r1 251 mov.l @r1, r1 252 or r7, r1 /* XXX P2 access */ 253 add r1, r2 /* r2 = page directory entry address */ 254 mov #1 r1 255 swap.b r1, r1 /* 0x100 (PG_V) */ 256 mov.l @r2, r2 /* r2 = pde */ 257 and r2, r1 258 tst r1, r1 259 bt 2f /* (pde & PG_V) == 0 -> tlb_handler */ 260 mov.l __L.VPN_MASK, r1 261 and r1, r2 /* zero attribute bits */ 262 mov.l __L.PT_MASK, r1 263 mov r0, r3 264 and r1, r3 /* r3 = va & 0x003ff000 */ 265 mov #-12 r1 266 shld r1, r3 /* r3 = (va & 0x003ff000) >> 12 */ 267 shll2 r3 /* r3 *= sizeof(pt_entry_t) */ 268 add r2, r3 /* r3 = page table entry address */ 269 or r7, r3 /* XXX P2 access */ 270 mov.l @r3, r3 /* r3 = page table entry */ 271 mov #1, r1 272 swap.b r1, r1 /* r1 = PG_V */ 273 and r3, r1 274 tst r1, r1 275 bt 2f /* (pte & PG_V) == 0 -> tlb_handler */ 276 mov #0xe, r1 277 swap.b r1, r1 /* r1 = _PG_PCMCIA (0x0e00) */ 278 and r3, r1 279 tst r1, r1 280 bt 4f 281 mov r3, r2 282 mov #-9 r1 283 shld r1, r2 284 mov #7, r1 285 and r1, r2 /* r2 = (pte >> 9) & 0x7 */ 286 mov.l __L.PTEA, r1 287 mov.l r2, @r1 288 mov.l __L.PTE_HW_BITS, r1 289 and r3, r1 290 mov #-9, r2 291 and r2, r3 /* pte &= ~PG_N XXX */ 292 mov.l __L.PTEL, r1 293 mov.l r3, @r1 294 bra 6f 295 nop 2964: 297 mov.l __L.PTE_HW_BITS, r1 298 and r1, r3 299 mov.l __L.P3SEGBASE, r1 300 cmp/hs r1, r0 /* va >= 0xc0000000 ? T = 1 */ 301 bf 5f 302 mov #1, r1 303 or r1, r3 /* PG_WT P3 write-through XXX */ 3045: 305 mov.l __L.PTEA, r1 306 xor r0, r0 307 mov.l r0, @r1 308 mov.l __L.PTEL, r1 309 mov.l r3, @r1 310 nop 3116: ldtlb 312 bra 3f 313 nop 3142: 315 mov.l 1f, r0 316 jsr @r0 317 mov r14, r6 3183: 319 __EXCEPTION_RETURN 320 .align 2 3211: .long _C_LABEL(tlb_handler) 322__L.TEA: .long SH4_TEA 323__L.TTB: .long SH4_TTB 324__L.PTEL: .long SH4_PTEL 325__L.PTEA: .long SH4_PTEA 326__L.P3SEGBASE: .long 0xc0000000 327__L.PTE_HW_BITS:.long 0x1ffff17e 328__L.PT_MASK: .long 0x003ff000 329__L.VPN_MASK: .long 0xfffff000 330_C_LABEL(sh4_vector_tlbmiss_end): .long 0 331#endif /* SH4 */ 332 333/* 334 * void sh_vector_interrupt(void) __attribute__((__noreturn__)): 335 * copied to VBR+0x600. This code should be relocatable. 336 */ 337 .globl _C_LABEL(sh_vector_interrupt), _C_LABEL(sh_vector_interrupt_end) 338 .align 2 339 .text 340_C_LABEL(sh_vector_interrupt): 341 __EXCEPTION_ENTRY 342 stc r0_bank,r6 /* ssp */ 343 /* Enable exception for P3 access */ 344 __INTR_MASK(r0, r1) 345 __EXCEPTION_UNBLOCK(r0, r1) 346 /* uvmexp.intrs++ */ 347 mov.l __L.uvmexp.intrs, r0 348 mov.l @r0, r1 349 add #1 r1 350 mov.l r1, @r0 351 /* Dispatch interrupt handler */ 352 mov.l __L.intc_intr, r0 353 jsr @r0 /* intc_intr(ssr, spc, ssp) */ 354 nop 355 /* Check for ASTs on exit to user mode. */ 356 mov.l __L.ast, r0 357 jsr @r0 358 mov r14, r4 359 __EXCEPTION_RETURN 360 .align 2 361__L.intc_intr: .long _C_LABEL(intc_intr) 362__L.ast: .long _C_LABEL(ast) 363__L.uvmexp.intrs: .long _C_LABEL(uvmexp) + UVMEXP_INTRS 364_C_LABEL(sh_vector_interrupt_end): .long 0 365