1/* $NetBSD: exception.S,v 1.23 2015/06/21 15:00:06 matt Exp $ */ 2 3/* 4 * Copyright (c) 1994-1997 Mark Brinicombe. 5 * Copyright (c) 1994 Brini. 6 * All rights reserved. 7 * 8 * This code is derived from software written for Brini by Mark Brinicombe 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by Brini. 21 * 4. The name of the company nor the name of the author may be used to 22 * endorse or promote products derived from this software without specific 23 * prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED 26 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28 * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 29 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * RiscBSD kernel project 38 * 39 * exception.S 40 * 41 * Low level handlers for exception vectors 42 * 43 * Created : 24/09/94 44 * 45 * Based on kate/display/abort.s 46 */ 47 48#include "assym.h" 49 50#include <arm/asm.h> 51 52#include <arm/locore.h> 53 54 RCSID("$NetBSD: exception.S,v 1.23 2015/06/21 15:00:06 matt Exp $") 55 56 .text 57 .align 0 58 59AST_ALIGNMENT_FAULT_LOCALS 60 61/* 62 * reset_entry: 63 * 64 * Handler for Reset exception. 65 */ 66ARM_ASENTRY_NP(reset_entry) 67 adr r0, .Lreset_panicmsg 68 mov r1, lr 69 bl _C_LABEL(panic) 70 /* NOTREACHED */ 71.Lreset_panicmsg: 72 .asciz "Reset vector called, LR = 0x%08x" 73 .balign 4 74ASEND(reset_entry) 75 76/* 77 * swi_entry 78 * 79 * Handler for the Software Interrupt exception. 80 */ 81ARM_ASENTRY_NP(swi_entry) 82 PUSHFRAME 83 ENABLE_ALIGNMENT_FAULTS 84 85 mov r0, sp /* Pass the frame to any function */ 86 bl _C_LABEL(swi_handler) /* It's a SWI ! */ 87 88 DO_AST_AND_RESTORE_ALIGNMENT_FAULTS 89 PULLFRAME 90 movs pc, lr /* Exit */ 91ASEND(swi_entry) 92 93/* 94 * prefetch_abort_entry: 95 * 96 * Handler for the Prefetch Abort exception. 97 */ 98ARM_ASENTRY_NP(prefetch_abort_entry) 99#ifdef __XSCALE__ 100 nop /* Make absolutely sure any pending */ 101 nop /* imprecise aborts have occurred. */ 102#endif 103 sub lr, lr, #0x00000004 /* Adjust the lr */ 104 105#ifdef _ARM_ARCH_7 106 /* 107 * After taking a Data Abort exception, the state of the exclusive 108 * monitors is UNKNOWN. Therefore ARM strongly recommends that the 109 * abort handling software performs a CLREX instruction 110 */ 111 clrex 112#endif 113 PUSHFRAMEINSVC 114 ENABLE_ALIGNMENT_FAULTS 115 116 ldr r1, .Lprefetch_abort_handler_address 117 adr lr, .Lexception_exit 118 mov r0, sp /* pass the stack pointer as r0 */ 119 ldr pc, [r1] 120 121.Labortprefetch: 122 adr r0, .Labortprefetchmsg 123 b _C_LABEL(panic) 124 125.Lprefetch_abort_handler_address: 126 .word _C_LABEL(prefetch_abort_handler_address) 127 128.Labortprefetchmsg: 129 .asciz "abortprefetch" 130 .align 0 131ASEND(prefetch_abort_entry) 132 133 .data 134 .p2align 2 135 .global _C_LABEL(prefetch_abort_handler_address) 136_C_LABEL(prefetch_abort_handler_address): 137 .word .Labortprefetch 138 139/* 140 * data_abort_entry: 141 * 142 * Handler for the Data Abort exception. 143 */ 144ASENTRY_NP(data_abort_entry) 145#ifdef __XSCALE__ 146 nop /* Make absolutely sure any pending */ 147 nop /* imprecise aborts have occurred. */ 148#endif 149 sub lr, lr, #0x00000008 /* Adjust the lr */ 150 151#ifdef _ARM_ARCH_7 152 /* 153 * After taking a Data Abort exception, the state of the exclusive 154 * monitors is UNKNOWN. Therefore ARM strongly recommends that the 155 * abort handling software performs a CLREX instruction 156 */ 157 clrex 158#endif 159 PUSHFRAMEINSVC /* Push trap frame and switch */ 160 /* to SVC32 mode */ 161 ENABLE_ALIGNMENT_FAULTS 162 163 ldr r1, .Ldata_abort_handler_address 164 adr lr, .Lexception_exit 165 mov r0, sp /* pass the stack pointer as r0 */ 166 ldr pc, [r1] 167 168.Ldata_abort_handler_address: 169 .word _C_LABEL(data_abort_handler_address) 170 171 .data 172 .p2align 2 173 .global _C_LABEL(data_abort_handler_address) 174_C_LABEL(data_abort_handler_address): 175 .word .Labortdata 176 177 .text 178.Labortdata: 179 adr r0, .Labortdatamsg 180 b _C_LABEL(panic) 181 182.Labortdatamsg: 183 .asciz "abortdata" 184 .align 0 185ASEND(data_abort_entry) 186 187/* 188 * address_exception_entry: 189 * 190 * Handler for the Address Exception exception. 191 * 192 * NOTE: This exception isn't really used on arm32. We 193 * print a warning message to the console and then treat 194 * it like a Data Abort. 195 */ 196ASENTRY_NP(address_exception_entry) 197#ifdef _ARM_ARCH_7 198 /* 199 * After taking a Data Abort exception, the state of the exclusive 200 * monitors is UNKNOWN. Therefore ARM strongly recommends that the 201 * abort handling software performs a CLREX instruction 202 */ 203 clrex 204#endif 205 push {r0-r3,ip,lr} 206 mrs r1, cpsr 207 mrs r2, spsr 208 mov r3, lr 209 adr r0, .Laddress_exception_msg 210 bl _C_LABEL(printf) /* XXX CLOBBERS LR!! */ 211 pop {r0-r3,ip,lr} 212 b _ASM_LABEL(data_abort_entry) 213.Laddress_exception_msg: 214 .asciz "Address Exception CPSR=0x%08x SPSR=0x%08x LR=0x%08x\n" 215 .balign 4 216 217/* 218 * General exception exit handler 219 * (Placed here to be within range of all the references to it) 220 * 221 * It exits straight away if not returning to USR mode. 222 * This loops around delivering any pending ASTs. 223 * Interrupts are disabled at suitable points to avoid ASTs 224 * being posted between testing and exit to user mode. 225 * 226 * This function uses PULLFRAMEFROMSVCANDEXIT and 227 * DO_AST_AND_RESTORE_ALIGNMENT_FAULTS thus should 228 * only be called if the exception handler used PUSHFRAMEINSVC 229 * followed by ENABLE_ALIGNMENT_FAULTS. 230 */ 231 232.Lexception_exit: 233 DO_AST_AND_RESTORE_ALIGNMENT_FAULTS 234 PULLFRAMEFROMSVCANDEXIT 235ASEND(address_exception_entry) 236 237/* 238 * undefined_entry: 239 * 240 * Handler for the Undefined Instruction exception. 241 * 242 * We indirect the undefined vector via the handler address 243 * in the data area. Entry to the undefined handler must 244 * look like direct entry from the vector. 245 */ 246ASENTRY_NP(undefined_entry) 247 str r0, [sp, #-8]! 248 GET_CURCPU(r0) 249 ldr r0, [r0, #CI_UNDEFSAVE+8] 250 str r0, [sp, #4] 251 pop {r0, pc} 252ASEND(undefined_entry) 253 254/* 255 * assembly bounce code for calling the kernel 256 * undefined instruction handler. This uses 257 * a standard trap frame and is called in SVC mode. 258 */ 259 260ENTRY_NP(undefinedinstruction_bounce) 261 PUSHFRAMEINSVC 262 ENABLE_ALIGNMENT_FAULTS 263 264 mov r0, sp 265 adr lr, .Lexception_exit 266 b _C_LABEL(undefinedinstruction) 267END(undefinedinstruction_bounce) 268