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 * SPDX-License-Identifier: GPL-2.0+
14 #include <asm-offsets.h>
17 #include <asm/arch/ixp425.h>
19 #define MMU_Control_M 0x001 /* Enable MMU */
20 #define MMU_Control_A 0x002 /* Enable address alignment faults */
21 #define MMU_Control_C 0x004 /* Enable cache */
22 #define MMU_Control_W 0x008 /* Enable write-buffer */
23 #define MMU_Control_P 0x010 /* Compatability: 32 bit code */
24 #define MMU_Control_D 0x020 /* Compatability: 32 bit data */
25 #define MMU_Control_L 0x040 /* Compatability: */
26 #define MMU_Control_B 0x080 /* Enable Big-Endian */
27 #define MMU_Control_S 0x100 /* Enable system protection */
28 #define MMU_Control_R 0x200 /* Enable ROM protection */
29 #define MMU_Control_I 0x1000 /* Enable Instruction cache */
30 #define MMU_Control_X 0x2000 /* Set interrupt vectors at 0xFFFF0000 */
31 #define MMU_Control_Init (MMU_Control_P|MMU_Control_D|MMU_Control_L)
38 .macro DELAY_FOR cycles, reg0
44 /* wait for coprocessor write complete */
46 mrc p15,0,\reg,c2,c0,0
54 ldr pc, _undefined_instruction
55 ldr pc, _software_interrupt
56 ldr pc, _prefetch_abort
63 _undefined_instruction: .word undefined_instruction
64 _software_interrupt: .word software_interrupt
65 _prefetch_abort: .word prefetch_abort
66 _data_abort: .word data_abort
67 _not_used: .word not_used
71 .balignl 16,0xdeadbeef
75 * Startup Code (reset vector)
77 * do important init only if we don't start from memory!
78 * - relocate armboot to ram
80 * - jump to second stage
85 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE)
86 .word CONFIG_SPL_TEXT_BASE
88 .word CONFIG_SYS_TEXT_BASE
92 * These are defined in the board-specific linker script.
93 * Subtracting _start from them lets the linker put their
94 * relative position in the executable instead of leaving
99 .word __bss_start - _start
103 .word __bss_end - _start
109 #ifdef CONFIG_USE_IRQ
110 /* IRQ stack memory (calculated at run-time) */
111 .globl IRQ_STACK_START
115 /* IRQ stack memory (calculated at run-time) */
116 .globl FIQ_STACK_START
121 /* IRQ stack memory (calculated at run-time) + 8 bytes */
122 .globl IRQ_STACK_START_IN
127 * the actual reset code
131 /* disable mmu, set big-endian */
133 mcr p15, 0, r0, c1, c0, 0
136 /* invalidate I & D caches & BTB */
137 mcr p15, 0, r0, c7, c7, 0
140 /* invalidate I & Data TLB */
141 mcr p15, 0, r0, c8, c7, 0
144 /* drain write and fill buffers */
145 mcr p15, 0, r0, c7, c10, 4
148 /* disable write buffer coalescing */
149 mrc p15, 0, r0, c1, c0, 1
151 mcr p15, 0, r0, c1, c0, 1
154 /* set EXP CS0 to the optimum timing */
155 ldr r1, =CONFIG_SYS_EXP_CS0
156 ldr r2, =IXP425_EXP_CS0
159 /* make sure flash is visible at 0 */
160 mov r1, #CONFIG_SYS_SDR_CONFIG
161 ldr r2, =IXP425_SDR_CONFIG
164 /* disable refresh cycles */
166 ldr r3, =IXP425_SDR_REFRESH
169 /* send nop command */
171 ldr r4, =IXP425_SDR_IR
175 /* set SDRAM internal refresh val */
176 ldr r1, =CONFIG_SYS_SDRAM_REFRESH_CNT
180 /* send precharge-all command to close all open banks */
185 /* provide 8 auto-refresh cycles */
193 /* set mode register in sdram */
194 mov r1, #CONFIG_SYS_SDR_MODE_CONFIG
198 /* send normal operation command */
203 /* invalidate I & D caches & BTB */
204 mcr p15, 0, r0, c7, c7, 0
207 /* invalidate I & Data TLB */
208 mcr p15, 0, r0, c8, c7, 0
211 /* drain write and fill buffers */
212 mcr p15, 0, r0, c7, c10, 4
215 /* remove flash mirror at 0x00000000 */
216 ldr r2, =IXP425_EXP_CFG0
218 bic r1, r1, #0x80000000
221 /* invalidate I & Data TLB */
222 mcr p15, 0, r0, c8, c7, 0
226 mrc p15, 0, r0, c1, c0, 0
227 orr r0, r0, #MMU_Control_I
228 mcr p15, 0, r0, c1, c0, 0
231 mrs r0,cpsr /* set the cpu to SVC32 mode */
232 bic r0,r0,#0x1f /* (superviser mode, M=10011) */
238 /*------------------------------------------------------------------------------*/
240 .globl c_runtime_cpu_setup
245 /****************************************************************************/
247 /* Interrupt handling */
249 /****************************************************************************/
251 /* IRQ stack frame */
253 #define S_FRAME_SIZE 72
275 #define MODE_SVC 0x13
277 /* use bad_save_user_regs for abort/prefetch/undef/swi ... */
279 .macro bad_save_user_regs
280 sub sp, sp, #S_FRAME_SIZE
281 stmia sp, {r0 - r12} /* Calling r0-r12 */
284 ldr r2, IRQ_STACK_START_IN
285 ldmia r2, {r2 - r4} /* get pc, cpsr, old_r0 */
286 add r0, sp, #S_FRAME_SIZE /* restore sp_SVC */
290 stmia r5, {r0 - r4} /* save sp_SVC, lr_SVC, pc, cpsr, old_r */
295 /* use irq_save_user_regs / irq_restore_user_regs for */
296 /* IRQ/FIQ handling */
298 .macro irq_save_user_regs
299 sub sp, sp, #S_FRAME_SIZE
300 stmia sp, {r0 - r12} /* Calling r0-r12 */
302 stmdb r8, {sp, lr}^ /* Calling SP, LR */
303 str lr, [r8, #0] /* Save calling PC */
305 str r6, [r8, #4] /* Save CPSR */
306 str r0, [r8, #8] /* Save OLD_R0 */
310 .macro irq_restore_user_regs
311 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
313 ldr lr, [sp, #S_PC] @ Get PC
314 add sp, sp, #S_FRAME_SIZE
315 subs pc, lr, #4 @ return & move spsr_svc into cpsr
319 ldr r13, IRQ_STACK_START_IN @ setup our mode stack
321 str lr, [r13] @ save caller lr / spsr
325 mov r13, #MODE_SVC @ prepare SVC-Mode
331 .macro get_irq_stack @ setup IRQ stack
332 ldr sp, IRQ_STACK_START
335 .macro get_fiq_stack @ setup FIQ stack
336 ldr sp, FIQ_STACK_START
340 /****************************************************************************/
342 /* exception handlers */
344 /****************************************************************************/
347 undefined_instruction:
350 bl do_undefined_instruction
356 bl do_software_interrupt
376 #ifdef CONFIG_USE_IRQ
383 irq_restore_user_regs
388 irq_save_user_regs /* someone ought to write a more */
389 bl do_fiq /* effiction fiq_save_user_regs */
390 irq_restore_user_regs
408 /****************************************************************************/
410 /* Reset function: Use Watchdog to reset */
412 /****************************************************************************/