]> git.ipfire.org Git - people/ms/u-boot.git/blame - arch/arm/cpu/ixp/start.S
Add GPL-2.0+ SPDX-License-Identifier to source files
[people/ms/u-boot.git] / arch / arm / cpu / ixp / start.S
CommitLineData
2d5b561e
WD
1/* vi: set ts=8 sw=8 noet: */
2/*
3 * u-boot - Startup Code for XScale IXP
4 *
5 * Copyright (C) 2003 Kyle Harris <kharris@nexus-tech.net>
6 *
7 * Based on startup code example contained in the
8 * Intel IXP4xx Programmer's Guide and past u-boot Start.S
9 * samples.
10 *
1a459660 11 * SPDX-License-Identifier: GPL-2.0+
2d5b561e
WD
12 */
13
25ddd1fb 14#include <asm-offsets.h>
2d5b561e
WD
15#include <config.h>
16#include <version.h>
17#include <asm/arch/ixp425.h>
18
42d1f039
WD
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 */
2d5b561e
WD
31#define MMU_Control_Init (MMU_Control_P|MMU_Control_D|MMU_Control_L)
32
33
34/*
35 * Macro definitions
36 */
42d1f039
WD
37 /* Delay a bit */
38 .macro DELAY_FOR cycles, reg0
39 ldr \reg0, =\cycles
40 subs \reg0, \reg0, #1
41 subne pc, pc, #0xc
42 .endm
43
44 /* wait for coprocessor write complete */
45 .macro CPWAIT reg
46 mrc p15,0,\reg,c2,c0,0
47 mov \reg,\reg
48 sub pc,pc,#4
49 .endm
2d5b561e
WD
50
51.globl _start
ce04bb41
MS
52_start:
53 ldr pc, _reset
2d5b561e
WD
54 ldr pc, _undefined_instruction
55 ldr pc, _software_interrupt
56 ldr pc, _prefetch_abort
57 ldr pc, _data_abort
58 ldr pc, _not_used
59 ldr pc, _irq
60 ldr pc, _fiq
61
ce04bb41 62_reset: .word reset
2d5b561e
WD
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
68_irq: .word irq
69_fiq: .word fiq
70
71 .balignl 16,0xdeadbeef
72
73
74/*
75 * Startup Code (reset vector)
76 *
77 * do important init only if we don't start from memory!
78 * - relocate armboot to ram
79 * - setup stack
80 * - jump to second stage
81 */
82
2af0a099 83.globl _TEXT_BASE
2d5b561e 84_TEXT_BASE:
508611bc
BT
85#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE)
86 .word CONFIG_SPL_TEXT_BASE
87#else
14d0a02a 88 .word CONFIG_SYS_TEXT_BASE
508611bc 89#endif
2d5b561e 90
2d5b561e 91/*
f6e20fc6 92 * These are defined in the board-specific linker script.
3336ca60
AA
93 * Subtracting _start from them lets the linker put their
94 * relative position in the executable instead of leaving
95 * them null.
2d5b561e 96 */
3336ca60
AA
97.globl _bss_start_ofs
98_bss_start_ofs:
99 .word __bss_start - _start
2d5b561e 100
3336ca60
AA
101.globl _bss_end_ofs
102_bss_end_ofs:
3929fb0a 103 .word __bss_end - _start
2d5b561e 104
f326cbba
PYC
105.globl _end_ofs
106_end_ofs:
107 .word _end - _start
108
2d5b561e
WD
109#ifdef CONFIG_USE_IRQ
110/* IRQ stack memory (calculated at run-time) */
111.globl IRQ_STACK_START
112IRQ_STACK_START:
113 .word 0x0badc0de
114
115/* IRQ stack memory (calculated at run-time) */
116.globl FIQ_STACK_START
117FIQ_STACK_START:
118 .word 0x0badc0de
119#endif
120
2af0a099
HS
121/* IRQ stack memory (calculated at run-time) + 8 bytes */
122.globl IRQ_STACK_START_IN
123IRQ_STACK_START_IN:
124 .word 0x0badc0de
125
2af0a099
HS
126/*
127 * the actual reset code
128 */
129
130reset:
131 /* disable mmu, set big-endian */
132 mov r0, #0xf8
133 mcr p15, 0, r0, c1, c0, 0
134 CPWAIT r0
135
136 /* invalidate I & D caches & BTB */
137 mcr p15, 0, r0, c7, c7, 0
138 CPWAIT r0
139
140 /* invalidate I & Data TLB */
141 mcr p15, 0, r0, c8, c7, 0
142 CPWAIT r0
143
144 /* drain write and fill buffers */
145 mcr p15, 0, r0, c7, c10, 4
146 CPWAIT r0
147
148 /* disable write buffer coalescing */
149 mrc p15, 0, r0, c1, c0, 1
150 orr r0, r0, #1
151 mcr p15, 0, r0, c1, c0, 1
152 CPWAIT r0
153
154 /* set EXP CS0 to the optimum timing */
155 ldr r1, =CONFIG_SYS_EXP_CS0
156 ldr r2, =IXP425_EXP_CS0
157 str r1, [r2]
158
159 /* make sure flash is visible at 0 */
2af0a099
HS
160 mov r1, #CONFIG_SYS_SDR_CONFIG
161 ldr r2, =IXP425_SDR_CONFIG
162 str r1, [r2]
163
164 /* disable refresh cycles */
165 mov r1, #0
166 ldr r3, =IXP425_SDR_REFRESH
167 str r1, [r3]
168
169 /* send nop command */
170 mov r1, #3
171 ldr r4, =IXP425_SDR_IR
172 str r1, [r4]
173 DELAY_FOR 0x4000, r0
174
175 /* set SDRAM internal refresh val */
176 ldr r1, =CONFIG_SYS_SDRAM_REFRESH_CNT
177 str r1, [r3]
178 DELAY_FOR 0x4000, r0
179
180 /* send precharge-all command to close all open banks */
181 mov r1, #2
182 str r1, [r4]
183 DELAY_FOR 0x4000, r0
184
185 /* provide 8 auto-refresh cycles */
186 mov r1, #4
187 mov r5, #8
188111: str r1, [r4]
189 DELAY_FOR 0x100, r0
190 subs r5, r5, #1
191 bne 111b
192
193 /* set mode register in sdram */
194 mov r1, #CONFIG_SYS_SDR_MODE_CONFIG
195 str r1, [r4]
196 DELAY_FOR 0x4000, r0
197
198 /* send normal operation command */
199 mov r1, #6
200 str r1, [r4]
201 DELAY_FOR 0x4000, r0
202
2af0a099
HS
203 /* invalidate I & D caches & BTB */
204 mcr p15, 0, r0, c7, c7, 0
205 CPWAIT r0
206
207 /* invalidate I & Data TLB */
208 mcr p15, 0, r0, c8, c7, 0
209 CPWAIT r0
210
211 /* drain write and fill buffers */
212 mcr p15, 0, r0, c7, c10, 4
213 CPWAIT r0
214
ce04bb41 215 /* remove flash mirror at 0x00000000 */
2af0a099
HS
216 ldr r2, =IXP425_EXP_CFG0
217 ldr r1, [r2]
218 bic r1, r1, #0x80000000
219 str r1, [r2]
220
2af0a099
HS
221 /* invalidate I & Data TLB */
222 mcr p15, 0, r0, c8, c7, 0
223 CPWAIT r0
224
225 /* enable I cache */
226 mrc p15, 0, r0, c1, c0, 0
227 orr r0, r0, #MMU_Control_I
228 mcr p15, 0, r0, c1, c0, 0
229 CPWAIT r0
230
231 mrs r0,cpsr /* set the cpu to SVC32 mode */
232 bic r0,r0,#0x1f /* (superviser mode, M=10011) */
233 orr r0,r0,#0x13
234 msr cpsr,r0
235
e05e5de7 236 bl _main
2af0a099
HS
237
238/*------------------------------------------------------------------------------*/
239
e05e5de7
AA
240 .globl c_runtime_cpu_setup
241c_runtime_cpu_setup:
242
243 bx lr
244
2d5b561e
WD
245/****************************************************************************/
246/* */
247/* Interrupt handling */
248/* */
249/****************************************************************************/
250
251/* IRQ stack frame */
252
253#define S_FRAME_SIZE 72
254
255#define S_OLD_R0 68
256#define S_PSR 64
257#define S_PC 60
258#define S_LR 56
259#define S_SP 52
260
261#define S_IP 48
262#define S_FP 44
263#define S_R10 40
264#define S_R9 36
265#define S_R8 32
266#define S_R7 28
267#define S_R6 24
268#define S_R5 20
269#define S_R4 16
270#define S_R3 12
271#define S_R2 8
272#define S_R1 4
273#define S_R0 0
274
275#define MODE_SVC 0x13
276
277 /* use bad_save_user_regs for abort/prefetch/undef/swi ... */
278
279 .macro bad_save_user_regs
280 sub sp, sp, #S_FRAME_SIZE
281 stmia sp, {r0 - r12} /* Calling r0-r12 */
282 add r8, sp, #S_PC
283
2af0a099 284 ldr r2, IRQ_STACK_START_IN
2d5b561e
WD
285 ldmia r2, {r2 - r4} /* get pc, cpsr, old_r0 */
286 add r0, sp, #S_FRAME_SIZE /* restore sp_SVC */
287
288 add r5, sp, #S_SP
289 mov r1, lr
290 stmia r5, {r0 - r4} /* save sp_SVC, lr_SVC, pc, cpsr, old_r */
291 mov r0, sp
292 .endm
293
294
295 /* use irq_save_user_regs / irq_restore_user_regs for */
296 /* IRQ/FIQ handling */
297
298 .macro irq_save_user_regs
299 sub sp, sp, #S_FRAME_SIZE
300 stmia sp, {r0 - r12} /* Calling r0-r12 */
301 add r8, sp, #S_PC
302 stmdb r8, {sp, lr}^ /* Calling SP, LR */
303 str lr, [r8, #0] /* Save calling PC */
304 mrs r6, spsr
305 str r6, [r8, #4] /* Save CPSR */
306 str r0, [r8, #8] /* Save OLD_R0 */
307 mov r0, sp
308 .endm
309
310 .macro irq_restore_user_regs
311 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
312 mov r0, r0
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
316 .endm
317
318 .macro get_bad_stack
2af0a099 319 ldr r13, IRQ_STACK_START_IN @ setup our mode stack
2d5b561e
WD
320
321 str lr, [r13] @ save caller lr / spsr
322 mrs lr, spsr
323 str lr, [r13, #4]
324
325 mov r13, #MODE_SVC @ prepare SVC-Mode
326 msr spsr_c, r13
327 mov lr, pc
328 movs pc, lr
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/****************************************************************************/
341/* */
342/* exception handlers */
343/* */
344/****************************************************************************/
345
346 .align 5
347undefined_instruction:
348 get_bad_stack
349 bad_save_user_regs
350 bl do_undefined_instruction
351
352 .align 5
353software_interrupt:
354 get_bad_stack
355 bad_save_user_regs
356 bl do_software_interrupt
357
358 .align 5
359prefetch_abort:
360 get_bad_stack
361 bad_save_user_regs
362 bl do_prefetch_abort
363
364 .align 5
365data_abort:
366 get_bad_stack
367 bad_save_user_regs
368 bl do_data_abort
369
370 .align 5
371not_used:
372 get_bad_stack
373 bad_save_user_regs
374 bl do_not_used
375
376#ifdef CONFIG_USE_IRQ
377
378 .align 5
379irq:
380 get_irq_stack
381 irq_save_user_regs
382 bl do_irq
383 irq_restore_user_regs
384
385 .align 5
386fiq:
387 get_fiq_stack
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
391
392#else
393
394 .align 5
395irq:
396 get_bad_stack
397 bad_save_user_regs
398 bl do_irq
399
400 .align 5
401fiq:
402 get_bad_stack
403 bad_save_user_regs
404 bl do_fiq
405
406#endif
407
408/****************************************************************************/
409/* */
410/* Reset function: Use Watchdog to reset */
411/* */
412/****************************************************************************/
413
414 .align 5
415.globl reset_cpu
416
417reset_cpu:
53677ef1 418 ldr r1, =0x482e
2d5b561e
WD
419 ldr r2, =IXP425_OSWK
420 str r1, [r2]
53677ef1 421 ldr r1, =0x0fff
2d5b561e
WD
422 ldr r2, =IXP425_OSWT
423 str r1, [r2]
53677ef1 424 ldr r1, =0x5
2d5b561e
WD
425 ldr r2, =IXP425_OSWE
426 str r1, [r2]
427 b reset_endless
428
2d5b561e 429reset_endless:
2d5b561e 430 b reset_endless