blob: 1e765b7024b521ac92573ff833c3a38475a75315 [file] [log] [blame]
wdenkf6f96f72003-07-15 20:04:06 +00001/*
2 * armboot - Startup Code for ARM925 CPU-core
3 *
4 * Copyright (c) 2003 Texas Instruments
5 *
6 * ----- Adapted for OMAP1510 from ARM920 code ------
7 *
Albert ARIBAUD60fbc8d2011-08-04 18:45:45 +02008 * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
9 * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
Detlev Zundelf1b3f2b2009-05-13 10:54:10 +020010 * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
wdenkf6f96f72003-07-15 20:04:06 +000011 * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
Wolfgang Denka1be4762008-05-20 16:00:29 +020012 * Copyright (c) 2003 Kshitij <kshitij@ti.com>
wdenkf6f96f72003-07-15 20:04:06 +000013 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +020014 * SPDX-License-Identifier: GPL-2.0+
wdenkf6f96f72003-07-15 20:04:06 +000015 */
16
Wolfgang Denk0191e472010-10-26 14:34:52 +020017#include <asm-offsets.h>
wdenkf6f96f72003-07-15 20:04:06 +000018#include <config.h>
19#include <version.h>
20
wdenkf6f96f72003-07-15 20:04:06 +000021/*
22 *************************************************************************
23 *
24 * Jump vector table as in table 3.1 in [1]
25 *
26 *************************************************************************
27 */
28
29
30.globl _start
31_start: b reset
32 ldr pc, _undefined_instruction
33 ldr pc, _software_interrupt
34 ldr pc, _prefetch_abort
35 ldr pc, _data_abort
36 ldr pc, _not_used
37 ldr pc, _irq
38 ldr pc, _fiq
39
40_undefined_instruction: .word undefined_instruction
41_software_interrupt: .word software_interrupt
42_prefetch_abort: .word prefetch_abort
43_data_abort: .word data_abort
44_not_used: .word not_used
45_irq: .word irq
46_fiq: .word fiq
47
48 .balignl 16,0xdeadbeef
49
50
51/*
52 *************************************************************************
53 *
54 * Startup Code (reset vector)
55 *
56 * do important init only if we don't start from memory!
57 * setup Memory and board specific bits prior to relocation.
58 * relocate armboot to ram
59 * setup stack
60 *
61 *************************************************************************
62 */
63
Heiko Schocherdf329fb2010-09-17 13:10:44 +020064.globl _TEXT_BASE
wdenkf6f96f72003-07-15 20:04:06 +000065_TEXT_BASE:
Benoît Thébaudeaua402da32013-04-11 09:35:42 +000066#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE)
67 .word CONFIG_SPL_TEXT_BASE
68#else
Wolfgang Denk0708bc62010-10-07 21:51:12 +020069 .word CONFIG_SYS_TEXT_BASE
Benoît Thébaudeaua402da32013-04-11 09:35:42 +000070#endif
wdenkf6f96f72003-07-15 20:04:06 +000071
wdenkf6f96f72003-07-15 20:04:06 +000072/*
wdenk927034e2004-02-08 19:38:38 +000073 * These are defined in the board-specific linker script.
Albert Aribaud126897e2010-11-25 22:45:02 +010074 * Subtracting _start from them lets the linker put their
75 * relative position in the executable instead of leaving
76 * them null.
wdenkf6f96f72003-07-15 20:04:06 +000077 */
Albert Aribaud126897e2010-11-25 22:45:02 +010078.globl _bss_start_ofs
79_bss_start_ofs:
80 .word __bss_start - _start
wdenk927034e2004-02-08 19:38:38 +000081
Albert Aribaud126897e2010-11-25 22:45:02 +010082.globl _bss_end_ofs
83_bss_end_ofs:
Simon Glassed70c8f2013-03-14 06:54:53 +000084 .word __bss_end - _start
wdenkf6f96f72003-07-15 20:04:06 +000085
Po-Yu Chuang1864b002011-03-01 23:02:04 +000086.globl _end_ofs
87_end_ofs:
88 .word _end - _start
89
wdenkf6f96f72003-07-15 20:04:06 +000090#ifdef CONFIG_USE_IRQ
91/* IRQ stack memory (calculated at run-time) */
92.globl IRQ_STACK_START
93IRQ_STACK_START:
94 .word 0x0badc0de
95
96/* IRQ stack memory (calculated at run-time) */
97.globl FIQ_STACK_START
98FIQ_STACK_START:
99 .word 0x0badc0de
100#endif
Heiko Schocherdf329fb2010-09-17 13:10:44 +0200101
Heiko Schocherdf329fb2010-09-17 13:10:44 +0200102/* IRQ stack memory (calculated at run-time) + 8 bytes */
103.globl IRQ_STACK_START_IN
104IRQ_STACK_START_IN:
105 .word 0x0badc0de
106
Heiko Schocherdf329fb2010-09-17 13:10:44 +0200107/*
108 * the actual reset code
109 */
110
111reset:
112 /*
113 * set the cpu to SVC32 mode
114 */
115 mrs r0,cpsr
116 bic r0,r0,#0x1f
117 orr r0,r0,#0xd3
118 msr cpsr,r0
119
120 /*
121 * Set up 925T mode
122 */
123 mov r1, #0x81 /* Set ARM925T configuration. */
124 mcr p15, 0, r1, c15, c1, 0 /* Write ARM925T configuration register. */
125
126 /*
127 * turn off the watchdog, unlock/diable sequence
128 */
129 mov r1, #0xF5
130 ldr r0, =WDTIM_MODE
131 strh r1, [r0]
132 mov r1, #0xA0
133 strh r1, [r0]
134
135 /*
136 * mask all IRQs by setting all bits in the INTMR - default
137 */
138 mov r1, #0xffffffff
139 ldr r0, =REG_IHL1_MIR
140 str r1, [r0]
141 ldr r0, =REG_IHL2_MIR
142 str r1, [r0]
143
144 /*
145 * wait for dpll to lock
146 */
147 ldr r0, =CK_DPLL1
148 mov r1, #0x10
149 strh r1, [r0]
150poll1:
151 ldrh r1, [r0]
152 ands r1, r1, #0x01
153 beq poll1
154
155 /*
156 * we do sys-critical inits only at reboot,
157 * not when booting from ram!
158 */
159#ifndef CONFIG_SKIP_LOWLEVEL_INIT
160 bl cpu_init_crit
161#endif
162
Albert ARIBAUDfacdae52013-01-08 10:18:02 +0000163 bl _main
Heiko Schocherdf329fb2010-09-17 13:10:44 +0200164
165/*------------------------------------------------------------------------------*/
166
Albert ARIBAUDfacdae52013-01-08 10:18:02 +0000167 .globl c_runtime_cpu_setup
168c_runtime_cpu_setup:
169
170 mov pc, lr
171
wdenkf6f96f72003-07-15 20:04:06 +0000172/*
173 *************************************************************************
174 *
175 * CPU_init_critical registers
176 *
177 * setup important registers
178 * setup memory timing
179 *
180 *************************************************************************
181 */
182
183
184cpu_init_crit:
185 /*
186 * flush v4 I/D caches
187 */
188 mov r0, #0
189 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
190 mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
191
192 /*
193 * disable MMU stuff and caches
194 */
195 mrc p15, 0, r0, c1, c0, 0
196 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
197 bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
198 orr r0, r0, #0x00000002 @ set bit 2 (A) Align
199 orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
200 mcr p15, 0, r0, c1, c0, 0
201
202 /*
203 * Go setup Memory and board specific bits prior to relocation.
204 */
205 mov ip, lr /* perserve link reg across call */
Wolfgang Denk7f88a5e2005-10-06 17:08:18 +0200206 bl lowlevel_init /* go setup pll,mux,memory */
wdenkf6f96f72003-07-15 20:04:06 +0000207 mov lr, ip /* restore link */
208 mov pc, lr /* back to my caller */
209/*
210 *************************************************************************
211 *
212 * Interrupt handling
213 *
214 *************************************************************************
215 */
216
217@
218@ IRQ stack frame.
219@
220#define S_FRAME_SIZE 72
221
222#define S_OLD_R0 68
223#define S_PSR 64
224#define S_PC 60
225#define S_LR 56
226#define S_SP 52
227
228#define S_IP 48
229#define S_FP 44
230#define S_R10 40
231#define S_R9 36
232#define S_R8 32
233#define S_R7 28
234#define S_R6 24
235#define S_R5 20
236#define S_R4 16
237#define S_R3 12
238#define S_R2 8
239#define S_R1 4
240#define S_R0 0
241
242#define MODE_SVC 0x13
243#define I_BIT 0x80
244
245/*
246 * use bad_save_user_regs for abort/prefetch/undef/swi ...
247 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
248 */
249
250 .macro bad_save_user_regs
251 sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current user stack
252 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
253
Heiko Schocherdf329fb2010-09-17 13:10:44 +0200254 ldr r2, IRQ_STACK_START_IN
wdenkf6f96f72003-07-15 20:04:06 +0000255 ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs)
256 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
257
258 add r5, sp, #S_SP
259 mov r1, lr
260 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
261 mov r0, sp @ save current stack into r0 (param register)
262 .endm
263
264 .macro irq_save_user_regs
265 sub sp, sp, #S_FRAME_SIZE
266 stmia sp, {r0 - r12} @ Calling r0-r12
267 add r8, sp, #S_PC @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
268 stmdb r8, {sp, lr}^ @ Calling SP, LR
269 str lr, [r8, #0] @ Save calling PC
270 mrs r6, spsr
271 str r6, [r8, #4] @ Save CPSR
272 str r0, [r8, #8] @ Save OLD_R0
273 mov r0, sp
274 .endm
275
276 .macro irq_restore_user_regs
277 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
278 mov r0, r0
279 ldr lr, [sp, #S_PC] @ Get PC
280 add sp, sp, #S_FRAME_SIZE
281 subs pc, lr, #4 @ return & move spsr_svc into cpsr
282 .endm
283
284 .macro get_bad_stack
Heiko Schocherdf329fb2010-09-17 13:10:44 +0200285 ldr r13, IRQ_STACK_START_IN
wdenkf6f96f72003-07-15 20:04:06 +0000286
287 str lr, [r13] @ save caller lr in position 0 of saved stack
288 mrs lr, spsr @ get the spsr
289 str lr, [r13, #4] @ save spsr in position 1 of saved stack
290
291 mov r13, #MODE_SVC @ prepare SVC-Mode
292 @ msr spsr_c, r13
293 msr spsr, r13 @ switch modes, make sure moves will execute
294 mov lr, pc @ capture return pc
295 movs pc, lr @ jump to next instruction & switch modes.
296 .endm
297
298 .macro get_irq_stack @ setup IRQ stack
299 ldr sp, IRQ_STACK_START
300 .endm
301
302 .macro get_fiq_stack @ setup FIQ stack
303 ldr sp, FIQ_STACK_START
304 .endm
305
306/*
307 * exception handlers
308 */
309 .align 5
310undefined_instruction:
311 get_bad_stack
312 bad_save_user_regs
Wolfgang Denka1be4762008-05-20 16:00:29 +0200313 bl do_undefined_instruction
wdenkf6f96f72003-07-15 20:04:06 +0000314
315 .align 5
316software_interrupt:
317 get_bad_stack
318 bad_save_user_regs
Wolfgang Denka1be4762008-05-20 16:00:29 +0200319 bl do_software_interrupt
wdenkf6f96f72003-07-15 20:04:06 +0000320
321 .align 5
322prefetch_abort:
323 get_bad_stack
324 bad_save_user_regs
Wolfgang Denka1be4762008-05-20 16:00:29 +0200325 bl do_prefetch_abort
wdenkf6f96f72003-07-15 20:04:06 +0000326
327 .align 5
328data_abort:
329 get_bad_stack
330 bad_save_user_regs
Wolfgang Denka1be4762008-05-20 16:00:29 +0200331 bl do_data_abort
wdenkf6f96f72003-07-15 20:04:06 +0000332
333 .align 5
334not_used:
335 get_bad_stack
336 bad_save_user_regs
Wolfgang Denka1be4762008-05-20 16:00:29 +0200337 bl do_not_used
wdenkf6f96f72003-07-15 20:04:06 +0000338
339#ifdef CONFIG_USE_IRQ
340
341 .align 5
342irq:
343 get_irq_stack
344 irq_save_user_regs
Wolfgang Denka1be4762008-05-20 16:00:29 +0200345 bl do_irq
wdenkf6f96f72003-07-15 20:04:06 +0000346 irq_restore_user_regs
347
348 .align 5
349fiq:
350 get_fiq_stack
351 /* someone ought to write a more effiction fiq_save_user_regs */
352 irq_save_user_regs
Wolfgang Denka1be4762008-05-20 16:00:29 +0200353 bl do_fiq
wdenkf6f96f72003-07-15 20:04:06 +0000354 irq_restore_user_regs
355
356#else
357
358 .align 5
359irq:
360 get_bad_stack
361 bad_save_user_regs
Wolfgang Denka1be4762008-05-20 16:00:29 +0200362 bl do_irq
wdenkf6f96f72003-07-15 20:04:06 +0000363
364 .align 5
365fiq:
366 get_bad_stack
367 bad_save_user_regs
Wolfgang Denka1be4762008-05-20 16:00:29 +0200368 bl do_fiq
wdenkf6f96f72003-07-15 20:04:06 +0000369
370#endif
371
372 .align 5
373.globl reset_cpu
374reset_cpu:
375 ldr r1, rstctl1 /* get clkm1 reset ctl */
wdenke58b0dc2003-07-27 00:21:01 +0000376 mov r3, #0x3 /* dsp_en + arm_rst = global reset */
377 strh r3, [r1] /* force reset */
378 mov r0, r0
wdenkf6f96f72003-07-15 20:04:06 +0000379_loop_forever:
380 b _loop_forever
381rstctl1:
382 .word 0xfffece10