blob: 0c28927ba0b6c69904569ac8300cf8098dc1c397 [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/*
wdenkf6e20fc2004-02-08 19:38:38 +0000100 * These are defined in the board-specific linker script.
wdenk6f213472003-08-29 22:00:43 +0000101 */
wdenkf6e20fc2004-02-08 19:38:38 +0000102.globl _bss_start
103_bss_start:
104 .word __bss_start
105
106.globl _bss_end
107_bss_end:
108 .word _end
wdenk6f213472003-08-29 22:00:43 +0000109
wdenk6f213472003-08-29 22:00:43 +0000110#ifdef CONFIG_USE_IRQ
111/* IRQ stack memory (calculated at run-time) */
112.globl IRQ_STACK_START
113IRQ_STACK_START:
114 .word 0x0badc0de
115
116/* IRQ stack memory (calculated at run-time) */
117.globl FIQ_STACK_START
118FIQ_STACK_START:
119 .word 0x0badc0de
120#endif
121
122
123/*
124 * the actual reset code
125 */
126
127reset:
128 /*
129 * set the cpu to SVC32 mode
130 */
131 mrs r0,cpsr
132 bic r0,r0,#0x1f
133 orr r0,r0,#0xd3
134 msr cpsr,r0
135
136
wdenk42d1f032003-10-15 23:53:47 +0000137 /*
wdenk6f213472003-08-29 22:00:43 +0000138 * turn off the watchdog, unlock/diable sequence
139 */
140 mov r1, #0xF5
141 ldr r0, =WDTIM_MODE
142 strh r1, [r0]
143 mov r1, #0xA0
144 strh r1, [r0]
145
146
wdenk6f213472003-08-29 22:00:43 +0000147 /*
148 * mask all IRQs by setting all bits in the INTMR - default
149 */
150
151 mov r1, #0xffffffff
152 ldr r0, =REG_IHL1_MIR
153 str r1, [r0]
154 ldr r0, =REG_IHL2_MIR
155 str r1, [r0]
wdenk6f213472003-08-29 22:00:43 +0000156
wdenk6f213472003-08-29 22:00:43 +0000157 /*
wdenka8c7c702003-12-06 19:49:23 +0000158 * we do sys-critical inits only at reboot,
159 * not when booting from ram!
wdenk6f213472003-08-29 22:00:43 +0000160 */
wdenka8c7c702003-12-06 19:49:23 +0000161#ifdef CONFIG_INIT_CRITICAL
162 bl cpu_init_crit
163#endif
164
165relocate: /* relocate U-Boot to RAM */
166 adr r0, _start /* r0 <- current position of code */
167 ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
168 cmp r0, r1 /* don't reloc during debug */
169 beq stack_setup
170
wdenk6f213472003-08-29 22:00:43 +0000171 ldr r2, _armboot_start
wdenkf6e20fc2004-02-08 19:38:38 +0000172 ldr r3, _bss_start
wdenka8c7c702003-12-06 19:49:23 +0000173 sub r2, r3, r2 /* r2 <- size of armboot */
174 add r2, r0, r2 /* r2 <- source end address */
wdenk6f213472003-08-29 22:00:43 +0000175
wdenk6f213472003-08-29 22:00:43 +0000176copy_loop:
wdenka8c7c702003-12-06 19:49:23 +0000177 ldmia r0!, {r3-r10} /* copy from source address [r0] */
178 stmia r1!, {r3-r10} /* copy to target address [r1] */
179 cmp r0, r2 /* until source end addreee [r2] */
wdenk6f213472003-08-29 22:00:43 +0000180 ble copy_loop
181
wdenka8c7c702003-12-06 19:49:23 +0000182 /* Set up the stack */
183stack_setup:
184 ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
185 sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
186 sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
187#ifdef CONFIG_USE_IRQ
188 sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
189#endif
190 sub sp, r0, #12 /* leave 3 words for abort-stack */
wdenk6f213472003-08-29 22:00:43 +0000191
wdenkf6e20fc2004-02-08 19:38:38 +0000192clear_bss:
193 ldr r0, _bss_start /* find start of bss segment */
194 add r0, r0, #4 /* start at first byte of bss */
195 ldr r1, _bss_end /* stop here */
196 mov r2, #0x00000000 /* clear */
197
198clbss_l:str r2, [r0] /* clear loop... */
199 add r0, r0, #4
200 cmp r0, r1
201 bne clbss_l
202
wdenk6f213472003-08-29 22:00:43 +0000203 ldr pc, _start_armboot
204
205_start_armboot:
206 .word start_armboot
207
208
209/*
210 *************************************************************************
211 *
212 * CPU_init_critical registers
213 *
214 * setup important registers
215 * setup memory timing
216 *
217 *************************************************************************
218 */
219
220
221cpu_init_crit:
222 /*
223 * flush v4 I/D caches
224 */
225 mov r0, #0
226 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
227 mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
228
229 /*
230 * disable MMU stuff and caches
231 */
232 mrc p15, 0, r0, c1, c0, 0
233 bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */
234 bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */
235 orr r0, r0, #0x00000002 /* set bit 2 (A) Align */
236 orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
237 mcr p15, 0, r0, c1, c0, 0
238
239 /*
240 * Go setup Memory and board specific bits prior to relocation.
241 */
242 mov ip, lr /* perserve link reg across call */
243 bl platformsetup /* go setup pll,mux,memory */
244 mov lr, ip /* restore link */
245 mov pc, lr /* back to my caller */
246/*
247 *************************************************************************
248 *
249 * Interrupt handling
250 *
251 *************************************************************************
252 */
253
254@
255@ IRQ stack frame.
256@
257#define S_FRAME_SIZE 72
258
259#define S_OLD_R0 68
260#define S_PSR 64
261#define S_PC 60
262#define S_LR 56
263#define S_SP 52
264
265#define S_IP 48
266#define S_FP 44
267#define S_R10 40
268#define S_R9 36
269#define S_R8 32
270#define S_R7 28
271#define S_R6 24
272#define S_R5 20
273#define S_R4 16
274#define S_R3 12
275#define S_R2 8
276#define S_R1 4
277#define S_R0 0
278
279#define MODE_SVC 0x13
280#define I_BIT 0x80
281
282/*
283 * use bad_save_user_regs for abort/prefetch/undef/swi ...
284 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
285 */
286
287 .macro bad_save_user_regs
288 @ carve out a frame on current user stack
289 sub sp, sp, #S_FRAME_SIZE
290 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
wdenkf6e20fc2004-02-08 19:38:38 +0000291
292 ldr r2, _armboot_start
293 sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
294 sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
wdenk6f213472003-08-29 22:00:43 +0000295 @ get values for "aborted" pc and cpsr (into parm regs)
296 ldmia r2, {r2 - r3}
297 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
298 add r5, sp, #S_SP
299 mov r1, lr
300 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
301 mov r0, sp @ save current stack into r0 (param register)
302 .endm
303
304 .macro irq_save_user_regs
305 sub sp, sp, #S_FRAME_SIZE
306 stmia sp, {r0 - r12} @ Calling r0-r12
307 @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
308 add r8, sp, #S_PC
309 stmdb r8, {sp, lr}^ @ Calling SP, LR
310 str lr, [r8, #0] @ Save calling PC
311 mrs r6, spsr
312 str r6, [r8, #4] @ Save CPSR
313 str r0, [r8, #8] @ Save OLD_R0
314 mov r0, sp
315 .endm
316
317 .macro irq_restore_user_regs
318 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
319 mov r0, r0
320 ldr lr, [sp, #S_PC] @ Get PC
321 add sp, sp, #S_FRAME_SIZE
322 subs pc, lr, #4 @ return & move spsr_svc into cpsr
323 .endm
324
325 .macro get_bad_stack
wdenkf6e20fc2004-02-08 19:38:38 +0000326 ldr r13, _armboot_start @ setup our mode stack
327 sub r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
328 sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
wdenk6f213472003-08-29 22:00:43 +0000329
330 str lr, [r13] @ save caller lr in position 0 of saved stack
331 mrs lr, spsr @ get the spsr
332 str lr, [r13, #4] @ save spsr in position 1 of saved stack
333 mov r13, #MODE_SVC @ prepare SVC-Mode
334 @ msr spsr_c, r13
335 msr spsr, r13 @ switch modes, make sure moves will execute
336 mov lr, pc @ capture return pc
337 movs pc, lr @ jump to next instruction & switch modes.
338 .endm
339
340 .macro get_irq_stack @ setup IRQ stack
341 ldr sp, IRQ_STACK_START
342 .endm
343
344 .macro get_fiq_stack @ setup FIQ stack
345 ldr sp, FIQ_STACK_START
346 .endm
347
348/*
349 * exception handlers
350 */
351 .align 5
352undefined_instruction:
353 get_bad_stack
354 bad_save_user_regs
355 bl do_undefined_instruction
356
357 .align 5
358software_interrupt:
359 get_bad_stack
360 bad_save_user_regs
361 bl do_software_interrupt
362
363 .align 5
364prefetch_abort:
365 get_bad_stack
366 bad_save_user_regs
367 bl do_prefetch_abort
368
369 .align 5
370data_abort:
371 get_bad_stack
372 bad_save_user_regs
373 bl do_data_abort
374
375 .align 5
376not_used:
377 get_bad_stack
378 bad_save_user_regs
379 bl do_not_used
380
381#ifdef CONFIG_USE_IRQ
382
383 .align 5
384irq:
385 get_irq_stack
386 irq_save_user_regs
387 bl do_irq
388 irq_restore_user_regs
389
390 .align 5
391fiq:
392 get_fiq_stack
393 /* someone ought to write a more effiction fiq_save_user_regs */
394 irq_save_user_regs
395 bl do_fiq
396 irq_restore_user_regs
397
398#else
399
400 .align 5
401irq:
402 get_bad_stack
403 bad_save_user_regs
404 bl do_irq
405
406 .align 5
407fiq:
408 get_bad_stack
409 bad_save_user_regs
410 bl do_fiq
411
412#endif
413
414 .align 5
415.globl reset_cpu
416reset_cpu:
417 ldr r1, rstctl1 /* get clkm1 reset ctl */
wdenk42d1f032003-10-15 23:53:47 +0000418 mov r3, #0x0
wdenk6f213472003-08-29 22:00:43 +0000419 strh r3, [r1] /* clear it */
420 mov r3, #0x8
421 strh r3, [r1] /* force dsp+arm reset */
422_loop_forever:
423 b _loop_forever
424
425
426rstctl1:
427 .word 0xfffece10