Merge git://git.denx.de/u-boot-fsl-qoriq
[oweals/u-boot.git] / arch / arm / cpu / armv8 / start.S
1 /*
2  * (C) Copyright 2013
3  * David Feng <fenghua@phytium.com.cn>
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <asm-offsets.h>
9 #include <config.h>
10 #include <linux/linkage.h>
11 #include <asm/macro.h>
12 #include <asm/armv8/mmu.h>
13
14 /*************************************************************************
15  *
16  * Startup Code (reset vector)
17  *
18  *************************************************************************/
19
20 .globl  _start
21 _start:
22         b       reset
23
24 #ifdef CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK
25 /*
26  * Various SoCs need something special and SoC-specific up front in
27  * order to boot, allow them to set that in their boot0.h file and then
28  * use it here.
29  */
30 #include <asm/arch/boot0.h>
31 ARM_SOC_BOOT0_HOOK
32 #endif
33
34         .align 3
35
36 .globl  _TEXT_BASE
37 _TEXT_BASE:
38         .quad   CONFIG_SYS_TEXT_BASE
39
40 /*
41  * These are defined in the linker script.
42  */
43 .globl  _end_ofs
44 _end_ofs:
45         .quad   _end - _start
46
47 .globl  _bss_start_ofs
48 _bss_start_ofs:
49         .quad   __bss_start - _start
50
51 .globl  _bss_end_ofs
52 _bss_end_ofs:
53         .quad   __bss_end - _start
54
55 reset:
56 #ifdef CONFIG_SYS_RESET_SCTRL
57         bl reset_sctrl
58 #endif
59         /*
60          * Could be EL3/EL2/EL1, Initial State:
61          * Little Endian, MMU Disabled, i/dCache Disabled
62          */
63         adr     x0, vectors
64         switch_el x1, 3f, 2f, 1f
65 3:      msr     vbar_el3, x0
66         mrs     x0, scr_el3
67         orr     x0, x0, #0xf                    /* SCR_EL3.NS|IRQ|FIQ|EA */
68         msr     scr_el3, x0
69         msr     cptr_el3, xzr                   /* Enable FP/SIMD */
70 #ifdef COUNTER_FREQUENCY
71         ldr     x0, =COUNTER_FREQUENCY
72         msr     cntfrq_el0, x0                  /* Initialize CNTFRQ */
73 #endif
74         b       0f
75 2:      msr     vbar_el2, x0
76         mov     x0, #0x33ff
77         msr     cptr_el2, x0                    /* Enable FP/SIMD */
78         b       0f
79 1:      msr     vbar_el1, x0
80         mov     x0, #3 << 20
81         msr     cpacr_el1, x0                   /* Enable FP/SIMD */
82 0:
83
84         /* Apply ARM core specific erratas */
85         bl      apply_core_errata
86
87         /*
88          * Cache/BPB/TLB Invalidate
89          * i-cache is invalidated before enabled in icache_enable()
90          * tlb is invalidated before mmu is enabled in dcache_enable()
91          * d-cache is invalidated before enabled in dcache_enable()
92          */
93
94         /* Processor specific initialization */
95         bl      lowlevel_init
96
97 #if CONFIG_IS_ENABLED(ARMV8_SPIN_TABLE)
98         branch_if_master x0, x1, master_cpu
99         b       spin_table_secondary_jump
100         /* never return */
101 #elif defined(CONFIG_ARMV8_MULTIENTRY)
102         branch_if_master x0, x1, master_cpu
103
104         /*
105          * Slave CPUs
106          */
107 slave_cpu:
108         wfe
109         ldr     x1, =CPU_RELEASE_ADDR
110         ldr     x0, [x1]
111         cbz     x0, slave_cpu
112         br      x0                      /* branch to the given address */
113 #endif /* CONFIG_ARMV8_MULTIENTRY */
114 master_cpu:
115         bl      _main
116
117 #ifdef CONFIG_SYS_RESET_SCTRL
118 reset_sctrl:
119         switch_el x1, 3f, 2f, 1f
120 3:
121         mrs     x0, sctlr_el3
122         b       0f
123 2:
124         mrs     x0, sctlr_el2
125         b       0f
126 1:
127         mrs     x0, sctlr_el1
128
129 0:
130         ldr     x1, =0xfdfffffa
131         and     x0, x0, x1
132
133         switch_el x1, 6f, 5f, 4f
134 6:
135         msr     sctlr_el3, x0
136         b       7f
137 5:
138         msr     sctlr_el2, x0
139         b       7f
140 4:
141         msr     sctlr_el1, x0
142
143 7:
144         dsb     sy
145         isb
146         b       __asm_invalidate_tlb_all
147         ret
148 #endif
149
150 /*-----------------------------------------------------------------------*/
151
152 WEAK(apply_core_errata)
153
154         mov     x29, lr                 /* Save LR */
155         /* For now, we support Cortex-A57 specific errata only */
156
157         /* Check if we are running on a Cortex-A57 core */
158         branch_if_a57_core x0, apply_a57_core_errata
159 0:
160         mov     lr, x29                 /* Restore LR */
161         ret
162
163 apply_a57_core_errata:
164
165 #ifdef CONFIG_ARM_ERRATA_828024
166         mrs     x0, S3_1_c15_c2_0       /* cpuactlr_el1 */
167         /* Disable non-allocate hint of w-b-n-a memory type */
168         orr     x0, x0, #1 << 49
169         /* Disable write streaming no L1-allocate threshold */
170         orr     x0, x0, #3 << 25
171         /* Disable write streaming no-allocate threshold */
172         orr     x0, x0, #3 << 27
173         msr     S3_1_c15_c2_0, x0       /* cpuactlr_el1 */
174 #endif
175
176 #ifdef CONFIG_ARM_ERRATA_826974
177         mrs     x0, S3_1_c15_c2_0       /* cpuactlr_el1 */
178         /* Disable speculative load execution ahead of a DMB */
179         orr     x0, x0, #1 << 59
180         msr     S3_1_c15_c2_0, x0       /* cpuactlr_el1 */
181 #endif
182
183 #ifdef CONFIG_ARM_ERRATA_833471
184         mrs     x0, S3_1_c15_c2_0       /* cpuactlr_el1 */
185         /* FPSCR write flush.
186          * Note that in some cases where a flush is unnecessary this
187             could impact performance. */
188         orr     x0, x0, #1 << 38
189         msr     S3_1_c15_c2_0, x0       /* cpuactlr_el1 */
190 #endif
191
192 #ifdef CONFIG_ARM_ERRATA_829520
193         mrs     x0, S3_1_c15_c2_0       /* cpuactlr_el1 */
194         /* Disable Indirect Predictor bit will prevent this erratum
195             from occurring
196          * Note that in some cases where a flush is unnecessary this
197             could impact performance. */
198         orr     x0, x0, #1 << 4
199         msr     S3_1_c15_c2_0, x0       /* cpuactlr_el1 */
200 #endif
201
202 #ifdef CONFIG_ARM_ERRATA_833069
203         mrs     x0, S3_1_c15_c2_0       /* cpuactlr_el1 */
204         /* Disable Enable Invalidates of BTB bit */
205         and     x0, x0, #0xE
206         msr     S3_1_c15_c2_0, x0       /* cpuactlr_el1 */
207 #endif
208         b 0b
209 ENDPROC(apply_core_errata)
210
211 /*-----------------------------------------------------------------------*/
212
213 WEAK(lowlevel_init)
214         mov     x29, lr                 /* Save LR */
215
216 #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
217         branch_if_slave x0, 1f
218         ldr     x0, =GICD_BASE
219         bl      gic_init_secure
220 1:
221 #if defined(CONFIG_GICV3)
222         ldr     x0, =GICR_BASE
223         bl      gic_init_secure_percpu
224 #elif defined(CONFIG_GICV2)
225         ldr     x0, =GICD_BASE
226         ldr     x1, =GICC_BASE
227         bl      gic_init_secure_percpu
228 #endif
229 #endif
230
231 #ifdef CONFIG_ARMV8_MULTIENTRY
232         branch_if_master x0, x1, 2f
233
234         /*
235          * Slave should wait for master clearing spin table.
236          * This sync prevent salves observing incorrect
237          * value of spin table and jumping to wrong place.
238          */
239 #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
240 #ifdef CONFIG_GICV2
241         ldr     x0, =GICC_BASE
242 #endif
243         bl      gic_wait_for_interrupt
244 #endif
245
246         /*
247          * All slaves will enter EL2 and optionally EL1.
248          */
249         bl      armv8_switch_to_el2
250 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
251         bl      armv8_switch_to_el1
252 #endif
253
254 #endif /* CONFIG_ARMV8_MULTIENTRY */
255
256 2:
257         mov     lr, x29                 /* Restore LR */
258         ret
259 ENDPROC(lowlevel_init)
260
261 WEAK(smp_kick_all_cpus)
262         /* Kick secondary cpus up by SGI 0 interrupt */
263 #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
264         ldr     x0, =GICD_BASE
265         b       gic_kick_secondary_cpus
266 #endif
267         ret
268 ENDPROC(smp_kick_all_cpus)
269
270 /*-----------------------------------------------------------------------*/
271
272 ENTRY(c_runtime_cpu_setup)
273         /* Relocate vBAR */
274         adr     x0, vectors
275         switch_el x1, 3f, 2f, 1f
276 3:      msr     vbar_el3, x0
277         b       0f
278 2:      msr     vbar_el2, x0
279         b       0f
280 1:      msr     vbar_el1, x0
281 0:
282
283         ret
284 ENDPROC(c_runtime_cpu_setup)