1/* 2 * vectors - Generic ARM exception table code 3 * 4 * Copyright (c) 1998 Dan Malek <dmalek@jlc.net> 5 * Copyright (c) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> 6 * Copyright (c) 2000 Wolfgang Denk <wd@denx.de> 7 * Copyright (c) 2001 Alex Züpke <azu@sysgo.de> 8 * Copyright (c) 2001 Marius Gröger <mag@sysgo.de> 9 * Copyright (c) 2002 Alex Züpke <azu@sysgo.de> 10 * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de> 11 * Copyright (c) 2002 Kyle Harris <kharris@nexus-tech.net> 12 * 13 * SPDX-License-Identifier: GPL-2.0+ 14 */ 15 16#include <config.h> 17 18/* 19 ************************************************************************* 20 * 21 * Symbol _start is referenced elsewhere, so make it global 22 * 23 ************************************************************************* 24 */ 25 26.globl _start 27 28/* 29 ************************************************************************* 30 * 31 * Vectors have their own section so linker script can map them easily 32 * 33 ************************************************************************* 34 */ 35 36 .section ".vectors", "ax" 37 38/* 39 ************************************************************************* 40 * 41 * Exception vectors as described in ARM reference manuals 42 * 43 * Uses indirect branch to allow reaching handlers anywhere in memory. 44 * 45 ************************************************************************* 46 */ 47 48_start: 49 50#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG 51 .word CONFIG_SYS_DV_NOR_BOOT_CFG 52#endif 53 54 b reset 55 ldr pc, _undefined_instruction 56 ldr pc, _software_interrupt 57 ldr pc, _prefetch_abort 58 ldr pc, _data_abort 59 ldr pc, _not_used 60 ldr pc, _irq 61 ldr pc, _fiq 62 63#ifdef CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK 64/* 65 * Various SoCs need something special and SoC-specific up front in 66 * order to boot, allow them to set that in their boot0.h file and then 67 * use it here. 68 */ 69#include <asm/arch/boot0.h> 70#endif 71 72/* 73 ************************************************************************* 74 * 75 * Indirect vectors table 76 * 77 * Symbols referenced here must be defined somewhere else 78 * 79 ************************************************************************* 80 */ 81 82 .globl _undefined_instruction 83 .globl _software_interrupt 84 .globl _prefetch_abort 85 .globl _data_abort 86 .globl _not_used 87 .globl _irq 88 .globl _fiq 89 90_undefined_instruction: .word undefined_instruction 91_software_interrupt: .word software_interrupt 92_prefetch_abort: .word prefetch_abort 93_data_abort: .word data_abort 94_not_used: .word not_used 95_irq: .word irq 96_fiq: .word fiq 97 98 .balignl 16,0xdeadbeef 99 100/* 101 ************************************************************************* 102 * 103 * Interrupt handling 104 * 105 ************************************************************************* 106 */ 107 108/* SPL interrupt handling: just hang */ 109 110#ifdef CONFIG_SPL_BUILD 111 112 .align 5 113undefined_instruction: 114software_interrupt: 115prefetch_abort: 116data_abort: 117not_used: 118irq: 119fiq: 120 1211: 122 bl 1b /* hang and never return */ 123 124#else /* !CONFIG_SPL_BUILD */ 125 126/* IRQ stack memory (calculated at run-time) + 8 bytes */ 127.globl IRQ_STACK_START_IN 128IRQ_STACK_START_IN: 129 .word 0x0badc0de 130 131@ 132@ IRQ stack frame. 133@ 134#define S_FRAME_SIZE 72 135 136#define S_OLD_R0 68 137#define S_PSR 64 138#define S_PC 60 139#define S_LR 56 140#define S_SP 52 141 142#define S_IP 48 143#define S_FP 44 144#define S_R10 40 145#define S_R9 36 146#define S_R8 32 147#define S_R7 28 148#define S_R6 24 149#define S_R5 20 150#define S_R4 16 151#define S_R3 12 152#define S_R2 8 153#define S_R1 4 154#define S_R0 0 155 156#define MODE_SVC 0x13 157#define I_BIT 0x80 158 159/* 160 * use bad_save_user_regs for abort/prefetch/undef/swi ... 161 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling 162 */ 163 164 .macro bad_save_user_regs 165 @ carve out a frame on current user stack 166 sub sp, sp, #S_FRAME_SIZE 167 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 168 ldr r2, IRQ_STACK_START_IN 169 @ get values for "aborted" pc and cpsr (into parm regs) 170 ldmia r2, {r2 - r3} 171 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack 172 add r5, sp, #S_SP 173 mov r1, lr 174 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr 175 mov r0, sp @ save current stack into r0 (param register) 176 .endm 177 178 .macro irq_save_user_regs 179 sub sp, sp, #S_FRAME_SIZE 180 stmia sp, {r0 - r12} @ Calling r0-r12 181 @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. 182 add r8, sp, #S_PC 183 stmdb r8, {sp, lr}^ @ Calling SP, LR 184 str lr, [r8, #0] @ Save calling PC 185 mrs r6, spsr 186 str r6, [r8, #4] @ Save CPSR 187 str r0, [r8, #8] @ Save OLD_R0 188 mov r0, sp 189 .endm 190 191 .macro irq_restore_user_regs 192 ldmia sp, {r0 - lr}^ @ Calling r0 - lr 193 mov r0, r0 194 ldr lr, [sp, #S_PC] @ Get PC 195 add sp, sp, #S_FRAME_SIZE 196 subs pc, lr, #4 @ return & move spsr_svc into cpsr 197 .endm 198 199 .macro get_bad_stack 200 ldr r13, IRQ_STACK_START_IN @ setup our mode stack 201 202 str lr, [r13] @ save caller lr in position 0 of saved stack 203 mrs lr, spsr @ get the spsr 204 str lr, [r13, #4] @ save spsr in position 1 of saved stack 205 mov r13, #MODE_SVC @ prepare SVC-Mode 206 @ msr spsr_c, r13 207 msr spsr, r13 @ switch modes, make sure moves will execute 208 mov lr, pc @ capture return pc 209 movs pc, lr @ jump to next instruction & switch modes. 210 .endm 211 212 .macro get_irq_stack @ setup IRQ stack 213 ldr sp, IRQ_STACK_START 214 .endm 215 216 .macro get_fiq_stack @ setup FIQ stack 217 ldr sp, FIQ_STACK_START 218 .endm 219 220/* 221 * exception handlers 222 */ 223 224 .align 5 225undefined_instruction: 226 get_bad_stack 227 bad_save_user_regs 228 bl do_undefined_instruction 229 230 .align 5 231software_interrupt: 232 get_bad_stack 233 bad_save_user_regs 234 bl do_software_interrupt 235 236 .align 5 237prefetch_abort: 238 get_bad_stack 239 bad_save_user_regs 240 bl do_prefetch_abort 241 242 .align 5 243data_abort: 244 get_bad_stack 245 bad_save_user_regs 246 bl do_data_abort 247 248 .align 5 249not_used: 250 get_bad_stack 251 bad_save_user_regs 252 bl do_not_used 253 254 255 .align 5 256irq: 257 get_bad_stack 258 bad_save_user_regs 259 bl do_irq 260 261 .align 5 262fiq: 263 get_bad_stack 264 bad_save_user_regs 265 bl do_fiq 266 267#endif /* CONFIG_SPL_BUILD */ 268