blob: 0717327050d06200a2871da2bcccfb290a45d1d7 [file] [log] [blame]
wdenk7eaacc52003-08-29 22:00:43 +00001/*
2 * armboot - Startup Code for ARM926EJS CPU-core
3 *
4 * Copyright (c) 2003 Texas Instruments
5 *
wdenke3a06802004-06-06 23:13:55 +00006 * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------
wdenk7eaacc52003-08-29 22:00:43 +00007 *
Albert ARIBAUD60fbc8d2011-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 Zundelf1b3f2b2009-05-13 10:54:10 +020010 * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
wdenk7eaacc52003-08-29 22:00:43 +000011 * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
12 * Copyright (c) 2003 Kshitij <kshitij@ti.com>
Albert ARIBAUD340983d2011-04-22 19:41:02 +020013 * Copyright (c) 2010 Albert Aribaud <albert.u.boot@aribaud.net>
wdenk7eaacc52003-08-29 22:00:43 +000014 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +020015 * SPDX-License-Identifier: GPL-2.0+
wdenk7eaacc52003-08-29 22:00:43 +000016 */
17
Wolfgang Denk0191e472010-10-26 14:34:52 +020018#include <asm-offsets.h>
wdenk7eaacc52003-08-29 22:00:43 +000019#include <config.h>
Wolfgang Denk66e8d442009-07-24 00:17:48 +020020#include <common.h>
wdenk7eaacc52003-08-29 22:00:43 +000021#include <version.h>
22
wdenk7eaacc52003-08-29 22:00:43 +000023/*
24 *************************************************************************
25 *
26 * Jump vector table as in table 3.1 in [1]
27 *
28 *************************************************************************
29 */
30
31
Heiko Schocherf49e9442011-09-14 19:59:37 +000032#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG
wdenk7eaacc52003-08-29 22:00:43 +000033.globl _start
34_start:
Heiko Schocherf49e9442011-09-14 19:59:37 +000035.globl _NOR_BOOT_CFG
36_NOR_BOOT_CFG:
37 .word CONFIG_SYS_DV_NOR_BOOT_CFG
38 b reset
39#else
40.globl _start
41_start:
wdenk7eaacc52003-08-29 22:00:43 +000042 b reset
Heiko Schocherf49e9442011-09-14 19:59:37 +000043#endif
Aneesh V552a3192011-07-13 05:11:07 +000044#ifdef CONFIG_SPL_BUILD
John Rigbya9f3cf52010-01-25 23:12:52 -070045/* No exception handlers in preloader */
46 ldr pc, _hang
47 ldr pc, _hang
48 ldr pc, _hang
49 ldr pc, _hang
50 ldr pc, _hang
51 ldr pc, _hang
52 ldr pc, _hang
53
54_hang:
55 .word do_hang
56/* pad to 64 byte boundary */
57 .word 0x12345678
58 .word 0x12345678
59 .word 0x12345678
60 .word 0x12345678
61 .word 0x12345678
62 .word 0x12345678
63 .word 0x12345678
64#else
wdenk7eaacc52003-08-29 22:00:43 +000065 ldr pc, _undefined_instruction
66 ldr pc, _software_interrupt
67 ldr pc, _prefetch_abort
68 ldr pc, _data_abort
69 ldr pc, _not_used
70 ldr pc, _irq
71 ldr pc, _fiq
72
73_undefined_instruction:
74 .word undefined_instruction
75_software_interrupt:
76 .word software_interrupt
77_prefetch_abort:
78 .word prefetch_abort
79_data_abort:
80 .word data_abort
81_not_used:
82 .word not_used
83_irq:
84 .word irq
85_fiq:
86 .word fiq
87
Aneesh V552a3192011-07-13 05:11:07 +000088#endif /* CONFIG_SPL_BUILD */
wdenk7eaacc52003-08-29 22:00:43 +000089 .balignl 16,0xdeadbeef
90
91
92/*
93 *************************************************************************
94 *
95 * Startup Code (reset vector)
96 *
97 * do important init only if we don't start from memory!
98 * setup Memory and board specific bits prior to relocation.
99 * relocate armboot to ram
100 * setup stack
101 *
102 *************************************************************************
103 */
104
wdenk7eaacc52003-08-29 22:00:43 +0000105#ifdef CONFIG_USE_IRQ
106/* IRQ stack memory (calculated at run-time) */
107.globl IRQ_STACK_START
108IRQ_STACK_START:
109 .word 0x0badc0de
110
111/* IRQ stack memory (calculated at run-time) */
112.globl FIQ_STACK_START
113FIQ_STACK_START:
114 .word 0x0badc0de
115#endif
Heiko Schocher0e2412a2010-09-17 13:10:42 +0200116
Heiko Schocher0e2412a2010-09-17 13:10:42 +0200117/* IRQ stack memory (calculated at run-time) + 8 bytes */
118.globl IRQ_STACK_START_IN
119IRQ_STACK_START_IN:
120 .word 0x0badc0de
121
Heiko Schocher0e2412a2010-09-17 13:10:42 +0200122/*
123 * the actual reset code
124 */
125
126reset:
127 /*
128 * set the cpu to SVC32 mode
129 */
130 mrs r0,cpsr
131 bic r0,r0,#0x1f
132 orr r0,r0,#0xd3
133 msr cpsr,r0
134
135 /*
136 * we do sys-critical inits only at reboot,
137 * not when booting from ram!
138 */
Christian Riesch11bf5762012-02-02 00:44:37 +0000139#ifndef CONFIG_SKIP_LOWLEVEL_INIT
Heiko Schocher0e2412a2010-09-17 13:10:42 +0200140 bl cpu_init_crit
Christian Riesch11bf5762012-02-02 00:44:37 +0000141#endif
Heiko Schocher0e2412a2010-09-17 13:10:42 +0200142
Albert ARIBAUDfacdae52013-01-08 10:18:02 +0000143 bl _main
Heiko Schocher0e2412a2010-09-17 13:10:42 +0200144
145/*------------------------------------------------------------------------------*/
146
Albert ARIBAUDfacdae52013-01-08 10:18:02 +0000147 .globl c_runtime_cpu_setup
148c_runtime_cpu_setup:
149
150 bx lr
151
wdenk7eaacc52003-08-29 22:00:43 +0000152/*
153 *************************************************************************
154 *
155 * CPU_init_critical registers
156 *
157 * setup important registers
158 * setup memory timing
159 *
160 *************************************************************************
161 */
Christian Riesch11bf5762012-02-02 00:44:37 +0000162#ifndef CONFIG_SKIP_LOWLEVEL_INIT
wdenk7eaacc52003-08-29 22:00:43 +0000163cpu_init_crit:
164 /*
Sughosh Ganu4cb71862012-02-02 00:44:38 +0000165 * flush D cache before disabling it
wdenk7eaacc52003-08-29 22:00:43 +0000166 */
167 mov r0, #0
Sughosh Ganu4cb71862012-02-02 00:44:38 +0000168flush_dcache:
169 mrc p15, 0, r15, c7, c10, 3
170 bne flush_dcache
171
172 mcr p15, 0, r0, c8, c7, 0 /* invalidate TLB */
173 mcr p15, 0, r0, c7, c5, 0 /* invalidate I Cache */
wdenk7eaacc52003-08-29 22:00:43 +0000174
175 /*
Christian Riescha927d262012-02-02 00:44:40 +0000176 * disable MMU and D cache
177 * enable I cache if CONFIG_SYS_ICACHE_OFF is not defined
wdenk7eaacc52003-08-29 22:00:43 +0000178 */
179 mrc p15, 0, r0, c1, c0, 0
Christian Riesch48c2d6d2012-02-02 00:44:39 +0000180 bic r0, r0, #0x00000300 /* clear bits 9:8 (---- --RS) */
wdenk7eaacc52003-08-29 22:00:43 +0000181 bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */
Christian Riesch48c2d6d2012-02-02 00:44:39 +0000182#ifdef CONFIG_SYS_EXCEPTION_VECTORS_HIGH
183 orr r0, r0, #0x00002000 /* set bit 13 (--V- ----) */
184#else
185 bic r0, r0, #0x00002000 /* clear bit 13 (--V- ----) */
186#endif
wdenk7eaacc52003-08-29 22:00:43 +0000187 orr r0, r0, #0x00000002 /* set bit 2 (A) Align */
Christian Riescha927d262012-02-02 00:44:40 +0000188#ifndef CONFIG_SYS_ICACHE_OFF
wdenk7eaacc52003-08-29 22:00:43 +0000189 orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
Christian Riescha927d262012-02-02 00:44:40 +0000190#endif
wdenk7eaacc52003-08-29 22:00:43 +0000191 mcr p15, 0, r0, c1, c0, 0
192
193 /*
194 * Go setup Memory and board specific bits prior to relocation.
195 */
196 mov ip, lr /* perserve link reg across call */
Wolfgang Denk7f88a5e2005-10-06 17:08:18 +0200197 bl lowlevel_init /* go setup pll,mux,memory */
wdenk7eaacc52003-08-29 22:00:43 +0000198 mov lr, ip /* restore link */
Heiko Schocherc8a6d752011-11-09 20:06:23 +0000199 mov pc, lr /* back to my caller */
Christian Riesch11bf5762012-02-02 00:44:37 +0000200#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
Stelian Pop72a6f142008-01-19 21:09:35 +0000201
Aneesh V552a3192011-07-13 05:11:07 +0000202#ifndef CONFIG_SPL_BUILD
wdenk7eaacc52003-08-29 22:00:43 +0000203/*
204 *************************************************************************
205 *
206 * Interrupt handling
207 *
208 *************************************************************************
209 */
210
211@
212@ IRQ stack frame.
213@
214#define S_FRAME_SIZE 72
215
216#define S_OLD_R0 68
217#define S_PSR 64
218#define S_PC 60
219#define S_LR 56
220#define S_SP 52
221
222#define S_IP 48
223#define S_FP 44
224#define S_R10 40
225#define S_R9 36
226#define S_R8 32
227#define S_R7 28
228#define S_R6 24
229#define S_R5 20
230#define S_R4 16
231#define S_R3 12
232#define S_R2 8
233#define S_R1 4
234#define S_R0 0
235
236#define MODE_SVC 0x13
237#define I_BIT 0x80
238
239/*
240 * use bad_save_user_regs for abort/prefetch/undef/swi ...
241 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
242 */
243
244 .macro bad_save_user_regs
245 @ carve out a frame on current user stack
246 sub sp, sp, #S_FRAME_SIZE
247 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
Heiko Schocher0e2412a2010-09-17 13:10:42 +0200248 ldr r2, IRQ_STACK_START_IN
wdenk7eaacc52003-08-29 22:00:43 +0000249 @ get values for "aborted" pc and cpsr (into parm regs)
250 ldmia r2, {r2 - r3}
251 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
252 add r5, sp, #S_SP
253 mov r1, lr
254 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
255 mov r0, sp @ save current stack into r0 (param register)
256 .endm
257
258 .macro irq_save_user_regs
259 sub sp, sp, #S_FRAME_SIZE
260 stmia sp, {r0 - r12} @ Calling r0-r12
261 @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
262 add r8, sp, #S_PC
263 stmdb r8, {sp, lr}^ @ Calling SP, LR
264 str lr, [r8, #0] @ Save calling PC
265 mrs r6, spsr
266 str r6, [r8, #4] @ Save CPSR
267 str r0, [r8, #8] @ Save OLD_R0
268 mov r0, sp
269 .endm
270
271 .macro irq_restore_user_regs
272 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
273 mov r0, r0
274 ldr lr, [sp, #S_PC] @ Get PC
275 add sp, sp, #S_FRAME_SIZE
276 subs pc, lr, #4 @ return & move spsr_svc into cpsr
277 .endm
278
279 .macro get_bad_stack
Heiko Schocher0e2412a2010-09-17 13:10:42 +0200280 ldr r13, IRQ_STACK_START_IN @ setup our mode stack
wdenk7eaacc52003-08-29 22:00:43 +0000281
282 str lr, [r13] @ save caller lr in position 0 of saved stack
283 mrs lr, spsr @ get the spsr
284 str lr, [r13, #4] @ save spsr in position 1 of saved stack
285 mov r13, #MODE_SVC @ prepare SVC-Mode
286 @ msr spsr_c, r13
287 msr spsr, r13 @ switch modes, make sure moves will execute
288 mov lr, pc @ capture return pc
289 movs pc, lr @ jump to next instruction & switch modes.
290 .endm
291
292 .macro get_irq_stack @ setup IRQ stack
293 ldr sp, IRQ_STACK_START
294 .endm
295
296 .macro get_fiq_stack @ setup FIQ stack
297 ldr sp, FIQ_STACK_START
298 .endm
Aneesh V552a3192011-07-13 05:11:07 +0000299#endif /* CONFIG_SPL_BUILD */
wdenk7eaacc52003-08-29 22:00:43 +0000300
301/*
302 * exception handlers
303 */
Aneesh V552a3192011-07-13 05:11:07 +0000304#ifdef CONFIG_SPL_BUILD
John Rigbya9f3cf52010-01-25 23:12:52 -0700305 .align 5
306do_hang:
John Rigbya9f3cf52010-01-25 23:12:52 -07003071:
308 bl 1b /* hang and never return */
Aneesh V552a3192011-07-13 05:11:07 +0000309#else /* !CONFIG_SPL_BUILD */
wdenk7eaacc52003-08-29 22:00:43 +0000310 .align 5
311undefined_instruction:
312 get_bad_stack
313 bad_save_user_regs
314 bl do_undefined_instruction
315
316 .align 5
317software_interrupt:
318 get_bad_stack
319 bad_save_user_regs
320 bl do_software_interrupt
321
322 .align 5
323prefetch_abort:
324 get_bad_stack
325 bad_save_user_regs
326 bl do_prefetch_abort
327
328 .align 5
329data_abort:
330 get_bad_stack
331 bad_save_user_regs
332 bl do_data_abort
333
334 .align 5
335not_used:
336 get_bad_stack
337 bad_save_user_regs
338 bl do_not_used
339
340#ifdef CONFIG_USE_IRQ
341
342 .align 5
343irq:
344 get_irq_stack
345 irq_save_user_regs
Wolfgang Denka1be4762008-05-20 16:00:29 +0200346 bl do_irq
wdenk7eaacc52003-08-29 22:00:43 +0000347 irq_restore_user_regs
348
349 .align 5
350fiq:
351 get_fiq_stack
352 /* someone ought to write a more effiction fiq_save_user_regs */
353 irq_save_user_regs
Wolfgang Denka1be4762008-05-20 16:00:29 +0200354 bl do_fiq
wdenk7eaacc52003-08-29 22:00:43 +0000355 irq_restore_user_regs
356
357#else
358
359 .align 5
360irq:
361 get_bad_stack
362 bad_save_user_regs
363 bl do_irq
364
365 .align 5
366fiq:
367 get_bad_stack
368 bad_save_user_regs
369 bl do_fiq
370
371#endif
Aneesh V552a3192011-07-13 05:11:07 +0000372#endif /* CONFIG_SPL_BUILD */