arm: mark save_boot_params_ret as a function
[oweals/u-boot.git] / arch / arm / cpu / armv7 / start.S
1 /*
2  * armboot - Startup Code for OMAP3530/ARM Cortex 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  * Copyright (c) 2006-2008 Syed Mohammed Khasim <x0khasim@ti.com>
12  *
13  * SPDX-License-Identifier:     GPL-2.0+
14  */
15
16 #include <asm-offsets.h>
17 #include <config.h>
18 #include <asm/system.h>
19 #include <linux/linkage.h>
20 #include <asm/armv7.h>
21
22 /*************************************************************************
23  *
24  * Startup Code (reset vector)
25  *
26  * Do important init only if we don't start from memory!
27  * Setup memory and board specific bits prior to relocation.
28  * Relocate armboot to ram. Setup stack.
29  *
30  *************************************************************************/
31
32         .globl  reset
33         .globl  save_boot_params_ret
34         .type   save_boot_params_ret,%function
35 #ifdef CONFIG_ARMV7_LPAE
36         .global switch_to_hypervisor_ret
37 #endif
38
39 reset:
40         /* Allow the board to save important registers */
41         b       save_boot_params
42 save_boot_params_ret:
43 #ifdef CONFIG_ARMV7_LPAE
44 /*
45  * check for Hypervisor support
46  */
47         mrc     p15, 0, r0, c0, c1, 1           @ read ID_PFR1
48         and     r0, r0, #CPUID_ARM_VIRT_MASK    @ mask virtualization bits
49         cmp     r0, #(1 << CPUID_ARM_VIRT_SHIFT)
50         beq     switch_to_hypervisor
51 switch_to_hypervisor_ret:
52 #endif
53         /*
54          * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
55          * except if in HYP mode already
56          */
57         mrs     r0, cpsr
58         and     r1, r0, #0x1f           @ mask mode bits
59         teq     r1, #0x1a               @ test for HYP mode
60         bicne   r0, r0, #0x1f           @ clear all mode bits
61         orrne   r0, r0, #0x13           @ set SVC mode
62         orr     r0, r0, #0xc0           @ disable FIQ and IRQ
63         msr     cpsr,r0
64
65 /*
66  * Setup vector:
67  * (OMAP4 spl TEXT_BASE is not 32 byte aligned.
68  * Continue to use ROM code vector only in OMAP4 spl)
69  */
70 #if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
71         /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
72         mrc     p15, 0, r0, c1, c0, 0   @ Read CP15 SCTLR Register
73         bic     r0, #CR_V               @ V = 0
74         mcr     p15, 0, r0, c1, c0, 0   @ Write CP15 SCTLR Register
75
76         /* Set vector address in CP15 VBAR register */
77         ldr     r0, =_start
78         mcr     p15, 0, r0, c12, c0, 0  @Set VBAR
79 #endif
80
81         /* the mask ROM code should have PLL and others stable */
82 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
83         bl      cpu_init_cp15
84 #ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY
85         bl      cpu_init_crit
86 #endif
87 #endif
88
89         bl      _main
90
91 /*------------------------------------------------------------------------------*/
92
93 ENTRY(c_runtime_cpu_setup)
94 /*
95  * If I-cache is enabled invalidate it
96  */
97 #ifndef CONFIG_SYS_ICACHE_OFF
98         mcr     p15, 0, r0, c7, c5, 0   @ invalidate icache
99         mcr     p15, 0, r0, c7, c10, 4  @ DSB
100         mcr     p15, 0, r0, c7, c5, 4   @ ISB
101 #endif
102
103         bx      lr
104
105 ENDPROC(c_runtime_cpu_setup)
106
107 /*************************************************************************
108  *
109  * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
110  *      __attribute__((weak));
111  *
112  * Stack pointer is not yet initialized at this moment
113  * Don't save anything to stack even if compiled with -O0
114  *
115  *************************************************************************/
116 ENTRY(save_boot_params)
117         b       save_boot_params_ret            @ back to my caller
118 ENDPROC(save_boot_params)
119         .weak   save_boot_params
120
121 #ifdef CONFIG_ARMV7_LPAE
122 ENTRY(switch_to_hypervisor)
123         b       switch_to_hypervisor_ret
124 ENDPROC(switch_to_hypervisor)
125         .weak   switch_to_hypervisor
126 #endif
127
128 /*************************************************************************
129  *
130  * cpu_init_cp15
131  *
132  * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless
133  * CONFIG_SYS_ICACHE_OFF is defined.
134  *
135  *************************************************************************/
136 ENTRY(cpu_init_cp15)
137         /*
138          * Invalidate L1 I/D
139          */
140         mov     r0, #0                  @ set up for MCR
141         mcr     p15, 0, r0, c8, c7, 0   @ invalidate TLBs
142         mcr     p15, 0, r0, c7, c5, 0   @ invalidate icache
143         mcr     p15, 0, r0, c7, c5, 6   @ invalidate BP array
144         mcr     p15, 0, r0, c7, c10, 4  @ DSB
145         mcr     p15, 0, r0, c7, c5, 4   @ ISB
146
147         /*
148          * disable MMU stuff and caches
149          */
150         mrc     p15, 0, r0, c1, c0, 0
151         bic     r0, r0, #0x00002000     @ clear bits 13 (--V-)
152         bic     r0, r0, #0x00000007     @ clear bits 2:0 (-CAM)
153         orr     r0, r0, #0x00000002     @ set bit 1 (--A-) Align
154         orr     r0, r0, #0x00000800     @ set bit 11 (Z---) BTB
155 #ifdef CONFIG_SYS_ICACHE_OFF
156         bic     r0, r0, #0x00001000     @ clear bit 12 (I) I-cache
157 #else
158         orr     r0, r0, #0x00001000     @ set bit 12 (I) I-cache
159 #endif
160         mcr     p15, 0, r0, c1, c0, 0
161
162 #ifdef CONFIG_ARM_ERRATA_716044
163         mrc     p15, 0, r0, c1, c0, 0   @ read system control register
164         orr     r0, r0, #1 << 11        @ set bit #11
165         mcr     p15, 0, r0, c1, c0, 0   @ write system control register
166 #endif
167
168 #if (defined(CONFIG_ARM_ERRATA_742230) || defined(CONFIG_ARM_ERRATA_794072))
169         mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
170         orr     r0, r0, #1 << 4         @ set bit #4
171         mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
172 #endif
173
174 #ifdef CONFIG_ARM_ERRATA_743622
175         mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
176         orr     r0, r0, #1 << 6         @ set bit #6
177         mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
178 #endif
179
180 #ifdef CONFIG_ARM_ERRATA_751472
181         mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
182         orr     r0, r0, #1 << 11        @ set bit #11
183         mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
184 #endif
185 #ifdef CONFIG_ARM_ERRATA_761320
186         mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
187         orr     r0, r0, #1 << 21        @ set bit #21
188         mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
189 #endif
190
191 #ifdef CONFIG_ARM_ERRATA_845369
192         mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
193         orr     r0, r0, #1 << 22        @ set bit #22
194         mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
195 #endif
196
197         mov     r5, lr                  @ Store my Caller
198         mrc     p15, 0, r1, c0, c0, 0   @ r1 has Read Main ID Register (MIDR)
199         mov     r3, r1, lsr #20         @ get variant field
200         and     r3, r3, #0xf            @ r3 has CPU variant
201         and     r4, r1, #0xf            @ r4 has CPU revision
202         mov     r2, r3, lsl #4          @ shift variant field for combined value
203         orr     r2, r4, r2              @ r2 has combined CPU variant + revision
204
205 #ifdef CONFIG_ARM_ERRATA_798870
206         cmp     r2, #0x30               @ Applies to lower than R3p0
207         bge     skip_errata_798870      @ skip if not affected rev
208         cmp     r2, #0x20               @ Applies to including and above R2p0
209         blt     skip_errata_798870      @ skip if not affected rev
210
211         mrc     p15, 1, r0, c15, c0, 0  @ read l2 aux ctrl reg
212         orr     r0, r0, #1 << 7         @ Enable hazard-detect timeout
213         push    {r1-r5}                 @ Save the cpu info registers
214         bl      v7_arch_cp15_set_l2aux_ctrl
215         isb                             @ Recommended ISB after l2actlr update
216         pop     {r1-r5}                 @ Restore the cpu info - fall through
217 skip_errata_798870:
218 #endif
219
220 #ifdef CONFIG_ARM_ERRATA_801819
221         cmp     r2, #0x24               @ Applies to lt including R2p4
222         bgt     skip_errata_801819      @ skip if not affected rev
223         cmp     r2, #0x20               @ Applies to including and above R2p0
224         blt     skip_errata_801819      @ skip if not affected rev
225         mrc     p15, 0, r0, c0, c0, 6   @ pick up REVIDR reg
226         and     r0, r0, #1 << 3         @ check REVIDR[3]
227         cmp     r0, #1 << 3
228         beq     skip_errata_801819      @ skip erratum if REVIDR[3] is set
229
230         mrc     p15, 0, r0, c1, c0, 1   @ read auxilary control register
231         orr     r0, r0, #3 << 27        @ Disables streaming. All write-allocate
232                                         @ lines allocate in the L1 or L2 cache.
233         orr     r0, r0, #3 << 25        @ Disables streaming. All write-allocate
234                                         @ lines allocate in the L1 cache.
235         push    {r1-r5}                 @ Save the cpu info registers
236         bl      v7_arch_cp15_set_acr
237         pop     {r1-r5}                 @ Restore the cpu info - fall through
238 skip_errata_801819:
239 #endif
240
241 #ifdef CONFIG_ARM_ERRATA_454179
242         cmp     r2, #0x21               @ Only on < r2p1
243         bge     skip_errata_454179
244
245         mrc     p15, 0, r0, c1, c0, 1   @ Read ACR
246         orr     r0, r0, #(0x3 << 6)     @ Set DBSM(BIT7) and IBE(BIT6) bits
247         push    {r1-r5}                 @ Save the cpu info registers
248         bl      v7_arch_cp15_set_acr
249         pop     {r1-r5}                 @ Restore the cpu info - fall through
250
251 skip_errata_454179:
252 #endif
253
254 #ifdef CONFIG_ARM_ERRATA_430973
255         cmp     r2, #0x21               @ Only on < r2p1
256         bge     skip_errata_430973
257
258         mrc     p15, 0, r0, c1, c0, 1   @ Read ACR
259         orr     r0, r0, #(0x1 << 6)     @ Set IBE bit
260         push    {r1-r5}                 @ Save the cpu info registers
261         bl      v7_arch_cp15_set_acr
262         pop     {r1-r5}                 @ Restore the cpu info - fall through
263
264 skip_errata_430973:
265 #endif
266
267 #ifdef CONFIG_ARM_ERRATA_621766
268         cmp     r2, #0x21               @ Only on < r2p1
269         bge     skip_errata_621766
270
271         mrc     p15, 0, r0, c1, c0, 1   @ Read ACR
272         orr     r0, r0, #(0x1 << 5)     @ Set L1NEON bit
273         push    {r1-r5}                 @ Save the cpu info registers
274         bl      v7_arch_cp15_set_acr
275         pop     {r1-r5}                 @ Restore the cpu info - fall through
276
277 skip_errata_621766:
278 #endif
279
280 #ifdef CONFIG_ARM_ERRATA_725233
281         cmp     r2, #0x21               @ Only on < r2p1 (Cortex A8)
282         bge     skip_errata_725233
283
284         mrc     p15, 1, r0, c9, c0, 2   @ Read L2ACR
285         orr     r0, r0, #(0x1 << 27)    @ L2 PLD data forwarding disable
286         push    {r1-r5}                 @ Save the cpu info registers
287         bl      v7_arch_cp15_set_l2aux_ctrl
288         pop     {r1-r5}                 @ Restore the cpu info - fall through
289
290 skip_errata_725233:
291 #endif
292
293 #ifdef CONFIG_ARM_ERRATA_852421
294         mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
295         orr     r0, r0, #1 << 24        @ set bit #24
296         mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
297 #endif
298
299 #ifdef CONFIG_ARM_ERRATA_852423
300         mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
301         orr     r0, r0, #1 << 12        @ set bit #12
302         mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
303 #endif
304
305         mov     pc, r5                  @ back to my caller
306 ENDPROC(cpu_init_cp15)
307
308 #if !defined(CONFIG_SKIP_LOWLEVEL_INIT) && \
309         !defined(CONFIG_SKIP_LOWLEVEL_INIT_ONLY)
310 /*************************************************************************
311  *
312  * CPU_init_critical registers
313  *
314  * setup important registers
315  * setup memory timing
316  *
317  *************************************************************************/
318 ENTRY(cpu_init_crit)
319         /*
320          * Jump to board specific initialization...
321          * The Mask ROM will have already initialized
322          * basic memory. Go here to bump up clock rate and handle
323          * wake up conditions.
324          */
325         b       lowlevel_init           @ go setup pll,mux,memory
326 ENDPROC(cpu_init_crit)
327 #endif