blob: 3e2358e132b0d37af789da5d7b2004df4c1070b7 [file] [log] [blame]
wdenk8ed96042005-01-09 23:16:25 +00001/*
2 * armboot - Startup Code for OMP2420/ARM1136 CPU-core
3 *
wdenk082acfd2005-01-10 00:01:04 +00004 * Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com>
wdenk8ed96042005-01-09 23:16:25 +00005 *
Albert ARIBAUDfa82f872011-08-04 18:45:45 +02006 * 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>
wdenk8ed96042005-01-09 23:16:25 +00009 * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
10 * Copyright (c) 2003 Kshitij <kshitij@ti.com>
11 *
Wolfgang Denk3765b3e2013-10-07 13:07:26 +020012 * SPDX-License-Identifier: GPL-2.0+
wdenk8ed96042005-01-09 23:16:25 +000013 */
14
Wolfgang Denk25ddd1f2010-10-26 14:34:52 +020015#include <asm-offsets.h>
wdenk8ed96042005-01-09 23:16:25 +000016#include <config.h>
17#include <version.h>
wdenk8ed96042005-01-09 23:16:25 +000018.globl _start
wdenk082acfd2005-01-10 00:01:04 +000019_start: b reset
Aneesh V401bb302011-07-13 05:11:07 +000020#ifdef CONFIG_SPL_BUILD
Kyungmin Park751b9b52008-01-17 16:43:25 +090021 ldr pc, _hang
22 ldr pc, _hang
23 ldr pc, _hang
24 ldr pc, _hang
25 ldr pc, _hang
26 ldr pc, _hang
27 ldr pc, _hang
28
29_hang:
30 .word do_hang
31 .word 0x12345678
32 .word 0x12345678
33 .word 0x12345678
34 .word 0x12345678
35 .word 0x12345678
36 .word 0x12345678
37 .word 0x12345678 /* now 16*4=64 */
38#else
wdenk8ed96042005-01-09 23:16:25 +000039 ldr pc, _undefined_instruction
40 ldr pc, _software_interrupt
41 ldr pc, _prefetch_abort
42 ldr pc, _data_abort
43 ldr pc, _not_used
44 ldr pc, _irq
45 ldr pc, _fiq
46
wdenk082acfd2005-01-10 00:01:04 +000047_undefined_instruction: .word undefined_instruction
wdenk8ed96042005-01-09 23:16:25 +000048_software_interrupt: .word software_interrupt
49_prefetch_abort: .word prefetch_abort
50_data_abort: .word data_abort
51_not_used: .word not_used
52_irq: .word irq
53_fiq: .word fiq
wdenk082acfd2005-01-10 00:01:04 +000054_pad: .word 0x12345678 /* now 16*4=64 */
Aneesh V401bb302011-07-13 05:11:07 +000055#endif /* CONFIG_SPL_BUILD */
wdenk8ed96042005-01-09 23:16:25 +000056.global _end_vect
57_end_vect:
58
59 .balignl 16,0xdeadbeef
60/*
61 *************************************************************************
62 *
63 * Startup Code (reset vector)
64 *
65 * do important init only if we don't start from memory!
66 * setup Memory and board specific bits prior to relocation.
67 * relocate armboot to ram
68 * setup stack
69 *
70 *************************************************************************
71 */
72
wdenk8ed96042005-01-09 23:16:25 +000073#ifdef CONFIG_USE_IRQ
74/* IRQ stack memory (calculated at run-time) */
75.globl IRQ_STACK_START
76IRQ_STACK_START:
77 .word 0x0badc0de
78
79/* IRQ stack memory (calculated at run-time) */
80.globl FIQ_STACK_START
81FIQ_STACK_START:
82 .word 0x0badc0de
83#endif
84
Heiko Schochere48b7c02010-09-17 13:10:40 +020085/* IRQ stack memory (calculated at run-time) + 8 bytes */
86.globl IRQ_STACK_START_IN
87IRQ_STACK_START_IN:
88 .word 0x0badc0de
Heiko Schochere48b7c02010-09-17 13:10:40 +020089
Heiko Schochere48b7c02010-09-17 13:10:40 +020090/*
91 * the actual reset code
92 */
93
94reset:
95 /*
96 * set the cpu to SVC32 mode
97 */
98 mrs r0,cpsr
99 bic r0,r0,#0x1f
100 orr r0,r0,#0xd3
101 msr cpsr,r0
102
Heiko Schochere48b7c02010-09-17 13:10:40 +0200103 /* the mask ROM code should have PLL and others stable */
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 Schochere48b7c02010-09-17 13:10:40 +0200109
110/*------------------------------------------------------------------------------*/
111
Albert ARIBAUDe05e5de2013-01-08 10:18:02 +0000112 .globl c_runtime_cpu_setup
113c_runtime_cpu_setup:
Heiko Schochere48b7c02010-09-17 13:10:40 +0200114
Albert ARIBAUDe05e5de2013-01-08 10:18:02 +0000115 bx lr
Heiko Schocherbafe7432010-10-13 07:57:14 +0200116
wdenk8ed96042005-01-09 23:16:25 +0000117/*
118 *************************************************************************
119 *
120 * CPU_init_critical registers
121 *
122 * setup important registers
123 * setup memory timing
124 *
125 *************************************************************************
126 */
Magnus Lilja40c642b2009-06-13 20:50:01 +0200127#ifndef CONFIG_SKIP_LOWLEVEL_INIT
wdenk8ed96042005-01-09 23:16:25 +0000128cpu_init_crit:
129 /*
130 * flush v4 I/D caches
131 */
132 mov r0, #0
George G. Davis409a07c2010-05-11 10:15:36 -0400133 mcr p15, 0, r0, c7, c7, 0 /* Invalidate I+D+BTB caches */
134 mcr p15, 0, r0, c8, c7, 0 /* Invalidate Unified TLB */
wdenk8ed96042005-01-09 23:16:25 +0000135
136 /*
137 * disable MMU stuff and caches
138 */
139 mrc p15, 0, r0, c1, c0, 0
140 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
141 bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
142 orr r0, r0, #0x00000002 @ set bit 2 (A) Align
wdenk8ed96042005-01-09 23:16:25 +0000143 orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
wdenk8ed96042005-01-09 23:16:25 +0000144 mcr p15, 0, r0, c1, c0, 0
145
146 /*
wdenk082acfd2005-01-10 00:01:04 +0000147 * Jump to board specific initialization... The Mask ROM will have already initialized
148 * basic memory. Go here to bump up clock rate and handle wake up conditions.
wdenk8ed96042005-01-09 23:16:25 +0000149 */
wdenk082acfd2005-01-10 00:01:04 +0000150 mov ip, lr /* persevere link reg across call */
Wolfgang Denk87cb6862005-10-06 17:08:18 +0200151 bl lowlevel_init /* go setup pll,mux,memory */
wdenk082acfd2005-01-10 00:01:04 +0000152 mov lr, ip /* restore link */
153 mov pc, lr /* back to my caller */
Magnus Lilja40c642b2009-06-13 20:50:01 +0200154#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
Kyungmin Park751b9b52008-01-17 16:43:25 +0900155
Aneesh V401bb302011-07-13 05:11:07 +0000156#ifndef CONFIG_SPL_BUILD
wdenk8ed96042005-01-09 23:16:25 +0000157/*
158 *************************************************************************
159 *
160 * Interrupt handling
161 *
162 *************************************************************************
163 */
164@
165@ IRQ stack frame.
166@
167#define S_FRAME_SIZE 72
168
169#define S_OLD_R0 68
170#define S_PSR 64
171#define S_PC 60
172#define S_LR 56
173#define S_SP 52
174
175#define S_IP 48
176#define S_FP 44
177#define S_R10 40
178#define S_R9 36
179#define S_R8 32
180#define S_R7 28
181#define S_R6 24
182#define S_R5 20
183#define S_R4 16
184#define S_R3 12
185#define S_R2 8
186#define S_R1 4
187#define S_R0 0
188
189#define MODE_SVC 0x13
190#define I_BIT 0x80
191
192/*
193 * use bad_save_user_regs for abort/prefetch/undef/swi ...
194 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
195 */
196
197 .macro bad_save_user_regs
wdenk082acfd2005-01-10 00:01:04 +0000198 sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current user stack
wdenk8ed96042005-01-09 23:16:25 +0000199 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
200
Heiko Schochere48b7c02010-09-17 13:10:40 +0200201 ldr r2, IRQ_STACK_START_IN @ set base 2 words into abort stack
wdenk082acfd2005-01-10 00:01:04 +0000202 ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs)
wdenk8ed96042005-01-09 23:16:25 +0000203 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
204
205 add r5, sp, #S_SP
206 mov r1, lr
wdenk082acfd2005-01-10 00:01:04 +0000207 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
208 mov r0, sp @ save current stack into r0 (param register)
wdenk8ed96042005-01-09 23:16:25 +0000209 .endm
210
211 .macro irq_save_user_regs
212 sub sp, sp, #S_FRAME_SIZE
213 stmia sp, {r0 - r12} @ Calling r0-r12
wdenk082acfd2005-01-10 00:01:04 +0000214 add r8, sp, #S_PC @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
215 stmdb r8, {sp, lr}^ @ Calling SP, LR
216 str lr, [r8, #0] @ Save calling PC
217 mrs r6, spsr
218 str r6, [r8, #4] @ Save CPSR
219 str r0, [r8, #8] @ Save OLD_R0
wdenk8ed96042005-01-09 23:16:25 +0000220 mov r0, sp
221 .endm
222
223 .macro irq_restore_user_regs
224 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
225 mov r0, r0
226 ldr lr, [sp, #S_PC] @ Get PC
227 add sp, sp, #S_FRAME_SIZE
228 subs pc, lr, #4 @ return & move spsr_svc into cpsr
229 .endm
230
231 .macro get_bad_stack
Heiko Schochere48b7c02010-09-17 13:10:40 +0200232 ldr r13, IRQ_STACK_START_IN @ setup our mode stack (enter in banked mode)
wdenk8ed96042005-01-09 23:16:25 +0000233
234 str lr, [r13] @ save caller lr in position 0 of saved stack
wdenk082acfd2005-01-10 00:01:04 +0000235 mrs lr, spsr @ get the spsr
236 str lr, [r13, #4] @ save spsr in position 1 of saved stack
wdenk8ed96042005-01-09 23:16:25 +0000237
238 mov r13, #MODE_SVC @ prepare SVC-Mode
239 @ msr spsr_c, r13
wdenk082acfd2005-01-10 00:01:04 +0000240 msr spsr, r13 @ switch modes, make sure moves will execute
241 mov lr, pc @ capture return pc
242 movs pc, lr @ jump to next instruction & switch modes.
wdenk8ed96042005-01-09 23:16:25 +0000243 .endm
244
245 .macro get_bad_stack_swi
wdenk082acfd2005-01-10 00:01:04 +0000246 sub r13, r13, #4 @ space on current stack for scratch reg.
247 str r0, [r13] @ save R0's value.
Heiko Schochere48b7c02010-09-17 13:10:40 +0200248 ldr r0, IRQ_STACK_START_IN @ get data regions start
wdenk8ed96042005-01-09 23:16:25 +0000249 str lr, [r0] @ save caller lr in position 0 of saved stack
Tetsuyuki Kobayashi4411b2a2013-04-05 00:12:51 +0000250 mrs lr, spsr @ get the spsr
wdenk082acfd2005-01-10 00:01:04 +0000251 str lr, [r0, #4] @ save spsr in position 1 of saved stack
Tetsuyuki Kobayashi4411b2a2013-04-05 00:12:51 +0000252 ldr lr, [r0] @ restore lr
wdenk082acfd2005-01-10 00:01:04 +0000253 ldr r0, [r13] @ restore r0
254 add r13, r13, #4 @ pop stack entry
wdenk8ed96042005-01-09 23:16:25 +0000255 .endm
256
257 .macro get_irq_stack @ setup IRQ stack
258 ldr sp, IRQ_STACK_START
259 .endm
260
261 .macro get_fiq_stack @ setup FIQ stack
262 ldr sp, FIQ_STACK_START
263 .endm
Aneesh V401bb302011-07-13 05:11:07 +0000264#endif /* CONFIG_SPL_BUILD */
wdenk8ed96042005-01-09 23:16:25 +0000265
266/*
267 * exception handlers
268 */
Aneesh V401bb302011-07-13 05:11:07 +0000269#ifdef CONFIG_SPL_BUILD
Kyungmin Park751b9b52008-01-17 16:43:25 +0900270 .align 5
271do_hang:
Kyungmin Park751b9b52008-01-17 16:43:25 +0900272 bl hang /* hang and never return */
Aneesh V401bb302011-07-13 05:11:07 +0000273#else /* !CONFIG_SPL_BUILD */
wdenk082acfd2005-01-10 00:01:04 +0000274 .align 5
wdenk8ed96042005-01-09 23:16:25 +0000275undefined_instruction:
276 get_bad_stack
277 bad_save_user_regs
wdenk082acfd2005-01-10 00:01:04 +0000278 bl do_undefined_instruction
wdenk8ed96042005-01-09 23:16:25 +0000279
280 .align 5
281software_interrupt:
282 get_bad_stack_swi
283 bad_save_user_regs
wdenk082acfd2005-01-10 00:01:04 +0000284 bl do_software_interrupt
wdenk8ed96042005-01-09 23:16:25 +0000285
286 .align 5
287prefetch_abort:
288 get_bad_stack
289 bad_save_user_regs
wdenk082acfd2005-01-10 00:01:04 +0000290 bl do_prefetch_abort
wdenk8ed96042005-01-09 23:16:25 +0000291
292 .align 5
293data_abort:
294 get_bad_stack
295 bad_save_user_regs
wdenk082acfd2005-01-10 00:01:04 +0000296 bl do_data_abort
wdenk8ed96042005-01-09 23:16:25 +0000297
298 .align 5
299not_used:
300 get_bad_stack
301 bad_save_user_regs
wdenk082acfd2005-01-10 00:01:04 +0000302 bl do_not_used
wdenk8ed96042005-01-09 23:16:25 +0000303
304#ifdef CONFIG_USE_IRQ
305
306 .align 5
307irq:
308 get_irq_stack
309 irq_save_user_regs
wdenk082acfd2005-01-10 00:01:04 +0000310 bl do_irq
wdenk8ed96042005-01-09 23:16:25 +0000311 irq_restore_user_regs
312
313 .align 5
314fiq:
315 get_fiq_stack
316 /* someone ought to write a more effiction fiq_save_user_regs */
317 irq_save_user_regs
wdenk082acfd2005-01-10 00:01:04 +0000318 bl do_fiq
wdenk8ed96042005-01-09 23:16:25 +0000319 irq_restore_user_regs
320
321#else
322
323 .align 5
324irq:
325 get_bad_stack
326 bad_save_user_regs
wdenk082acfd2005-01-10 00:01:04 +0000327 bl do_irq
wdenk8ed96042005-01-09 23:16:25 +0000328
329 .align 5
330fiq:
331 get_bad_stack
332 bad_save_user_regs
wdenk082acfd2005-01-10 00:01:04 +0000333 bl do_fiq
wdenk8ed96042005-01-09 23:16:25 +0000334
335#endif
336 .align 5
337.global arm1136_cache_flush
338arm1136_cache_flush:
Aneesh Ve47f2db2011-06-16 23:30:48 +0000339#if !defined(CONFIG_SYS_ICACHE_OFF)
wdenk8ed96042005-01-09 23:16:25 +0000340 mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache
Heiko Schocher7e4a9e62010-09-17 13:10:32 +0200341#endif
Aneesh Ve47f2db2011-06-16 23:30:48 +0000342#if !defined(CONFIG_SYS_DCACHE_OFF)
Heiko Schocher7e4a9e62010-09-17 13:10:32 +0200343 mcr p15, 0, r1, c7, c14, 0 @ invalidate D cache
344#endif
wdenk8ed96042005-01-09 23:16:25 +0000345 mov pc, lr @ back to caller
Aneesh V401bb302011-07-13 05:11:07 +0000346#endif /* CONFIG_SPL_BUILD */