1/* 2 * Copyright 2012, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Ithamar R. Adema <ithamar@upgrade-android.com> 7 * 8 */ 9 10#include <asm_defs.h> 11 12#define CPSR_MODE_MASK 0x1f 13#define CPSR_MODE_USR 0x10 14#define CPSR_MODE_FIQ 0x11 15#define CPSR_MODE_IRQ 0x12 16#define CPSR_MODE_SVC 0x13 17#define CPSR_MODE_ABT 0x17 18#define CPSR_MODE_UND 0x1b 19 20/* The following two macros are taken from FreeBSD... */ 21 22.macro PUSHFRAMEINSVC 23 stmdb sp, {r0-r3} /* Save 4 registers */ 24 mov r0, lr /* Save xxx32 r14 */ 25 mov r1, sp /* Save xxx32 sp */ 26 mrs r3, spsr /* Save xxx32 spsr */ 27 mrs r2, cpsr /* Get the CPSR */ 28 bic r2, r2, #(CPSR_MODE_MASK) /* Fix for SVC mode */ 29 orr r2, r2, #(CPSR_MODE_SVC) 30 msr cpsr_c, r2 /* Punch into SVC mode */ 31 mov r2, sp /* Save SVC sp */ 32 str r0, [sp, #-4]! /* Push return address */ 33 str lr, [sp, #-4]! /* Push SVC lr */ 34 str r2, [sp, #-4]! /* Push SVC sp */ 35 msr spsr_all, r3 /* Restore correct spsr */ 36 ldmdb r1, {r0-r3} /* Restore 4 regs from xxx mode */ 37 sub sp, sp, #(4*15) /* Adjust the stack pointer */ 38 stmia sp, {r0-r12} /* Push the user mode registers */ 39 add r0, sp, #(4*13) /* Adjust the stack pointer */ 40 stmia r0, {r13-r14}^ /* Push the user mode registers */ 41 mov r0, r0 /* NOP for previous instruction */ 42 mrs r0, spsr_all 43 str r0, [sp, #-4]! /* Save spsr */ 44.endm 45 46.macro PULLFRAMEFROMSVCANDEXIT 47 ldr r0, [sp], #0x0004 /* Get the SPSR from stack */ 48 msr spsr_all, r0 /* restore SPSR */ 49 ldmia sp, {r0-r14}^ /* Restore registers (usr mode) */ 50 mov r0, r0 /* NOP for previous instruction */ 51 add sp, sp, #(4*15) /* Adjust the stack pointer */ 52 ldmia sp, {sp, lr, pc}^ /* Restore lr and exit */ 53.endm 54 55.text 56 57.globl _vectors_start 58_vectors_start: 59 ldr pc, _arm_reset 60 ldr pc, _arm_undefined 61 ldr pc, _arm_syscall 62 ldr pc, _arm_prefetch_abort 63 ldr pc, _arm_data_abort 64 ldr pc, _arm_reserved 65 ldr pc, _arm_irq 66 ldr pc, _arm_fiq 67 68 69_arm_reset: 70 .word arm_reserved // actually reset, but not used when mapped 71 72_arm_undefined: 73 .word arm_undefined 74 75_arm_syscall: 76 .word arm_syscall 77 78_arm_prefetch_abort: 79 .word arm_prefetch_abort 80 81_arm_data_abort: 82 .word arm_data_abort 83 84_arm_reserved: 85 .word arm_reserved 86 87_arm_irq: 88 .word arm_irq 89 90_arm_fiq: 91 .word arm_fiq 92 93 94.globl _vectors_end 95_vectors_end: 96 .rept 64 97 .word 0xdeadbeef 98 .endr 99 100abort_stack: 101 .word . - 4 102 .word 0xdeadbeef 103 104 .rept 64 105 .word 0xcafebabe 106 .endr 107 108irq_stack: 109 .word . - 4 110 .word 0xcafebabe 111 112 .rept 64 113 .word 0xaaaabbbb 114 .endr 115 116fiq_stack: 117 .word . - 4 118 .word 0xaaaabbbb 119 120 .rept 64 121 .word 0xccccdddd 122 .endr 123 124und_stack: 125 .word . - 4 126 .word 0xccccdddd 127 128 129FUNCTION(arm_undefined): 130 PUSHFRAMEINSVC 131 132 mov r0, sp 133 bl arch_arm_undefined 134 135 PULLFRAMEFROMSVCANDEXIT 136FUNCTION_END(arm_undefined) 137 138 139FUNCTION(arm_syscall): 140 PUSHFRAMEINSVC 141 142 mov r0, sp 143 bl arch_arm_syscall 144 145 PULLFRAMEFROMSVCANDEXIT 146FUNCTION_END(arm_syscall) 147 148 149FUNCTION(arm_prefetch_abort): 150#ifdef __XSCALE__ 151 nop /* Make absolutely sure any pending */ 152 nop /* imprecise aborts have occurred. */ 153#endif 154 add lr, lr, #4 155 PUSHFRAMEINSVC 156 157 mov r0, sp 158 bl arch_arm_prefetch_abort 159 160 PULLFRAMEFROMSVCANDEXIT 161FUNCTION_END(arm_prefetch_abort) 162 163 164FUNCTION(arm_data_abort): 165#ifdef __XSCALE__ 166 nop /* Make absolutely sure any pending */ 167 nop /* imprecise aborts have occurred. */ 168#endif 169 sub lr, lr, #8 /* Adjust the lr */ 170 PUSHFRAMEINSVC 171 172 mov r0, sp 173 bl arch_arm_data_abort 174 175 PULLFRAMEFROMSVCANDEXIT 176FUNCTION_END(arm_data_abort) 177 178 179FUNCTION(arm_reserved): 180 b . 181FUNCTION_END(arm_reserved) 182 183 184FUNCTION(arm_irq): 185 sub lr, lr, #4 186 PUSHFRAMEINSVC 187 188 mov r0, sp /* iframe */ 189 bl arch_arm_irq 190 191 PULLFRAMEFROMSVCANDEXIT 192FUNCTION_END(arm_irq) 193 194 195FUNCTION(arm_fiq): 196 sub lr, lr, #4 197 PUSHFRAMEINSVC 198 199 mov r0, sp /* iframe */ 200 bl arch_arm_fiq 201 202 PULLFRAMEFROMSVCANDEXIT 203FUNCTION_END(arm_fiq) 204 205 206 207FUNCTION(arm_vector_init): 208 mrs r1, cpsr 209 bic r1, r1, #CPSR_MODE_MASK 210 211 /* move into modes and set initial sp */ 212 mov r0, r1 213 orr r0, r0, #CPSR_MODE_FIQ 214 msr cpsr_c, r0 215 ldr sp, fiq_stack 216 217 mov r0, r1 218 orr r0, r0, #CPSR_MODE_IRQ 219 msr cpsr_c, r0 220 ldr sp, irq_stack 221 222 mov r0, r1 223 orr r0, r0, #CPSR_MODE_ABT 224 msr cpsr_c, r0 225 ldr sp, abort_stack 226 227 mov r0, r1 228 orr r0, r0, #CPSR_MODE_UND 229 msr cpsr_c, r0 230 ldr sp, und_stack 231 232 /* ... and return back to supervisor mode */ 233 mov r0, r1 234 orr r0, r0, #CPSR_MODE_SVC 235 msr cpsr_c, r0 236 237 bx lr 238FUNCTION_END(arm_vector_init) 239