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: 1201: 121 bl 1b /* hang and never return */ 122 123#else /* !CONFIG_SPL_BUILD */ 124 125/* IRQ stack memory (calculated at run-time) + 8 bytes */ 126.globl IRQ_STACK_START_IN 127IRQ_STACK_START_IN: 128#ifdef IRAM_BASE_ADDR 129 .word IRAM_BASE_ADDR + 0x20 130#else 131 .word 0x0badc0de 132#endif 133 134@ 135@ IRQ stack frame. 136@ 137#define S_FRAME_SIZE 72 138 139#define S_OLD_R0 68 140#define S_PSR 64 141#define S_PC 60 142#define S_LR 56 143#define S_SP 52 144 145#define S_IP 48 146#define S_FP 44 147#define S_R10 40 148#define S_R9 36 149#define S_R8 32 150#define S_R7 28 151#define S_R6 24 152#define S_R5 20 153#define S_R4 16 154#define S_R3 12 155#define S_R2 8 156#define S_R1 4 157#define S_R0 0 158 159#define MODE_SVC 0x13 160#define I_BIT 0x80 161 162/* 163 * use bad_save_user_regs for abort/prefetch/undef/swi ... 164 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling 165 */ 166 167 .macro bad_save_user_regs 168 @ carve out a frame on current user stack 169 sub sp, sp, #S_FRAME_SIZE 170 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 171 ldr r2, IRQ_STACK_START_IN 172 @ get values for "aborted" pc and cpsr (into parm regs) 173 ldmia r2, {r2 - r3} 174 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack 175 add r5, sp, #S_SP 176 mov r1, lr 177 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr 178 mov r0, sp @ save current stack into r0 (param register) 179 .endm 180 181 .macro irq_save_user_regs 182 sub sp, sp, #S_FRAME_SIZE 183 stmia sp, {r0 - r12} @ Calling r0-r12 184 @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. 185 add r8, sp, #S_PC 186 stmdb r8, {sp, lr}^ @ Calling SP, LR 187 str lr, [r8, #0] @ Save calling PC 188 mrs r6, spsr 189 str r6, [r8, #4] @ Save CPSR 190 str r0, [r8, #8] @ Save OLD_R0 191 mov r0, sp 192 .endm 193 194 .macro irq_restore_user_regs 195 ldmia sp, {r0 - lr}^ @ Calling r0 - lr 196 mov r0, r0 197 ldr lr, [sp, #S_PC] @ Get PC 198 add sp, sp, #S_FRAME_SIZE 199 subs pc, lr, #4 @ return & move spsr_svc into cpsr 200 .endm 201 202 .macro get_bad_stack 203 ldr r13, IRQ_STACK_START_IN @ setup our mode stack 204 205 str lr, [r13] @ save caller lr in position 0 of saved stack 206 mrs lr, spsr @ get the spsr 207 str lr, [r13, #4] @ save spsr in position 1 of saved stack 208 mov r13, #MODE_SVC @ prepare SVC-Mode 209 @ msr spsr_c, r13 210 msr spsr, r13 @ switch modes, make sure moves will execute 211 mov lr, pc @ capture return pc 212 movs pc, lr @ jump to next instruction & switch modes. 213 .endm 214 215 .macro get_irq_stack @ setup IRQ stack 216 ldr sp, IRQ_STACK_START 217 .endm 218 219 .macro get_fiq_stack @ setup FIQ stack 220 ldr sp, FIQ_STACK_START 221 .endm 222 223/* 224 * exception handlers 225 */ 226 227 .align 5 228undefined_instruction: 229 get_bad_stack 230 bad_save_user_regs 231 bl do_undefined_instruction 232 233 .align 5 234software_interrupt: 235 get_bad_stack 236 bad_save_user_regs 237 bl do_software_interrupt 238 239 .align 5 240prefetch_abort: 241 get_bad_stack 242 bad_save_user_regs 243 bl do_prefetch_abort 244 245 .align 5 246data_abort: 247 get_bad_stack 248 bad_save_user_regs 249 bl do_data_abort 250 251 .align 5 252not_used: 253 get_bad_stack 254 bad_save_user_regs 255 bl do_not_used 256 257 258 .align 5 259irq: 260 get_bad_stack 261 bad_save_user_regs 262 bl do_irq 263 264 .align 5 265fiq: 266 get_bad_stack 267 bad_save_user_regs 268 bl do_fiq 269 270#endif /* CONFIG_SPL_BUILD */ 271