]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/arm1176/start.S
b353d69603249eb0ede6ecfb81ab29fad81c2a03
[karo-tx-uboot.git] / arch / arm / cpu / arm1176 / start.S
1 /*
2  *  armboot - Startup Code for ARM1176 CPU-core
3  *
4  * Copyright (c) 2007   Samsung Electronics
5  *
6  * Copyright (C) 2008
7  * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
8  *
9  * SPDX-License-Identifier:     GPL-2.0+
10  *
11  * 2007-09-21 - Restructured codes by jsgood (jsgood.yang@samsung.com)
12  * 2007-09-21 - Added MoviNAND and OneNAND boot codes by
13  * jsgood (jsgood.yang@samsung.com)
14  * Base codes by scsuh (sc.suh)
15  */
16
17 #include <asm-offsets.h>
18 #include <config.h>
19 #include <version.h>
20
21 #ifndef CONFIG_SYS_PHY_UBOOT_BASE
22 #define CONFIG_SYS_PHY_UBOOT_BASE       CONFIG_SYS_UBOOT_BASE
23 #endif
24
25 /*
26  *************************************************************************
27  *
28  * Jump vector table as in table 3.1 in [1]
29  *
30  *************************************************************************
31  */
32
33 .globl _start
34 _start: b       reset
35 #ifndef CONFIG_SPL_BUILD
36         ldr     pc, _undefined_instruction
37         ldr     pc, _software_interrupt
38         ldr     pc, _prefetch_abort
39         ldr     pc, _data_abort
40         ldr     pc, _not_used
41         ldr     pc, _irq
42         ldr     pc, _fiq
43
44 _undefined_instruction:
45         .word undefined_instruction
46 _software_interrupt:
47         .word software_interrupt
48 _prefetch_abort:
49         .word prefetch_abort
50 _data_abort:
51         .word data_abort
52 _not_used:
53         .word not_used
54 _irq:
55         .word irq
56 _fiq:
57         .word fiq
58 _pad:
59         .word 0x12345678 /* now 16*4=64 */
60 #else
61         . = _start + 64
62 #endif
63
64         .balignl 16,0xdeadbeef
65 /*
66  *************************************************************************
67  *
68  * Startup Code (reset vector)
69  *
70  * do important init only if we don't start from memory!
71  * setup Memory and board specific bits prior to relocation.
72  * relocate armboot to ram
73  * setup stack
74  *
75  *************************************************************************
76  */
77
78 /* IRQ stack memory (calculated at run-time) + 8 bytes */
79 .globl IRQ_STACK_START_IN
80 IRQ_STACK_START_IN:
81         .word   0x0badc0de
82
83 /*
84  * the actual reset code
85  */
86
87 reset:
88         /*
89          * set the cpu to SVC32 mode
90          */
91         mrs     r0, cpsr
92         bic     r0, r0, #0x3f
93         orr     r0, r0, #0xd3
94         msr     cpsr, r0
95
96 /*
97  *************************************************************************
98  *
99  * CPU_init_critical registers
100  *
101  * setup important registers
102  * setup memory timing
103  *
104  *************************************************************************
105  */
106         /*
107          * we do sys-critical inits only at reboot,
108          * not when booting from ram!
109          */
110 cpu_init_crit:
111         /*
112          * When booting from NAND - it has definitely been a reset, so, no need
113          * to flush caches and disable the MMU
114          */
115 #ifndef CONFIG_SPL_BUILD
116         /*
117          * flush v4 I/D caches
118          */
119         mov     r0, #0
120         mcr     p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */
121         mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */
122
123         /*
124          * disable MMU stuff and caches
125          */
126         mrc     p15, 0, r0, c1, c0, 0
127         bic     r0, r0, #0x00002300     @ clear bits 13, 9:8 (--V- --RS)
128         bic     r0, r0, #0x00000087     @ clear bits 7, 2:0 (B--- -CAM)
129         orr     r0, r0, #0x00000002     @ set bit 2 (A) Align
130         orr     r0, r0, #0x00001000     @ set bit 12 (I) I-Cache
131
132         /* Prepare to disable the MMU */
133         adr     r2, mmu_disable_phys
134         sub     r2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - CONFIG_SYS_TEXT_BASE)
135         b       mmu_disable
136
137         .align 5
138         /* Run in a single cache-line */
139 mmu_disable:
140         mcr     p15, 0, r0, c1, c0, 0
141         nop
142         nop
143         mov     pc, r2
144 mmu_disable_phys:
145
146 #ifdef CONFIG_DISABLE_TCM
147         /*
148          * Disable the TCMs
149          */
150         mrc     p15, 0, r0, c0, c0, 2   /* Return TCM details */
151         cmp     r0, #0
152         beq     skip_tcmdisable
153         mov     r1, #0
154         mov     r2, #1
155         tst     r0, r2
156         mcrne   p15, 0, r1, c9, c1, 1   /* Disable Instruction TCM if present*/
157         tst     r0, r2, LSL #16
158         mcrne   p15, 0, r1, c9, c1, 0   /* Disable Data TCM if present*/
159 skip_tcmdisable:
160 #endif
161 #endif
162
163 #ifdef CONFIG_PERIPORT_REMAP
164         /* Peri port setup */
165         ldr     r0, =CONFIG_PERIPORT_BASE
166         orr     r0, r0, #CONFIG_PERIPORT_SIZE
167         mcr     p15,0,r0,c15,c2,4
168 #endif
169
170         /*
171          * Go setup Memory and board specific bits prior to relocation.
172          */
173         bl      lowlevel_init           /* go setup pll,mux,memory */
174
175         bl      _main
176
177 /*------------------------------------------------------------------------------*/
178
179         .globl  c_runtime_cpu_setup
180 c_runtime_cpu_setup:
181
182         mov     pc, lr
183
184 #ifndef CONFIG_SPL_BUILD
185 /*
186  *************************************************************************
187  *
188  * Interrupt handling
189  *
190  *************************************************************************
191  */
192 @
193 @ IRQ stack frame.
194 @
195 #define S_FRAME_SIZE    72
196
197 #define S_OLD_R0        68
198 #define S_PSR           64
199 #define S_PC            60
200 #define S_LR            56
201 #define S_SP            52
202
203 #define S_IP            48
204 #define S_FP            44
205 #define S_R10           40
206 #define S_R9            36
207 #define S_R8            32
208 #define S_R7            28
209 #define S_R6            24
210 #define S_R5            20
211 #define S_R4            16
212 #define S_R3            12
213 #define S_R2            8
214 #define S_R1            4
215 #define S_R0            0
216
217 #define MODE_SVC 0x13
218 #define I_BIT    0x80
219
220 /*
221  * use bad_save_user_regs for abort/prefetch/undef/swi ...
222  */
223
224         .macro  bad_save_user_regs
225         /* carve out a frame on current user stack */
226         sub     sp, sp, #S_FRAME_SIZE
227         /* Save user registers (now in svc mode) r0-r12 */
228         stmia   sp, {r0 - r12}
229
230         ldr     r2, IRQ_STACK_START_IN
231         /* get values for "aborted" pc and cpsr (into parm regs) */
232         ldmia   r2, {r2 - r3}
233         /* grab pointer to old stack */
234         add     r0, sp, #S_FRAME_SIZE
235
236         add     r5, sp, #S_SP
237         mov     r1, lr
238         /* save sp_SVC, lr_SVC, pc, cpsr */
239         stmia   r5, {r0 - r3}
240         /* save current stack into r0 (param register) */
241         mov     r0, sp
242         .endm
243
244         .macro get_bad_stack
245         ldr     r13, IRQ_STACK_START_IN         @ setup our mode stack
246
247         /* save caller lr in position 0 of saved stack */
248         str     lr, [r13]
249         /* get the spsr */
250         mrs     lr, spsr
251         /* save spsr in position 1 of saved stack */
252         str     lr, [r13, #4]
253
254         /* prepare SVC-Mode */
255         mov     r13, #MODE_SVC
256         @ msr   spsr_c, r13
257         /* switch modes, make sure moves will execute */
258         msr     spsr, r13
259         /* capture return pc */
260         mov     lr, pc
261         /* jump to next instruction & switch modes. */
262         movs    pc, lr
263         .endm
264
265         .macro get_bad_stack_swi
266         /* space on current stack for scratch reg. */
267         sub     r13, r13, #4
268         /* save R0's value. */
269         str     r0, [r13]
270         ldr     r13, IRQ_STACK_START_IN         @ setup our mode stack
271         /* save caller lr in position 0 of saved stack */
272         str     lr, [r0]
273         /* get the spsr */
274         mrs     lr, spsr
275         /* save spsr in position 1 of saved stack */
276         str     lr, [r0, #4]
277         /* restore lr */
278         ldr     lr, [r0]
279         /* restore r0 */
280         ldr     r0, [r13]
281         /* pop stack entry */
282         add     r13, r13, #4
283         .endm
284
285 /*
286  * exception handlers
287  */
288         .align  5
289 undefined_instruction:
290         get_bad_stack
291         bad_save_user_regs
292         bl      do_undefined_instruction
293
294         .align  5
295 software_interrupt:
296         get_bad_stack_swi
297         bad_save_user_regs
298         bl      do_software_interrupt
299
300         .align  5
301 prefetch_abort:
302         get_bad_stack
303         bad_save_user_regs
304         bl      do_prefetch_abort
305
306         .align  5
307 data_abort:
308         get_bad_stack
309         bad_save_user_regs
310         bl      do_data_abort
311
312         .align  5
313 not_used:
314         get_bad_stack
315         bad_save_user_regs
316         bl      do_not_used
317
318         .align  5
319 irq:
320         get_bad_stack
321         bad_save_user_regs
322         bl      do_irq
323
324         .align  5
325 fiq:
326         get_bad_stack
327         bad_save_user_regs
328         bl      do_fiq
329 #endif /* CONFIG_SPL_BUILD */