blob: 5aac7736444c5e7101d680478f23be93c16f7e38 [file] [log] [blame]
Dirk Behme7d75a102008-12-14 09:47:13 +01001/*
2 * armboot - Startup Code for OMAP3530/ARM Cortex CPU-core
3 *
4 * Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com>
5 *
6 * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
7 * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
Detlev Zundelf1b3f2b2009-05-13 10:54:10 +02008 * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
Dirk Behme7d75a102008-12-14 09:47:13 +01009 * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
10 * Copyright (c) 2003 Kshitij <kshitij@ti.com>
11 * Copyright (c) 2006-2008 Syed Mohammed Khasim <x0khasim@ti.com>
12 *
Wolfgang Denkbd8ec7e2013-10-07 13:07:26 +020013 * SPDX-License-Identifier: GPL-2.0+
Dirk Behme7d75a102008-12-14 09:47:13 +010014 */
15
Wolfgang Denk0191e472010-10-26 14:34:52 +020016#include <asm-offsets.h>
Dirk Behme7d75a102008-12-14 09:47:13 +010017#include <config.h>
18#include <version.h>
Aneesh V688ee132011-11-21 23:34:00 +000019#include <asm/system.h>
Aneesh Vfd8798b2012-03-08 07:20:18 +000020#include <linux/linkage.h>
Dirk Behme7d75a102008-12-14 09:47:13 +010021
22.globl _start
23_start: b reset
24 ldr pc, _undefined_instruction
25 ldr pc, _software_interrupt
26 ldr pc, _prefetch_abort
27 ldr pc, _data_abort
28 ldr pc, _not_used
29 ldr pc, _irq
30 ldr pc, _fiq
Aneesh Vef0f76e2011-07-21 09:10:18 -040031#ifdef CONFIG_SPL_BUILD
32_undefined_instruction: .word _undefined_instruction
33_software_interrupt: .word _software_interrupt
34_prefetch_abort: .word _prefetch_abort
35_data_abort: .word _data_abort
36_not_used: .word _not_used
37_irq: .word _irq
38_fiq: .word _fiq
39_pad: .word 0x12345678 /* now 16*4=64 */
40#else
Marek Vasuteb54c6b2013-12-14 05:55:26 +010041.globl _undefined_instruction
Dirk Behme7d75a102008-12-14 09:47:13 +010042_undefined_instruction: .word undefined_instruction
Marek Vasuteb54c6b2013-12-14 05:55:26 +010043.globl _software_interrupt
Dirk Behme7d75a102008-12-14 09:47:13 +010044_software_interrupt: .word software_interrupt
Marek Vasuteb54c6b2013-12-14 05:55:26 +010045.globl _prefetch_abort
Dirk Behme7d75a102008-12-14 09:47:13 +010046_prefetch_abort: .word prefetch_abort
Marek Vasuteb54c6b2013-12-14 05:55:26 +010047.globl _data_abort
Dirk Behme7d75a102008-12-14 09:47:13 +010048_data_abort: .word data_abort
Marek Vasuteb54c6b2013-12-14 05:55:26 +010049.globl _not_used
Dirk Behme7d75a102008-12-14 09:47:13 +010050_not_used: .word not_used
Marek Vasuteb54c6b2013-12-14 05:55:26 +010051.globl _irq
Dirk Behme7d75a102008-12-14 09:47:13 +010052_irq: .word irq
Marek Vasuteb54c6b2013-12-14 05:55:26 +010053.globl _fiq
Dirk Behme7d75a102008-12-14 09:47:13 +010054_fiq: .word fiq
55_pad: .word 0x12345678 /* now 16*4=64 */
Aneesh Vef0f76e2011-07-21 09:10:18 -040056#endif /* CONFIG_SPL_BUILD */
57
Dirk Behme7d75a102008-12-14 09:47:13 +010058.global _end_vect
59_end_vect:
60
61 .balignl 16,0xdeadbeef
62/*************************************************************************
63 *
64 * Startup Code (reset vector)
65 *
66 * do important init only if we don't start from memory!
67 * setup Memory and board specific bits prior to relocation.
68 * relocate armboot to ram
69 * setup stack
70 *
71 *************************************************************************/
72
Heiko Schocher56d0a4d2010-09-17 13:10:41 +020073.globl _TEXT_BASE
Dirk Behme7d75a102008-12-14 09:47:13 +010074_TEXT_BASE:
Benoît Thébaudeaua402da32013-04-11 09:35:42 +000075#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE)
76 .word CONFIG_SPL_TEXT_BASE
77#else
Wolfgang Denk0708bc62010-10-07 21:51:12 +020078 .word CONFIG_SYS_TEXT_BASE
Benoît Thébaudeaua402da32013-04-11 09:35:42 +000079#endif
Dirk Behme7d75a102008-12-14 09:47:13 +010080
Dirk Behme7d75a102008-12-14 09:47:13 +010081/*
82 * These are defined in the board-specific linker script.
83 */
Heiko Schocher661a29e2010-10-11 14:08:15 +020084.globl _bss_start_ofs
85_bss_start_ofs:
86 .word __bss_start - _start
Dirk Behme7d75a102008-12-14 09:47:13 +010087
Heiko Schocher661a29e2010-10-11 14:08:15 +020088.globl _bss_end_ofs
89_bss_end_ofs:
Simon Glassed70c8f2013-03-14 06:54:53 +000090 .word __bss_end - _start
Dirk Behme7d75a102008-12-14 09:47:13 +010091
Po-Yu Chuang1864b002011-03-01 23:02:04 +000092.globl _end_ofs
93_end_ofs:
94 .word _end - _start
95
Dirk Behme7d75a102008-12-14 09:47:13 +010096#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 Schocher56d0a4d2010-09-17 13:10:41 +0200108/* IRQ stack memory (calculated at run-time) + 8 bytes */
109.globl IRQ_STACK_START_IN
110IRQ_STACK_START_IN:
111 .word 0x0badc0de
112
Dirk Behme7d75a102008-12-14 09:47:13 +0100113/*
114 * the actual reset code
115 */
116
117reset:
Aneesh V13a74c12011-07-21 09:10:27 -0400118 bl save_boot_params
Dirk Behme7d75a102008-12-14 09:47:13 +0100119 /*
Andre Przywara7acb96b2013-04-02 05:43:36 +0000120 * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
121 * except if in HYP mode already
Dirk Behme7d75a102008-12-14 09:47:13 +0100122 */
123 mrs r0, cpsr
Andre Przywara7acb96b2013-04-02 05:43:36 +0000124 and r1, r0, #0x1f @ mask mode bits
125 teq r1, #0x1a @ test for HYP mode
126 bicne r0, r0, #0x1f @ clear all mode bits
127 orrne r0, r0, #0x13 @ set SVC mode
128 orr r0, r0, #0xc0 @ disable FIQ and IRQ
Dirk Behme7d75a102008-12-14 09:47:13 +0100129 msr cpsr,r0
130
Aneesh V688ee132011-11-21 23:34:00 +0000131/*
132 * Setup vector:
133 * (OMAP4 spl TEXT_BASE is not 32 byte aligned.
134 * Continue to use ROM code vector only in OMAP4 spl)
135 */
136#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
137 /* Set V=0 in CP15 SCTRL register - for VBAR to point to vector */
138 mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTRL Register
139 bic r0, #CR_V @ V = 0
140 mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTRL Register
141
142 /* Set vector address in CP15 VBAR register */
143 ldr r0, =_start
144 mcr p15, 0, r0, c12, c0, 0 @Set VBAR
145#endif
146
Dirk Behme7d75a102008-12-14 09:47:13 +0100147 /* the mask ROM code should have PLL and others stable */
148#ifndef CONFIG_SKIP_LOWLEVEL_INIT
Simon Glass277e3082011-11-05 03:56:51 +0000149 bl cpu_init_cp15
Dirk Behme7d75a102008-12-14 09:47:13 +0100150 bl cpu_init_crit
151#endif
152
Albert ARIBAUDfacdae52013-01-08 10:18:02 +0000153 bl _main
Heiko Schocher56d0a4d2010-09-17 13:10:41 +0200154
155/*------------------------------------------------------------------------------*/
156
Albert ARIBAUDfacdae52013-01-08 10:18:02 +0000157ENTRY(c_runtime_cpu_setup)
Aneesh V3e3bc1e2011-06-16 23:30:49 +0000158/*
159 * If I-cache is enabled invalidate it
160 */
161#ifndef CONFIG_SYS_ICACHE_OFF
162 mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
163 mcr p15, 0, r0, c7, c10, 4 @ DSB
164 mcr p15, 0, r0, c7, c5, 4 @ ISB
165#endif
Tetsuyuki Kobayashi61c70db2012-06-25 02:40:57 +0000166/*
167 * Move vector table
168 */
Tetsuyuki Kobayashi61c70db2012-06-25 02:40:57 +0000169 /* Set vector address in CP15 VBAR register */
170 ldr r0, =_start
Tetsuyuki Kobayashi61c70db2012-06-25 02:40:57 +0000171 mcr p15, 0, r0, c12, c0, 0 @Set VBAR
Tetsuyuki Kobayashi61c70db2012-06-25 02:40:57 +0000172
Albert ARIBAUDfacdae52013-01-08 10:18:02 +0000173 bx lr
Heiko Schocher56d0a4d2010-09-17 13:10:41 +0200174
Albert ARIBAUDfacdae52013-01-08 10:18:02 +0000175ENDPROC(c_runtime_cpu_setup)
Heiko Schocher661a29e2010-10-11 14:08:15 +0200176
Dirk Behme7d75a102008-12-14 09:47:13 +0100177/*************************************************************************
178 *
Tetsuyuki Kobayashi153ba382012-07-06 21:14:20 +0000179 * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
180 * __attribute__((weak));
181 *
182 * Stack pointer is not yet initialized at this moment
183 * Don't save anything to stack even if compiled with -O0
184 *
185 *************************************************************************/
186ENTRY(save_boot_params)
187 bx lr @ back to my caller
188ENDPROC(save_boot_params)
189 .weak save_boot_params
190
191/*************************************************************************
192 *
Simon Glass277e3082011-11-05 03:56:51 +0000193 * cpu_init_cp15
Dirk Behme7d75a102008-12-14 09:47:13 +0100194 *
Simon Glass277e3082011-11-05 03:56:51 +0000195 * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless
196 * CONFIG_SYS_ICACHE_OFF is defined.
Dirk Behme7d75a102008-12-14 09:47:13 +0100197 *
198 *************************************************************************/
Aneesh Vfd8798b2012-03-08 07:20:18 +0000199ENTRY(cpu_init_cp15)
Dirk Behme7d75a102008-12-14 09:47:13 +0100200 /*
201 * Invalidate L1 I/D
202 */
203 mov r0, #0 @ set up for MCR
204 mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
205 mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
Aneesh V3e3bc1e2011-06-16 23:30:49 +0000206 mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array
207 mcr p15, 0, r0, c7, c10, 4 @ DSB
208 mcr p15, 0, r0, c7, c5, 4 @ ISB
Dirk Behme7d75a102008-12-14 09:47:13 +0100209
210 /*
211 * disable MMU stuff and caches
212 */
213 mrc p15, 0, r0, c1, c0, 0
214 bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
215 bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
216 orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
Aneesh V3e3bc1e2011-06-16 23:30:49 +0000217 orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
218#ifdef CONFIG_SYS_ICACHE_OFF
219 bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache
220#else
221 orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache
222#endif
Dirk Behme7d75a102008-12-14 09:47:13 +0100223 mcr p15, 0, r0, c1, c0, 0
Stephen Warrene9d59c92013-02-26 12:28:27 +0000224
Stephen Warrenc63c3502013-03-04 13:29:40 +0000225#ifdef CONFIG_ARM_ERRATA_716044
226 mrc p15, 0, r0, c1, c0, 0 @ read system control register
227 orr r0, r0, #1 << 11 @ set bit #11
228 mcr p15, 0, r0, c1, c0, 0 @ write system control register
229#endif
230
Stephen Warrene9d59c92013-02-26 12:28:27 +0000231#ifdef CONFIG_ARM_ERRATA_742230
232 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
233 orr r0, r0, #1 << 4 @ set bit #4
234 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
235#endif
236
237#ifdef CONFIG_ARM_ERRATA_743622
238 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
239 orr r0, r0, #1 << 6 @ set bit #6
240 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
241#endif
242
243#ifdef CONFIG_ARM_ERRATA_751472
244 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
245 orr r0, r0, #1 << 11 @ set bit #11
246 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
247#endif
248
Simon Glass277e3082011-11-05 03:56:51 +0000249 mov pc, lr @ back to my caller
Aneesh Vfd8798b2012-03-08 07:20:18 +0000250ENDPROC(cpu_init_cp15)
Dirk Behme7d75a102008-12-14 09:47:13 +0100251
Simon Glass277e3082011-11-05 03:56:51 +0000252#ifndef CONFIG_SKIP_LOWLEVEL_INIT
253/*************************************************************************
254 *
255 * CPU_init_critical registers
256 *
257 * setup important registers
258 * setup memory timing
259 *
260 *************************************************************************/
Aneesh Vfd8798b2012-03-08 07:20:18 +0000261ENTRY(cpu_init_crit)
Dirk Behme7d75a102008-12-14 09:47:13 +0100262 /*
263 * Jump to board specific initialization...
264 * The Mask ROM will have already initialized
265 * basic memory. Go here to bump up clock rate and handle
266 * wake up conditions.
267 */
Benoît Thébaudeau0a167902012-08-10 12:05:16 +0000268 b lowlevel_init @ go setup pll,mux,memory
Aneesh Vfd8798b2012-03-08 07:20:18 +0000269ENDPROC(cpu_init_crit)
Rob Herringa6932872011-06-28 05:39:38 +0000270#endif
Aneesh Vef0f76e2011-07-21 09:10:18 -0400271
272#ifndef CONFIG_SPL_BUILD
Dirk Behme7d75a102008-12-14 09:47:13 +0100273/*
274 *************************************************************************
275 *
276 * Interrupt handling
277 *
278 *************************************************************************
279 */
280@
281@ IRQ stack frame.
282@
283#define S_FRAME_SIZE 72
284
285#define S_OLD_R0 68
286#define S_PSR 64
287#define S_PC 60
288#define S_LR 56
289#define S_SP 52
290
291#define S_IP 48
292#define S_FP 44
293#define S_R10 40
294#define S_R9 36
295#define S_R8 32
296#define S_R7 28
297#define S_R6 24
298#define S_R5 20
299#define S_R4 16
300#define S_R3 12
301#define S_R2 8
302#define S_R1 4
303#define S_R0 0
304
305#define MODE_SVC 0x13
306#define I_BIT 0x80
307
308/*
309 * use bad_save_user_regs for abort/prefetch/undef/swi ...
310 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
311 */
312
313 .macro bad_save_user_regs
314 sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current
315 @ user stack
316 stmia sp, {r0 - r12} @ Save user registers (now in
317 @ svc mode) r0-r12
Heiko Schocher56d0a4d2010-09-17 13:10:41 +0200318 ldr r2, IRQ_STACK_START_IN @ set base 2 words into abort
Dirk Behme7d75a102008-12-14 09:47:13 +0100319 @ stack
320 ldmia r2, {r2 - r3} @ get values for "aborted" pc
321 @ and cpsr (into parm regs)
322 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
323
324 add r5, sp, #S_SP
325 mov r1, lr
326 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
327 mov r0, sp @ save current stack into r0
328 @ (param register)
329 .endm
330
331 .macro irq_save_user_regs
332 sub sp, sp, #S_FRAME_SIZE
333 stmia sp, {r0 - r12} @ Calling r0-r12
334 add r8, sp, #S_PC @ !! R8 NEEDS to be saved !!
335 @ a reserved stack spot would
336 @ be good.
337 stmdb r8, {sp, lr}^ @ Calling SP, LR
338 str lr, [r8, #0] @ Save calling PC
339 mrs r6, spsr
340 str r6, [r8, #4] @ Save CPSR
341 str r0, [r8, #8] @ Save OLD_R0
342 mov r0, sp
343 .endm
344
345 .macro irq_restore_user_regs
346 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
347 mov r0, r0
348 ldr lr, [sp, #S_PC] @ Get PC
349 add sp, sp, #S_FRAME_SIZE
350 subs pc, lr, #4 @ return & move spsr_svc into
351 @ cpsr
352 .endm
353
354 .macro get_bad_stack
Heiko Schocher56d0a4d2010-09-17 13:10:41 +0200355 ldr r13, IRQ_STACK_START_IN @ setup our mode stack (enter
356 @ in banked mode)
Dirk Behme7d75a102008-12-14 09:47:13 +0100357
358 str lr, [r13] @ save caller lr in position 0
359 @ of saved stack
360 mrs lr, spsr @ get the spsr
361 str lr, [r13, #4] @ save spsr in position 1 of
362 @ saved stack
363
364 mov r13, #MODE_SVC @ prepare SVC-Mode
365 @ msr spsr_c, r13
366 msr spsr, r13 @ switch modes, make sure
367 @ moves will execute
368 mov lr, pc @ capture return pc
369 movs pc, lr @ jump to next instruction &
370 @ switch modes.
371 .endm
372
373 .macro get_bad_stack_swi
374 sub r13, r13, #4 @ space on current stack for
375 @ scratch reg.
376 str r0, [r13] @ save R0's value.
Heiko Schocher56d0a4d2010-09-17 13:10:41 +0200377 ldr r0, IRQ_STACK_START_IN @ get data regions start
Dirk Behme7d75a102008-12-14 09:47:13 +0100378 @ spots for abort stack
379 str lr, [r0] @ save caller lr in position 0
380 @ of saved stack
Tetsuyuki Kobayashib023a952013-04-05 00:12:51 +0000381 mrs lr, spsr @ get the spsr
Dirk Behme7d75a102008-12-14 09:47:13 +0100382 str lr, [r0, #4] @ save spsr in position 1 of
383 @ saved stack
Tetsuyuki Kobayashib023a952013-04-05 00:12:51 +0000384 ldr lr, [r0] @ restore lr
Dirk Behme7d75a102008-12-14 09:47:13 +0100385 ldr r0, [r13] @ restore r0
386 add r13, r13, #4 @ pop stack entry
387 .endm
388
389 .macro get_irq_stack @ setup IRQ stack
390 ldr sp, IRQ_STACK_START
391 .endm
392
393 .macro get_fiq_stack @ setup FIQ stack
394 ldr sp, FIQ_STACK_START
395 .endm
396
397/*
398 * exception handlers
399 */
400 .align 5
401undefined_instruction:
402 get_bad_stack
403 bad_save_user_regs
404 bl do_undefined_instruction
405
406 .align 5
407software_interrupt:
408 get_bad_stack_swi
409 bad_save_user_regs
410 bl do_software_interrupt
411
412 .align 5
413prefetch_abort:
414 get_bad_stack
415 bad_save_user_regs
416 bl do_prefetch_abort
417
418 .align 5
419data_abort:
420 get_bad_stack
421 bad_save_user_regs
422 bl do_data_abort
423
424 .align 5
425not_used:
426 get_bad_stack
427 bad_save_user_regs
428 bl do_not_used
429
430#ifdef CONFIG_USE_IRQ
431
432 .align 5
433irq:
434 get_irq_stack
435 irq_save_user_regs
436 bl do_irq
437 irq_restore_user_regs
438
439 .align 5
440fiq:
441 get_fiq_stack
442 /* someone ought to write a more effective fiq_save_user_regs */
443 irq_save_user_regs
444 bl do_fiq
445 irq_restore_user_regs
446
447#else
448
449 .align 5
450irq:
451 get_bad_stack
452 bad_save_user_regs
453 bl do_irq
454
455 .align 5
456fiq:
457 get_bad_stack
458 bad_save_user_regs
459 bl do_fiq
460
Aneesh Vef0f76e2011-07-21 09:10:18 -0400461#endif /* CONFIG_USE_IRQ */
462#endif /* CONFIG_SPL_BUILD */