blob: 7404ea734816b9d7e7c5dd4acfe6342bc2071dac [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
Wolfgang Denk74f43042005-09-25 01:48:28 +020070#ifdef CONFIG_USE_IRQ
71/* IRQ stack memory (calculated at run-time) */
72.globl IRQ_STACK_START
73IRQ_STACK_START:
74 .word 0x0badc0de
75
76/* IRQ stack memory (calculated at run-time) */
77.globl FIQ_STACK_START
78FIQ_STACK_START:
79 .word 0x0badc0de
80#endif
81
Heiko Schocherc6c2ceb2010-09-17 13:10:51 +020082/* IRQ stack memory (calculated at run-time) + 8 bytes */
83.globl IRQ_STACK_START_IN
84IRQ_STACK_START_IN:
85 .word 0x0badc0de
86
Heiko Schocherc6c2ceb2010-09-17 13:10:51 +020087/*
88 * the actual reset code
89 */
90
91reset:
92 /*
93 * set the cpu to SVC32 mode
94 */
95 mrs r0,cpsr
96 bic r0,r0,#0x1f
97 orr r0,r0,#0xd3
98 msr cpsr,r0
99
100 /*
101 * we do sys-critical inits only at reboot,
102 * not when booting from ram!
103 */
104#ifndef CONFIG_SKIP_LOWLEVEL_INIT
105 bl cpu_init_crit
106#endif
107
Albert ARIBAUDe05e5de2013-01-08 10:18:02 +0000108 bl _main
Heiko Schocherc6c2ceb2010-09-17 13:10:51 +0200109
110/*------------------------------------------------------------------------------*/
111
Albert ARIBAUDe05e5de2013-01-08 10:18:02 +0000112 .globl c_runtime_cpu_setup
113c_runtime_cpu_setup:
114
115 mov pc, lr
116
Wolfgang Denk74f43042005-09-25 01:48:28 +0200117/*
118 *************************************************************************
119 *
120 * CPU_init_critical registers
121 *
122 * setup important registers
123 * setup memory timing
124 *
125 *************************************************************************
126 */
127
Jean-Christophe PLAGNIOL-VILLARD8fc3bb42009-05-15 23:45:20 +0200128#ifndef CONFIG_SKIP_LOWLEVEL_INIT
Wolfgang Denk74f43042005-09-25 01:48:28 +0200129cpu_init_crit:
130 /* arm_int_generic assumes the ARM boot monitor, or user software,
131 * has initialized the platform
132 */
133 mov pc, lr /* back to my caller */
Jean-Christophe PLAGNIOL-VILLARD8fc3bb42009-05-15 23:45:20 +0200134#endif
Wolfgang Denk74f43042005-09-25 01:48:28 +0200135/*
136 *************************************************************************
137 *
138 * Interrupt handling
139 *
140 *************************************************************************
141 */
142
143@
144@ IRQ stack frame.
145@
146#define S_FRAME_SIZE 72
147
148#define S_OLD_R0 68
149#define S_PSR 64
150#define S_PC 60
151#define S_LR 56
152#define S_SP 52
153
154#define S_IP 48
155#define S_FP 44
156#define S_R10 40
157#define S_R9 36
158#define S_R8 32
159#define S_R7 28
160#define S_R6 24
161#define S_R5 20
162#define S_R4 16
163#define S_R3 12
164#define S_R2 8
165#define S_R1 4
166#define S_R0 0
167
168#define MODE_SVC 0x13
169#define I_BIT 0x80
170
171/*
172 * use bad_save_user_regs for abort/prefetch/undef/swi ...
173 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
174 */
175
176 .macro bad_save_user_regs
177 @ carve out a frame on current user stack
178 sub sp, sp, #S_FRAME_SIZE
179 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
180
Heiko Schocherc6c2ceb2010-09-17 13:10:51 +0200181 ldr r2, IRQ_STACK_START_IN
Wolfgang Denk74f43042005-09-25 01:48:28 +0200182 @ get values for "aborted" pc and cpsr (into parm regs)
183 ldmia r2, {r2 - r3}
184 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
185 add r5, sp, #S_SP
186 mov r1, lr
187 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
188 mov r0, sp @ save current stack into r0 (param register)
189 .endm
190
191 .macro irq_save_user_regs
192 sub sp, sp, #S_FRAME_SIZE
193 stmia sp, {r0 - r12} @ Calling r0-r12
194 @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
195 add r8, sp, #S_PC
196 stmdb r8, {sp, lr}^ @ Calling SP, LR
197 str lr, [r8, #0] @ Save calling PC
198 mrs r6, spsr
199 str r6, [r8, #4] @ Save CPSR
200 str r0, [r8, #8] @ Save OLD_R0
201 mov r0, sp
202 .endm
203
204 .macro irq_restore_user_regs
205 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
206 mov r0, r0
207 ldr lr, [sp, #S_PC] @ Get PC
208 add sp, sp, #S_FRAME_SIZE
209 subs pc, lr, #4 @ return & move spsr_svc into cpsr
210 .endm
211
212 .macro get_bad_stack
Heiko Schocherc6c2ceb2010-09-17 13:10:51 +0200213 ldr r13, IRQ_STACK_START_IN @ setup our mode stack
Wolfgang Denk74f43042005-09-25 01:48:28 +0200214
215 str lr, [r13] @ save caller lr in position 0 of saved stack
216 mrs lr, spsr @ get the spsr
217 str lr, [r13, #4] @ save spsr in position 1 of saved stack
218 mov r13, #MODE_SVC @ prepare SVC-Mode
219 @ msr spsr_c, r13
220 msr spsr, r13 @ switch modes, make sure moves will execute
221 mov lr, pc @ capture return pc
222 movs pc, lr @ jump to next instruction & switch modes.
223 .endm
224
225 .macro get_irq_stack @ setup IRQ stack
226 ldr sp, IRQ_STACK_START
227 .endm
228
229 .macro get_fiq_stack @ setup FIQ stack
230 ldr sp, FIQ_STACK_START
231 .endm
232
233/*
234 * exception handlers
235 */
236 .align 5
237.globl undefined_instruction
238undefined_instruction:
239 get_bad_stack
240 bad_save_user_regs
241 bl do_undefined_instruction
242
243 .align 5
244.globl software_interrupt
245software_interrupt:
246 get_bad_stack
247 bad_save_user_regs
248 bl do_software_interrupt
249
250 .align 5
251.globl prefetch_abort
252prefetch_abort:
253 get_bad_stack
254 bad_save_user_regs
255 bl do_prefetch_abort
256
257 .align 5
258.globl data_abort
259data_abort:
260 get_bad_stack
261 bad_save_user_regs
262 bl do_data_abort
263
264 .align 5
265.globl not_used
266not_used:
267 get_bad_stack
268 bad_save_user_regs
269 bl do_not_used
270
271#ifdef CONFIG_USE_IRQ
272 .align 5
273.globl irq
274irq:
275 get_irq_stack
276 irq_save_user_regs
Wolfgang Denk53677ef2008-05-20 16:00:29 +0200277 bl do_irq
Wolfgang Denk74f43042005-09-25 01:48:28 +0200278 irq_restore_user_regs
279
280 .align 5
281.globl fiq
282fiq:
283 get_fiq_stack
284 /* someone ought to write a more effiction fiq_save_user_regs */
285 irq_save_user_regs
Wolfgang Denk53677ef2008-05-20 16:00:29 +0200286 bl do_fiq
Wolfgang Denk74f43042005-09-25 01:48:28 +0200287 irq_restore_user_regs
288
289#else
290
291 .align 5
Wolfgang Denkfe7eb5d2005-09-25 02:00:47 +0200292.globl irq
Wolfgang Denk74f43042005-09-25 01:48:28 +0200293irq:
294 get_bad_stack
295 bad_save_user_regs
296 bl do_irq
297
298 .align 5
Wolfgang Denkfe7eb5d2005-09-25 02:00:47 +0200299.globl fiq
Wolfgang Denk74f43042005-09-25 01:48:28 +0200300fiq:
301 get_bad_stack
302 bad_save_user_regs
303 bl do_fiq
304
305#endif