rockchip: arm: use 'arch-rockchip' for common header
[platform/kernel/u-boot.git] / arch / arm / cpu / armv8 / start.S
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * (C) Copyright 2013
4  * David Feng <fenghua@phytium.com.cn>
5  */
6
7 #include <asm-offsets.h>
8 #include <config.h>
9 #include <linux/linkage.h>
10 #include <asm/macro.h>
11 #include <asm/armv8/mmu.h>
12
13 /*************************************************************************
14  *
15  * Startup Code (reset vector)
16  *
17  *************************************************************************/
18
19 .globl  _start
20 _start:
21 #if defined(LINUX_KERNEL_IMAGE_HEADER)
22 #include <asm/boot0-linux-kernel-header.h>
23 #elif defined(CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK)
24 /*
25  * Various SoCs need something special and SoC-specific up front in
26  * order to boot, allow them to set that in their boot0.h file and then
27  * use it here.
28  */
29 #ifdef CONFIG_ARCH_ROCKCHIP
30 #include <asm/arch-rockchip/boot0.h>
31 #else
32 #include <asm/arch/boot0.h>
33 #endif
34 #else
35         b       reset
36 #endif
37
38         .align 3
39
40 .globl  _TEXT_BASE
41 _TEXT_BASE:
42         .quad   CONFIG_SYS_TEXT_BASE
43
44 /*
45  * These are defined in the linker script.
46  */
47 .globl  _end_ofs
48 _end_ofs:
49         .quad   _end - _start
50
51 .globl  _bss_start_ofs
52 _bss_start_ofs:
53         .quad   __bss_start - _start
54
55 .globl  _bss_end_ofs
56 _bss_end_ofs:
57         .quad   __bss_end - _start
58
59 reset:
60         /* Allow the board to save important registers */
61         b       save_boot_params
62 .globl  save_boot_params_ret
63 save_boot_params_ret:
64
65 #if CONFIG_POSITION_INDEPENDENT
66         /*
67          * Fix .rela.dyn relocations. This allows U-Boot to be loaded to and
68          * executed at a different address than it was linked at.
69          */
70 pie_fixup:
71         adr     x0, _start              /* x0 <- Runtime value of _start */
72         ldr     x1, _TEXT_BASE          /* x1 <- Linked value of _start */
73         sub     x9, x0, x1              /* x9 <- Run-vs-link offset */
74         adr     x2, __rel_dyn_start     /* x2 <- Runtime &__rel_dyn_start */
75         adr     x3, __rel_dyn_end       /* x3 <- Runtime &__rel_dyn_end */
76 pie_fix_loop:
77         ldp     x0, x1, [x2], #16       /* (x0, x1) <- (Link location, fixup) */
78         ldr     x4, [x2], #8            /* x4 <- addend */
79         cmp     w1, #1027               /* relative fixup? */
80         bne     pie_skip_reloc
81         /* relative fix: store addend plus offset at dest location */
82         add     x0, x0, x9
83         add     x4, x4, x9
84         str     x4, [x0]
85 pie_skip_reloc:
86         cmp     x2, x3
87         b.lo    pie_fix_loop
88 pie_fixup_done:
89 #endif
90
91 #ifdef CONFIG_SYS_RESET_SCTRL
92         bl reset_sctrl
93 #endif
94
95 #if defined(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) || !defined(CONFIG_SPL_BUILD)
96 .macro  set_vbar, regname, reg
97         msr     \regname, \reg
98 .endm
99         adr     x0, vectors
100 #else
101 .macro  set_vbar, regname, reg
102 .endm
103 #endif
104         /*
105          * Could be EL3/EL2/EL1, Initial State:
106          * Little Endian, MMU Disabled, i/dCache Disabled
107          */
108         switch_el x1, 3f, 2f, 1f
109 3:      set_vbar vbar_el3, x0
110         mrs     x0, scr_el3
111         orr     x0, x0, #0xf                    /* SCR_EL3.NS|IRQ|FIQ|EA */
112         msr     scr_el3, x0
113         msr     cptr_el3, xzr                   /* Enable FP/SIMD */
114 #ifdef COUNTER_FREQUENCY
115         ldr     x0, =COUNTER_FREQUENCY
116         msr     cntfrq_el0, x0                  /* Initialize CNTFRQ */
117 #endif
118         b       0f
119 2:      set_vbar        vbar_el2, x0
120         mov     x0, #0x33ff
121         msr     cptr_el2, x0                    /* Enable FP/SIMD */
122         b       0f
123 1:      set_vbar        vbar_el1, x0
124         mov     x0, #3 << 20
125         msr     cpacr_el1, x0                   /* Enable FP/SIMD */
126 0:
127
128         /*
129          * Enable SMPEN bit for coherency.
130          * This register is not architectural but at the moment
131          * this bit should be set for A53/A57/A72.
132          */
133 #ifdef CONFIG_ARMV8_SET_SMPEN
134         switch_el x1, 3f, 1f, 1f
135 3:
136         mrs     x0, S3_1_c15_c2_1               /* cpuectlr_el1 */
137         orr     x0, x0, #0x40
138         msr     S3_1_c15_c2_1, x0
139 1:
140 #endif
141
142         /* Apply ARM core specific erratas */
143         bl      apply_core_errata
144
145         /*
146          * Cache/BPB/TLB Invalidate
147          * i-cache is invalidated before enabled in icache_enable()
148          * tlb is invalidated before mmu is enabled in dcache_enable()
149          * d-cache is invalidated before enabled in dcache_enable()
150          */
151
152         /* Processor specific initialization */
153         bl      lowlevel_init
154
155 #if defined(CONFIG_ARMV8_SPIN_TABLE) && !defined(CONFIG_SPL_BUILD)
156         branch_if_master x0, x1, master_cpu
157         b       spin_table_secondary_jump
158         /* never return */
159 #elif defined(CONFIG_ARMV8_MULTIENTRY)
160         branch_if_master x0, x1, master_cpu
161
162         /*
163          * Slave CPUs
164          */
165 slave_cpu:
166         wfe
167         ldr     x1, =CPU_RELEASE_ADDR
168         ldr     x0, [x1]
169         cbz     x0, slave_cpu
170         br      x0                      /* branch to the given address */
171 #endif /* CONFIG_ARMV8_MULTIENTRY */
172 master_cpu:
173         bl      _main
174
175 #ifdef CONFIG_SYS_RESET_SCTRL
176 reset_sctrl:
177         switch_el x1, 3f, 2f, 1f
178 3:
179         mrs     x0, sctlr_el3
180         b       0f
181 2:
182         mrs     x0, sctlr_el2
183         b       0f
184 1:
185         mrs     x0, sctlr_el1
186
187 0:
188         ldr     x1, =0xfdfffffa
189         and     x0, x0, x1
190
191         switch_el x1, 6f, 5f, 4f
192 6:
193         msr     sctlr_el3, x0
194         b       7f
195 5:
196         msr     sctlr_el2, x0
197         b       7f
198 4:
199         msr     sctlr_el1, x0
200
201 7:
202         dsb     sy
203         isb
204         b       __asm_invalidate_tlb_all
205         ret
206 #endif
207
208 /*-----------------------------------------------------------------------*/
209
210 WEAK(apply_core_errata)
211
212         mov     x29, lr                 /* Save LR */
213         /* For now, we support Cortex-A53, Cortex-A57 specific errata */
214
215         /* Check if we are running on a Cortex-A53 core */
216         branch_if_a53_core x0, apply_a53_core_errata
217
218         /* Check if we are running on a Cortex-A57 core */
219         branch_if_a57_core x0, apply_a57_core_errata
220 0:
221         mov     lr, x29                 /* Restore LR */
222         ret
223
224 apply_a53_core_errata:
225
226 #ifdef CONFIG_ARM_ERRATA_855873
227         mrs     x0, midr_el1
228         tst     x0, #(0xf << 20)
229         b.ne    0b
230
231         mrs     x0, midr_el1
232         and     x0, x0, #0xf
233         cmp     x0, #3
234         b.lt    0b
235
236         mrs     x0, S3_1_c15_c2_0       /* cpuactlr_el1 */
237         /* Enable data cache clean as data cache clean/invalidate */
238         orr     x0, x0, #1 << 44
239         msr     S3_1_c15_c2_0, x0       /* cpuactlr_el1 */
240 #endif
241         b 0b
242
243 apply_a57_core_errata:
244
245 #ifdef CONFIG_ARM_ERRATA_828024
246         mrs     x0, S3_1_c15_c2_0       /* cpuactlr_el1 */
247         /* Disable non-allocate hint of w-b-n-a memory type */
248         orr     x0, x0, #1 << 49
249         /* Disable write streaming no L1-allocate threshold */
250         orr     x0, x0, #3 << 25
251         /* Disable write streaming no-allocate threshold */
252         orr     x0, x0, #3 << 27
253         msr     S3_1_c15_c2_0, x0       /* cpuactlr_el1 */
254 #endif
255
256 #ifdef CONFIG_ARM_ERRATA_826974
257         mrs     x0, S3_1_c15_c2_0       /* cpuactlr_el1 */
258         /* Disable speculative load execution ahead of a DMB */
259         orr     x0, x0, #1 << 59
260         msr     S3_1_c15_c2_0, x0       /* cpuactlr_el1 */
261 #endif
262
263 #ifdef CONFIG_ARM_ERRATA_833471
264         mrs     x0, S3_1_c15_c2_0       /* cpuactlr_el1 */
265         /* FPSCR write flush.
266          * Note that in some cases where a flush is unnecessary this
267             could impact performance. */
268         orr     x0, x0, #1 << 38
269         msr     S3_1_c15_c2_0, x0       /* cpuactlr_el1 */
270 #endif
271
272 #ifdef CONFIG_ARM_ERRATA_829520
273         mrs     x0, S3_1_c15_c2_0       /* cpuactlr_el1 */
274         /* Disable Indirect Predictor bit will prevent this erratum
275             from occurring
276          * Note that in some cases where a flush is unnecessary this
277             could impact performance. */
278         orr     x0, x0, #1 << 4
279         msr     S3_1_c15_c2_0, x0       /* cpuactlr_el1 */
280 #endif
281
282 #ifdef CONFIG_ARM_ERRATA_833069
283         mrs     x0, S3_1_c15_c2_0       /* cpuactlr_el1 */
284         /* Disable Enable Invalidates of BTB bit */
285         and     x0, x0, #0xE
286         msr     S3_1_c15_c2_0, x0       /* cpuactlr_el1 */
287 #endif
288         b 0b
289 ENDPROC(apply_core_errata)
290
291 /*-----------------------------------------------------------------------*/
292
293 WEAK(lowlevel_init)
294         mov     x29, lr                 /* Save LR */
295
296 #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
297         branch_if_slave x0, 1f
298         ldr     x0, =GICD_BASE
299         bl      gic_init_secure
300 1:
301 #if defined(CONFIG_GICV3)
302         ldr     x0, =GICR_BASE
303         bl      gic_init_secure_percpu
304 #elif defined(CONFIG_GICV2)
305         ldr     x0, =GICD_BASE
306         ldr     x1, =GICC_BASE
307         bl      gic_init_secure_percpu
308 #endif
309 #endif
310
311 #ifdef CONFIG_ARMV8_MULTIENTRY
312         branch_if_master x0, x1, 2f
313
314         /*
315          * Slave should wait for master clearing spin table.
316          * This sync prevent salves observing incorrect
317          * value of spin table and jumping to wrong place.
318          */
319 #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
320 #ifdef CONFIG_GICV2
321         ldr     x0, =GICC_BASE
322 #endif
323         bl      gic_wait_for_interrupt
324 #endif
325
326         /*
327          * All slaves will enter EL2 and optionally EL1.
328          */
329         adr     x4, lowlevel_in_el2
330         ldr     x5, =ES_TO_AARCH64
331         bl      armv8_switch_to_el2
332
333 lowlevel_in_el2:
334 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
335         adr     x4, lowlevel_in_el1
336         ldr     x5, =ES_TO_AARCH64
337         bl      armv8_switch_to_el1
338
339 lowlevel_in_el1:
340 #endif
341
342 #endif /* CONFIG_ARMV8_MULTIENTRY */
343
344 2:
345         mov     lr, x29                 /* Restore LR */
346         ret
347 ENDPROC(lowlevel_init)
348
349 WEAK(smp_kick_all_cpus)
350         /* Kick secondary cpus up by SGI 0 interrupt */
351 #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
352         ldr     x0, =GICD_BASE
353         b       gic_kick_secondary_cpus
354 #endif
355         ret
356 ENDPROC(smp_kick_all_cpus)
357
358 /*-----------------------------------------------------------------------*/
359
360 ENTRY(c_runtime_cpu_setup)
361 #if defined(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) || !defined(CONFIG_SPL_BUILD)
362         /* Relocate vBAR */
363         adr     x0, vectors
364         switch_el x1, 3f, 2f, 1f
365 3:      msr     vbar_el3, x0
366         b       0f
367 2:      msr     vbar_el2, x0
368         b       0f
369 1:      msr     vbar_el1, x0
370 0:
371 #endif
372
373         ret
374 ENDPROC(c_runtime_cpu_setup)
375
376 WEAK(save_boot_params)
377         b       save_boot_params_ret    /* back to my caller */
378 ENDPROC(save_boot_params)