]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/armv8/start.S
540a5db8438b782060b09005ff558046e762efcf
[karo-tx-uboot.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 <version.h>
11 #include <linux/linkage.h>
12 #include <asm/macro.h>
13 #include <asm/armv8/mmu.h>
14
15 /*************************************************************************
16  *
17  * Startup Code (reset vector)
18  *
19  *************************************************************************/
20
21 .globl  _start
22 _start:
23         b       reset
24
25         .align 3
26
27 .globl  _TEXT_BASE
28 _TEXT_BASE:
29         .quad   CONFIG_SYS_TEXT_BASE
30
31 /*
32  * These are defined in the linker script.
33  */
34 .globl  _end_ofs
35 _end_ofs:
36         .quad   _end - _start
37
38 .globl  _bss_start_ofs
39 _bss_start_ofs:
40         .quad   __bss_start - _start
41
42 .globl  _bss_end_ofs
43 _bss_end_ofs:
44         .quad   __bss_end - _start
45
46 reset:
47         /*
48          * Could be EL3/EL2/EL1, Initial State:
49          * Little Endian, MMU Disabled, i/dCache Disabled
50          */
51         adr     x0, vectors
52         switch_el x1, 3f, 2f, 1f
53 3:      msr     vbar_el3, x0
54         mrs     x0, scr_el3
55         orr     x0, x0, #0xf                    /* SCR_EL3.NS|IRQ|FIQ|EA */
56         msr     scr_el3, x0
57         msr     cptr_el3, xzr                   /* Enable FP/SIMD */
58         ldr     x0, =COUNTER_FREQUENCY
59         msr     cntfrq_el0, x0                  /* Initialize CNTFRQ */
60         b       0f
61 2:      msr     vbar_el2, x0
62         mov     x0, #0x33ff
63         msr     cptr_el2, x0                    /* Enable FP/SIMD */
64         b       0f
65 1:      msr     vbar_el1, x0
66         mov     x0, #3 << 20
67         msr     cpacr_el1, x0                   /* Enable FP/SIMD */
68 0:
69
70         /* Apply ARM core specific erratas */
71         bl      apply_core_errata
72
73         /*
74          * Cache/BPB/TLB Invalidate
75          * i-cache is invalidated before enabled in icache_enable()
76          * tlb is invalidated before mmu is enabled in dcache_enable()
77          * d-cache is invalidated before enabled in dcache_enable()
78          */
79
80         /* Processor specific initialization */
81         bl      lowlevel_init
82
83         branch_if_master x0, x1, master_cpu
84
85         /*
86          * Slave CPUs
87          */
88 slave_cpu:
89         wfe
90         ldr     x1, =CPU_RELEASE_ADDR
91         ldr     x0, [x1]
92         cbz     x0, slave_cpu
93         br      x0                      /* branch to the given address */
94
95         /*
96          * Master CPU
97          */
98 master_cpu:
99         bl      _main
100
101 /*-----------------------------------------------------------------------*/
102
103 WEAK(apply_core_errata)
104
105         mov     x29, lr                 /* Save LR */
106         /* For now, we support Cortex-A57 specific errata only */
107
108         /* Check if we are running on a Cortex-A57 core */
109         branch_if_a57_core x0, apply_a57_core_errata
110 0:
111         mov     lr, x29                 /* Restore LR */
112         ret
113
114 apply_a57_core_errata:
115
116 #ifdef CONFIG_ARM_ERRATA_828024
117         mrs     x0, S3_1_c15_c2_0       /* cpuactlr_el1 */
118         /* Disable non-allocate hint of w-b-n-a memory type */
119         mov     x0, #0x1 << 49
120         /* Disable write streaming no L1-allocate threshold */
121         mov     x0, #0x3 << 25
122         /* Disable write streaming no-allocate threshold */
123         mov     x0, #0x3 << 27
124         msr     S3_1_c15_c2_0, x0       /* cpuactlr_el1 */
125 #endif
126
127 #ifdef CONFIG_ARM_ERRATA_826974
128         mrs     x0, S3_1_c15_c2_0       /* cpuactlr_el1 */
129         /* Disable speculative load execution ahead of a DMB */
130         mov     x0, #0x1 << 59
131         msr     S3_1_c15_c2_0, x0       /* cpuactlr_el1 */
132 #endif
133
134 #ifdef CONFIG_ARM_ERRATA_833069
135         mrs     x0, S3_1_c15_c2_0       /* cpuactlr_el1 */
136         /* Disable Enable Invalidates of BTB bit */
137         and     x0, x0, #0xE
138         msr     S3_1_c15_c2_0, x0       /* cpuactlr_el1 */
139 #endif
140         b 0b
141 ENDPROC(apply_core_errata)
142
143 /*-----------------------------------------------------------------------*/
144
145 WEAK(lowlevel_init)
146         mov     x29, lr                 /* Save LR */
147
148 #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
149         branch_if_slave x0, 1f
150         ldr     x0, =GICD_BASE
151         bl      gic_init_secure
152 1:
153 #if defined(CONFIG_GICV3)
154         ldr     x0, =GICR_BASE
155         bl      gic_init_secure_percpu
156 #elif defined(CONFIG_GICV2)
157         ldr     x0, =GICD_BASE
158         ldr     x1, =GICC_BASE
159         bl      gic_init_secure_percpu
160 #endif
161 #endif
162
163         branch_if_master x0, x1, 2f
164
165         /*
166          * Slave should wait for master clearing spin table.
167          * This sync prevent salves observing incorrect
168          * value of spin table and jumping to wrong place.
169          */
170 #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
171 #ifdef CONFIG_GICV2
172         ldr     x0, =GICC_BASE
173 #endif
174         bl      gic_wait_for_interrupt
175 #endif
176
177         /*
178          * All slaves will enter EL2 and optionally EL1.
179          */
180         bl      armv8_switch_to_el2
181 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
182         bl      armv8_switch_to_el1
183 #endif
184
185 2:
186         mov     lr, x29                 /* Restore LR */
187         ret
188 ENDPROC(lowlevel_init)
189
190 WEAK(smp_kick_all_cpus)
191         /* Kick secondary cpus up by SGI 0 interrupt */
192         mov     x29, lr                 /* Save LR */
193 #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
194         ldr     x0, =GICD_BASE
195         bl      gic_kick_secondary_cpus
196 #endif
197         mov     lr, x29                 /* Restore LR */
198         ret
199 ENDPROC(smp_kick_all_cpus)
200
201 /*-----------------------------------------------------------------------*/
202
203 ENTRY(c_runtime_cpu_setup)
204         /* Relocate vBAR */
205         adr     x0, vectors
206         switch_el x1, 3f, 2f, 1f
207 3:      msr     vbar_el3, x0
208         b       0f
209 2:      msr     vbar_el2, x0
210         b       0f
211 1:      msr     vbar_el1, x0
212 0:
213
214         ret
215 ENDPROC(c_runtime_cpu_setup)