2 * armboot - Startup Code for ARM926EJS CPU-core
4 * Copyright (c) 2003 Texas Instruments
6 * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------
8 * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
9 * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
10 * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
11 * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
12 * Copyright (c) 2003 Kshitij <kshitij@ti.com>
13 * Copyright (c) 2010 Albert Aribaud <albert.u.boot@aribaud.net>
15 * SPDX-License-Identifier: GPL-2.0+
18 #include <asm-offsets.h>
24 *************************************************************************
26 * Jump vector table as in table 3.1 in [1]
28 *************************************************************************
32 #ifdef CONFIG_SYS_DV_NOR_BOOT_CFG
37 .word CONFIG_SYS_DV_NOR_BOOT_CFG
44 #ifdef CONFIG_SPL_BUILD
45 /* No exception handlers in preloader */
56 /* pad to 64 byte boundary */
65 ldr pc, _undefined_instruction
66 ldr pc, _software_interrupt
67 ldr pc, _prefetch_abort
73 _undefined_instruction:
74 .word undefined_instruction
76 .word software_interrupt
88 #endif /* CONFIG_SPL_BUILD */
89 .balignl 16,0xdeadbeef
93 *************************************************************************
95 * Startup Code (reset vector)
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
102 *************************************************************************
105 #ifdef CONFIG_USE_IRQ
106 /* IRQ stack memory (calculated at run-time) */
107 .globl IRQ_STACK_START
111 /* IRQ stack memory (calculated at run-time) */
112 .globl FIQ_STACK_START
117 /* IRQ stack memory (calculated at run-time) + 8 bytes */
118 .globl IRQ_STACK_START_IN
123 * the actual reset code
128 * set the cpu to SVC32 mode
136 * we do sys-critical inits only at reboot,
137 * not when booting from ram!
139 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
145 /*------------------------------------------------------------------------------*/
147 .globl c_runtime_cpu_setup
153 *************************************************************************
155 * CPU_init_critical registers
157 * setup important registers
158 * setup memory timing
160 *************************************************************************
162 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
165 * flush D cache before disabling it
169 mrc p15, 0, r15, c7, c10, 3
172 mcr p15, 0, r0, c8, c7, 0 /* invalidate TLB */
173 mcr p15, 0, r0, c7, c5, 0 /* invalidate I Cache */
176 * disable MMU and D cache
177 * enable I cache if CONFIG_SYS_ICACHE_OFF is not defined
179 mrc p15, 0, r0, c1, c0, 0
180 bic r0, r0, #0x00000300 /* clear bits 9:8 (---- --RS) */
181 bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */
182 #ifdef CONFIG_SYS_EXCEPTION_VECTORS_HIGH
183 orr r0, r0, #0x00002000 /* set bit 13 (--V- ----) */
185 bic r0, r0, #0x00002000 /* clear bit 13 (--V- ----) */
187 orr r0, r0, #0x00000002 /* set bit 2 (A) Align */
188 #ifndef CONFIG_SYS_ICACHE_OFF
189 orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
191 mcr p15, 0, r0, c1, c0, 0
194 * Go setup Memory and board specific bits prior to relocation.
196 mov ip, lr /* perserve link reg across call */
197 bl lowlevel_init /* go setup pll,mux,memory */
198 mov lr, ip /* restore link */
199 mov pc, lr /* back to my caller */
200 #endif /* CONFIG_SKIP_LOWLEVEL_INIT */
202 #ifndef CONFIG_SPL_BUILD
204 *************************************************************************
208 *************************************************************************
214 #define S_FRAME_SIZE 72
236 #define MODE_SVC 0x13
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
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
248 ldr r2, IRQ_STACK_START_IN
249 @ get values for "aborted" pc and cpsr (into parm regs)
251 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
254 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
255 mov r0, sp @ save current stack into r0 (param register)
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.
263 stmdb r8, {sp, lr}^ @ Calling SP, LR
264 str lr, [r8, #0] @ Save calling PC
266 str r6, [r8, #4] @ Save CPSR
267 str r0, [r8, #8] @ Save OLD_R0
271 .macro irq_restore_user_regs
272 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
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
280 ldr r13, IRQ_STACK_START_IN @ setup our mode stack
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
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.
292 .macro get_irq_stack @ setup IRQ stack
293 ldr sp, IRQ_STACK_START
296 .macro get_fiq_stack @ setup FIQ stack
297 ldr sp, FIQ_STACK_START
299 #endif /* CONFIG_SPL_BUILD */
304 #ifdef CONFIG_SPL_BUILD
308 bl 1b /* hang and never return */
309 #else /* !CONFIG_SPL_BUILD */
311 undefined_instruction:
314 bl do_undefined_instruction
320 bl do_software_interrupt
340 #ifdef CONFIG_USE_IRQ
347 irq_restore_user_regs
352 /* someone ought to write a more effiction fiq_save_user_regs */
355 irq_restore_user_regs
372 #endif /* CONFIG_SPL_BUILD */