]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/sa1100/start.S
arm: remove unneeded symbol offsets and _TEXT_BASE
[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 #ifdef CONFIG_USE_IRQ
60 /* IRQ stack memory (calculated at run-time) */
61 .globl IRQ_STACK_START
62 IRQ_STACK_START:
63         .word   0x0badc0de
64
65 /* IRQ stack memory (calculated at run-time) */
66 .globl FIQ_STACK_START
67 FIQ_STACK_START:
68         .word 0x0badc0de
69 #endif
70
71 /* IRQ stack memory (calculated at run-time) + 8 bytes */
72 .globl IRQ_STACK_START_IN
73 IRQ_STACK_START_IN:
74         .word   0x0badc0de
75
76 /*
77  * the actual reset code
78  */
79
80 reset:
81         /*
82          * set the cpu to SVC32 mode
83          */
84         mrs     r0,cpsr
85         bic     r0,r0,#0x1f
86         orr     r0,r0,#0xd3
87         msr     cpsr,r0
88
89         /*
90          * we do sys-critical inits only at reboot,
91          * not when booting from ram!
92          */
93 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
94         bl      cpu_init_crit
95 #endif
96
97         bl      _main
98
99 /*------------------------------------------------------------------------------*/
100
101         .globl  c_runtime_cpu_setup
102 c_runtime_cpu_setup:
103
104         mov     pc, lr
105
106 /*
107  *************************************************************************
108  *
109  * CPU_init_critical registers
110  *
111  * setup important registers
112  * setup memory timing
113  *
114  *************************************************************************
115  */
116
117
118 /* Interrupt-Controller base address */
119 IC_BASE:        .word   0x90050000
120 #define ICMR    0x04
121
122
123 /* Reset-Controller */
124 RST_BASE:               .word   0x90030000
125 #define RSRR    0x00
126 #define RCSR    0x04
127
128
129 /* PWR */
130 PWR_BASE:               .word   0x90020000
131 #define PSPR    0x08
132 #define PPCR    0x14
133 cpuspeed:               .word   CONFIG_SYS_CPUSPEED
134
135
136 cpu_init_crit:
137         /*
138          * mask all IRQs
139          */
140         ldr     r0, IC_BASE
141         mov     r1, #0x00
142         str     r1, [r0, #ICMR]
143
144         /* set clock speed */
145         ldr     r0, PWR_BASE
146         ldr     r1, cpuspeed
147         str     r1, [r0, #PPCR]
148
149         /*
150          * before relocating, we have to setup RAM timing
151          * because memory timing is board-dependend, you will
152          * find a lowlevel_init.S in your board directory.
153          */
154         mov     ip,     lr
155         bl      lowlevel_init
156         mov     lr,     ip
157
158         /*
159          * disable MMU stuff and enable I-cache
160          */
161         mrc     p15,0,r0,c1,c0
162         bic     r0, r0, #0x00002000     @ clear bit 13 (X)
163         bic     r0, r0, #0x0000000f     @ clear bits 3-0 (WCAM)
164         orr     r0, r0, #0x00001000     @ set bit 12 (I) Icache
165         orr     r0, r0, #0x00000002     @ set bit 2 (A) Align
166         mcr     p15,0,r0,c1,c0
167
168         /*
169          * flush v4 I/D caches
170          */
171         mov     r0, #0
172         mcr     p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */
173         mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */
174
175         mov     pc, lr
176
177
178 /*
179  *************************************************************************
180  *
181  * Interrupt handling
182  *
183  *************************************************************************
184  */
185
186 @
187 @ IRQ stack frame.
188 @
189 #define S_FRAME_SIZE    72
190
191 #define S_OLD_R0        68
192 #define S_PSR           64
193 #define S_PC            60
194 #define S_LR            56
195 #define S_SP            52
196
197 #define S_IP            48
198 #define S_FP            44
199 #define S_R10           40
200 #define S_R9            36
201 #define S_R8            32
202 #define S_R7            28
203 #define S_R6            24
204 #define S_R5            20
205 #define S_R4            16
206 #define S_R3            12
207 #define S_R2            8
208 #define S_R1            4
209 #define S_R0            0
210
211 #define MODE_SVC 0x13
212 #define I_BIT    0x80
213
214 /*
215  * use bad_save_user_regs for abort/prefetch/undef/swi ...
216  * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
217  */
218
219         .macro  bad_save_user_regs
220         sub     sp, sp, #S_FRAME_SIZE
221         stmia   sp, {r0 - r12}                  @ Calling r0-r12
222         add     r8, sp, #S_PC
223
224         ldr     r2, IRQ_STACK_START_IN
225         ldmia   r2, {r2 - r4}                   @ get pc, cpsr, old_r0
226         add     r0, sp, #S_FRAME_SIZE           @ restore sp_SVC
227
228         add     r5, sp, #S_SP
229         mov     r1, lr
230         stmia   r5, {r0 - r4}                   @ save sp_SVC, lr_SVC, pc, cpsr, old_r
231         mov     r0, sp
232         .endm
233
234         .macro  irq_save_user_regs
235         sub     sp, sp, #S_FRAME_SIZE
236         stmia   sp, {r0 - r12}                  @ Calling r0-r12
237         add     r8, sp, #S_PC
238         stmdb   r8, {sp, lr}^                   @ Calling SP, LR
239         str     lr, [r8, #0]                    @ Save calling PC
240         mrs     r6, spsr
241         str     r6, [r8, #4]                    @ Save CPSR
242         str     r0, [r8, #8]                    @ Save OLD_R0
243         mov     r0, sp
244         .endm
245
246         .macro  irq_restore_user_regs
247         ldmia   sp, {r0 - lr}^                  @ Calling r0 - lr
248         mov     r0, r0
249         ldr     lr, [sp, #S_PC]                 @ Get PC
250         add     sp, sp, #S_FRAME_SIZE
251         subs    pc, lr, #4                      @ return & move spsr_svc into cpsr
252         .endm
253
254         .macro get_bad_stack
255         ldr     r13, IRQ_STACK_START_IN         @ setup our mode stack
256
257         str     lr, [r13]                       @ save caller lr / spsr
258         mrs     lr, spsr
259         str     lr, [r13, #4]
260
261         mov     r13, #MODE_SVC                  @ prepare SVC-Mode
262         msr     spsr_c, r13
263         mov     lr, pc
264         movs    pc, lr
265         .endm
266
267         .macro get_irq_stack                    @ setup IRQ stack
268         ldr     sp, IRQ_STACK_START
269         .endm
270
271         .macro get_fiq_stack                    @ setup FIQ stack
272         ldr     sp, FIQ_STACK_START
273         .endm
274
275 /*
276  * exception handlers
277  */
278         .align  5
279 undefined_instruction:
280         get_bad_stack
281         bad_save_user_regs
282         bl      do_undefined_instruction
283
284         .align  5
285 software_interrupt:
286         get_bad_stack
287         bad_save_user_regs
288         bl      do_software_interrupt
289
290         .align  5
291 prefetch_abort:
292         get_bad_stack
293         bad_save_user_regs
294         bl      do_prefetch_abort
295
296         .align  5
297 data_abort:
298         get_bad_stack
299         bad_save_user_regs
300         bl      do_data_abort
301
302         .align  5
303 not_used:
304         get_bad_stack
305         bad_save_user_regs
306         bl      do_not_used
307
308 #ifdef CONFIG_USE_IRQ
309
310         .align  5
311 irq:
312         get_irq_stack
313         irq_save_user_regs
314         bl      do_irq
315         irq_restore_user_regs
316
317         .align  5
318 fiq:
319         get_fiq_stack
320         /* someone ought to write a more effiction fiq_save_user_regs */
321         irq_save_user_regs
322         bl      do_fiq
323         irq_restore_user_regs
324
325 #else
326
327         .align  5
328 irq:
329         get_bad_stack
330         bad_save_user_regs
331         bl      do_irq
332
333         .align  5
334 fiq:
335         get_bad_stack
336         bad_save_user_regs
337         bl      do_fiq
338
339 #endif
340
341         .align  5
342 .globl reset_cpu
343 reset_cpu:
344         ldr     r0, RST_BASE
345         mov     r1, #0x0                        @ set bit 3-0 ...
346         str     r1, [r0, #RCSR]                 @ ... to clear in RCSR
347         mov     r1, #0x1
348         str     r1, [r0, #RSRR]                 @ and perform reset
349         b       reset_cpu                       @ silly, but repeat endlessly