]> git.ipfire.org Git - thirdparty/u-boot.git/blob - arch/arm/cpu/ixp/start.S
Coding Style cleanup: remove trailing white space
[thirdparty/u-boot.git] / arch / arm / cpu / ixp / start.S
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 *
11 * SPDX-License-Identifier: GPL-2.0+
12 */
13
14 #include <asm-offsets.h>
15 #include <config.h>
16 #include <version.h>
17 #include <asm/arch/ixp425.h>
18
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)
32
33
34 /*
35 * Macro definitions
36 */
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
50
51 .globl _start
52 _start:
53 ldr pc, _reset
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
62 _reset: .word reset
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
83 .globl _TEXT_BASE
84 _TEXT_BASE:
85 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE)
86 .word CONFIG_SPL_TEXT_BASE
87 #else
88 .word CONFIG_SYS_TEXT_BASE
89 #endif
90
91 /*
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
95 * them null.
96 */
97 .globl _bss_start_ofs
98 _bss_start_ofs:
99 .word __bss_start - _start
100
101 .globl _bss_end_ofs
102 _bss_end_ofs:
103 .word __bss_end - _start
104
105 .globl _end_ofs
106 _end_ofs:
107 .word _end - _start
108
109 #ifdef CONFIG_USE_IRQ
110 /* IRQ stack memory (calculated at run-time) */
111 .globl IRQ_STACK_START
112 IRQ_STACK_START:
113 .word 0x0badc0de
114
115 /* IRQ stack memory (calculated at run-time) */
116 .globl FIQ_STACK_START
117 FIQ_STACK_START:
118 .word 0x0badc0de
119 #endif
120
121 /* IRQ stack memory (calculated at run-time) + 8 bytes */
122 .globl IRQ_STACK_START_IN
123 IRQ_STACK_START_IN:
124 .word 0x0badc0de
125
126 /*
127 * the actual reset code
128 */
129
130 reset:
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 */
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
188 111: 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
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
215 /* remove flash mirror at 0x00000000 */
216 ldr r2, =IXP425_EXP_CFG0
217 ldr r1, [r2]
218 bic r1, r1, #0x80000000
219 str r1, [r2]
220
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
236 bl _main
237
238 /*------------------------------------------------------------------------------*/
239
240 .globl c_runtime_cpu_setup
241 c_runtime_cpu_setup:
242
243 bx lr
244
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
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 */
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
319 ldr r13, IRQ_STACK_START_IN @ setup our mode stack
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
347 undefined_instruction:
348 get_bad_stack
349 bad_save_user_regs
350 bl do_undefined_instruction
351
352 .align 5
353 software_interrupt:
354 get_bad_stack
355 bad_save_user_regs
356 bl do_software_interrupt
357
358 .align 5
359 prefetch_abort:
360 get_bad_stack
361 bad_save_user_regs
362 bl do_prefetch_abort
363
364 .align 5
365 data_abort:
366 get_bad_stack
367 bad_save_user_regs
368 bl do_data_abort
369
370 .align 5
371 not_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
379 irq:
380 get_irq_stack
381 irq_save_user_regs
382 bl do_irq
383 irq_restore_user_regs
384
385 .align 5
386 fiq:
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
395 irq:
396 get_bad_stack
397 bad_save_user_regs
398 bl do_irq
399
400 .align 5
401 fiq:
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
417 reset_cpu:
418 ldr r1, =0x482e
419 ldr r2, =IXP425_OSWK
420 str r1, [r2]
421 ldr r1, =0x0fff
422 ldr r2, =IXP425_OSWT
423 str r1, [r2]
424 ldr r1, =0x5
425 ldr r2, =IXP425_OSWE
426 str r1, [r2]
427 b reset_endless
428
429 reset_endless:
430 b reset_endless