blob: eefe1ed254955455154528040e0302a95200f4c3 [file] [log] [blame]
Dirk Behme0b02b182008-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 Zundel792a09e2009-05-13 10:54:10 +02008 * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
Dirk Behme0b02b182008-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 Denk3765b3e2013-10-07 13:07:26 +020013 * SPDX-License-Identifier: GPL-2.0+
Dirk Behme0b02b182008-12-14 09:47:13 +010014 */
15
Wolfgang Denk25ddd1f2010-10-26 14:34:52 +020016#include <asm-offsets.h>
Dirk Behme0b02b182008-12-14 09:47:13 +010017#include <config.h>
18#include <version.h>
Aneesh Va8c68632011-11-21 23:34:00 +000019#include <asm/system.h>
Aneesh V74236ac2012-03-08 07:20:18 +000020#include <linux/linkage.h>
Dirk Behme0b02b182008-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 V033ca722011-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 Vasut7cbe6382013-12-14 05:55:26 +010041.globl _undefined_instruction
Dirk Behme0b02b182008-12-14 09:47:13 +010042_undefined_instruction: .word undefined_instruction
Marek Vasut7cbe6382013-12-14 05:55:26 +010043.globl _software_interrupt
Dirk Behme0b02b182008-12-14 09:47:13 +010044_software_interrupt: .word software_interrupt
Marek Vasut7cbe6382013-12-14 05:55:26 +010045.globl _prefetch_abort
Dirk Behme0b02b182008-12-14 09:47:13 +010046_prefetch_abort: .word prefetch_abort
Marek Vasut7cbe6382013-12-14 05:55:26 +010047.globl _data_abort
Dirk Behme0b02b182008-12-14 09:47:13 +010048_data_abort: .word data_abort
Marek Vasut7cbe6382013-12-14 05:55:26 +010049.globl _not_used
Dirk Behme0b02b182008-12-14 09:47:13 +010050_not_used: .word not_used
Marek Vasut7cbe6382013-12-14 05:55:26 +010051.globl _irq
Dirk Behme0b02b182008-12-14 09:47:13 +010052_irq: .word irq
Marek Vasut7cbe6382013-12-14 05:55:26 +010053.globl _fiq
Dirk Behme0b02b182008-12-14 09:47:13 +010054_fiq: .word fiq
55_pad: .word 0x12345678 /* now 16*4=64 */
Aneesh V033ca722011-07-21 09:10:18 -040056#endif /* CONFIG_SPL_BUILD */
57
Dirk Behme0b02b182008-12-14 09:47:13 +010058 .balignl 16,0xdeadbeef
59/*************************************************************************
60 *
61 * Startup Code (reset vector)
62 *
63 * do important init only if we don't start from memory!
64 * setup Memory and board specific bits prior to relocation.
65 * relocate armboot to ram
66 * setup stack
67 *
68 *************************************************************************/
69
Dirk Behme0b02b182008-12-14 09:47:13 +010070#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 Schocher561142a2010-09-17 13:10:41 +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 Schocher561142a2010-09-17 13:10:41 +020087/*
88 * the actual reset code
89 */
90
91reset:
Aneesh V8cf686e2011-07-21 09:10:27 -040092 bl save_boot_params
Heiko Schocher561142a2010-09-17 13:10:41 +020093 /*
Andre Przywarac4a4e2e2013-04-02 05:43:36 +000094 * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
95 * except if in HYP mode already
Heiko Schocher561142a2010-09-17 13:10:41 +020096 */
97 mrs r0, cpsr
Andre Przywarac4a4e2e2013-04-02 05:43:36 +000098 and r1, r0, #0x1f @ mask mode bits
99 teq r1, #0x1a @ test for HYP mode
100 bicne r0, r0, #0x1f @ clear all mode bits
101 orrne r0, r0, #0x13 @ set SVC mode
102 orr r0, r0, #0xc0 @ disable FIQ and IRQ
Heiko Schocher561142a2010-09-17 13:10:41 +0200103 msr cpsr,r0
104
Aneesh Va8c68632011-11-21 23:34:00 +0000105/*
106 * Setup vector:
107 * (OMAP4 spl TEXT_BASE is not 32 byte aligned.
108 * Continue to use ROM code vector only in OMAP4 spl)
109 */
110#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
111 /* Set V=0 in CP15 SCTRL register - for VBAR to point to vector */
112 mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTRL Register
113 bic r0, #CR_V @ V = 0
114 mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTRL Register
115
116 /* Set vector address in CP15 VBAR register */
117 ldr r0, =_start
118 mcr p15, 0, r0, c12, c0, 0 @Set VBAR
119#endif
120
Heiko Schocher561142a2010-09-17 13:10:41 +0200121 /* the mask ROM code should have PLL and others stable */
122#ifndef CONFIG_SKIP_LOWLEVEL_INIT
Simon Glass80433c92011-11-05 03:56:51 +0000123 bl cpu_init_cp15
Heiko Schocher561142a2010-09-17 13:10:41 +0200124 bl cpu_init_crit
125#endif
126
Albert ARIBAUDe05e5de2013-01-08 10:18:02 +0000127 bl _main
Heiko Schocher561142a2010-09-17 13:10:41 +0200128
129/*------------------------------------------------------------------------------*/
130
Albert ARIBAUDe05e5de2013-01-08 10:18:02 +0000131ENTRY(c_runtime_cpu_setup)
Aneesh Vc2dd0d42011-06-16 23:30:49 +0000132/*
133 * If I-cache is enabled invalidate it
134 */
135#ifndef CONFIG_SYS_ICACHE_OFF
136 mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
137 mcr p15, 0, r0, c7, c10, 4 @ DSB
138 mcr p15, 0, r0, c7, c5, 4 @ ISB
139#endif
Tetsuyuki Kobayashif8b9d1d2012-06-25 02:40:57 +0000140/*
141 * Move vector table
142 */
Tetsuyuki Kobayashif8b9d1d2012-06-25 02:40:57 +0000143 /* Set vector address in CP15 VBAR register */
144 ldr r0, =_start
Tetsuyuki Kobayashif8b9d1d2012-06-25 02:40:57 +0000145 mcr p15, 0, r0, c12, c0, 0 @Set VBAR
Tetsuyuki Kobayashif8b9d1d2012-06-25 02:40:57 +0000146
Albert ARIBAUDe05e5de2013-01-08 10:18:02 +0000147 bx lr
Heiko Schocher561142a2010-09-17 13:10:41 +0200148
Albert ARIBAUDe05e5de2013-01-08 10:18:02 +0000149ENDPROC(c_runtime_cpu_setup)
Heiko Schocherc3d3a542010-10-11 14:08:15 +0200150
Dirk Behme0b02b182008-12-14 09:47:13 +0100151/*************************************************************************
152 *
Tetsuyuki Kobayashi6f0dba82012-07-06 21:14:20 +0000153 * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
154 * __attribute__((weak));
155 *
156 * Stack pointer is not yet initialized at this moment
157 * Don't save anything to stack even if compiled with -O0
158 *
159 *************************************************************************/
160ENTRY(save_boot_params)
161 bx lr @ back to my caller
162ENDPROC(save_boot_params)
163 .weak save_boot_params
164
165/*************************************************************************
166 *
Simon Glass80433c92011-11-05 03:56:51 +0000167 * cpu_init_cp15
Dirk Behme0b02b182008-12-14 09:47:13 +0100168 *
Simon Glass80433c92011-11-05 03:56:51 +0000169 * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless
170 * CONFIG_SYS_ICACHE_OFF is defined.
Dirk Behme0b02b182008-12-14 09:47:13 +0100171 *
172 *************************************************************************/
Aneesh V74236ac2012-03-08 07:20:18 +0000173ENTRY(cpu_init_cp15)
Dirk Behme0b02b182008-12-14 09:47:13 +0100174 /*
175 * Invalidate L1 I/D
176 */
177 mov r0, #0 @ set up for MCR
178 mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
179 mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
Aneesh Vc2dd0d42011-06-16 23:30:49 +0000180 mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array
181 mcr p15, 0, r0, c7, c10, 4 @ DSB
182 mcr p15, 0, r0, c7, c5, 4 @ ISB
Dirk Behme0b02b182008-12-14 09:47:13 +0100183
184 /*
185 * disable MMU stuff and caches
186 */
187 mrc p15, 0, r0, c1, c0, 0
188 bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
189 bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
190 orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
Aneesh Vc2dd0d42011-06-16 23:30:49 +0000191 orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
192#ifdef CONFIG_SYS_ICACHE_OFF
193 bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache
194#else
195 orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache
196#endif
Dirk Behme0b02b182008-12-14 09:47:13 +0100197 mcr p15, 0, r0, c1, c0, 0
Stephen Warren06785872013-02-26 12:28:27 +0000198
Stephen Warrenc5d47522013-03-04 13:29:40 +0000199#ifdef CONFIG_ARM_ERRATA_716044
200 mrc p15, 0, r0, c1, c0, 0 @ read system control register
201 orr r0, r0, #1 << 11 @ set bit #11
202 mcr p15, 0, r0, c1, c0, 0 @ write system control register
203#endif
204
Nitin Gargf71cbfe2014-04-02 08:55:01 -0500205#if (defined(CONFIG_ARM_ERRATA_742230) || defined(CONFIG_ARM_ERRATA_794072))
Stephen Warren06785872013-02-26 12:28:27 +0000206 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
207 orr r0, r0, #1 << 4 @ set bit #4
208 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
209#endif
210
211#ifdef CONFIG_ARM_ERRATA_743622
212 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
213 orr r0, r0, #1 << 6 @ set bit #6
214 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
215#endif
216
217#ifdef CONFIG_ARM_ERRATA_751472
218 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
219 orr r0, r0, #1 << 11 @ set bit #11
220 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
221#endif
Nitin Gargb7588e32014-04-02 08:55:02 -0500222#ifdef CONFIG_ARM_ERRATA_761320
223 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
224 orr r0, r0, #1 << 21 @ set bit #21
225 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
226#endif
Stephen Warren06785872013-02-26 12:28:27 +0000227
Simon Glass80433c92011-11-05 03:56:51 +0000228 mov pc, lr @ back to my caller
Aneesh V74236ac2012-03-08 07:20:18 +0000229ENDPROC(cpu_init_cp15)
Simon Glass80433c92011-11-05 03:56:51 +0000230
231#ifndef CONFIG_SKIP_LOWLEVEL_INIT
232/*************************************************************************
233 *
234 * CPU_init_critical registers
235 *
236 * setup important registers
237 * setup memory timing
238 *
239 *************************************************************************/
Aneesh V74236ac2012-03-08 07:20:18 +0000240ENTRY(cpu_init_crit)
Dirk Behme0b02b182008-12-14 09:47:13 +0100241 /*
242 * Jump to board specific initialization...
243 * The Mask ROM will have already initialized
244 * basic memory. Go here to bump up clock rate and handle
245 * wake up conditions.
246 */
Benoît Thébaudeau63ee53a2012-08-10 12:05:16 +0000247 b lowlevel_init @ go setup pll,mux,memory
Aneesh V74236ac2012-03-08 07:20:18 +0000248ENDPROC(cpu_init_crit)
Rob Herring22193542011-06-28 05:39:38 +0000249#endif
Aneesh V033ca722011-07-21 09:10:18 -0400250
251#ifndef CONFIG_SPL_BUILD
Dirk Behme0b02b182008-12-14 09:47:13 +0100252/*
253 *************************************************************************
254 *
255 * Interrupt handling
256 *
257 *************************************************************************
258 */
259@
260@ IRQ stack frame.
261@
262#define S_FRAME_SIZE 72
263
264#define S_OLD_R0 68
265#define S_PSR 64
266#define S_PC 60
267#define S_LR 56
268#define S_SP 52
269
270#define S_IP 48
271#define S_FP 44
272#define S_R10 40
273#define S_R9 36
274#define S_R8 32
275#define S_R7 28
276#define S_R6 24
277#define S_R5 20
278#define S_R4 16
279#define S_R3 12
280#define S_R2 8
281#define S_R1 4
282#define S_R0 0
283
284#define MODE_SVC 0x13
285#define I_BIT 0x80
286
287/*
288 * use bad_save_user_regs for abort/prefetch/undef/swi ...
289 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
290 */
291
292 .macro bad_save_user_regs
293 sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current
294 @ user stack
295 stmia sp, {r0 - r12} @ Save user registers (now in
296 @ svc mode) r0-r12
Heiko Schocher561142a2010-09-17 13:10:41 +0200297 ldr r2, IRQ_STACK_START_IN @ set base 2 words into abort
Dirk Behme0b02b182008-12-14 09:47:13 +0100298 @ stack
299 ldmia r2, {r2 - r3} @ get values for "aborted" pc
300 @ and cpsr (into parm regs)
301 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
302
303 add r5, sp, #S_SP
304 mov r1, lr
305 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
306 mov r0, sp @ save current stack into r0
307 @ (param register)
308 .endm
309
310 .macro irq_save_user_regs
311 sub sp, sp, #S_FRAME_SIZE
312 stmia sp, {r0 - r12} @ Calling r0-r12
313 add r8, sp, #S_PC @ !! R8 NEEDS to be saved !!
314 @ a reserved stack spot would
315 @ be good.
316 stmdb r8, {sp, lr}^ @ Calling SP, LR
317 str lr, [r8, #0] @ Save calling PC
318 mrs r6, spsr
319 str r6, [r8, #4] @ Save CPSR
320 str r0, [r8, #8] @ Save OLD_R0
321 mov r0, sp
322 .endm
323
324 .macro irq_restore_user_regs
325 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
326 mov r0, r0
327 ldr lr, [sp, #S_PC] @ Get PC
328 add sp, sp, #S_FRAME_SIZE
329 subs pc, lr, #4 @ return & move spsr_svc into
330 @ cpsr
331 .endm
332
333 .macro get_bad_stack
Heiko Schocher561142a2010-09-17 13:10:41 +0200334 ldr r13, IRQ_STACK_START_IN @ setup our mode stack (enter
335 @ in banked mode)
Dirk Behme0b02b182008-12-14 09:47:13 +0100336
337 str lr, [r13] @ save caller lr in position 0
338 @ of saved stack
339 mrs lr, spsr @ get the spsr
340 str lr, [r13, #4] @ save spsr in position 1 of
341 @ saved stack
342
343 mov r13, #MODE_SVC @ prepare SVC-Mode
344 @ msr spsr_c, r13
345 msr spsr, r13 @ switch modes, make sure
346 @ moves will execute
347 mov lr, pc @ capture return pc
348 movs pc, lr @ jump to next instruction &
349 @ switch modes.
350 .endm
351
352 .macro get_bad_stack_swi
353 sub r13, r13, #4 @ space on current stack for
354 @ scratch reg.
355 str r0, [r13] @ save R0's value.
Heiko Schocher561142a2010-09-17 13:10:41 +0200356 ldr r0, IRQ_STACK_START_IN @ get data regions start
Dirk Behme0b02b182008-12-14 09:47:13 +0100357 @ spots for abort stack
358 str lr, [r0] @ save caller lr in position 0
359 @ of saved stack
Tetsuyuki Kobayashi4411b2a2013-04-05 00:12:51 +0000360 mrs lr, spsr @ get the spsr
Dirk Behme0b02b182008-12-14 09:47:13 +0100361 str lr, [r0, #4] @ save spsr in position 1 of
362 @ saved stack
Tetsuyuki Kobayashi4411b2a2013-04-05 00:12:51 +0000363 ldr lr, [r0] @ restore lr
Dirk Behme0b02b182008-12-14 09:47:13 +0100364 ldr r0, [r13] @ restore r0
365 add r13, r13, #4 @ pop stack entry
366 .endm
367
368 .macro get_irq_stack @ setup IRQ stack
369 ldr sp, IRQ_STACK_START
370 .endm
371
372 .macro get_fiq_stack @ setup FIQ stack
373 ldr sp, FIQ_STACK_START
374 .endm
375
376/*
377 * exception handlers
378 */
379 .align 5
380undefined_instruction:
381 get_bad_stack
382 bad_save_user_regs
383 bl do_undefined_instruction
384
385 .align 5
386software_interrupt:
387 get_bad_stack_swi
388 bad_save_user_regs
389 bl do_software_interrupt
390
391 .align 5
392prefetch_abort:
393 get_bad_stack
394 bad_save_user_regs
395 bl do_prefetch_abort
396
397 .align 5
398data_abort:
399 get_bad_stack
400 bad_save_user_regs
401 bl do_data_abort
402
403 .align 5
404not_used:
405 get_bad_stack
406 bad_save_user_regs
407 bl do_not_used
408
409#ifdef CONFIG_USE_IRQ
410
411 .align 5
412irq:
413 get_irq_stack
414 irq_save_user_regs
415 bl do_irq
416 irq_restore_user_regs
417
418 .align 5
419fiq:
420 get_fiq_stack
421 /* someone ought to write a more effective fiq_save_user_regs */
422 irq_save_user_regs
423 bl do_fiq
424 irq_restore_user_regs
425
426#else
427
428 .align 5
429irq:
430 get_bad_stack
431 bad_save_user_regs
432 bl do_irq
433
434 .align 5
435fiq:
436 get_bad_stack
437 bad_save_user_regs
438 bl do_fiq
439
Aneesh V033ca722011-07-21 09:10:18 -0400440#endif /* CONFIG_USE_IRQ */
441#endif /* CONFIG_SPL_BUILD */