Prepare v2023.10
[platform/kernel/u-boot.git] / arch / arm / cpu / armv7 / start.S
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * armboot - Startup Code for OMAP3530/ARM Cortex CPU-core
4  *
5  * Copyright (c) 2004   Texas Instruments <r-woodruff2@ti.com>
6  *
7  * Copyright (c) 2001   Marius Gröger <mag@sysgo.de>
8  * Copyright (c) 2002   Alex Züpke <azu@sysgo.de>
9  * Copyright (c) 2002   Gary Jennejohn <garyj@denx.de>
10  * Copyright (c) 2003   Richard Woodruff <r-woodruff2@ti.com>
11  * Copyright (c) 2003   Kshitij <kshitij@ti.com>
12  * Copyright (c) 2006-2008 Syed Mohammed Khasim <x0khasim@ti.com>
13  */
14
15 #include <asm-offsets.h>
16 #include <config.h>
17 #include <asm/system.h>
18 #include <linux/linkage.h>
19 #include <asm/armv7.h>
20 #include <system-constants.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_POSITION_INDEPENDENT
44         /*
45          * Fix .rela.dyn relocations. This allows U-Boot to loaded to and
46          * executed at a different address than it was linked at.
47          */
48 pie_fixup:
49         adr     r0, reset       /* r0 <- Runtime value of reset label */
50         ldr     r1, =reset      /* r1 <- Linked value of reset label */
51         subs    r4, r0, r1      /* r4 <- Runtime-vs-link offset */
52         beq     pie_fixup_done
53
54         adr     r0, pie_fixup
55         ldr     r1, _rel_dyn_start_ofs
56         add     r2, r0, r1      /* r2 <- Runtime &__rel_dyn_start */
57         ldr     r1, _rel_dyn_end_ofs
58         add     r3, r0, r1      /* r3 <- Runtime &__rel_dyn_end */
59
60 pie_fix_loop:
61         ldr     r0, [r2]        /* r0 <- Link location */
62         ldr     r1, [r2, #4]    /* r1 <- fixup */
63         cmp     r1, #23         /* relative fixup? */
64         bne     pie_skip_reloc
65
66         /* relative fix: increase location by offset */
67         add     r0, r4
68         ldr     r1, [r0]
69         add     r1, r4
70         str     r1, [r0]
71         str     r0, [r2]
72         add     r2, #8
73 pie_skip_reloc:
74         cmp     r2, r3
75         blo     pie_fix_loop
76 pie_fixup_done:
77 #endif
78
79 #ifdef CONFIG_ARMV7_LPAE
80 /*
81  * check for Hypervisor support
82  */
83         mrc     p15, 0, r0, c0, c1, 1           @ read ID_PFR1
84         and     r0, r0, #CPUID_ARM_VIRT_MASK    @ mask virtualization bits
85         cmp     r0, #(1 << CPUID_ARM_VIRT_SHIFT)
86         beq     switch_to_hypervisor
87 switch_to_hypervisor_ret:
88 #endif
89         /*
90          * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
91          * except if in HYP mode already
92          */
93         mrs     r0, cpsr
94         and     r1, r0, #0x1f           @ mask mode bits
95         teq     r1, #0x1a               @ test for HYP mode
96         bicne   r0, r0, #0x1f           @ clear all mode bits
97         orrne   r0, r0, #0x13           @ set SVC mode
98         orr     r0, r0, #0xc0           @ disable FIQ and IRQ
99         msr     cpsr,r0
100
101 #if !CONFIG_IS_ENABLED(SYS_NO_VECTOR_TABLE)
102 /*
103  * Setup vector:
104  */
105         /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
106         mrc     p15, 0, r0, c1, c0, 0   @ Read CP15 SCTLR Register
107         bic     r0, #CR_V               @ V = 0
108         mcr     p15, 0, r0, c1, c0, 0   @ Write CP15 SCTLR Register
109
110 #ifdef CONFIG_HAS_VBAR
111         /* Set vector address in CP15 VBAR register */
112         ldr     r0, =_start
113         mcr     p15, 0, r0, c12, c0, 0  @Set VBAR
114 #endif
115 #endif
116
117         /* the mask ROM code should have PLL and others stable */
118 #if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT)
119 #ifdef CONFIG_CPU_V7A
120         bl      cpu_init_cp15
121 #endif
122 #if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT_ONLY)
123         bl      cpu_init_crit
124 #endif
125 #endif
126
127         bl      _main
128
129 /*------------------------------------------------------------------------------*/
130
131 ENTRY(c_runtime_cpu_setup)
132 /*
133  * If I-cache is enabled invalidate it
134  */
135 #if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
136         mcr     p15, 0, r0, c7, c5, 0   @ invalidate icache
137         dsb
138         isb
139 #endif
140
141         bx      lr
142
143 ENDPROC(c_runtime_cpu_setup)
144
145 /*************************************************************************
146  *
147  * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
148  *      __attribute__((weak));
149  *
150  * Stack pointer is not yet initialized at this moment
151  * Don't save anything to stack even if compiled with -O0
152  *
153  *************************************************************************/
154 WEAK(save_boot_params)
155         b       save_boot_params_ret            @ back to my caller
156 ENDPROC(save_boot_params)
157
158 #ifdef CONFIG_ARMV7_LPAE
159 WEAK(switch_to_hypervisor)
160         b       switch_to_hypervisor_ret
161 ENDPROC(switch_to_hypervisor)
162 #endif
163
164 /*************************************************************************
165  *
166  * cpu_init_cp15
167  *
168  * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless
169  * CONFIG_SYS_ICACHE_OFF is defined.
170  *
171  *************************************************************************/
172 ENTRY(cpu_init_cp15)
173
174 #if CONFIG_IS_ENABLED(ARMV7_SET_CORTEX_SMPEN)
175         /*
176          * The Arm Cortex-A7 TRM says this bit must be enabled before
177          * "any cache or TLB maintenance operations are performed".
178          */
179         mrc     p15, 0, r0, c1, c0, 1   @ read auxilary control register
180         orr     r0, r0, #1 << 6         @ set SMP bit to enable coherency
181         mcr     p15, 0, r0, c1, c0, 1   @ write auxilary control register
182 #endif
183
184         /*
185          * Invalidate L1 I/D
186          */
187         mov     r0, #0                  @ set up for MCR
188         mcr     p15, 0, r0, c8, c7, 0   @ invalidate TLBs
189         mcr     p15, 0, r0, c7, c5, 0   @ invalidate icache
190         mcr     p15, 0, r0, c7, c5, 6   @ invalidate BP array
191         dsb
192         isb
193
194         /*
195          * disable MMU stuff and caches
196          */
197         mrc     p15, 0, r0, c1, c0, 0
198         bic     r0, r0, #0x00002000     @ clear bits 13 (--V-)
199         bic     r0, r0, #0x00000007     @ clear bits 2:0 (-CAM)
200         orr     r0, r0, #0x00000002     @ set bit 1 (--A-) Align
201         orr     r0, r0, #0x00000800     @ set bit 11 (Z---) BTB
202 #if CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
203         bic     r0, r0, #0x00001000     @ clear bit 12 (I) I-cache
204 #else
205         orr     r0, r0, #0x00001000     @ set bit 12 (I) I-cache
206 #endif
207         mcr     p15, 0, r0, c1, c0, 0
208
209 #ifdef CONFIG_ARM_ERRATA_716044
210         mrc     p15, 0, r0, c1, c0, 0   @ read system control register
211         orr     r0, r0, #1 << 11        @ set bit #11
212         mcr     p15, 0, r0, c1, c0, 0   @ write system control register
213 #endif
214
215 #if (defined(CONFIG_ARM_ERRATA_742230) || defined(CONFIG_ARM_ERRATA_794072))
216         mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
217         orr     r0, r0, #1 << 4         @ set bit #4
218         mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
219 #endif
220
221 #ifdef CONFIG_ARM_ERRATA_743622
222         mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
223         orr     r0, r0, #1 << 6         @ set bit #6
224         mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
225 #endif
226
227 #ifdef CONFIG_ARM_ERRATA_751472
228         mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
229         orr     r0, r0, #1 << 11        @ set bit #11
230         mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
231 #endif
232 #ifdef CONFIG_ARM_ERRATA_761320
233         mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
234         orr     r0, r0, #1 << 21        @ set bit #21
235         mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
236 #endif
237
238 #ifdef CONFIG_ARM_ERRATA_845369
239         mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
240         orr     r0, r0, #1 << 22        @ set bit #22
241         mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
242 #endif
243
244         mov     r5, lr                  @ Store my Caller
245         mrc     p15, 0, r1, c0, c0, 0   @ r1 has Read Main ID Register (MIDR)
246         mov     r3, r1, lsr #20         @ get variant field
247         and     r3, r3, #0xf            @ r3 has CPU variant
248         and     r4, r1, #0xf            @ r4 has CPU revision
249         mov     r2, r3, lsl #4          @ shift variant field for combined value
250         orr     r2, r4, r2              @ r2 has combined CPU variant + revision
251
252 /* Early stack for ERRATA that needs into call C code */
253 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
254         ldr     r0, =(CONFIG_SPL_STACK)
255 #else
256         ldr     r0, =(SYS_INIT_SP_ADDR)
257 #endif
258         bic     r0, r0, #7      /* 8-byte alignment for ABI compliance */
259         mov     sp, r0
260
261 #ifdef CONFIG_ARM_ERRATA_798870
262         cmp     r2, #0x30               @ Applies to lower than R3p0
263         bge     skip_errata_798870      @ skip if not affected rev
264         cmp     r2, #0x20               @ Applies to including and above R2p0
265         blt     skip_errata_798870      @ skip if not affected rev
266
267         mrc     p15, 1, r0, c15, c0, 0  @ read l2 aux ctrl reg
268         orr     r0, r0, #1 << 7         @ Enable hazard-detect timeout
269         push    {r1-r5}                 @ Save the cpu info registers
270         bl      v7_arch_cp15_set_l2aux_ctrl
271         isb                             @ Recommended ISB after l2actlr update
272         pop     {r1-r5}                 @ Restore the cpu info - fall through
273 skip_errata_798870:
274 #endif
275
276 #ifdef CONFIG_ARM_ERRATA_801819
277         cmp     r2, #0x24               @ Applies to lt including R2p4
278         bgt     skip_errata_801819      @ skip if not affected rev
279         cmp     r2, #0x20               @ Applies to including and above R2p0
280         blt     skip_errata_801819      @ skip if not affected rev
281         mrc     p15, 0, r0, c0, c0, 6   @ pick up REVIDR reg
282         and     r0, r0, #1 << 3         @ check REVIDR[3]
283         cmp     r0, #1 << 3
284         beq     skip_errata_801819      @ skip erratum if REVIDR[3] is set
285
286         mrc     p15, 0, r0, c1, c0, 1   @ read auxilary control register
287         orr     r0, r0, #3 << 27        @ Disables streaming. All write-allocate
288                                         @ lines allocate in the L1 or L2 cache.
289         orr     r0, r0, #3 << 25        @ Disables streaming. All write-allocate
290                                         @ lines allocate in the L1 cache.
291         push    {r1-r5}                 @ Save the cpu info registers
292         bl      v7_arch_cp15_set_acr
293         pop     {r1-r5}                 @ Restore the cpu info - fall through
294 skip_errata_801819:
295 #endif
296
297 #ifdef CONFIG_ARM_CORTEX_A15_CVE_2017_5715
298         mrc     p15, 0, r0, c1, c0, 1   @ read auxilary control register
299         orr     r0, r0, #1 << 0         @ Enable invalidates of BTB
300         push    {r1-r5}                 @ Save the cpu info registers
301         bl      v7_arch_cp15_set_acr
302         pop     {r1-r5}                 @ Restore the cpu info - fall through
303 #endif
304
305 #ifdef CONFIG_ARM_ERRATA_454179
306         mrc     p15, 0, r0, c1, c0, 1   @ Read ACR
307
308         cmp     r2, #0x21               @ Only on < r2p1
309         orrlt   r0, r0, #(0x3 << 6)     @ Set DBSM(BIT7) and IBE(BIT6) bits
310
311         push    {r1-r5}                 @ Save the cpu info registers
312         bl      v7_arch_cp15_set_acr
313         pop     {r1-r5}                 @ Restore the cpu info - fall through
314 #endif
315
316 #if defined(CONFIG_ARM_ERRATA_430973) || defined (CONFIG_ARM_CORTEX_A8_CVE_2017_5715)
317         mrc     p15, 0, r0, c1, c0, 1   @ Read ACR
318
319 #ifdef CONFIG_ARM_CORTEX_A8_CVE_2017_5715
320         orr     r0, r0, #(0x1 << 6)     @ Set IBE bit always to enable OS WA
321 #else
322         cmp     r2, #0x21               @ Only on < r2p1
323         orrlt   r0, r0, #(0x1 << 6)     @ Set IBE bit
324 #endif
325         push    {r1-r5}                 @ Save the cpu info registers
326         bl      v7_arch_cp15_set_acr
327         pop     {r1-r5}                 @ Restore the cpu info - fall through
328 #endif
329
330 #ifdef CONFIG_ARM_ERRATA_621766
331         mrc     p15, 0, r0, c1, c0, 1   @ Read ACR
332
333         cmp     r2, #0x21               @ Only on < r2p1
334         orrlt   r0, r0, #(0x1 << 5)     @ Set L1NEON bit
335
336         push    {r1-r5}                 @ Save the cpu info registers
337         bl      v7_arch_cp15_set_acr
338         pop     {r1-r5}                 @ Restore the cpu info - fall through
339 #endif
340
341 #ifdef CONFIG_ARM_ERRATA_725233
342         mrc     p15, 1, r0, c9, c0, 2   @ Read L2ACR
343
344         cmp     r2, #0x21               @ Only on < r2p1 (Cortex A8)
345         orrlt   r0, r0, #(0x1 << 27)    @ L2 PLD data forwarding disable
346
347         push    {r1-r5}                 @ Save the cpu info registers
348         bl      v7_arch_cp15_set_l2aux_ctrl
349         pop     {r1-r5}                 @ Restore the cpu info - fall through
350 #endif
351
352 #ifdef CONFIG_ARM_ERRATA_852421
353         mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
354         orr     r0, r0, #1 << 24        @ set bit #24
355         mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
356 #endif
357
358 #ifdef CONFIG_ARM_ERRATA_852423
359         mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
360         orr     r0, r0, #1 << 12        @ set bit #12
361         mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
362 #endif
363
364         mov     pc, r5                  @ back to my caller
365 ENDPROC(cpu_init_cp15)
366
367 #if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT) && \
368         !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT_ONLY)
369 /*************************************************************************
370  *
371  * CPU_init_critical registers
372  *
373  * setup important registers
374  * setup memory timing
375  *
376  *************************************************************************/
377 ENTRY(cpu_init_crit)
378         /*
379          * Jump to board specific initialization...
380          * The Mask ROM will have already initialized
381          * basic memory. Go here to bump up clock rate and handle
382          * wake up conditions.
383          */
384         b       lowlevel_init           @ go setup pll,mux,memory
385 ENDPROC(cpu_init_crit)
386 #endif
387
388 #if CONFIG_POSITION_INDEPENDENT
389 _rel_dyn_start_ofs:
390         .word   __rel_dyn_start - pie_fixup
391 _rel_dyn_end_ofs:
392         .word   __rel_dyn_end - pie_fixup
393 #endif