]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/arm920t/start.S
zynq: add UART nodes to device tree to initialize UART with OF
[karo-tx-uboot.git] / arch / arm / cpu / arm920t / start.S
1 /*
2  *  armboot - Startup Code for ARM920 CPU-core
3  *
4  *  Copyright (c) 2001  Marius Gröger <mag@sysgo.de>
5  *  Copyright (c) 2002  Alex Züpke <azu@sysgo.de>
6  *  Copyright (c) 2002  Gary Jennejohn <garyj@denx.de>
7  *
8  * SPDX-License-Identifier:     GPL-2.0+
9  */
10
11 #include <asm-offsets.h>
12 #include <common.h>
13 #include <config.h>
14
15 /*
16  *************************************************************************
17  *
18  * Jump vector table as in table 3.1 in [1]
19  *
20  *************************************************************************
21  */
22
23
24 .globl _start
25 _start: b       start_code
26         ldr     pc, _undefined_instruction
27         ldr     pc, _software_interrupt
28         ldr     pc, _prefetch_abort
29         ldr     pc, _data_abort
30         ldr     pc, _not_used
31         ldr     pc, _irq
32         ldr     pc, _fiq
33
34 _undefined_instruction: .word undefined_instruction
35 _software_interrupt:    .word software_interrupt
36 _prefetch_abort:        .word prefetch_abort
37 _data_abort:            .word data_abort
38 _not_used:              .word not_used
39 _irq:                   .word irq
40 _fiq:                   .word fiq
41
42         .balignl 16,0xdeadbeef
43
44
45 /*
46  *************************************************************************
47  *
48  * Startup Code (called from the ARM reset exception vector)
49  *
50  * do important init only if we don't start from memory!
51  * relocate armboot to ram
52  * setup stack
53  * jump to second stage
54  *
55  *************************************************************************
56  */
57
58 #ifdef CONFIG_USE_IRQ
59 /* IRQ stack memory (calculated at run-time) */
60 .globl IRQ_STACK_START
61 IRQ_STACK_START:
62         .word   0x0badc0de
63
64 /* IRQ stack memory (calculated at run-time) */
65 .globl FIQ_STACK_START
66 FIQ_STACK_START:
67         .word 0x0badc0de
68 #endif
69
70 /* IRQ stack memory (calculated at run-time) + 8 bytes */
71 .globl IRQ_STACK_START_IN
72 IRQ_STACK_START_IN:
73         .word   0x0badc0de
74
75 /*
76  * the actual start code
77  */
78
79 start_code:
80         /*
81          * set the cpu to SVC32 mode
82          */
83         mrs     r0, cpsr
84         bic     r0, r0, #0x1f
85         orr     r0, r0, #0xd3
86         msr     cpsr, r0
87
88 #if     defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK)
89         /*
90          * relocate exception table
91          */
92         ldr     r0, =_start
93         ldr     r1, =0x0
94         mov     r2, #16
95 copyex:
96         subs    r2, r2, #1
97         ldr     r3, [r0], #4
98         str     r3, [r1], #4
99         bne     copyex
100 #endif
101
102 #ifdef CONFIG_S3C24X0
103         /* turn off the watchdog */
104
105 # if defined(CONFIG_S3C2400)
106 #  define pWTCON        0x15300000
107 #  define INTMSK        0x14400008      /* Interrupt-Controller base addresses */
108 #  define CLKDIVN       0x14800014      /* clock divisor register */
109 #else
110 #  define pWTCON        0x53000000
111 #  define INTMSK        0x4A000008      /* Interrupt-Controller base addresses */
112 #  define INTSUBMSK     0x4A00001C
113 #  define CLKDIVN       0x4C000014      /* clock divisor register */
114 # endif
115
116         ldr     r0, =pWTCON
117         mov     r1, #0x0
118         str     r1, [r0]
119
120         /*
121          * mask all IRQs by setting all bits in the INTMR - default
122          */
123         mov     r1, #0xffffffff
124         ldr     r0, =INTMSK
125         str     r1, [r0]
126 # if defined(CONFIG_S3C2410)
127         ldr     r1, =0x3ff
128         ldr     r0, =INTSUBMSK
129         str     r1, [r0]
130 # endif
131
132         /* FCLK:HCLK:PCLK = 1:2:4 */
133         /* default FCLK is 120 MHz ! */
134         ldr     r0, =CLKDIVN
135         mov     r1, #3
136         str     r1, [r0]
137 #endif  /* CONFIG_S3C24X0 */
138
139         /*
140          * we do sys-critical inits only at reboot,
141          * not when booting from ram!
142          */
143 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
144         bl      cpu_init_crit
145 #endif
146
147         bl      _main
148
149 /*------------------------------------------------------------------------------*/
150
151         .globl  c_runtime_cpu_setup
152 c_runtime_cpu_setup:
153
154         mov     pc, lr
155
156 /*
157  *************************************************************************
158  *
159  * CPU_init_critical registers
160  *
161  * setup important registers
162  * setup memory timing
163  *
164  *************************************************************************
165  */
166
167
168 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
169 cpu_init_crit:
170         /*
171          * flush v4 I/D caches
172          */
173         mov     r0, #0
174         mcr     p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */
175         mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */
176
177         /*
178          * disable MMU stuff and caches
179          */
180         mrc     p15, 0, r0, c1, c0, 0
181         bic     r0, r0, #0x00002300     @ clear bits 13, 9:8 (--V- --RS)
182         bic     r0, r0, #0x00000087     @ clear bits 7, 2:0 (B--- -CAM)
183         orr     r0, r0, #0x00000002     @ set bit 2 (A) Align
184         orr     r0, r0, #0x00001000     @ set bit 12 (I) I-Cache
185         mcr     p15, 0, r0, c1, c0, 0
186
187         /*
188          * before relocating, we have to setup RAM timing
189          * because memory timing is board-dependend, you will
190          * find a lowlevel_init.S in your board directory.
191          */
192         mov     ip, lr
193
194         bl      lowlevel_init
195
196         mov     lr, ip
197         mov     pc, lr
198 #endif /* CONFIG_SKIP_LOWLEVEL_INIT */
199
200 /*
201  *************************************************************************
202  *
203  * Interrupt handling
204  *
205  *************************************************************************
206  */
207
208 @
209 @ IRQ stack frame.
210 @
211 #define S_FRAME_SIZE    72
212
213 #define S_OLD_R0        68
214 #define S_PSR           64
215 #define S_PC            60
216 #define S_LR            56
217 #define S_SP            52
218
219 #define S_IP            48
220 #define S_FP            44
221 #define S_R10           40
222 #define S_R9            36
223 #define S_R8            32
224 #define S_R7            28
225 #define S_R6            24
226 #define S_R5            20
227 #define S_R4            16
228 #define S_R3            12
229 #define S_R2            8
230 #define S_R1            4
231 #define S_R0            0
232
233 #define MODE_SVC        0x13
234 #define I_BIT           0x80
235
236 /*
237  * use bad_save_user_regs for abort/prefetch/undef/swi ...
238  * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
239  */
240
241         .macro  bad_save_user_regs
242         sub     sp, sp, #S_FRAME_SIZE
243         stmia   sp, {r0 - r12}                  @ Calling r0-r12
244         ldr     r2, IRQ_STACK_START_IN
245         ldmia   r2, {r2 - r3}                   @ get pc, cpsr
246         add     r0, sp, #S_FRAME_SIZE           @ restore sp_SVC
247
248         add     r5, sp, #S_SP
249         mov     r1, lr
250         stmia   r5, {r0 - r3}                   @ save sp_SVC, lr_SVC, pc, cpsr
251         mov     r0, sp
252         .endm
253
254         .macro  irq_save_user_regs
255         sub     sp, sp, #S_FRAME_SIZE
256         stmia   sp, {r0 - r12}                  @ Calling r0-r12
257         add     r7, sp, #S_PC
258         stmdb   r7, {sp, lr}^                   @ Calling SP, LR
259         str     lr, [r7, #0]                    @ Save calling PC
260         mrs     r6, spsr
261         str     r6, [r7, #4]                    @ Save CPSR
262         str     r0, [r7, #8]                    @ Save OLD_R0
263         mov     r0, sp
264         .endm
265
266         .macro  irq_restore_user_regs
267         ldmia   sp, {r0 - lr}^                  @ Calling r0 - lr
268         mov     r0, r0
269         ldr     lr, [sp, #S_PC]                 @ Get PC
270         add     sp, sp, #S_FRAME_SIZE
271         /* return & move spsr_svc into cpsr */
272         subs    pc, lr, #4
273         .endm
274
275         .macro get_bad_stack
276         ldr     r13, IRQ_STACK_START_IN         @ setup our mode stack
277
278         str     lr, [r13]                       @ save caller lr / spsr
279         mrs     lr, spsr
280         str     lr, [r13, #4]
281
282         mov     r13, #MODE_SVC                  @ prepare SVC-Mode
283         @ msr   spsr_c, r13
284         msr     spsr, r13
285         mov     lr, pc
286         movs    pc, lr
287         .endm
288
289         .macro get_irq_stack                    @ setup IRQ stack
290         ldr     sp, IRQ_STACK_START
291         .endm
292
293         .macro get_fiq_stack                    @ setup FIQ stack
294         ldr     sp, FIQ_STACK_START
295         .endm
296
297 /*
298  * exception handlers
299  */
300         .align  5
301 undefined_instruction:
302         get_bad_stack
303         bad_save_user_regs
304         bl      do_undefined_instruction
305
306         .align  5
307 software_interrupt:
308         get_bad_stack
309         bad_save_user_regs
310         bl      do_software_interrupt
311
312         .align  5
313 prefetch_abort:
314         get_bad_stack
315         bad_save_user_regs
316         bl      do_prefetch_abort
317
318         .align  5
319 data_abort:
320         get_bad_stack
321         bad_save_user_regs
322         bl      do_data_abort
323
324         .align  5
325 not_used:
326         get_bad_stack
327         bad_save_user_regs
328         bl      do_not_used
329
330 #ifdef CONFIG_USE_IRQ
331
332         .align  5
333 irq:
334         get_irq_stack
335         irq_save_user_regs
336         bl      do_irq
337         irq_restore_user_regs
338
339         .align  5
340 fiq:
341         get_fiq_stack
342         /* someone ought to write a more effiction fiq_save_user_regs */
343         irq_save_user_regs
344         bl      do_fiq
345         irq_restore_user_regs
346
347 #else
348
349         .align  5
350 irq:
351         get_bad_stack
352         bad_save_user_regs
353         bl      do_irq
354
355         .align  5
356 fiq:
357         get_bad_stack
358         bad_save_user_regs
359         bl      do_fiq
360
361 #endif