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