blob: 5783df1ef2a6986eccc27438955d99450f697680 [file] [log] [blame]
Wolfgang Denk74f43042005-09-25 01:48:28 +02001/*
2 * armboot - Startup Code for ARM926EJS CPU-core
3 *
4 * Copyright (c) 2003 Texas Instruments
5 *
6 * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------
7 *
Albert ARIBAUDfa82f872011-08-04 18:45:45 +02008 * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
9 * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
Detlev Zundel792a09e2009-05-13 10:54:10 +020010 * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
Wolfgang Denk74f43042005-09-25 01:48:28 +020011 * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
12 * Copyright (c) 2003 Kshitij <kshitij@ti.com>
13 *
Wolfgang Denk1a459662013-07-08 09:37:19 +020014 * SPDX-License-Identifier: GPL-2.0+
Wolfgang Denk74f43042005-09-25 01:48:28 +020015 */
16
Wolfgang Denk25ddd1f2010-10-26 14:34:52 +020017#include <asm-offsets.h>
Wolfgang Denk74f43042005-09-25 01:48:28 +020018#include <config.h>
19#include <version.h>
20
21/*
22 *************************************************************************
23 *
24 * Jump vector table
25 *
26 *************************************************************************
27 */
28
29.globl _start
30_start:
31 b reset
32 ldr pc, _undefined_instruction
33 ldr pc, _software_interrupt
34 ldr pc, _prefetch_abort
35 ldr pc, _data_abort
36 ldr pc, _not_used
37 ldr pc, _irq
38 ldr pc, _fiq
39
40_undefined_instruction:
41 .word undefined_instruction
42_software_interrupt:
43 .word software_interrupt
44_prefetch_abort:
45 .word prefetch_abort
46_data_abort:
47 .word data_abort
48_not_used:
49 .word not_used
50_irq:
51 .word irq
52_fiq:
53 .word fiq
54
55 .balignl 16,0xdeadbeef
56
57/*
58 *************************************************************************
59 *
60 * Startup Code (reset vector)
61 *
62 * do important init only if we don't start from memory!
63 * setup memory and board specific bits prior to relocation.
64 * relocate armboot to ram
65 * setup stack
66 *
67 *************************************************************************
68 */
69
Heiko Schocherc6c2ceb2010-09-17 13:10:51 +020070.globl _TEXT_BASE
Wolfgang Denk74f43042005-09-25 01:48:28 +020071_TEXT_BASE:
Benoît Thébaudeau508611b2013-04-11 09:35:42 +000072#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE)
73 .word CONFIG_SPL_TEXT_BASE
74#else
75 .word CONFIG_SYS_TEXT_BASE
76#endif
Wolfgang Denk74f43042005-09-25 01:48:28 +020077
Wolfgang Denk74f43042005-09-25 01:48:28 +020078/*
79 * These are defined in the board-specific linker script.
Albert Aribaud3336ca62010-11-25 22:45:02 +010080 * Subtracting _start from them lets the linker put their
81 * relative position in the executable instead of leaving
82 * them null.
Wolfgang Denk74f43042005-09-25 01:48:28 +020083 */
Albert Aribaud3336ca62010-11-25 22:45:02 +010084.globl _bss_start_ofs
85_bss_start_ofs:
86 .word __bss_start - _start
Wolfgang Denk74f43042005-09-25 01:48:28 +020087
Albert Aribaud3336ca62010-11-25 22:45:02 +010088.globl _bss_end_ofs
89_bss_end_ofs:
Simon Glass3929fb02013-03-14 06:54:53 +000090 .word __bss_end - _start
Wolfgang Denk74f43042005-09-25 01:48:28 +020091
Po-Yu Chuangf326cbb2011-03-01 23:02:04 +000092.globl _end_ofs
93_end_ofs:
94 .word _end - _start
95
Wolfgang Denk74f43042005-09-25 01:48:28 +020096#ifdef CONFIG_USE_IRQ
97/* IRQ stack memory (calculated at run-time) */
98.globl IRQ_STACK_START
99IRQ_STACK_START:
100 .word 0x0badc0de
101
102/* IRQ stack memory (calculated at run-time) */
103.globl FIQ_STACK_START
104FIQ_STACK_START:
105 .word 0x0badc0de
106#endif
107
Heiko Schocherc6c2ceb2010-09-17 13:10:51 +0200108/* IRQ stack memory (calculated at run-time) + 8 bytes */
109.globl IRQ_STACK_START_IN
110IRQ_STACK_START_IN:
111 .word 0x0badc0de
112
Heiko Schocherc6c2ceb2010-09-17 13:10:51 +0200113/*
114 * the actual reset code
115 */
116
117reset:
118 /*
119 * set the cpu to SVC32 mode
120 */
121 mrs r0,cpsr
122 bic r0,r0,#0x1f
123 orr r0,r0,#0xd3
124 msr cpsr,r0
125
126 /*
127 * we do sys-critical inits only at reboot,
128 * not when booting from ram!
129 */
130#ifndef CONFIG_SKIP_LOWLEVEL_INIT
131 bl cpu_init_crit
132#endif
133
Albert ARIBAUDe05e5de2013-01-08 10:18:02 +0000134 bl _main
Heiko Schocherc6c2ceb2010-09-17 13:10:51 +0200135
136/*------------------------------------------------------------------------------*/
137
Albert ARIBAUDe05e5de2013-01-08 10:18:02 +0000138 .globl c_runtime_cpu_setup
139c_runtime_cpu_setup:
140
141 mov pc, lr
142
Wolfgang Denk74f43042005-09-25 01:48:28 +0200143/*
144 *************************************************************************
145 *
146 * CPU_init_critical registers
147 *
148 * setup important registers
149 * setup memory timing
150 *
151 *************************************************************************
152 */
153
Jean-Christophe PLAGNIOL-VILLARD8fc3bb42009-05-15 23:45:20 +0200154#ifndef CONFIG_SKIP_LOWLEVEL_INIT
Wolfgang Denk74f43042005-09-25 01:48:28 +0200155cpu_init_crit:
156 /* arm_int_generic assumes the ARM boot monitor, or user software,
157 * has initialized the platform
158 */
159 mov pc, lr /* back to my caller */
Jean-Christophe PLAGNIOL-VILLARD8fc3bb42009-05-15 23:45:20 +0200160#endif
Wolfgang Denk74f43042005-09-25 01:48:28 +0200161/*
162 *************************************************************************
163 *
164 * Interrupt handling
165 *
166 *************************************************************************
167 */
168
169@
170@ IRQ stack frame.
171@
172#define S_FRAME_SIZE 72
173
174#define S_OLD_R0 68
175#define S_PSR 64
176#define S_PC 60
177#define S_LR 56
178#define S_SP 52
179
180#define S_IP 48
181#define S_FP 44
182#define S_R10 40
183#define S_R9 36
184#define S_R8 32
185#define S_R7 28
186#define S_R6 24
187#define S_R5 20
188#define S_R4 16
189#define S_R3 12
190#define S_R2 8
191#define S_R1 4
192#define S_R0 0
193
194#define MODE_SVC 0x13
195#define I_BIT 0x80
196
197/*
198 * use bad_save_user_regs for abort/prefetch/undef/swi ...
199 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
200 */
201
202 .macro bad_save_user_regs
203 @ carve out a frame on current user stack
204 sub sp, sp, #S_FRAME_SIZE
205 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
206
Heiko Schocherc6c2ceb2010-09-17 13:10:51 +0200207 ldr r2, IRQ_STACK_START_IN
Wolfgang Denk74f43042005-09-25 01:48:28 +0200208 @ get values for "aborted" pc and cpsr (into parm regs)
209 ldmia r2, {r2 - r3}
210 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
211 add r5, sp, #S_SP
212 mov r1, lr
213 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
214 mov r0, sp @ save current stack into r0 (param register)
215 .endm
216
217 .macro irq_save_user_regs
218 sub sp, sp, #S_FRAME_SIZE
219 stmia sp, {r0 - r12} @ Calling r0-r12
220 @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
221 add r8, sp, #S_PC
222 stmdb r8, {sp, lr}^ @ Calling SP, LR
223 str lr, [r8, #0] @ Save calling PC
224 mrs r6, spsr
225 str r6, [r8, #4] @ Save CPSR
226 str r0, [r8, #8] @ Save OLD_R0
227 mov r0, sp
228 .endm
229
230 .macro irq_restore_user_regs
231 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
232 mov r0, r0
233 ldr lr, [sp, #S_PC] @ Get PC
234 add sp, sp, #S_FRAME_SIZE
235 subs pc, lr, #4 @ return & move spsr_svc into cpsr
236 .endm
237
238 .macro get_bad_stack
Heiko Schocherc6c2ceb2010-09-17 13:10:51 +0200239 ldr r13, IRQ_STACK_START_IN @ setup our mode stack
Wolfgang Denk74f43042005-09-25 01:48:28 +0200240
241 str lr, [r13] @ save caller lr in position 0 of saved stack
242 mrs lr, spsr @ get the spsr
243 str lr, [r13, #4] @ save spsr in position 1 of saved stack
244 mov r13, #MODE_SVC @ prepare SVC-Mode
245 @ msr spsr_c, r13
246 msr spsr, r13 @ switch modes, make sure moves will execute
247 mov lr, pc @ capture return pc
248 movs pc, lr @ jump to next instruction & switch modes.
249 .endm
250
251 .macro get_irq_stack @ setup IRQ stack
252 ldr sp, IRQ_STACK_START
253 .endm
254
255 .macro get_fiq_stack @ setup FIQ stack
256 ldr sp, FIQ_STACK_START
257 .endm
258
259/*
260 * exception handlers
261 */
262 .align 5
263.globl undefined_instruction
264undefined_instruction:
265 get_bad_stack
266 bad_save_user_regs
267 bl do_undefined_instruction
268
269 .align 5
270.globl software_interrupt
271software_interrupt:
272 get_bad_stack
273 bad_save_user_regs
274 bl do_software_interrupt
275
276 .align 5
277.globl prefetch_abort
278prefetch_abort:
279 get_bad_stack
280 bad_save_user_regs
281 bl do_prefetch_abort
282
283 .align 5
284.globl data_abort
285data_abort:
286 get_bad_stack
287 bad_save_user_regs
288 bl do_data_abort
289
290 .align 5
291.globl not_used
292not_used:
293 get_bad_stack
294 bad_save_user_regs
295 bl do_not_used
296
297#ifdef CONFIG_USE_IRQ
298 .align 5
299.globl irq
300irq:
301 get_irq_stack
302 irq_save_user_regs
Wolfgang Denk53677ef2008-05-20 16:00:29 +0200303 bl do_irq
Wolfgang Denk74f43042005-09-25 01:48:28 +0200304 irq_restore_user_regs
305
306 .align 5
307.globl fiq
308fiq:
309 get_fiq_stack
310 /* someone ought to write a more effiction fiq_save_user_regs */
311 irq_save_user_regs
Wolfgang Denk53677ef2008-05-20 16:00:29 +0200312 bl do_fiq
Wolfgang Denk74f43042005-09-25 01:48:28 +0200313 irq_restore_user_regs
314
315#else
316
317 .align 5
Wolfgang Denkfe7eb5d2005-09-25 02:00:47 +0200318.globl irq
Wolfgang Denk74f43042005-09-25 01:48:28 +0200319irq:
320 get_bad_stack
321 bad_save_user_regs
322 bl do_irq
323
324 .align 5
Wolfgang Denkfe7eb5d2005-09-25 02:00:47 +0200325.globl fiq
Wolfgang Denk74f43042005-09-25 01:48:28 +0200326fiq:
327 get_bad_stack
328 bad_save_user_regs
329 bl do_fiq
330
331#endif