blob: 2ca6e2494a7ad4dac2c2ae4ab4c8d573b6eb3f63 [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
Philipp Tomsichcc00f0e2017-10-10 16:21:01 +020027 ldr pc, _undefined_instruction
28 ldr pc, _software_interrupt
29 ldr pc, _prefetch_abort
30 ldr pc, _data_abort
31 ldr pc, _not_used
32 ldr pc, _irq
33 ldr pc, _fiq
34 .endm
35
36
37/*
Albert ARIBAUD9852cc62014-04-15 16:13:51 +020038 *************************************************************************
39 *
40 * Symbol _start is referenced elsewhere, so make it global
41 *
42 *************************************************************************
43 */
44
45.globl _start
46
47/*
48 *************************************************************************
49 *
50 * Vectors have their own section so linker script can map them easily
51 *
52 *************************************************************************
53 */
54
Georges Savoundararadjc3810842014-10-28 23:16:10 +010055 .section ".vectors", "ax"
Albert ARIBAUD9852cc62014-04-15 16:13:51 +020056
Philipp Tomsichcc00f0e2017-10-10 16:21:01 +020057#if defined(CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK)
58/*
59 * Various SoCs need something special and SoC-specific up front in
60 * order to boot, allow them to set that in their boot0.h file and then
61 * use it here.
62 *
63 * To allow a boot0 hook to insert a 'special' sequence after the vector
64 * table (e.g. for the socfpga), the presence of a boot0 hook supresses
65 * the below vector table and assumes that the vector table is filled in
66 * by the boot0 hook. The requirements for a boot0 hook thus are:
67 * (1) defines '_start:' as appropriate
68 * (2) inserts the vector table using ARM_VECTORS as appropriate
69 */
70#include <asm/arch/boot0.h>
71
72#else
73
Albert ARIBAUD9852cc62014-04-15 16:13:51 +020074/*
75 *************************************************************************
76 *
77 * Exception vectors as described in ARM reference manuals
78 *
79 * Uses indirect branch to allow reaching handlers anywhere in memory.
80 *
81 *************************************************************************
82 */
83
Benoît Thébaudeaudf66ec62014-09-03 23:32:34 +020084_start:
Albert ARIBAUD9852cc62014-04-15 16:13:51 +020085#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG
86 .word CONFIG_SYS_DV_NOR_BOOT_CFG
87#endif
Philipp Tomsichcc00f0e2017-10-10 16:21:01 +020088 ARM_VECTORS
89#endif /* !defined(CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK) */
Andre Przywara48321ba2016-05-31 10:45:06 -070090
Albert ARIBAUD9852cc62014-04-15 16:13:51 +020091/*
92 *************************************************************************
93 *
94 * Indirect vectors table
95 *
96 * Symbols referenced here must be defined somewhere else
97 *
98 *************************************************************************
99 */
100
Lokesh Vutlad9805842018-08-27 15:57:10 +0530101 .globl _reset
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200102 .globl _undefined_instruction
103 .globl _software_interrupt
104 .globl _prefetch_abort
105 .globl _data_abort
106 .globl _not_used
107 .globl _irq
108 .globl _fiq
109
Lokesh Vutlad9805842018-08-27 15:57:10 +0530110#ifdef CONFIG_ARCH_K3
111_reset: .word reset
112#endif
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200113_undefined_instruction: .word undefined_instruction
114_software_interrupt: .word software_interrupt
115_prefetch_abort: .word prefetch_abort
116_data_abort: .word data_abort
117_not_used: .word not_used
118_irq: .word irq
119_fiq: .word fiq
120
121 .balignl 16,0xdeadbeef
122
123/*
124 *************************************************************************
125 *
126 * Interrupt handling
127 *
128 *************************************************************************
129 */
130
131/* SPL interrupt handling: just hang */
132
133#ifdef CONFIG_SPL_BUILD
134
135 .align 5
136undefined_instruction:
137software_interrupt:
138prefetch_abort:
139data_abort:
140not_used:
141irq:
142fiq:
Albert ARIBAUD9852cc62014-04-15 16:13:51 +02001431:
Andrew F. Davisdf1f7e22018-06-11 14:04:17 -0500144 b 1b /* hang and never return */
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200145
146#else /* !CONFIG_SPL_BUILD */
147
148/* IRQ stack memory (calculated at run-time) + 8 bytes */
149.globl IRQ_STACK_START_IN
150IRQ_STACK_START_IN:
Lothar Waßmannedb1a3f2017-06-08 10:16:36 +0200151#ifdef IRAM_BASE_ADDR
152 .word IRAM_BASE_ADDR + 0x20
153#else
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200154 .word 0x0badc0de
Lothar Waßmannedb1a3f2017-06-08 10:16:36 +0200155#endif
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200156
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200157@
158@ IRQ stack frame.
159@
160#define S_FRAME_SIZE 72
161
162#define S_OLD_R0 68
163#define S_PSR 64
164#define S_PC 60
165#define S_LR 56
166#define S_SP 52
167
168#define S_IP 48
169#define S_FP 44
170#define S_R10 40
171#define S_R9 36
172#define S_R8 32
173#define S_R7 28
174#define S_R6 24
175#define S_R5 20
176#define S_R4 16
177#define S_R3 12
178#define S_R2 8
179#define S_R1 4
180#define S_R0 0
181
182#define MODE_SVC 0x13
183#define I_BIT 0x80
184
185/*
186 * use bad_save_user_regs for abort/prefetch/undef/swi ...
187 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
188 */
189
190 .macro bad_save_user_regs
191 @ carve out a frame on current user stack
192 sub sp, sp, #S_FRAME_SIZE
193 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
194 ldr r2, IRQ_STACK_START_IN
195 @ get values for "aborted" pc and cpsr (into parm regs)
196 ldmia r2, {r2 - r3}
197 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
198 add r5, sp, #S_SP
199 mov r1, lr
200 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
201 mov r0, sp @ save current stack into r0 (param register)
202 .endm
203
204 .macro irq_save_user_regs
205 sub sp, sp, #S_FRAME_SIZE
206 stmia sp, {r0 - r12} @ Calling r0-r12
207 @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
208 add r8, sp, #S_PC
209 stmdb r8, {sp, lr}^ @ Calling SP, LR
210 str lr, [r8, #0] @ Save calling PC
211 mrs r6, spsr
212 str r6, [r8, #4] @ Save CPSR
213 str r0, [r8, #8] @ Save OLD_R0
214 mov r0, sp
215 .endm
216
217 .macro irq_restore_user_regs
218 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
219 mov r0, r0
220 ldr lr, [sp, #S_PC] @ Get PC
221 add sp, sp, #S_FRAME_SIZE
222 subs pc, lr, #4 @ return & move spsr_svc into cpsr
223 .endm
224
225 .macro get_bad_stack
226 ldr r13, IRQ_STACK_START_IN @ setup our mode stack
227
228 str lr, [r13] @ save caller lr in position 0 of saved stack
229 mrs lr, spsr @ get the spsr
230 str lr, [r13, #4] @ save spsr in position 1 of saved stack
231 mov r13, #MODE_SVC @ prepare SVC-Mode
232 @ msr spsr_c, r13
233 msr spsr, r13 @ switch modes, make sure moves will execute
234 mov lr, pc @ capture return pc
235 movs pc, lr @ jump to next instruction & switch modes.
236 .endm
237
238 .macro get_irq_stack @ setup IRQ stack
239 ldr sp, IRQ_STACK_START
240 .endm
241
242 .macro get_fiq_stack @ setup FIQ stack
243 ldr sp, FIQ_STACK_START
244 .endm
245
246/*
247 * exception handlers
248 */
249
250 .align 5
251undefined_instruction:
252 get_bad_stack
253 bad_save_user_regs
254 bl do_undefined_instruction
255
256 .align 5
257software_interrupt:
258 get_bad_stack
259 bad_save_user_regs
260 bl do_software_interrupt
261
262 .align 5
263prefetch_abort:
264 get_bad_stack
265 bad_save_user_regs
266 bl do_prefetch_abort
267
268 .align 5
269data_abort:
270 get_bad_stack
271 bad_save_user_regs
272 bl do_data_abort
273
274 .align 5
275not_used:
276 get_bad_stack
277 bad_save_user_regs
278 bl do_not_used
279
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200280
281 .align 5
282irq:
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200283 get_bad_stack
284 bad_save_user_regs
285 bl do_irq
286
287 .align 5
288fiq:
289 get_bad_stack
290 bad_save_user_regs
291 bl do_fiq
292
Albert ARIBAUD9852cc62014-04-15 16:13:51 +0200293#endif /* CONFIG_SPL_BUILD */