2
* armboot - Startup Code for ARM920 CPU-core
4
* Copyright (c) 2001 Marius Grļæ½ger <mag@sysgo.de>
5
* Copyright (c) 2002 Alex Zļæ½pke <azu@sysgo.de>
6
* Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
8
* See file CREDITS for list of people who contributed to this
11
* This program is free software; you can redistribute it and/or
12
* modify it under the terms of the GNU General Public License as
13
* published by the Free Software Foundation; either version 2 of
14
* the License, or (at your option) any later version.
16
* This program is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
* GNU General Public License for more details.
21
* You should have received a copy of the GNU General Public License
22
* along with this program; if not, write to the Free Software
23
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
33
*************************************************************************
35
* Jump vector table as in table 3.1 in [1]
37
*************************************************************************
43
ldr pc, _undefined_instruction
44
ldr pc, _software_interrupt
45
ldr pc, _prefetch_abort
51
_undefined_instruction: .word undefined_instruction
52
_software_interrupt: .word software_interrupt
53
_prefetch_abort: .word prefetch_abort
54
_data_abort: .word data_abort
55
_not_used: .word not_used
59
.balignl 16,0xdeadbeef
63
*************************************************************************
65
* Startup Code (reset vector)
67
* do important init only if we don't start from memory!
68
* relocate armboot to ram
70
* jump to second stage
72
*************************************************************************
83
* These are defined in the board-specific linker script.
94
/* IRQ stack memory (calculated at run-time) */
95
.globl IRQ_STACK_START
99
/* IRQ stack memory (calculated at run-time) */
100
.globl FIQ_STACK_START
107
* the actual reset code
112
* set the cpu to SVC32 mode
119
#define pWDTCTL 0x80001400 /* Watchdog Timer control register */
120
#define pINTENC 0x8000050C /* Interupt-Controller enable clear register */
121
#define pCLKSET 0x80000420 /* clock divisor register */
123
/* disable watchdog, set watchdog control register to
124
* all zeros (default reset)
131
* mask all IRQs by setting all bits in the INTENC register (default)
137
/* FCLK:HCLK:PCLK = 1:2:2 */
138
/* default FCLK is 200 MHz, using 14.7456 MHz fin */
141
@ ldr r1, =0x0005ee39 @ 1: 2: 4
145
* we do sys-critical inits only at reboot,
146
* not when booting from ram!
148
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
152
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
153
relocate: /* relocate U-Boot to RAM */
154
adr r0, _start /* r0 <- current position of code */
155
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
156
cmp r0, r1 /* don't reloc during debug */
159
ldr r2, _armboot_start
161
sub r2, r3, r2 /* r2 <- size of armboot */
162
add r2, r0, r2 /* r2 <- source end address */
165
ldmia r0!, {r3-r10} /* copy from source address [r0] */
166
stmia r1!, {r3-r10} /* copy to target address [r1] */
167
cmp r0, r2 /* until source end addreee [r2] */
168
blt copy_loop /* a 'ble' here actually copies */
169
/* four bytes of bss */
170
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
172
/* Set up the stack */
174
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
175
sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */
176
sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */
177
#ifdef CONFIG_USE_IRQ
178
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
180
sub sp, r0, #12 /* leave 3 words for abort-stack */
183
ldr r0, _bss_start /* find start of bss segment */
184
@add r0, r0, #4 /* start at first byte of bss */
185
/* why inc. 4 bytes past then? */
186
ldr r1, _bss_end /* stop here */
187
mov r2, #0x00000000 /* clear */
189
clbss_l:str r2, [r0] /* clear loop... */
194
ldr pc, _start_armboot
196
_start_armboot: .word start_armboot
200
*************************************************************************
202
* CPU_init_critical registers
204
* setup important registers
205
* setup memory timing
207
*************************************************************************
213
* flush v4 I/D caches
216
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
217
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
220
* disable MMU stuff and caches
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
orr r0, r0, #0x40000000 @ set bit 30 (nF) notFastBus
228
mcr p15, 0, r0, c1, c0, 0
232
* before relocating, we have to setup RAM timing
233
* because memory timing is board-dependend, you will
234
* find a lowlevel_init.S in your board directory.
244
*************************************************************************
248
*************************************************************************
254
#define S_FRAME_SIZE 72
276
#define MODE_SVC 0x13
280
* use bad_save_user_regs for abort/prefetch/undef/swi ...
281
* use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
284
.macro bad_save_user_regs
285
sub sp, sp, #S_FRAME_SIZE
286
stmia sp, {r0 - r12} @ Calling r0-r12
287
ldr r2, _armboot_start
288
sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
289
sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
290
ldmia r2, {r2 - r3} @ get pc, cpsr
291
add r0, sp, #S_FRAME_SIZE @ restore sp_SVC
295
stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
299
.macro irq_save_user_regs
300
sub sp, sp, #S_FRAME_SIZE
301
stmia sp, {r0 - r12} @ Calling r0-r12
303
stmdb r8, {sp, lr}^ @ Calling SP, LR
304
str lr, [r8, #0] @ Save calling PC
306
str r6, [r8, #4] @ Save CPSR
307
str r0, [r8, #8] @ Save OLD_R0
311
.macro irq_restore_user_regs
312
ldmia sp, {r0 - lr}^ @ Calling r0 - lr
314
ldr lr, [sp, #S_PC] @ Get PC
315
add sp, sp, #S_FRAME_SIZE
316
subs pc, lr, #4 @ return & move spsr_svc into cpsr
320
ldr r13, _armboot_start @ setup our mode stack
321
sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
322
sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
324
str lr, [r13] @ save caller lr / spsr
328
mov r13, #MODE_SVC @ prepare SVC-Mode
335
.macro get_irq_stack @ setup IRQ stack
336
ldr sp, IRQ_STACK_START
339
.macro get_fiq_stack @ setup FIQ stack
340
ldr sp, FIQ_STACK_START
347
undefined_instruction:
350
bl do_undefined_instruction
356
bl do_software_interrupt
376
#ifdef CONFIG_USE_IRQ
383
irq_restore_user_regs
388
/* someone ought to write a more effiction fiq_save_user_regs */
391
irq_restore_user_regs
412
bl disable_interrupts
414
/* Disable watchdog */
423
/* Enable the watchdog */