blob: 39d7409b030a323e9a38e9fcb70fe9a9e6d9e39a [file] [log] [blame]
wdenk6f213472003-08-29 22:00:43 +00001/*
2 * armboot - Startup Code for ARM926EJS CPU-core
3 *
4 * Copyright (c) 2003 Texas Instruments
5 *
6 * ----- Adapted for OMAP1610 from ARM925t code ------
7 *
8 * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
9 * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
10 * Copyright (c) 2002 Gary Jennejohn <gj@denx.de>
11 * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
12 * Copyright (c) 2003 Kshitij <kshitij@ti.com>
13 *
14 * See file CREDITS for list of people who contributed to this
15 * project.
16 *
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License as
19 * published by the Free Software Foundation; either version 2 of
20 * the License, or (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
30 * MA 02111-1307 USA
31 */
32
33
wdenk6f213472003-08-29 22:00:43 +000034#include <config.h>
35#include <version.h>
36
37#if defined(CONFIG_OMAP1610)
38#include <./configs/omap1510.h>
39#endif
40
41/*
42 *************************************************************************
43 *
44 * Jump vector table as in table 3.1 in [1]
45 *
46 *************************************************************************
47 */
48
49
50.globl _start
51_start:
52 b reset
53 ldr pc, _undefined_instruction
54 ldr pc, _software_interrupt
55 ldr pc, _prefetch_abort
56 ldr pc, _data_abort
57 ldr pc, _not_used
58 ldr pc, _irq
59 ldr pc, _fiq
60
61_undefined_instruction:
62 .word undefined_instruction
63_software_interrupt:
64 .word software_interrupt
65_prefetch_abort:
66 .word prefetch_abort
67_data_abort:
68 .word data_abort
69_not_used:
70 .word not_used
71_irq:
72 .word irq
73_fiq:
74 .word fiq
75
76 .balignl 16,0xdeadbeef
77
78
79/*
80 *************************************************************************
81 *
82 * Startup Code (reset vector)
83 *
84 * do important init only if we don't start from memory!
85 * setup Memory and board specific bits prior to relocation.
86 * relocate armboot to ram
87 * setup stack
88 *
89 *************************************************************************
90 */
91
wdenk6f213472003-08-29 22:00:43 +000092_TEXT_BASE:
93 .word TEXT_BASE
94
95.globl _armboot_start
96_armboot_start:
97 .word _start
98
99/*
100 * Note: _armboot_end_data and _armboot_end are defined
101 * by the (board-dependent) linker script.
102 * _armboot_end_data is the first usable FLASH address after armboot
103 */
104.globl _armboot_end_data
105_armboot_end_data:
106 .word armboot_end_data
107.globl _armboot_end
108_armboot_end:
109 .word armboot_end
110
wdenk6f213472003-08-29 22:00:43 +0000111#ifdef CONFIG_USE_IRQ
112/* IRQ stack memory (calculated at run-time) */
113.globl IRQ_STACK_START
114IRQ_STACK_START:
115 .word 0x0badc0de
116
117/* IRQ stack memory (calculated at run-time) */
118.globl FIQ_STACK_START
119FIQ_STACK_START:
120 .word 0x0badc0de
121#endif
122
123
124/*
125 * the actual reset code
126 */
127
128reset:
129 /*
130 * set the cpu to SVC32 mode
131 */
132 mrs r0,cpsr
133 bic r0,r0,#0x1f
134 orr r0,r0,#0xd3
135 msr cpsr,r0
136
137
wdenk42d1f032003-10-15 23:53:47 +0000138 /*
wdenk6f213472003-08-29 22:00:43 +0000139 * turn off the watchdog, unlock/diable sequence
140 */
141 mov r1, #0xF5
142 ldr r0, =WDTIM_MODE
143 strh r1, [r0]
144 mov r1, #0xA0
145 strh r1, [r0]
146
147
wdenk6f213472003-08-29 22:00:43 +0000148 /*
149 * mask all IRQs by setting all bits in the INTMR - default
150 */
151
152 mov r1, #0xffffffff
153 ldr r0, =REG_IHL1_MIR
154 str r1, [r0]
155 ldr r0, =REG_IHL2_MIR
156 str r1, [r0]
wdenk6f213472003-08-29 22:00:43 +0000157
wdenk6f213472003-08-29 22:00:43 +0000158 /*
wdenka8c7c702003-12-06 19:49:23 +0000159 * we do sys-critical inits only at reboot,
160 * not when booting from ram!
wdenk6f213472003-08-29 22:00:43 +0000161 */
wdenka8c7c702003-12-06 19:49:23 +0000162#ifdef CONFIG_INIT_CRITICAL
163 bl cpu_init_crit
164#endif
165
166relocate: /* relocate U-Boot to RAM */
167 adr r0, _start /* r0 <- current position of code */
168 ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
169 cmp r0, r1 /* don't reloc during debug */
170 beq stack_setup
171
wdenk6f213472003-08-29 22:00:43 +0000172 ldr r2, _armboot_start
173 ldr r3, _armboot_end
wdenka8c7c702003-12-06 19:49:23 +0000174 sub r2, r3, r2 /* r2 <- size of armboot */
175 add r2, r0, r2 /* r2 <- source end address */
wdenk6f213472003-08-29 22:00:43 +0000176
wdenk6f213472003-08-29 22:00:43 +0000177copy_loop:
wdenka8c7c702003-12-06 19:49:23 +0000178 ldmia r0!, {r3-r10} /* copy from source address [r0] */
179 stmia r1!, {r3-r10} /* copy to target address [r1] */
180 cmp r0, r2 /* until source end addreee [r2] */
wdenk6f213472003-08-29 22:00:43 +0000181 ble copy_loop
182
wdenka8c7c702003-12-06 19:49:23 +0000183 /* Set up the stack */
184stack_setup:
185 ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
186 sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
187 sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
188#ifdef CONFIG_USE_IRQ
189 sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
190#endif
191 sub sp, r0, #12 /* leave 3 words for abort-stack */
wdenk6f213472003-08-29 22:00:43 +0000192
193 ldr pc, _start_armboot
194
195_start_armboot:
196 .word start_armboot
197
198
199/*
200 *************************************************************************
201 *
202 * CPU_init_critical registers
203 *
204 * setup important registers
205 * setup memory timing
206 *
207 *************************************************************************
208 */
209
210
211cpu_init_crit:
212 /*
213 * flush v4 I/D caches
214 */
215 mov r0, #0
216 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
217 mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
218
219 /*
220 * disable MMU stuff and caches
221 */
222 mrc p15, 0, r0, c1, c0, 0
223 bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */
224 bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */
225 orr r0, r0, #0x00000002 /* set bit 2 (A) Align */
226 orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
227 mcr p15, 0, r0, c1, c0, 0
228
229 /*
230 * Go setup Memory and board specific bits prior to relocation.
231 */
232 mov ip, lr /* perserve link reg across call */
233 bl platformsetup /* go setup pll,mux,memory */
234 mov lr, ip /* restore link */
235 mov pc, lr /* back to my caller */
236/*
237 *************************************************************************
238 *
239 * Interrupt handling
240 *
241 *************************************************************************
242 */
243
244@
245@ IRQ stack frame.
246@
247#define S_FRAME_SIZE 72
248
249#define S_OLD_R0 68
250#define S_PSR 64
251#define S_PC 60
252#define S_LR 56
253#define S_SP 52
254
255#define S_IP 48
256#define S_FP 44
257#define S_R10 40
258#define S_R9 36
259#define S_R8 32
260#define S_R7 28
261#define S_R6 24
262#define S_R5 20
263#define S_R4 16
264#define S_R3 12
265#define S_R2 8
266#define S_R1 4
267#define S_R0 0
268
269#define MODE_SVC 0x13
270#define I_BIT 0x80
271
272/*
273 * use bad_save_user_regs for abort/prefetch/undef/swi ...
274 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
275 */
276
277 .macro bad_save_user_regs
278 @ carve out a frame on current user stack
279 sub sp, sp, #S_FRAME_SIZE
280 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
281 ldr r2, _armboot_end @ find top of stack
282 add r2, r2, #CONFIG_STACKSIZE @ find base of normal stack
283 sub r2, r2, #8 @ set base 2 words into abort stack
284 @ get values for "aborted" pc and cpsr (into parm regs)
285 ldmia r2, {r2 - r3}
286 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
287 add r5, sp, #S_SP
288 mov r1, lr
289 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
290 mov r0, sp @ save current stack into r0 (param register)
291 .endm
292
293 .macro irq_save_user_regs
294 sub sp, sp, #S_FRAME_SIZE
295 stmia sp, {r0 - r12} @ Calling r0-r12
296 @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
297 add r8, sp, #S_PC
298 stmdb r8, {sp, lr}^ @ Calling SP, LR
299 str lr, [r8, #0] @ Save calling PC
300 mrs r6, spsr
301 str r6, [r8, #4] @ Save CPSR
302 str r0, [r8, #8] @ Save OLD_R0
303 mov r0, sp
304 .endm
305
306 .macro irq_restore_user_regs
307 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
308 mov r0, r0
309 ldr lr, [sp, #S_PC] @ Get PC
310 add sp, sp, #S_FRAME_SIZE
311 subs pc, lr, #4 @ return & move spsr_svc into cpsr
312 .endm
313
314 .macro get_bad_stack
315 @ get bottom of stack (into sp by by user stack pointer).
316 ldr r13, _armboot_end
317 @ head to reserved words at the top of the stack
318 add r13, r13, #CONFIG_STACKSIZE
319 sub r13, r13, #8 @ reserved a couple spots in abort stack
320
321 str lr, [r13] @ save caller lr in position 0 of saved stack
322 mrs lr, spsr @ get the spsr
323 str lr, [r13, #4] @ save spsr in position 1 of saved stack
324 mov r13, #MODE_SVC @ prepare SVC-Mode
325 @ msr spsr_c, r13
326 msr spsr, r13 @ switch modes, make sure moves will execute
327 mov lr, pc @ capture return pc
328 movs pc, lr @ jump to next instruction & switch modes.
329 .endm
330
331 .macro get_irq_stack @ setup IRQ stack
332 ldr sp, IRQ_STACK_START
333 .endm
334
335 .macro get_fiq_stack @ setup FIQ stack
336 ldr sp, FIQ_STACK_START
337 .endm
338
339/*
340 * exception handlers
341 */
342 .align 5
343undefined_instruction:
344 get_bad_stack
345 bad_save_user_regs
346 bl do_undefined_instruction
347
348 .align 5
349software_interrupt:
350 get_bad_stack
351 bad_save_user_regs
352 bl do_software_interrupt
353
354 .align 5
355prefetch_abort:
356 get_bad_stack
357 bad_save_user_regs
358 bl do_prefetch_abort
359
360 .align 5
361data_abort:
362 get_bad_stack
363 bad_save_user_regs
364 bl do_data_abort
365
366 .align 5
367not_used:
368 get_bad_stack
369 bad_save_user_regs
370 bl do_not_used
371
372#ifdef CONFIG_USE_IRQ
373
374 .align 5
375irq:
376 get_irq_stack
377 irq_save_user_regs
378 bl do_irq
379 irq_restore_user_regs
380
381 .align 5
382fiq:
383 get_fiq_stack
384 /* someone ought to write a more effiction fiq_save_user_regs */
385 irq_save_user_regs
386 bl do_fiq
387 irq_restore_user_regs
388
389#else
390
391 .align 5
392irq:
393 get_bad_stack
394 bad_save_user_regs
395 bl do_irq
396
397 .align 5
398fiq:
399 get_bad_stack
400 bad_save_user_regs
401 bl do_fiq
402
403#endif
404
405 .align 5
406.globl reset_cpu
407reset_cpu:
408 ldr r1, rstctl1 /* get clkm1 reset ctl */
wdenk42d1f032003-10-15 23:53:47 +0000409 mov r3, #0x0
wdenk6f213472003-08-29 22:00:43 +0000410 strh r3, [r1] /* clear it */
411 mov r3, #0x8
412 strh r3, [r1] /* force dsp+arm reset */
413_loop_forever:
414 b _loop_forever
415
416
417rstctl1:
418 .word 0xfffece10