]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/arm1136/start.S
arm1136: move cache code from start.S to cache.c
[karo-tx-uboot.git] / arch / arm / cpu / arm1136 / start.S
1 /*
2  *  armboot - Startup Code for OMP2420/ARM1136 CPU-core
3  *
4  *  Copyright (c) 2004  Texas Instruments <r-woodruff2@ti.com>
5  *
6  *  Copyright (c) 2001  Marius Gröger <mag@sysgo.de>
7  *  Copyright (c) 2002  Alex Züpke <azu@sysgo.de>
8  *  Copyright (c) 2002  Gary Jennejohn <garyj@denx.de>
9  *  Copyright (c) 2003  Richard Woodruff <r-woodruff2@ti.com>
10  *  Copyright (c) 2003  Kshitij <kshitij@ti.com>
11  *
12  * SPDX-License-Identifier:     GPL-2.0+
13  */
14
15 #include <asm-offsets.h>
16 #include <config.h>
17 #include <version.h>
18 .globl _start
19 _start: b       reset
20 #ifdef CONFIG_SPL_BUILD
21         ldr     pc, _hang
22         ldr     pc, _hang
23         ldr     pc, _hang
24         ldr     pc, _hang
25         ldr     pc, _hang
26         ldr     pc, _hang
27         ldr     pc, _hang
28
29 _hang:
30         .word   do_hang
31         .word   0x12345678
32         .word   0x12345678
33         .word   0x12345678
34         .word   0x12345678
35         .word   0x12345678
36         .word   0x12345678
37         .word   0x12345678      /* now 16*4=64 */
38 #else
39         ldr     pc, _undefined_instruction
40         ldr     pc, _software_interrupt
41         ldr     pc, _prefetch_abort
42         ldr     pc, _data_abort
43         ldr     pc, _not_used
44         ldr     pc, _irq
45         ldr     pc, _fiq
46
47 _undefined_instruction: .word undefined_instruction
48 _software_interrupt:    .word software_interrupt
49 _prefetch_abort:        .word prefetch_abort
50 _data_abort:            .word data_abort
51 _not_used:              .word not_used
52 _irq:                   .word irq
53 _fiq:                   .word fiq
54 _pad:                   .word 0x12345678 /* now 16*4=64 */
55 #endif  /* CONFIG_SPL_BUILD */
56 .global _end_vect
57 _end_vect:
58
59         .balignl 16,0xdeadbeef
60 /*
61  *************************************************************************
62  *
63  * Startup Code (reset vector)
64  *
65  * do important init only if we don't start from memory!
66  * setup Memory and board specific bits prior to relocation.
67  * relocate armboot to ram
68  * setup stack
69  *
70  *************************************************************************
71  */
72
73 #ifdef CONFIG_USE_IRQ
74 /* IRQ stack memory (calculated at run-time) */
75 .globl IRQ_STACK_START
76 IRQ_STACK_START:
77         .word   0x0badc0de
78
79 /* IRQ stack memory (calculated at run-time) */
80 .globl FIQ_STACK_START
81 FIQ_STACK_START:
82         .word 0x0badc0de
83 #endif
84
85 /* IRQ stack memory (calculated at run-time) + 8 bytes */
86 .globl IRQ_STACK_START_IN
87 IRQ_STACK_START_IN:
88         .word   0x0badc0de
89
90 /*
91  * the actual reset code
92  */
93
94 reset:
95         /*
96          * set the cpu to SVC32 mode
97          */
98         mrs     r0,cpsr
99         bic     r0,r0,#0x1f
100         orr     r0,r0,#0xd3
101         msr     cpsr,r0
102
103         /* the mask ROM code should have PLL and others stable */
104 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
105         bl  cpu_init_crit
106 #endif
107
108         bl      _main
109
110 /*------------------------------------------------------------------------------*/
111
112         .globl  c_runtime_cpu_setup
113 c_runtime_cpu_setup:
114
115         bx      lr
116
117 /*
118  *************************************************************************
119  *
120  * CPU_init_critical registers
121  *
122  * setup important registers
123  * setup memory timing
124  *
125  *************************************************************************
126  */
127 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
128 cpu_init_crit:
129         /*
130          * flush v4 I/D caches
131          */
132         mov     r0, #0
133         mcr     p15, 0, r0, c7, c7, 0   /* Invalidate I+D+BTB caches */
134         mcr     p15, 0, r0, c8, c7, 0   /* Invalidate Unified TLB */
135
136         /*
137          * disable MMU stuff and caches
138          */
139         mrc     p15, 0, r0, c1, c0, 0
140         bic     r0, r0, #0x00002300     @ clear bits 13, 9:8 (--V- --RS)
141         bic     r0, r0, #0x00000087     @ clear bits 7, 2:0 (B--- -CAM)
142         orr     r0, r0, #0x00000002     @ set bit 2 (A) Align
143         orr     r0, r0, #0x00001000     @ set bit 12 (I) I-Cache
144         mcr     p15, 0, r0, c1, c0, 0
145
146         /*
147          * Jump to board specific initialization... The Mask ROM will have already initialized
148          * basic memory.  Go here to bump up clock rate and handle wake up conditions.
149          */
150         mov     ip, lr          /* persevere link reg across call */
151         bl      lowlevel_init   /* go setup pll,mux,memory */
152         mov     lr, ip          /* restore link */
153         mov     pc, lr          /* back to my caller */
154 #endif /* CONFIG_SKIP_LOWLEVEL_INIT */
155
156 #ifndef CONFIG_SPL_BUILD
157 /*
158  *************************************************************************
159  *
160  * Interrupt handling
161  *
162  *************************************************************************
163  */
164 @
165 @ IRQ stack frame.
166 @
167 #define S_FRAME_SIZE    72
168
169 #define S_OLD_R0        68
170 #define S_PSR           64
171 #define S_PC            60
172 #define S_LR            56
173 #define S_SP            52
174
175 #define S_IP            48
176 #define S_FP            44
177 #define S_R10           40
178 #define S_R9            36
179 #define S_R8            32
180 #define S_R7            28
181 #define S_R6            24
182 #define S_R5            20
183 #define S_R4            16
184 #define S_R3            12
185 #define S_R2            8
186 #define S_R1            4
187 #define S_R0            0
188
189 #define MODE_SVC 0x13
190 #define I_BIT    0x80
191
192 /*
193  * use bad_save_user_regs for abort/prefetch/undef/swi ...
194  * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
195  */
196
197         .macro  bad_save_user_regs
198         sub     sp, sp, #S_FRAME_SIZE           @ carve out a frame on current user stack
199         stmia   sp, {r0 - r12}                  @ Save user registers (now in svc mode) r0-r12
200
201         ldr     r2, IRQ_STACK_START_IN          @ set base 2 words into abort stack
202         ldmia   r2, {r2 - r3}                   @ get values for "aborted" pc and cpsr (into parm regs)
203         add     r0, sp, #S_FRAME_SIZE           @ grab pointer to old stack
204
205         add     r5, sp, #S_SP
206         mov     r1, lr
207         stmia   r5, {r0 - r3}                   @ save sp_SVC, lr_SVC, pc, cpsr
208         mov     r0, sp                          @ save current stack into r0 (param register)
209         .endm
210
211         .macro  irq_save_user_regs
212         sub     sp, sp, #S_FRAME_SIZE
213         stmia   sp, {r0 - r12}                  @ Calling r0-r12
214         add     r8, sp, #S_PC                   @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
215         stmdb   r8, {sp, lr}^                   @ Calling SP, LR
216         str     lr, [r8, #0]                    @ Save calling PC
217         mrs     r6, spsr
218         str     r6, [r8, #4]                    @ Save CPSR
219         str     r0, [r8, #8]                    @ Save OLD_R0
220         mov     r0, sp
221         .endm
222
223         .macro  irq_restore_user_regs
224         ldmia   sp, {r0 - lr}^                  @ Calling r0 - lr
225         mov     r0, r0
226         ldr     lr, [sp, #S_PC]                 @ Get PC
227         add     sp, sp, #S_FRAME_SIZE
228         subs    pc, lr, #4                      @ return & move spsr_svc into cpsr
229         .endm
230
231         .macro get_bad_stack
232         ldr     r13, IRQ_STACK_START_IN         @ setup our mode stack (enter in banked mode)
233
234         str     lr, [r13]                       @ save caller lr in position 0 of saved stack
235         mrs     lr, spsr                        @ get the spsr
236         str     lr, [r13, #4]                   @ save spsr in position 1 of saved stack
237
238         mov     r13, #MODE_SVC                  @ prepare SVC-Mode
239         @ msr   spsr_c, r13
240         msr     spsr, r13                       @ switch modes, make sure moves will execute
241         mov     lr, pc                          @ capture return pc
242         movs    pc, lr                          @ jump to next instruction & switch modes.
243         .endm
244
245         .macro get_bad_stack_swi
246         sub     r13, r13, #4                    @ space on current stack for scratch reg.
247         str     r0, [r13]                       @ save R0's value.
248         ldr     r0, IRQ_STACK_START_IN          @ get data regions start
249         str     lr, [r0]                        @ save caller lr in position 0 of saved stack
250         mrs     lr, spsr                        @ get the spsr
251         str     lr, [r0, #4]                    @ save spsr in position 1 of saved stack
252         ldr     lr, [r0]                        @ restore lr
253         ldr     r0, [r13]                       @ restore r0
254         add     r13, r13, #4                    @ pop stack entry
255         .endm
256
257         .macro get_irq_stack                    @ setup IRQ stack
258         ldr     sp, IRQ_STACK_START
259         .endm
260
261         .macro get_fiq_stack                    @ setup FIQ stack
262         ldr     sp, FIQ_STACK_START
263         .endm
264 #endif  /* CONFIG_SPL_BUILD */
265
266 /*
267  * exception handlers
268  */
269 #ifdef CONFIG_SPL_BUILD
270         .align  5
271 do_hang:
272         bl      hang                            /* hang and never return */
273 #else   /* !CONFIG_SPL_BUILD */
274         .align  5
275 undefined_instruction:
276         get_bad_stack
277         bad_save_user_regs
278         bl      do_undefined_instruction
279
280         .align  5
281 software_interrupt:
282         get_bad_stack_swi
283         bad_save_user_regs
284         bl      do_software_interrupt
285
286         .align  5
287 prefetch_abort:
288         get_bad_stack
289         bad_save_user_regs
290         bl      do_prefetch_abort
291
292         .align  5
293 data_abort:
294         get_bad_stack
295         bad_save_user_regs
296         bl      do_data_abort
297
298         .align  5
299 not_used:
300         get_bad_stack
301         bad_save_user_regs
302         bl      do_not_used
303
304 #ifdef CONFIG_USE_IRQ
305
306         .align  5
307 irq:
308         get_irq_stack
309         irq_save_user_regs
310         bl      do_irq
311         irq_restore_user_regs
312
313         .align  5
314 fiq:
315         get_fiq_stack
316         /* someone ought to write a more effiction fiq_save_user_regs */
317         irq_save_user_regs
318         bl      do_fiq
319         irq_restore_user_regs
320
321 #else
322
323         .align  5
324 irq:
325         get_bad_stack
326         bad_save_user_regs
327         bl      do_irq
328
329         .align  5
330 fiq:
331         get_bad_stack
332         bad_save_user_regs
333         bl      do_fiq
334
335 #endif
336 #endif  /* CONFIG_SPL_BUILD */