blob: a54c84b062b1fa1f80a6dce5ce9e84c01354ad30 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001/* SPDX-License-Identifier: GPL-2.0+ */
Albert ARIBAUD41623c92014-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 ARIBAUD41623c92014-04-15 16:13:51 +020013 */
14
Christian Rieschdb993fc2014-07-07 11:07:25 +020015#include <config.h>
16
Albert ARIBAUD41623c92014-04-15 16:13:51 +020017/*
Philipp Tomsichef70a422017-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 Vutlaf70b72e2018-08-27 15:57:10 +053022#ifdef CONFIG_ARCH_K3
23 ldr pc, _reset
24#else
Philipp Tomsichef70a422017-10-10 16:21:01 +020025 b reset
Lokesh Vutlaf70b72e2018-08-27 15:57:10 +053026#endif
Pali Rohár5165d2a2022-04-06 16:20:19 +020027#if !CONFIG_IS_ENABLED(SYS_NO_VECTOR_TABLE)
Philipp Tomsichef70a422017-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ár5165d2a2022-04-06 16:20:19 +020035#endif
Philipp Tomsichef70a422017-10-10 16:21:01 +020036 .endm
37
38
39/*
Albert ARIBAUD41623c92014-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 Savoundararadjc57a6422014-10-28 23:16:10 +010057 .section ".vectors", "ax"
Albert ARIBAUD41623c92014-04-15 16:13:51 +020058
Philipp Tomsichef70a422017-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 Tomsichef70a422017-10-10 16:21:01 +020073#else
74
Albert ARIBAUD41623c92014-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ébaudeaua7f99bf2014-09-03 23:32:34 +020085_start:
Albert ARIBAUD41623c92014-04-15 16:13:51 +020086#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG
87 .word CONFIG_SYS_DV_NOR_BOOT_CFG
88#endif
Philipp Tomsichef70a422017-10-10 16:21:01 +020089 ARM_VECTORS
90#endif /* !defined(CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK) */
Andre Przywaracdaa6332016-05-31 10:45:06 -070091
Pali Rohár5165d2a2022-04-06 16:20:19 +020092#if !CONFIG_IS_ENABLED(SYS_NO_VECTOR_TABLE)
Albert ARIBAUD41623c92014-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 Vutlaf70b72e2018-08-27 15:57:10 +0530103 .globl _reset
Albert ARIBAUD41623c92014-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 Vutlaf70b72e2018-08-27 15:57:10 +0530112#ifdef CONFIG_ARCH_K3
113_reset: .word reset
114#endif
Albert ARIBAUD41623c92014-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ár5165d2a2022-04-06 16:20:19 +0200124#endif
Albert ARIBAUD41623c92014-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ár5165d2a2022-04-06 16:20:19 +0200138#if !CONFIG_IS_ENABLED(SYS_NO_VECTOR_TABLE)
Albert ARIBAUD41623c92014-04-15 16:13:51 +0200139 .align 5
140undefined_instruction:
141software_interrupt:
142prefetch_abort:
143data_abort:
144not_used:
145irq:
146fiq:
Albert ARIBAUD41623c92014-04-15 16:13:51 +02001471:
Andrew F. Davisa1b73c12018-06-11 14:04:17 -0500148 b 1b /* hang and never return */
Pali Rohár5165d2a2022-04-06 16:20:19 +0200149#endif
Albert ARIBAUD41623c92014-04-15 16:13:51 +0200150
151#else /* !CONFIG_SPL_BUILD */
152
153/* IRQ stack memory (calculated at run-time) + 8 bytes */
154.globl IRQ_STACK_START_IN
155IRQ_STACK_START_IN:
Lothar Waßmann69c5d762017-06-08 10:16:36 +0200156#ifdef IRAM_BASE_ADDR
157 .word IRAM_BASE_ADDR + 0x20
158#else
Albert ARIBAUD41623c92014-04-15 16:13:51 +0200159 .word 0x0badc0de
Lothar Waßmann69c5d762017-06-08 10:16:36 +0200160#endif
Albert ARIBAUD41623c92014-04-15 16:13:51 +0200161
Albert ARIBAUD41623c92014-04-15 16:13:51 +0200162@
163@ IRQ stack frame.
164@
165#define S_FRAME_SIZE 72
166
167#define S_OLD_R0 68
168#define S_PSR 64
169#define S_PC 60
170#define S_LR 56
171#define S_SP 52
172
173#define S_IP 48
174#define S_FP 44
175#define S_R10 40
176#define S_R9 36
177#define S_R8 32
178#define S_R7 28
179#define S_R6 24
180#define S_R5 20
181#define S_R4 16
182#define S_R3 12
183#define S_R2 8
184#define S_R1 4
185#define S_R0 0
186
187#define MODE_SVC 0x13
188#define I_BIT 0x80
189
190/*
191 * use bad_save_user_regs for abort/prefetch/undef/swi ...
192 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
193 */
194
195 .macro bad_save_user_regs
196 @ carve out a frame on current user stack
197 sub sp, sp, #S_FRAME_SIZE
198 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
199 ldr r2, IRQ_STACK_START_IN
200 @ get values for "aborted" pc and cpsr (into parm regs)
201 ldmia r2, {r2 - r3}
202 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
203 add r5, sp, #S_SP
204 mov r1, lr
205 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
206 mov r0, sp @ save current stack into r0 (param register)
207 .endm
208
209 .macro irq_save_user_regs
210 sub sp, sp, #S_FRAME_SIZE
211 stmia sp, {r0 - r12} @ Calling r0-r12
212 @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
213 add r8, sp, #S_PC
214 stmdb r8, {sp, lr}^ @ Calling SP, LR
215 str lr, [r8, #0] @ Save calling PC
216 mrs r6, spsr
217 str r6, [r8, #4] @ Save CPSR
218 str r0, [r8, #8] @ Save OLD_R0
219 mov r0, sp
220 .endm
221
222 .macro irq_restore_user_regs
223 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
224 mov r0, r0
225 ldr lr, [sp, #S_PC] @ Get PC
226 add sp, sp, #S_FRAME_SIZE
227 subs pc, lr, #4 @ return & move spsr_svc into cpsr
228 .endm
229
230 .macro get_bad_stack
231 ldr r13, IRQ_STACK_START_IN @ setup our mode stack
232
233 str lr, [r13] @ save caller lr in position 0 of saved stack
234 mrs lr, spsr @ get the spsr
235 str lr, [r13, #4] @ save spsr in position 1 of saved stack
236 mov r13, #MODE_SVC @ prepare SVC-Mode
237 @ msr spsr_c, r13
238 msr spsr, r13 @ switch modes, make sure moves will execute
239 mov lr, pc @ capture return pc
240 movs pc, lr @ jump to next instruction & switch modes.
241 .endm
242
243 .macro get_irq_stack @ setup IRQ stack
244 ldr sp, IRQ_STACK_START
245 .endm
246
247 .macro get_fiq_stack @ setup FIQ stack
248 ldr sp, FIQ_STACK_START
249 .endm
250
251/*
252 * exception handlers
253 */
254
255 .align 5
256undefined_instruction:
257 get_bad_stack
258 bad_save_user_regs
259 bl do_undefined_instruction
260
261 .align 5
262software_interrupt:
263 get_bad_stack
264 bad_save_user_regs
265 bl do_software_interrupt
266
267 .align 5
268prefetch_abort:
269 get_bad_stack
270 bad_save_user_regs
271 bl do_prefetch_abort
272
273 .align 5
274data_abort:
275 get_bad_stack
276 bad_save_user_regs
277 bl do_data_abort
278
279 .align 5
280not_used:
281 get_bad_stack
282 bad_save_user_regs
283 bl do_not_used
284
Albert ARIBAUD41623c92014-04-15 16:13:51 +0200285
286 .align 5
287irq:
288 get_bad_stack
289 bad_save_user_regs
290 bl do_irq
291
292 .align 5
293fiq:
294 get_bad_stack
295 bad_save_user_regs
296 bl do_fiq
297
Albert ARIBAUD41623c92014-04-15 16:13:51 +0200298#endif /* CONFIG_SPL_BUILD */