blob: b6b879339df6bdb88579423f7dc0a32e597f64c5 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001/* SPDX-License-Identifier: GPL-2.0+ */
Albert ARIBAUD9852cc62014-04-15 16:13:51 +02002/*
3 * vectors - Generic ARM exception table code
4 *
5 * Copyright (c) 1998 Dan Malek <dmalek@jlc.net>
6 * Copyright (c) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
7 * Copyright (c) 2000 Wolfgang Denk <wd@denx.de>
8 * Copyright (c) 2001 Alex Züpke <azu@sysgo.de>
9 * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
10 * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
11 * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
12 * Copyright (c) 2002 Kyle Harris <kharris@nexus-tech.net>
Albert ARIBAUD9852cc62014-04-15 16:13:51 +020013 */
14
Christian Riesch80c5a532014-07-07 11:07:25 +020015#include <config.h>
16
Albert ARIBAUD9852cc62014-04-15 16:13:51 +020017/*
Philipp Tomsichcc00f0e2017-10-10 16:21:01 +020018 * A macro to allow insertion of an ARM exception vector either
19 * for the non-boot0 case or by a boot0-header.
20 */
21 .macro ARM_VECTORS
Lokesh Vutlad9805842018-08-27 15:57:10 +053022#ifdef CONFIG_ARCH_K3
23 ldr pc, _reset
24#else
Philipp Tomsichcc00f0e2017-10-10 16:21:01 +020025 b reset
Lokesh Vutlad9805842018-08-27 15:57:10 +053026#endif
Pali Rohár40046d22022-04-06 16:20:19 +020027#if !CONFIG_IS_ENABLED(SYS_NO_VECTOR_TABLE)
Philipp Tomsichcc00f0e2017-10-10 16:21:01 +020028 ldr pc, _undefined_instruction
29 ldr pc, _software_interrupt
30 ldr pc, _prefetch_abort
31 ldr pc, _data_abort
32 ldr pc, _not_used
33 ldr pc, _irq
34 ldr pc, _fiq
Pali Rohár40046d22022-04-06 16:20:19 +020035#endif
Philipp Tomsichcc00f0e2017-10-10 16:21:01 +020036 .endm
37
38
39/*
Albert ARIBAUD9852cc62014-04-15 16:13:51 +020040 *************************************************************************
41 *
42 * Symbol _start is referenced elsewhere, so make it global
43 *
44 *************************************************************************
45 */
46
47.globl _start
48
49/*
50 *************************************************************************
51 *
52 * Vectors have their own section so linker script can map them easily
53 *
54 *************************************************************************
55 */
56
Georges Savoundararadjc3810842014-10-28 23:16:10 +010057 .section ".vectors", "ax"
Albert ARIBAUD9852cc62014-04-15 16:13:51 +020058
Philipp Tomsichcc00f0e2017-10-10 16:21:01 +020059#if defined(CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK)
60/*
61 * Various SoCs need something special and SoC-specific up front in
62 * order to boot, allow them to set that in their boot0.h file and then
63 * use it here.
64 *
65 * To allow a boot0 hook to insert a 'special' sequence after the vector
66 * table (e.g. for the socfpga), the presence of a boot0 hook supresses
67 * the below vector table and assumes that the vector table is filled in
68 * by the boot0 hook. The requirements for a boot0 hook thus are:
69 * (1) defines '_start:' as appropriate
70 * (2) inserts the vector table using ARM_VECTORS as appropriate
71 */
72#include <asm/arch/boot0.h>
Philipp Tomsichcc00f0e2017-10-10 16:21:01 +020073#else
74
Albert ARIBAUD9852cc62014-04-15 16:13:51 +020075/*
76 *************************************************************************
77 *
78 * Exception vectors as described in ARM reference manuals
79 *
80 * Uses indirect branch to allow reaching handlers anywhere in memory.
81 *
82 *************************************************************************
83 */
84
Benoît Thébaudeaudf66ec62014-09-03 23:32:34 +020085_start:
Tom Rini6a5dccc2022-11-16 13:10:41 -050086#ifdef CFG_SYS_DV_NOR_BOOT_CFG
87 .word CFG_SYS_DV_NOR_BOOT_CFG
Albert ARIBAUD9852cc62014-04-15 16:13:51 +020088#endif
Philipp Tomsichcc00f0e2017-10-10 16:21:01 +020089 ARM_VECTORS
90#endif /* !defined(CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK) */
Andre Przywara48321ba2016-05-31 10:45:06 -070091
Pali Rohár40046d22022-04-06 16:20:19 +020092#if !CONFIG_IS_ENABLED(SYS_NO_VECTOR_TABLE)
Albert ARIBAUD9852cc62014-04-15 16:13:51 +020093/*
94 *************************************************************************
95 *
96 * Indirect vectors table
97 *
98 * Symbols referenced here must be defined somewhere else
99 *
100 *************************************************************************
101 */
102
Lokesh Vutlad9805842018-08-27 15:57:10 +0530103 .globl _reset
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200104 .globl _undefined_instruction
105 .globl _software_interrupt
106 .globl _prefetch_abort
107 .globl _data_abort
108 .globl _not_used
109 .globl _irq
110 .globl _fiq
111
Lokesh Vutlad9805842018-08-27 15:57:10 +0530112#ifdef CONFIG_ARCH_K3
113_reset: .word reset
114#endif
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200115_undefined_instruction: .word undefined_instruction
116_software_interrupt: .word software_interrupt
117_prefetch_abort: .word prefetch_abort
118_data_abort: .word data_abort
119_not_used: .word not_used
120_irq: .word irq
121_fiq: .word fiq
122
123 .balignl 16,0xdeadbeef
Pali Rohár40046d22022-04-06 16:20:19 +0200124#endif
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200125
126/*
127 *************************************************************************
128 *
129 * Interrupt handling
130 *
131 *************************************************************************
132 */
133
134/* SPL interrupt handling: just hang */
135
136#ifdef CONFIG_SPL_BUILD
137
Pali Rohár40046d22022-04-06 16:20:19 +0200138#if !CONFIG_IS_ENABLED(SYS_NO_VECTOR_TABLE)
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200139 .align 5
140undefined_instruction:
Csókás Bence2c6e70b2023-12-19 14:33:18 +0100141#if CONFIG_IS_ENABLED(USE_SEPARATE_FAULT_HANDLERS)
142 b undefined_instruction
143#endif
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200144software_interrupt:
Csókás Bence2c6e70b2023-12-19 14:33:18 +0100145#if CONFIG_IS_ENABLED(USE_SEPARATE_FAULT_HANDLERS)
146 b software_interrupt
147#endif
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200148prefetch_abort:
Csókás Bence2c6e70b2023-12-19 14:33:18 +0100149#if CONFIG_IS_ENABLED(USE_SEPARATE_FAULT_HANDLERS)
150 b prefetch_abort
151#endif
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200152data_abort:
Csókás Bence2c6e70b2023-12-19 14:33:18 +0100153#if CONFIG_IS_ENABLED(USE_SEPARATE_FAULT_HANDLERS)
154 b data_abort
155#endif
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200156not_used:
Csókás Bence2c6e70b2023-12-19 14:33:18 +0100157#if CONFIG_IS_ENABLED(USE_SEPARATE_FAULT_HANDLERS)
158 b not_used
159#endif
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200160irq:
Csókás Bence2c6e70b2023-12-19 14:33:18 +0100161#if CONFIG_IS_ENABLED(USE_SEPARATE_FAULT_HANDLERS)
162 b irq
163#endif
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200164fiq:
Albert ARIBAUD9852cc62014-04-15 16:13:51 +02001651:
Andrew F. Davisdf1f7e22018-06-11 14:04:17 -0500166 b 1b /* hang and never return */
Pali Rohár40046d22022-04-06 16:20:19 +0200167#endif
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200168
169#else /* !CONFIG_SPL_BUILD */
170
171/* IRQ stack memory (calculated at run-time) + 8 bytes */
172.globl IRQ_STACK_START_IN
173IRQ_STACK_START_IN:
Lothar Waßmannedb1a3f2017-06-08 10:16:36 +0200174#ifdef IRAM_BASE_ADDR
175 .word IRAM_BASE_ADDR + 0x20
176#else
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200177 .word 0x0badc0de
Lothar Waßmannedb1a3f2017-06-08 10:16:36 +0200178#endif
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200179
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200180@
181@ IRQ stack frame.
182@
183#define S_FRAME_SIZE 72
184
185#define S_OLD_R0 68
186#define S_PSR 64
187#define S_PC 60
188#define S_LR 56
189#define S_SP 52
190
191#define S_IP 48
192#define S_FP 44
193#define S_R10 40
194#define S_R9 36
195#define S_R8 32
196#define S_R7 28
197#define S_R6 24
198#define S_R5 20
199#define S_R4 16
200#define S_R3 12
201#define S_R2 8
202#define S_R1 4
203#define S_R0 0
204
205#define MODE_SVC 0x13
206#define I_BIT 0x80
207
208/*
209 * use bad_save_user_regs for abort/prefetch/undef/swi ...
210 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
211 */
212
213 .macro bad_save_user_regs
214 @ carve out a frame on current user stack
215 sub sp, sp, #S_FRAME_SIZE
216 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
217 ldr r2, IRQ_STACK_START_IN
218 @ get values for "aborted" pc and cpsr (into parm regs)
219 ldmia r2, {r2 - r3}
220 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
221 add r5, sp, #S_SP
222 mov r1, lr
223 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
224 mov r0, sp @ save current stack into r0 (param register)
225 .endm
226
227 .macro irq_save_user_regs
228 sub sp, sp, #S_FRAME_SIZE
229 stmia sp, {r0 - r12} @ Calling r0-r12
230 @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
231 add r8, sp, #S_PC
232 stmdb r8, {sp, lr}^ @ Calling SP, LR
233 str lr, [r8, #0] @ Save calling PC
234 mrs r6, spsr
235 str r6, [r8, #4] @ Save CPSR
236 str r0, [r8, #8] @ Save OLD_R0
237 mov r0, sp
238 .endm
239
240 .macro irq_restore_user_regs
241 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
242 mov r0, r0
243 ldr lr, [sp, #S_PC] @ Get PC
244 add sp, sp, #S_FRAME_SIZE
245 subs pc, lr, #4 @ return & move spsr_svc into cpsr
246 .endm
247
248 .macro get_bad_stack
249 ldr r13, IRQ_STACK_START_IN @ setup our mode stack
250
251 str lr, [r13] @ save caller lr in position 0 of saved stack
252 mrs lr, spsr @ get the spsr
253 str lr, [r13, #4] @ save spsr in position 1 of saved stack
254 mov r13, #MODE_SVC @ prepare SVC-Mode
255 @ msr spsr_c, r13
256 msr spsr, r13 @ switch modes, make sure moves will execute
257 mov lr, pc @ capture return pc
258 movs pc, lr @ jump to next instruction & switch modes.
259 .endm
260
Sean Andersone82259c2023-10-27 16:40:13 -0400261 .macro get_bad_stack_swi
262 sub r13, r13, #4 @ space on current stack for scratch reg.
263 str r0, [r13] @ save R0's value.
264 ldr r0, IRQ_STACK_START_IN @ get data regions start
265 str lr, [r0] @ save caller lr in position 0 of saved stack
266 mrs lr, spsr @ get the spsr
267 str lr, [r0, #4] @ save spsr in position 1 of saved stack
268 ldr lr, [r0] @ restore lr
269 ldr r0, [r13] @ restore r0
270 add r13, r13, #4 @ pop stack entry
271 .endm
272
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200273 .macro get_irq_stack @ setup IRQ stack
274 ldr sp, IRQ_STACK_START
275 .endm
276
277 .macro get_fiq_stack @ setup FIQ stack
278 ldr sp, FIQ_STACK_START
279 .endm
280
281/*
282 * exception handlers
283 */
284
285 .align 5
286undefined_instruction:
287 get_bad_stack
288 bad_save_user_regs
289 bl do_undefined_instruction
290
291 .align 5
292software_interrupt:
Sean Andersone82259c2023-10-27 16:40:13 -0400293 get_bad_stack_swi
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200294 bad_save_user_regs
295 bl do_software_interrupt
Sean Andersonbf641f22023-10-27 16:40:15 -0400296#if CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK)
297 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
298 mov r0, r0
299 ldr lr, [sp, #S_PC] @ Get PC
300 add sp, sp, #S_FRAME_SIZE
301 movs pc, lr @ return & move spsr_svc into cpsr
302#endif
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200303
304 .align 5
305prefetch_abort:
306 get_bad_stack
307 bad_save_user_regs
308 bl do_prefetch_abort
309
310 .align 5
311data_abort:
312 get_bad_stack
313 bad_save_user_regs
314 bl do_data_abort
315
316 .align 5
317not_used:
318 get_bad_stack
319 bad_save_user_regs
320 bl do_not_used
321
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200322
323 .align 5
324irq:
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200325 get_bad_stack
326 bad_save_user_regs
327 bl do_irq
328
329 .align 5
330fiq:
331 get_bad_stack
332 bad_save_user_regs
333 bl do_fiq
334
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200335#endif /* CONFIG_SPL_BUILD */