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