]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/sa1100/start.S
Merge branch 'u-boot/master' into u-boot-arm/master
[karo-tx-uboot.git] / arch / arm / cpu / sa1100 / start.S
1 /*
2  *  armboot - Startup Code for SA1100 CPU
3  *
4  *  Copyright (C) 1998  Dan Malek <dmalek@jlc.net>
5  *  Copyright (C) 1999  Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
6  *  Copyright (C) 2000  Wolfgang Denk <wd@denx.de>
7  *  Copyright (c) 2001  Alex Züpke <azu@sysgo.de>
8  *
9  * SPDX-License-Identifier:     GPL-2.0+
10  */
11
12 #include <asm-offsets.h>
13 #include <config.h>
14 #include <version.h>
15
16 /*
17  *************************************************************************
18  *
19  * Jump vector table as in table 3.1 in [1]
20  *
21  *************************************************************************
22  */
23
24
25 .globl _start
26 _start: b       reset
27         ldr     pc, _undefined_instruction
28         ldr     pc, _software_interrupt
29         ldr     pc, _prefetch_abort
30         ldr     pc, _data_abort
31         ldr     pc, _not_used
32         ldr     pc, _irq
33         ldr     pc, _fiq
34
35 _undefined_instruction: .word undefined_instruction
36 _software_interrupt:    .word software_interrupt
37 _prefetch_abort:        .word prefetch_abort
38 _data_abort:            .word data_abort
39 _not_used:              .word not_used
40 _irq:                   .word irq
41 _fiq:                   .word fiq
42
43         .balignl 16,0xdeadbeef
44
45
46 /*
47  *************************************************************************
48  *
49  * Startup Code (reset vector)
50  *
51  * do important init only if we don't start from memory!
52  * relocate armboot to ram
53  * setup stack
54  * jump to second stage
55  *
56  *************************************************************************
57  */
58
59 .globl _TEXT_BASE
60 _TEXT_BASE:
61 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE)
62         .word   CONFIG_SPL_TEXT_BASE
63 #else
64         .word   CONFIG_SYS_TEXT_BASE
65 #endif
66
67 /*
68  * These are defined in the board-specific linker script.
69  * Subtracting _start from them lets the linker put their
70  * relative position in the executable instead of leaving
71  * them null.
72  */
73 .globl _bss_start_ofs
74 _bss_start_ofs:
75         .word __bss_start - _start
76
77 .globl _bss_end_ofs
78 _bss_end_ofs:
79         .word __bss_end - _start
80
81 .globl _end_ofs
82 _end_ofs:
83         .word _end - _start
84
85 #ifdef CONFIG_USE_IRQ
86 /* IRQ stack memory (calculated at run-time) */
87 .globl IRQ_STACK_START
88 IRQ_STACK_START:
89         .word   0x0badc0de
90
91 /* IRQ stack memory (calculated at run-time) */
92 .globl FIQ_STACK_START
93 FIQ_STACK_START:
94         .word 0x0badc0de
95 #endif
96
97 /* IRQ stack memory (calculated at run-time) + 8 bytes */
98 .globl IRQ_STACK_START_IN
99 IRQ_STACK_START_IN:
100         .word   0x0badc0de
101
102 /*
103  * the actual reset code
104  */
105
106 reset:
107         /*
108          * set the cpu to SVC32 mode
109          */
110         mrs     r0,cpsr
111         bic     r0,r0,#0x1f
112         orr     r0,r0,#0xd3
113         msr     cpsr,r0
114
115         /*
116          * we do sys-critical inits only at reboot,
117          * not when booting from ram!
118          */
119 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
120         bl      cpu_init_crit
121 #endif
122
123         bl      _main
124
125 /*------------------------------------------------------------------------------*/
126
127         .globl  c_runtime_cpu_setup
128 c_runtime_cpu_setup:
129
130         mov     pc, lr
131
132 /*
133  *************************************************************************
134  *
135  * CPU_init_critical registers
136  *
137  * setup important registers
138  * setup memory timing
139  *
140  *************************************************************************
141  */
142
143
144 /* Interrupt-Controller base address */
145 IC_BASE:        .word   0x90050000
146 #define ICMR    0x04
147
148
149 /* Reset-Controller */
150 RST_BASE:               .word   0x90030000
151 #define RSRR    0x00
152 #define RCSR    0x04
153
154
155 /* PWR */
156 PWR_BASE:               .word   0x90020000
157 #define PSPR    0x08
158 #define PPCR    0x14
159 cpuspeed:               .word   CONFIG_SYS_CPUSPEED
160
161
162 cpu_init_crit:
163         /*
164          * mask all IRQs
165          */
166         ldr     r0, IC_BASE
167         mov     r1, #0x00
168         str     r1, [r0, #ICMR]
169
170         /* set clock speed */
171         ldr     r0, PWR_BASE
172         ldr     r1, cpuspeed
173         str     r1, [r0, #PPCR]
174
175         /*
176          * before relocating, we have to setup RAM timing
177          * because memory timing is board-dependend, you will
178          * find a lowlevel_init.S in your board directory.
179          */
180         mov     ip,     lr
181         bl      lowlevel_init
182         mov     lr,     ip
183
184         /*
185          * disable MMU stuff and enable I-cache
186          */
187         mrc     p15,0,r0,c1,c0
188         bic     r0, r0, #0x00002000     @ clear bit 13 (X)
189         bic     r0, r0, #0x0000000f     @ clear bits 3-0 (WCAM)
190         orr     r0, r0, #0x00001000     @ set bit 12 (I) Icache
191         orr     r0, r0, #0x00000002     @ set bit 2 (A) Align
192         mcr     p15,0,r0,c1,c0
193
194         /*
195          * flush v4 I/D caches
196          */
197         mov     r0, #0
198         mcr     p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */
199         mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */
200
201         mov     pc, lr
202
203
204 /*
205  *************************************************************************
206  *
207  * Interrupt handling
208  *
209  *************************************************************************
210  */
211
212 @
213 @ IRQ stack frame.
214 @
215 #define S_FRAME_SIZE    72
216
217 #define S_OLD_R0        68
218 #define S_PSR           64
219 #define S_PC            60
220 #define S_LR            56
221 #define S_SP            52
222
223 #define S_IP            48
224 #define S_FP            44
225 #define S_R10           40
226 #define S_R9            36
227 #define S_R8            32
228 #define S_R7            28
229 #define S_R6            24
230 #define S_R5            20
231 #define S_R4            16
232 #define S_R3            12
233 #define S_R2            8
234 #define S_R1            4
235 #define S_R0            0
236
237 #define MODE_SVC 0x13
238 #define I_BIT    0x80
239
240 /*
241  * use bad_save_user_regs for abort/prefetch/undef/swi ...
242  * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
243  */
244
245         .macro  bad_save_user_regs
246         sub     sp, sp, #S_FRAME_SIZE
247         stmia   sp, {r0 - r12}                  @ Calling r0-r12
248         add     r8, sp, #S_PC
249
250         ldr     r2, IRQ_STACK_START_IN
251         ldmia   r2, {r2 - r4}                   @ get pc, cpsr, old_r0
252         add     r0, sp, #S_FRAME_SIZE           @ restore sp_SVC
253
254         add     r5, sp, #S_SP
255         mov     r1, lr
256         stmia   r5, {r0 - r4}                   @ save sp_SVC, lr_SVC, pc, cpsr, old_r
257         mov     r0, sp
258         .endm
259
260         .macro  irq_save_user_regs
261         sub     sp, sp, #S_FRAME_SIZE
262         stmia   sp, {r0 - r12}                  @ Calling r0-r12
263         add     r8, sp, #S_PC
264         stmdb   r8, {sp, lr}^                   @ Calling SP, LR
265         str     lr, [r8, #0]                    @ Save calling PC
266         mrs     r6, spsr
267         str     r6, [r8, #4]                    @ Save CPSR
268         str     r0, [r8, #8]                    @ Save OLD_R0
269         mov     r0, sp
270         .endm
271
272         .macro  irq_restore_user_regs
273         ldmia   sp, {r0 - lr}^                  @ Calling r0 - lr
274         mov     r0, r0
275         ldr     lr, [sp, #S_PC]                 @ Get PC
276         add     sp, sp, #S_FRAME_SIZE
277         subs    pc, lr, #4                      @ return & move spsr_svc into cpsr
278         .endm
279
280         .macro get_bad_stack
281         ldr     r13, IRQ_STACK_START_IN         @ setup our mode stack
282
283         str     lr, [r13]                       @ save caller lr / spsr
284         mrs     lr, spsr
285         str     lr, [r13, #4]
286
287         mov     r13, #MODE_SVC                  @ prepare SVC-Mode
288         msr     spsr_c, r13
289         mov     lr, pc
290         movs    pc, lr
291         .endm
292
293         .macro get_irq_stack                    @ setup IRQ stack
294         ldr     sp, IRQ_STACK_START
295         .endm
296
297         .macro get_fiq_stack                    @ setup FIQ stack
298         ldr     sp, FIQ_STACK_START
299         .endm
300
301 /*
302  * exception handlers
303  */
304         .align  5
305 undefined_instruction:
306         get_bad_stack
307         bad_save_user_regs
308         bl      do_undefined_instruction
309
310         .align  5
311 software_interrupt:
312         get_bad_stack
313         bad_save_user_regs
314         bl      do_software_interrupt
315
316         .align  5
317 prefetch_abort:
318         get_bad_stack
319         bad_save_user_regs
320         bl      do_prefetch_abort
321
322         .align  5
323 data_abort:
324         get_bad_stack
325         bad_save_user_regs
326         bl      do_data_abort
327
328         .align  5
329 not_used:
330         get_bad_stack
331         bad_save_user_regs
332         bl      do_not_used
333
334 #ifdef CONFIG_USE_IRQ
335
336         .align  5
337 irq:
338         get_irq_stack
339         irq_save_user_regs
340         bl      do_irq
341         irq_restore_user_regs
342
343         .align  5
344 fiq:
345         get_fiq_stack
346         /* someone ought to write a more effiction fiq_save_user_regs */
347         irq_save_user_regs
348         bl      do_fiq
349         irq_restore_user_regs
350
351 #else
352
353         .align  5
354 irq:
355         get_bad_stack
356         bad_save_user_regs
357         bl      do_irq
358
359         .align  5
360 fiq:
361         get_bad_stack
362         bad_save_user_regs
363         bl      do_fiq
364
365 #endif
366
367         .align  5
368 .globl reset_cpu
369 reset_cpu:
370         ldr     r0, RST_BASE
371         mov     r1, #0x0                        @ set bit 3-0 ...
372         str     r1, [r0, #RCSR]                 @ ... to clear in RCSR
373         mov     r1, #0x1
374         str     r1, [r0, #RSRR]                 @ and perform reset
375         b       reset_cpu                       @ silly, but repeat endlessly