1/* $NetBSD: exception.S,v 1.18 2012/09/12 23:06:15 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#include <machine/asm.h> 50#include <machine/cpu.h> 51#include <machine/frame.h> 52 53 RCSID("$NetBSD: exception.S,v 1.18 2012/09/12 23:06:15 matt Exp $") 54 55 .text 56 .align 0 57 58AST_ALIGNMENT_FAULT_LOCALS 59 60/* 61 * reset_entry: 62 * 63 * Handler for Reset exception. 64 */ 65ASENTRY_NP(reset_entry) 66 adr r0, Lreset_panicmsg 67 mov r1, lr 68 bl _C_LABEL(panic) 69 /* NOTREACHED */ 70Lreset_panicmsg: 71 .asciz "Reset vector called, LR = 0x%08x" 72 .balign 4 73 74/* 75 * swi_entry 76 * 77 * Handler for the Software Interrupt exception. 78 */ 79ASENTRY_NP(swi_entry) 80 PUSHFRAME 81 ENABLE_ALIGNMENT_FAULTS 82 83 mov r0, sp /* Pass the frame to any function */ 84 bl _C_LABEL(swi_handler) /* It's a SWI ! */ 85 86 DO_AST_AND_RESTORE_ALIGNMENT_FAULTS 87 PULLFRAME 88 movs pc, lr /* Exit */ 89 90/* 91 * prefetch_abort_entry: 92 * 93 * Handler for the Prefetch Abort exception. 94 */ 95ASENTRY_NP(prefetch_abort_entry) 96#ifdef __XSCALE__ 97 nop /* Make absolutely sure any pending */ 98 nop /* imprecise aborts have occurred. */ 99#endif 100 sub lr, lr, #0x00000004 /* Adjust the lr */ 101 102 PUSHFRAMEINSVC 103 ENABLE_ALIGNMENT_FAULTS 104 105 ldr r1, Lprefetch_abort_handler_address 106 adr lr, exception_exit 107 mov r0, sp /* pass the stack pointer as r0 */ 108 ldr pc, [r1] 109 110Lprefetch_abort_handler_address: 111 .word _C_LABEL(prefetch_abort_handler_address) 112 113 .data 114 .p2align 2 115 .global _C_LABEL(prefetch_abort_handler_address) 116_C_LABEL(prefetch_abort_handler_address): 117 .word abortprefetch 118 119 .text 120abortprefetch: 121 adr r0, abortprefetchmsg 122 b _C_LABEL(panic) 123 124abortprefetchmsg: 125 .asciz "abortprefetch" 126 .align 0 127 128/* 129 * data_abort_entry: 130 * 131 * Handler for the Data Abort exception. 132 */ 133ASENTRY_NP(data_abort_entry) 134#ifdef __XSCALE__ 135 nop /* Make absolutely sure any pending */ 136 nop /* imprecise aborts have occurred. */ 137#endif 138 sub lr, lr, #0x00000008 /* Adjust the lr */ 139 140 PUSHFRAMEINSVC /* Push trap frame and switch */ 141 /* to SVC32 mode */ 142 ENABLE_ALIGNMENT_FAULTS 143 144 ldr r1, Ldata_abort_handler_address 145 adr lr, exception_exit 146 mov r0, sp /* pass the stack pointer as r0 */ 147 ldr pc, [r1] 148 149Ldata_abort_handler_address: 150 .word _C_LABEL(data_abort_handler_address) 151 152 .data 153 .p2align 2 154 .global _C_LABEL(data_abort_handler_address) 155_C_LABEL(data_abort_handler_address): 156 .word abortdata 157 158 .text 159abortdata: 160 adr r0, abortdatamsg 161 b _C_LABEL(panic) 162 163abortdatamsg: 164 .asciz "abortdata" 165 .align 0 166 167/* 168 * address_exception_entry: 169 * 170 * Handler for the Address Exception exception. 171 * 172 * NOTE: This exception isn't really used on arm32. We 173 * print a warning message to the console and then treat 174 * it like a Data Abort. 175 */ 176ASENTRY_NP(address_exception_entry) 177 mrs r1, cpsr_all 178 mrs r2, spsr_all 179 mov r3, lr 180 adr r0, Laddress_exception_msg 181 bl _C_LABEL(printf) /* XXX CLOBBERS LR!! */ 182 b data_abort_entry 183Laddress_exception_msg: 184 .asciz "Address Exception CPSR=0x%08x SPSR=0x%08x LR=0x%08x\n" 185 .balign 4 186 187/* 188 * General exception exit handler 189 * (Placed here to be within range of all the references to it) 190 * 191 * It exits straight away if not returning to USR mode. 192 * This loops around delivering any pending ASTs. 193 * Interrupts are disabled at suitable points to avoid ASTs 194 * being posted between testing and exit to user mode. 195 * 196 * This function uses PULLFRAMEFROMSVCANDEXIT and 197 * DO_AST_AND_RESTORE_ALIGNMENT_FAULTS thus should 198 * only be called if the exception handler used PUSHFRAMEINSVC 199 * followed by ENABLE_ALIGNMENT_FAULTS. 200 */ 201 202exception_exit: 203 DO_AST_AND_RESTORE_ALIGNMENT_FAULTS 204 PULLFRAMEFROMSVCANDEXIT 205 206/* 207 * undefined_entry: 208 * 209 * Handler for the Undefined Instruction exception. 210 * 211 * We indirect the undefined vector via the handler address 212 * in the data area. Entry to the undefined handler must 213 * look like direct entry from the vector. 214 */ 215ASENTRY_NP(undefined_entry) 216 stmfd sp!, {r0, r1} 217 GET_CURCPU(r0) 218 ldr r1, [sp], #0x0004 219 str r1, [r0, #CI_UNDEFSAVE]! 220 ldr r1, [sp], #0x0004 221 str r1, [r0, #0x0004] 222 ldmia r0, {r0, r1, pc} 223 224/* 225 * assembly bounce code for calling the kernel 226 * undefined instruction handler. This uses 227 * a standard trap frame and is called in SVC mode. 228 */ 229 230ENTRY_NP(undefinedinstruction_bounce) 231 PUSHFRAMEINSVC 232 ENABLE_ALIGNMENT_FAULTS 233 234 mov r0, sp 235 adr lr, exception_exit 236 b _C_LABEL(undefinedinstruction) 237