1 /* vi: set ts=8 sw=8 noet: */
3 * u-boot - Startup Code for XScale IXP
5 * Copyright (C) 2003 Kyle Harris <kharris@nexus-tech.net>
7 * Based on startup code example contained in the
8 * Intel IXP4xx Programmer's Guide and past u-boot Start.S
11 * See file CREDITS for list of people who contributed to this
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32 #include <asm/arch/ixp425.h>
34 #define MMU_Control_M 0x001 // Enable MMU
35 #define MMU_Control_A 0x002 // Enable address alignment faults
36 #define MMU_Control_C 0x004 // Enable cache
37 #define MMU_Control_W 0x008 // Enable write-buffer
38 #define MMU_Control_P 0x010 // Compatability: 32 bit code
39 #define MMU_Control_D 0x020 // Compatability: 32 bit data
40 #define MMU_Control_L 0x040 // Compatability:
41 #define MMU_Control_B 0x080 // Enable Big-Endian
42 #define MMU_Control_S 0x100 // Enable system protection
43 #define MMU_Control_R 0x200 // Enable ROM protection
44 #define MMU_Control_I 0x1000 // Enable Instruction cache
45 #define MMU_Control_X 0x2000 // Set interrupt vectors at 0xFFFF0000
46 #define MMU_Control_Init (MMU_Control_P|MMU_Control_D|MMU_Control_L)
53 .macro DELAY_FOR cycles, reg0
59 // wait for coprocessor write complete
61 mrc p15,0,\reg,c2,c0,0
68 ldr pc, _undefined_instruction
69 ldr pc, _software_interrupt
70 ldr pc, _prefetch_abort
76 _undefined_instruction: .word undefined_instruction
77 _software_interrupt: .word software_interrupt
78 _prefetch_abort: .word prefetch_abort
79 _data_abort: .word data_abort
80 _not_used: .word not_used
84 .balignl 16,0xdeadbeef
88 * Startup Code (reset vector)
90 * do important init only if we don't start from memory!
91 * - relocate armboot to ram
93 * - jump to second stage
104 * Note: _armboot_end_data and _armboot_end are defined
105 * by the (board-dependent) linker script.
106 * _armboot_end_data is the first usable FLASH address after armboot
108 .globl _armboot_end_data
110 .word armboot_end_data
116 * This is defined in the board specific linker script
127 * _armboot_real_end is the first usable RAM address behind armboot
128 * and the various stacks
130 .globl _armboot_real_end
135 * We relocate uboot to this address (end of RAM - 128 KiB)
141 #ifdef CONFIG_USE_IRQ
142 /* IRQ stack memory (calculated at run-time) */
143 .globl IRQ_STACK_START
147 /* IRQ stack memory (calculated at run-time) */
148 .globl FIQ_STACK_START
153 /****************************************************************************/
155 /* the actual reset code */
157 /****************************************************************************/
160 /* disable mmu, set big-endian */
162 mcr p15, 0, r0, c1, c0, 0
165 /* invalidate I & D caches & BTB */
166 mcr p15, 0, r0, c7, c7, 0
169 /* invalidate I & Data TLB */
170 mcr p15, 0, r0, c8, c7, 0
173 /* drain write and fill buffers */
174 mcr p15, 0, r0, c7, c10, 4
177 /* disable write buffer coalescing */
178 mrc p15, 0, r0, c1, c0, 1
180 mcr p15, 0, r0, c1, c0, 1
183 /* set EXP CS0 to the optimum timing */
185 ldr r2, =IXP425_EXP_CS0
188 /* make sure flash is visible at 0 */
189 ldr r2, =IXP425_EXP_CFG0
191 orr r1, r1, #0x80000000
194 mov r1, #CFG_SDR_CONFIG
195 ldr r2, =IXP425_SDR_CONFIG
198 /* disable refresh cycles */
200 ldr r3, =IXP425_SDR_REFRESH
203 /* send nop command */
205 ldr r4, =IXP425_SDR_IR
209 /* set SDRAM internal refresh val */
210 ldr r1, =CFG_SDRAM_REFRESH_CNT
214 /* send precharge-all command to close all open banks */
219 /* provide 8 auto-refresh cycles */
227 /* set mode register in sdram */
232 /* send normal operation command */
250 /* invalidate I & D caches & BTB */
251 mcr p15, 0, r0, c7, c7, 0
254 /* invalidate I & Data TLB */
255 mcr p15, 0, r0, c8, c7, 0
258 /* drain write and fill buffers */
259 mcr p15, 0, r0, c7, c10, 4
262 /* move flash to 0x50000000 */
263 ldr r2, =IXP425_EXP_CFG0
265 bic r1, r1, #0x80000000
275 /* invalidate I & Data TLB */
276 mcr p15, 0, r0, c8, c7, 0
280 mrc p15, 0, r0, c1, c0, 0
281 orr r0, r0, #MMU_Control_I
282 mcr p15, 0, r0, c1, c0, 0
285 mrs r0,cpsr /* set the cpu to SVC32 mode */
286 bic r0,r0,#0x1f /* (superviser mode, M=10011) */
290 relocate: /* relocate U-Boot to RAM */
291 adr r0, _start /* r0 <- current position of code */
292 ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
293 cmp r0, r1 /* don't reloc during debug */
296 ldr r2, _armboot_start
298 sub r2, r3, r2 /* r2 <- size of armboot */
299 add r2, r0, r2 /* r2 <- source end address */
302 ldmia r0!, {r3-r10} /* copy from source address [r0] */
303 stmia r1!, {r3-r10} /* copy to target address [r1] */
304 cmp r0, r2 /* until source end addreee [r2] */
307 /* Set up the stack */
311 ldr r0, _uboot_reloc /* upper 128 KiB: relocated uboot */
312 sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
313 /* FIXME: bdinfo should be here */
314 sub sp, r0, #12 /* leave 3 words for abort-stack */
318 ldr r0, _bss_start /* find start of bss segment */
319 add r0, r0, #4 /* start at first byte of bss */
320 ldr r1, _bss_end /* stop here */
321 mov r2, #0x00000000 /* clear */
323 clbss_l:str r2, [r0] /* clear loop... */
329 ldr pc, _start_armboot
331 _start_armboot: .word start_armboot
336 /****************************************************************************/
338 /* Interrupt handling */
340 /****************************************************************************/
342 /* IRQ stack frame */
344 #define S_FRAME_SIZE 72
366 #define MODE_SVC 0x13
368 /* use bad_save_user_regs for abort/prefetch/undef/swi ... */
370 .macro bad_save_user_regs
371 sub sp, sp, #S_FRAME_SIZE
372 stmia sp, {r0 - r12} /* Calling r0-r12 */
376 add r2, r2, #CONFIG_STACKSIZE
378 ldmia r2, {r2 - r4} /* get pc, cpsr, old_r0 */
379 add r0, sp, #S_FRAME_SIZE /* restore sp_SVC */
383 stmia r5, {r0 - r4} /* save sp_SVC, lr_SVC, pc, cpsr, old_r */
388 /* use irq_save_user_regs / irq_restore_user_regs for */
389 /* IRQ/FIQ handling */
391 .macro irq_save_user_regs
392 sub sp, sp, #S_FRAME_SIZE
393 stmia sp, {r0 - r12} /* Calling r0-r12 */
395 stmdb r8, {sp, lr}^ /* Calling SP, LR */
396 str lr, [r8, #0] /* Save calling PC */
398 str r6, [r8, #4] /* Save CPSR */
399 str r0, [r8, #8] /* Save OLD_R0 */
403 .macro irq_restore_user_regs
404 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
406 ldr lr, [sp, #S_PC] @ Get PC
407 add sp, sp, #S_FRAME_SIZE
408 subs pc, lr, #4 @ return & move spsr_svc into cpsr
412 ldr r13, _armboot_end @ setup our mode stack
413 add r13, r13, #CONFIG_STACKSIZE @ resides at top of normal stack
416 str lr, [r13] @ save caller lr / spsr
420 mov r13, #MODE_SVC @ prepare SVC-Mode
426 .macro get_irq_stack @ setup IRQ stack
427 ldr sp, IRQ_STACK_START
430 .macro get_fiq_stack @ setup FIQ stack
431 ldr sp, FIQ_STACK_START
435 /****************************************************************************/
437 /* exception handlers */
439 /****************************************************************************/
442 undefined_instruction:
445 bl do_undefined_instruction
451 bl do_software_interrupt
471 #ifdef CONFIG_USE_IRQ
478 irq_restore_user_regs
483 irq_save_user_regs /* someone ought to write a more */
484 bl do_fiq /* effiction fiq_save_user_regs */
485 irq_restore_user_regs
503 /****************************************************************************/
505 /* Reset function: Use Watchdog to reset */
507 /****************************************************************************/