Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
[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 .global _end_vect
65 _end_vect:
66         .balignl 16,0xdeadbeef
67 /*
68  *************************************************************************
69  *
70  * Startup Code (reset vector)
71  *
72  * do important init only if we don't start from memory!
73  * setup Memory and board specific bits prior to relocation.
74  * relocate armboot to ram
75  * setup stack
76  *
77  *************************************************************************
78  */
79
80 .globl _TEXT_BASE
81 _TEXT_BASE:
82 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE)
83         .word   CONFIG_SPL_TEXT_BASE
84 #else
85         .word   CONFIG_SYS_TEXT_BASE
86 #endif
87
88 /*
89  * These are defined in the board-specific linker script.
90  * Subtracting _start from them lets the linker put their
91  * relative position in the executable instead of leaving
92  * them null.
93  */
94
95 .globl _bss_start_ofs
96 _bss_start_ofs:
97         .word __bss_start - _start
98
99 .globl _bss_end_ofs
100 _bss_end_ofs:
101         .word __bss_end - _start
102
103 .globl _end_ofs
104 _end_ofs:
105         .word _end - _start
106
107 /* IRQ stack memory (calculated at run-time) + 8 bytes */
108 .globl IRQ_STACK_START_IN
109 IRQ_STACK_START_IN:
110         .word   0x0badc0de
111
112 /*
113  * the actual reset code
114  */
115
116 reset:
117         /*
118          * set the cpu to SVC32 mode
119          */
120         mrs     r0, cpsr
121         bic     r0, r0, #0x3f
122         orr     r0, r0, #0xd3
123         msr     cpsr, r0
124
125 /*
126  *************************************************************************
127  *
128  * CPU_init_critical registers
129  *
130  * setup important registers
131  * setup memory timing
132  *
133  *************************************************************************
134  */
135         /*
136          * we do sys-critical inits only at reboot,
137          * not when booting from ram!
138          */
139 cpu_init_crit:
140         /*
141          * When booting from NAND - it has definitely been a reset, so, no need
142          * to flush caches and disable the MMU
143          */
144 #ifndef CONFIG_SPL_BUILD
145         /*
146          * flush v4 I/D caches
147          */
148         mov     r0, #0
149         mcr     p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */
150         mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */
151
152         /*
153          * disable MMU stuff and caches
154          */
155         mrc     p15, 0, r0, c1, c0, 0
156         bic     r0, r0, #0x00002300     @ clear bits 13, 9:8 (--V- --RS)
157         bic     r0, r0, #0x00000087     @ clear bits 7, 2:0 (B--- -CAM)
158         orr     r0, r0, #0x00000002     @ set bit 2 (A) Align
159         orr     r0, r0, #0x00001000     @ set bit 12 (I) I-Cache
160
161         /* Prepare to disable the MMU */
162         adr     r2, mmu_disable_phys
163         sub     r2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - CONFIG_SYS_TEXT_BASE)
164         b       mmu_disable
165
166         .align 5
167         /* Run in a single cache-line */
168 mmu_disable:
169         mcr     p15, 0, r0, c1, c0, 0
170         nop
171         nop
172         mov     pc, r2
173 mmu_disable_phys:
174
175 #ifdef CONFIG_DISABLE_TCM
176         /*
177          * Disable the TCMs
178          */
179         mrc     p15, 0, r0, c0, c0, 2   /* Return TCM details */
180         cmp     r0, #0
181         beq     skip_tcmdisable
182         mov     r1, #0
183         mov     r2, #1
184         tst     r0, r2
185         mcrne   p15, 0, r1, c9, c1, 1   /* Disable Instruction TCM if present*/
186         tst     r0, r2, LSL #16
187         mcrne   p15, 0, r1, c9, c1, 0   /* Disable Data TCM if present*/
188 skip_tcmdisable:
189 #endif
190 #endif
191
192 #ifdef CONFIG_PERIPORT_REMAP
193         /* Peri port setup */
194         ldr     r0, =CONFIG_PERIPORT_BASE
195         orr     r0, r0, #CONFIG_PERIPORT_SIZE
196         mcr     p15,0,r0,c15,c2,4
197 #endif
198
199         /*
200          * Go setup Memory and board specific bits prior to relocation.
201          */
202         bl      lowlevel_init           /* go setup pll,mux,memory */
203
204         bl      _main
205
206 /*------------------------------------------------------------------------------*/
207
208         .globl  c_runtime_cpu_setup
209 c_runtime_cpu_setup:
210
211         mov     pc, lr
212
213 #ifndef CONFIG_SPL_BUILD
214 /*
215  *************************************************************************
216  *
217  * Interrupt handling
218  *
219  *************************************************************************
220  */
221 @
222 @ IRQ stack frame.
223 @
224 #define S_FRAME_SIZE    72
225
226 #define S_OLD_R0        68
227 #define S_PSR           64
228 #define S_PC            60
229 #define S_LR            56
230 #define S_SP            52
231
232 #define S_IP            48
233 #define S_FP            44
234 #define S_R10           40
235 #define S_R9            36
236 #define S_R8            32
237 #define S_R7            28
238 #define S_R6            24
239 #define S_R5            20
240 #define S_R4            16
241 #define S_R3            12
242 #define S_R2            8
243 #define S_R1            4
244 #define S_R0            0
245
246 #define MODE_SVC 0x13
247 #define I_BIT    0x80
248
249 /*
250  * use bad_save_user_regs for abort/prefetch/undef/swi ...
251  */
252
253         .macro  bad_save_user_regs
254         /* carve out a frame on current user stack */
255         sub     sp, sp, #S_FRAME_SIZE
256         /* Save user registers (now in svc mode) r0-r12 */
257         stmia   sp, {r0 - r12}
258
259         ldr     r2, IRQ_STACK_START_IN
260         /* get values for "aborted" pc and cpsr (into parm regs) */
261         ldmia   r2, {r2 - r3}
262         /* grab pointer to old stack */
263         add     r0, sp, #S_FRAME_SIZE
264
265         add     r5, sp, #S_SP
266         mov     r1, lr
267         /* save sp_SVC, lr_SVC, pc, cpsr */
268         stmia   r5, {r0 - r3}
269         /* save current stack into r0 (param register) */
270         mov     r0, sp
271         .endm
272
273         .macro get_bad_stack
274         ldr     r13, IRQ_STACK_START_IN         @ setup our mode stack
275
276         /* save caller lr in position 0 of saved stack */
277         str     lr, [r13]
278         /* get the spsr */
279         mrs     lr, spsr
280         /* save spsr in position 1 of saved stack */
281         str     lr, [r13, #4]
282
283         /* prepare SVC-Mode */
284         mov     r13, #MODE_SVC
285         @ msr   spsr_c, r13
286         /* switch modes, make sure moves will execute */
287         msr     spsr, r13
288         /* capture return pc */
289         mov     lr, pc
290         /* jump to next instruction & switch modes. */
291         movs    pc, lr
292         .endm
293
294         .macro get_bad_stack_swi
295         /* space on current stack for scratch reg. */
296         sub     r13, r13, #4
297         /* save R0's value. */
298         str     r0, [r13]
299         ldr     r13, IRQ_STACK_START_IN         @ setup our mode stack
300         /* save caller lr in position 0 of saved stack */
301         str     lr, [r0]
302         /* get the spsr */
303         mrs     lr, spsr
304         /* save spsr in position 1 of saved stack */
305         str     lr, [r0, #4]
306         /* restore lr */
307         ldr     lr, [r0]
308         /* restore r0 */
309         ldr     r0, [r13]
310         /* pop stack entry */
311         add     r13, r13, #4
312         .endm
313
314 /*
315  * exception handlers
316  */
317         .align  5
318 undefined_instruction:
319         get_bad_stack
320         bad_save_user_regs
321         bl      do_undefined_instruction
322
323         .align  5
324 software_interrupt:
325         get_bad_stack_swi
326         bad_save_user_regs
327         bl      do_software_interrupt
328
329         .align  5
330 prefetch_abort:
331         get_bad_stack
332         bad_save_user_regs
333         bl      do_prefetch_abort
334
335         .align  5
336 data_abort:
337         get_bad_stack
338         bad_save_user_regs
339         bl      do_data_abort
340
341         .align  5
342 not_used:
343         get_bad_stack
344         bad_save_user_regs
345         bl      do_not_used
346
347         .align  5
348 irq:
349         get_bad_stack
350         bad_save_user_regs
351         bl      do_irq
352
353         .align  5
354 fiq:
355         get_bad_stack
356         bad_save_user_regs
357         bl      do_fiq
358 #endif /* CONFIG_SPL_BUILD */