blob: 13567b9ce4c99ef00efa1d190d0aecea6817e8ec [file] [log] [blame]
wdenkf8062712005-01-09 23:16:25 +00001/*
2 * armboot - Startup Code for OMP2420/ARM1136 CPU-core
3 *
wdenk2e405bf2005-01-10 00:01:04 +00004 * Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com>
wdenkf8062712005-01-09 23:16:25 +00005 *
Albert ARIBAUD60fbc8d2011-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 Zundelf1b3f2b2009-05-13 10:54:10 +02008 * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
wdenkf8062712005-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 Denkbd8ec7e2013-10-07 13:07:26 +020012 * SPDX-License-Identifier: GPL-2.0+
wdenkf8062712005-01-09 23:16:25 +000013 */
14
Wolfgang Denk0191e472010-10-26 14:34:52 +020015#include <asm-offsets.h>
wdenkf8062712005-01-09 23:16:25 +000016#include <config.h>
17#include <version.h>
wdenkf8062712005-01-09 23:16:25 +000018.globl _start
wdenk2e405bf2005-01-10 00:01:04 +000019_start: b reset
Aneesh V552a3192011-07-13 05:11:07 +000020#ifdef CONFIG_SPL_BUILD
Kyungmin Park33174212008-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
wdenkf8062712005-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
wdenk2e405bf2005-01-10 00:01:04 +000047_undefined_instruction: .word undefined_instruction
wdenkf8062712005-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
wdenk2e405bf2005-01-10 00:01:04 +000054_pad: .word 0x12345678 /* now 16*4=64 */
Aneesh V552a3192011-07-13 05:11:07 +000055#endif /* CONFIG_SPL_BUILD */
wdenkf8062712005-01-09 23:16:25 +000056
57 .balignl 16,0xdeadbeef
58/*
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 */
70
wdenkf8062712005-01-09 23:16:25 +000071#ifdef CONFIG_USE_IRQ
72/* IRQ stack memory (calculated at run-time) */
73.globl IRQ_STACK_START
74IRQ_STACK_START:
75 .word 0x0badc0de
76
77/* IRQ stack memory (calculated at run-time) */
78.globl FIQ_STACK_START
79FIQ_STACK_START:
80 .word 0x0badc0de
81#endif
Heiko Schocher504f87c2010-09-17 13:10:40 +020082
Heiko Schocher504f87c2010-09-17 13:10:40 +020083/* IRQ stack memory (calculated at run-time) + 8 bytes */
84.globl IRQ_STACK_START_IN
85IRQ_STACK_START_IN:
86 .word 0x0badc0de
Heiko Schocher504f87c2010-09-17 13:10:40 +020087
Heiko Schocher504f87c2010-09-17 13:10:40 +020088/*
89 * the actual reset code
90 */
91
92reset:
93 /*
94 * set the cpu to SVC32 mode
95 */
96 mrs r0,cpsr
97 bic r0,r0,#0x1f
98 orr r0,r0,#0xd3
99 msr cpsr,r0
100
Heiko Schocher504f87c2010-09-17 13:10:40 +0200101 /* the mask ROM code should have PLL and others stable */
102#ifndef CONFIG_SKIP_LOWLEVEL_INIT
103 bl cpu_init_crit
104#endif
105
Albert ARIBAUDfacdae52013-01-08 10:18:02 +0000106 bl _main
Heiko Schocher504f87c2010-09-17 13:10:40 +0200107
108/*------------------------------------------------------------------------------*/
109
Albert ARIBAUDfacdae52013-01-08 10:18:02 +0000110 .globl c_runtime_cpu_setup
111c_runtime_cpu_setup:
wdenkf8062712005-01-09 23:16:25 +0000112
Albert ARIBAUDfacdae52013-01-08 10:18:02 +0000113 bx lr
Heiko Schocher429ddf62010-10-13 07:57:14 +0200114
wdenkf8062712005-01-09 23:16:25 +0000115/*
116 *************************************************************************
117 *
118 * CPU_init_critical registers
119 *
120 * setup important registers
121 * setup memory timing
122 *
123 *************************************************************************
124 */
Magnus Lilja4133f652009-06-13 20:50:01 +0200125#ifndef CONFIG_SKIP_LOWLEVEL_INIT
wdenkf8062712005-01-09 23:16:25 +0000126cpu_init_crit:
127 /*
128 * flush v4 I/D caches
129 */
130 mov r0, #0
George G. Davis15967892010-05-11 10:15:36 -0400131 mcr p15, 0, r0, c7, c7, 0 /* Invalidate I+D+BTB caches */
132 mcr p15, 0, r0, c8, c7, 0 /* Invalidate Unified TLB */
wdenkf8062712005-01-09 23:16:25 +0000133
134 /*
135 * disable MMU stuff and caches
136 */
137 mrc p15, 0, r0, c1, c0, 0
138 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
139 bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
140 orr r0, r0, #0x00000002 @ set bit 2 (A) Align
wdenkf8062712005-01-09 23:16:25 +0000141 orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
wdenkf8062712005-01-09 23:16:25 +0000142 mcr p15, 0, r0, c1, c0, 0
143
144 /*
wdenk2e405bf2005-01-10 00:01:04 +0000145 * Jump to board specific initialization... The Mask ROM will have already initialized
146 * basic memory. Go here to bump up clock rate and handle wake up conditions.
wdenkf8062712005-01-09 23:16:25 +0000147 */
wdenk2e405bf2005-01-10 00:01:04 +0000148 mov ip, lr /* persevere link reg across call */
Wolfgang Denk7f88a5e2005-10-06 17:08:18 +0200149 bl lowlevel_init /* go setup pll,mux,memory */
wdenk2e405bf2005-01-10 00:01:04 +0000150 mov lr, ip /* restore link */
151 mov pc, lr /* back to my caller */
Magnus Lilja4133f652009-06-13 20:50:01 +0200152#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
Kyungmin Park33174212008-01-17 16:43:25 +0900153
Aneesh V552a3192011-07-13 05:11:07 +0000154#ifndef CONFIG_SPL_BUILD
wdenkf8062712005-01-09 23:16:25 +0000155/*
156 *************************************************************************
157 *
158 * Interrupt handling
159 *
160 *************************************************************************
161 */
162@
163@ IRQ stack frame.
164@
165#define S_FRAME_SIZE 72
166
167#define S_OLD_R0 68
168#define S_PSR 64
169#define S_PC 60
170#define S_LR 56
171#define S_SP 52
172
173#define S_IP 48
174#define S_FP 44
175#define S_R10 40
176#define S_R9 36
177#define S_R8 32
178#define S_R7 28
179#define S_R6 24
180#define S_R5 20
181#define S_R4 16
182#define S_R3 12
183#define S_R2 8
184#define S_R1 4
185#define S_R0 0
186
187#define MODE_SVC 0x13
188#define I_BIT 0x80
189
190/*
191 * use bad_save_user_regs for abort/prefetch/undef/swi ...
192 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
193 */
194
195 .macro bad_save_user_regs
wdenk2e405bf2005-01-10 00:01:04 +0000196 sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current user stack
wdenkf8062712005-01-09 23:16:25 +0000197 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
198
Heiko Schocher504f87c2010-09-17 13:10:40 +0200199 ldr r2, IRQ_STACK_START_IN @ set base 2 words into abort stack
wdenk2e405bf2005-01-10 00:01:04 +0000200 ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs)
wdenkf8062712005-01-09 23:16:25 +0000201 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
202
203 add r5, sp, #S_SP
204 mov r1, lr
wdenk2e405bf2005-01-10 00:01:04 +0000205 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
206 mov r0, sp @ save current stack into r0 (param register)
wdenkf8062712005-01-09 23:16:25 +0000207 .endm
208
209 .macro irq_save_user_regs
210 sub sp, sp, #S_FRAME_SIZE
211 stmia sp, {r0 - r12} @ Calling r0-r12
wdenk2e405bf2005-01-10 00:01:04 +0000212 add r8, sp, #S_PC @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
213 stmdb r8, {sp, lr}^ @ Calling SP, LR
214 str lr, [r8, #0] @ Save calling PC
215 mrs r6, spsr
216 str r6, [r8, #4] @ Save CPSR
217 str r0, [r8, #8] @ Save OLD_R0
wdenkf8062712005-01-09 23:16:25 +0000218 mov r0, sp
219 .endm
220
221 .macro irq_restore_user_regs
222 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
223 mov r0, r0
224 ldr lr, [sp, #S_PC] @ Get PC
225 add sp, sp, #S_FRAME_SIZE
226 subs pc, lr, #4 @ return & move spsr_svc into cpsr
227 .endm
228
229 .macro get_bad_stack
Heiko Schocher504f87c2010-09-17 13:10:40 +0200230 ldr r13, IRQ_STACK_START_IN @ setup our mode stack (enter in banked mode)
wdenkf8062712005-01-09 23:16:25 +0000231
232 str lr, [r13] @ save caller lr in position 0 of saved stack
wdenk2e405bf2005-01-10 00:01:04 +0000233 mrs lr, spsr @ get the spsr
234 str lr, [r13, #4] @ save spsr in position 1 of saved stack
wdenkf8062712005-01-09 23:16:25 +0000235
236 mov r13, #MODE_SVC @ prepare SVC-Mode
237 @ msr spsr_c, r13
wdenk2e405bf2005-01-10 00:01:04 +0000238 msr spsr, r13 @ switch modes, make sure moves will execute
239 mov lr, pc @ capture return pc
240 movs pc, lr @ jump to next instruction & switch modes.
wdenkf8062712005-01-09 23:16:25 +0000241 .endm
242
243 .macro get_bad_stack_swi
wdenk2e405bf2005-01-10 00:01:04 +0000244 sub r13, r13, #4 @ space on current stack for scratch reg.
245 str r0, [r13] @ save R0's value.
Heiko Schocher504f87c2010-09-17 13:10:40 +0200246 ldr r0, IRQ_STACK_START_IN @ get data regions start
wdenkf8062712005-01-09 23:16:25 +0000247 str lr, [r0] @ save caller lr in position 0 of saved stack
Tetsuyuki Kobayashib023a952013-04-05 00:12:51 +0000248 mrs lr, spsr @ get the spsr
wdenk2e405bf2005-01-10 00:01:04 +0000249 str lr, [r0, #4] @ save spsr in position 1 of saved stack
Tetsuyuki Kobayashib023a952013-04-05 00:12:51 +0000250 ldr lr, [r0] @ restore lr
wdenk2e405bf2005-01-10 00:01:04 +0000251 ldr r0, [r13] @ restore r0
252 add r13, r13, #4 @ pop stack entry
wdenkf8062712005-01-09 23:16:25 +0000253 .endm
254
255 .macro get_irq_stack @ setup IRQ stack
256 ldr sp, IRQ_STACK_START
257 .endm
258
259 .macro get_fiq_stack @ setup FIQ stack
260 ldr sp, FIQ_STACK_START
261 .endm
Aneesh V552a3192011-07-13 05:11:07 +0000262#endif /* CONFIG_SPL_BUILD */
wdenkf8062712005-01-09 23:16:25 +0000263
264/*
265 * exception handlers
266 */
Aneesh V552a3192011-07-13 05:11:07 +0000267#ifdef CONFIG_SPL_BUILD
Kyungmin Park33174212008-01-17 16:43:25 +0900268 .align 5
269do_hang:
Kyungmin Park33174212008-01-17 16:43:25 +0900270 bl hang /* hang and never return */
Aneesh V552a3192011-07-13 05:11:07 +0000271#else /* !CONFIG_SPL_BUILD */
wdenk2e405bf2005-01-10 00:01:04 +0000272 .align 5
wdenkf8062712005-01-09 23:16:25 +0000273undefined_instruction:
274 get_bad_stack
275 bad_save_user_regs
wdenk2e405bf2005-01-10 00:01:04 +0000276 bl do_undefined_instruction
wdenkf8062712005-01-09 23:16:25 +0000277
278 .align 5
279software_interrupt:
280 get_bad_stack_swi
281 bad_save_user_regs
wdenk2e405bf2005-01-10 00:01:04 +0000282 bl do_software_interrupt
wdenkf8062712005-01-09 23:16:25 +0000283
284 .align 5
285prefetch_abort:
286 get_bad_stack
287 bad_save_user_regs
wdenk2e405bf2005-01-10 00:01:04 +0000288 bl do_prefetch_abort
wdenkf8062712005-01-09 23:16:25 +0000289
290 .align 5
291data_abort:
292 get_bad_stack
293 bad_save_user_regs
wdenk2e405bf2005-01-10 00:01:04 +0000294 bl do_data_abort
wdenkf8062712005-01-09 23:16:25 +0000295
296 .align 5
297not_used:
298 get_bad_stack
299 bad_save_user_regs
wdenk2e405bf2005-01-10 00:01:04 +0000300 bl do_not_used
wdenkf8062712005-01-09 23:16:25 +0000301
302#ifdef CONFIG_USE_IRQ
303
304 .align 5
305irq:
306 get_irq_stack
307 irq_save_user_regs
wdenk2e405bf2005-01-10 00:01:04 +0000308 bl do_irq
wdenkf8062712005-01-09 23:16:25 +0000309 irq_restore_user_regs
310
311 .align 5
312fiq:
313 get_fiq_stack
314 /* someone ought to write a more effiction fiq_save_user_regs */
315 irq_save_user_regs
wdenk2e405bf2005-01-10 00:01:04 +0000316 bl do_fiq
wdenkf8062712005-01-09 23:16:25 +0000317 irq_restore_user_regs
318
319#else
320
321 .align 5
322irq:
323 get_bad_stack
324 bad_save_user_regs
wdenk2e405bf2005-01-10 00:01:04 +0000325 bl do_irq
wdenkf8062712005-01-09 23:16:25 +0000326
327 .align 5
328fiq:
329 get_bad_stack
330 bad_save_user_regs
wdenk2e405bf2005-01-10 00:01:04 +0000331 bl do_fiq
wdenkf8062712005-01-09 23:16:25 +0000332
333#endif
Aneesh V552a3192011-07-13 05:11:07 +0000334#endif /* CONFIG_SPL_BUILD */