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