]>
Commit | Line | Data |
---|---|---|
2f78eae5 | 1 | /* |
9f3183d2 | 2 | * (C) Copyright 2014-2015 Freescale Semiconductor |
2f78eae5 YS |
3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | |
5 | * | |
6 | * Extracted from armv8/start.S | |
7 | */ | |
8 | ||
9 | #include <config.h> | |
10 | #include <linux/linkage.h> | |
40f8dec5 | 11 | #include <asm/gic.h> |
2f78eae5 | 12 | #include <asm/macro.h> |
fa18ed76 | 13 | #include <asm/arch-fsl-layerscape/soc.h> |
9f3183d2 MH |
14 | #ifdef CONFIG_MP |
15 | #include <asm/arch/mp.h> | |
16 | #endif | |
f6a70b3a PJ |
17 | #ifdef CONFIG_FSL_LSCH3 |
18 | #include <asm/arch-fsl-layerscape/immap_lsch3.h> | |
19 | #endif | |
ec6617c3 | 20 | #include <asm/u-boot.h> |
2f78eae5 | 21 | |
fa18ed76 WS |
22 | /* Get GIC offset |
23 | * For LS1043a rev1.0, GIC base address align with 4k. | |
24 | * For LS1043a rev1.1, if DCFG_GIC400_ALIGN[GIC_ADDR_BIT] | |
25 | * is set, GIC base address align with 4K, or else align | |
26 | * with 64k. | |
27 | * output: | |
28 | * x0: the base address of GICD | |
29 | * x1: the base address of GICC | |
30 | */ | |
31 | ENTRY(get_gic_offset) | |
32 | ldr x0, =GICD_BASE | |
33 | #ifdef CONFIG_GICV2 | |
34 | ldr x1, =GICC_BASE | |
35 | #endif | |
36 | #ifdef CONFIG_HAS_FEATURE_GIC64K_ALIGN | |
37 | ldr x2, =DCFG_CCSR_SVR | |
38 | ldr w2, [x2] | |
39 | rev w2, w2 | |
a8f33034 W |
40 | lsr w3, w2, #16 |
41 | ldr w4, =SVR_DEV(SVR_LS1043A) | |
fa18ed76 WS |
42 | cmp w3, w4 |
43 | b.ne 1f | |
44 | ands w2, w2, #0xff | |
45 | cmp w2, #REV1_0 | |
46 | b.eq 1f | |
47 | ldr x2, =SCFG_GIC400_ALIGN | |
48 | ldr w2, [x2] | |
49 | rev w2, w2 | |
50 | tbnz w2, #GIC_ADDR_BIT, 1f | |
51 | ldr x0, =GICD_BASE_64K | |
52 | #ifdef CONFIG_GICV2 | |
53 | ldr x1, =GICC_BASE_64K | |
54 | #endif | |
55 | 1: | |
56 | #endif | |
57 | ret | |
58 | ENDPROC(get_gic_offset) | |
59 | ||
60 | ENTRY(smp_kick_all_cpus) | |
61 | /* Kick secondary cpus up by SGI 0 interrupt */ | |
62 | #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3) | |
63 | mov x29, lr /* Save LR */ | |
64 | bl get_gic_offset | |
65 | bl gic_kick_secondary_cpus | |
66 | mov lr, x29 /* Restore LR */ | |
67 | #endif | |
68 | ret | |
69 | ENDPROC(smp_kick_all_cpus) | |
70 | ||
71 | ||
2f78eae5 YS |
72 | ENTRY(lowlevel_init) |
73 | mov x29, lr /* Save LR */ | |
74 | ||
399e2bb6 YS |
75 | switch_el x1, 1f, 100f, 100f /* skip if not in EL3 */ |
76 | 1: | |
77 | ||
c055cee1 | 78 | #if defined (CONFIG_SYS_FSL_HAS_CCN504) |
2b690b98 PK |
79 | |
80 | /* Set Wuo bit for RN-I 20 */ | |
4a3ab193 | 81 | #ifdef CONFIG_ARCH_LS2080A |
2b690b98 PK |
82 | ldr x0, =CCI_AUX_CONTROL_BASE(20) |
83 | ldr x1, =0x00000010 | |
84 | bl ccn504_set_aux | |
d037261f PJ |
85 | |
86 | /* | |
87 | * Set forced-order mode in RNI-6, RNI-20 | |
88 | * This is required for performance optimization on LS2088A | |
89 | * LS2080A family does not support setting forced-order mode, | |
90 | * so skip this operation for LS2080A family | |
91 | */ | |
92 | bl get_svr | |
93 | lsr w0, w0, #16 | |
a8f33034 | 94 | ldr w1, =SVR_DEV(SVR_LS2080A) |
d037261f PJ |
95 | cmp w0, w1 |
96 | b.eq 1f | |
97 | ||
98 | ldr x0, =CCI_AUX_CONTROL_BASE(6) | |
99 | ldr x1, =0x00000020 | |
100 | bl ccn504_set_aux | |
101 | ldr x0, =CCI_AUX_CONTROL_BASE(20) | |
102 | ldr x1, =0x00000020 | |
103 | bl ccn504_set_aux | |
104 | 1: | |
2b690b98 PK |
105 | #endif |
106 | ||
07c66000 | 107 | /* Add fully-coherent masters to DVM domain */ |
3ffa95c2 BS |
108 | ldr x0, =CCI_MN_BASE |
109 | ldr x1, =CCI_MN_RNF_NODEID_LIST | |
110 | ldr x2, =CCI_MN_DVM_DOMAIN_CTL_SET | |
111 | bl ccn504_add_masters_to_dvm | |
112 | ||
113 | /* Set all RN-I ports to QoS of 15 */ | |
114 | ldr x0, =CCI_S0_QOS_CONTROL_BASE(0) | |
115 | ldr x1, =0x00FF000C | |
116 | bl ccn504_set_qos | |
117 | ldr x0, =CCI_S1_QOS_CONTROL_BASE(0) | |
118 | ldr x1, =0x00FF000C | |
119 | bl ccn504_set_qos | |
120 | ldr x0, =CCI_S2_QOS_CONTROL_BASE(0) | |
121 | ldr x1, =0x00FF000C | |
122 | bl ccn504_set_qos | |
123 | ||
124 | ldr x0, =CCI_S0_QOS_CONTROL_BASE(2) | |
125 | ldr x1, =0x00FF000C | |
126 | bl ccn504_set_qos | |
127 | ldr x0, =CCI_S1_QOS_CONTROL_BASE(2) | |
128 | ldr x1, =0x00FF000C | |
129 | bl ccn504_set_qos | |
130 | ldr x0, =CCI_S2_QOS_CONTROL_BASE(2) | |
131 | ldr x1, =0x00FF000C | |
132 | bl ccn504_set_qos | |
133 | ||
134 | ldr x0, =CCI_S0_QOS_CONTROL_BASE(6) | |
135 | ldr x1, =0x00FF000C | |
136 | bl ccn504_set_qos | |
137 | ldr x0, =CCI_S1_QOS_CONTROL_BASE(6) | |
138 | ldr x1, =0x00FF000C | |
139 | bl ccn504_set_qos | |
140 | ldr x0, =CCI_S2_QOS_CONTROL_BASE(6) | |
141 | ldr x1, =0x00FF000C | |
142 | bl ccn504_set_qos | |
143 | ||
144 | ldr x0, =CCI_S0_QOS_CONTROL_BASE(12) | |
145 | ldr x1, =0x00FF000C | |
146 | bl ccn504_set_qos | |
147 | ldr x0, =CCI_S1_QOS_CONTROL_BASE(12) | |
148 | ldr x1, =0x00FF000C | |
149 | bl ccn504_set_qos | |
150 | ldr x0, =CCI_S2_QOS_CONTROL_BASE(12) | |
151 | ldr x1, =0x00FF000C | |
152 | bl ccn504_set_qos | |
153 | ||
154 | ldr x0, =CCI_S0_QOS_CONTROL_BASE(16) | |
155 | ldr x1, =0x00FF000C | |
156 | bl ccn504_set_qos | |
157 | ldr x0, =CCI_S1_QOS_CONTROL_BASE(16) | |
158 | ldr x1, =0x00FF000C | |
159 | bl ccn504_set_qos | |
160 | ldr x0, =CCI_S2_QOS_CONTROL_BASE(16) | |
161 | ldr x1, =0x00FF000C | |
162 | bl ccn504_set_qos | |
163 | ||
164 | ldr x0, =CCI_S0_QOS_CONTROL_BASE(20) | |
165 | ldr x1, =0x00FF000C | |
166 | bl ccn504_set_qos | |
167 | ldr x0, =CCI_S1_QOS_CONTROL_BASE(20) | |
168 | ldr x1, =0x00FF000C | |
169 | bl ccn504_set_qos | |
170 | ldr x0, =CCI_S2_QOS_CONTROL_BASE(20) | |
171 | ldr x1, =0x00FF000C | |
172 | bl ccn504_set_qos | |
c055cee1 | 173 | #endif /* CONFIG_SYS_FSL_HAS_CCN504 */ |
07c66000 | 174 | |
1e49a231 | 175 | #ifdef SMMU_BASE |
2f78eae5 YS |
176 | /* Set the SMMU page size in the sACR register */ |
177 | ldr x1, =SMMU_BASE | |
178 | ldr w0, [x1, #0x10] | |
179 | orr w0, w0, #1 << 16 /* set sACR.pagesize to indicate 64K page */ | |
180 | str w0, [x1, #0x10] | |
1e49a231 | 181 | #endif |
2f78eae5 YS |
182 | |
183 | /* Initialize GIC Secure Bank Status */ | |
184 | #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3) | |
185 | branch_if_slave x0, 1f | |
fa18ed76 | 186 | bl get_gic_offset |
2f78eae5 YS |
187 | bl gic_init_secure |
188 | 1: | |
189 | #ifdef CONFIG_GICV3 | |
190 | ldr x0, =GICR_BASE | |
191 | bl gic_init_secure_percpu | |
192 | #elif defined(CONFIG_GICV2) | |
fa18ed76 | 193 | bl get_gic_offset |
2f78eae5 YS |
194 | bl gic_init_secure_percpu |
195 | #endif | |
196 | #endif | |
197 | ||
399e2bb6 | 198 | 100: |
40f8dec5 | 199 | branch_if_master x0, x1, 2f |
2f78eae5 | 200 | |
9f3183d2 | 201 | #if defined(CONFIG_MP) && defined(CONFIG_ARMV8_MULTIENTRY) |
40f8dec5 YS |
202 | ldr x0, =secondary_boot_func |
203 | blr x0 | |
9f3183d2 | 204 | #endif |
9c66ce66 | 205 | |
9f3183d2 | 206 | 2: |
399e2bb6 YS |
207 | switch_el x1, 1f, 100f, 100f /* skip if not in EL3 */ |
208 | 1: | |
9c66ce66 BS |
209 | #ifdef CONFIG_FSL_TZPC_BP147 |
210 | /* Set Non Secure access for all devices protected via TZPC */ | |
211 | ldr x1, =TZPCDECPROT_0_SET_BASE /* Decode Protection-0 Set Reg */ | |
212 | orr w0, w0, #1 << 3 /* DCFG_RESET is accessible from NS world */ | |
213 | str w0, [x1] | |
214 | ||
215 | isb | |
216 | dsb sy | |
217 | #endif | |
218 | ||
219 | #ifdef CONFIG_FSL_TZASC_400 | |
d5df606d PJ |
220 | /* |
221 | * LS2080 and its personalities does not support TZASC | |
222 | * So skip TZASC related operations | |
223 | */ | |
224 | bl get_svr | |
225 | lsr w0, w0, #16 | |
a8f33034 | 226 | ldr w1, =SVR_DEV(SVR_LS2080A) |
d5df606d PJ |
227 | cmp w0, w1 |
228 | b.eq 1f | |
229 | ||
9c66ce66 BS |
230 | /* Set TZASC so that: |
231 | * a. We use only Region0 whose global secure write/read is EN | |
232 | * b. We use only Region0 whose NSAID write/read is EN | |
233 | * | |
234 | * NOTE: As per the CCSR map doc, TZASC 3 and TZASC 4 are just | |
235 | * placeholders. | |
236 | */ | |
85a9a14e | 237 | #ifdef CONFIG_FSL_TZASC_1 |
9c66ce66 | 238 | ldr x1, =TZASC_GATE_KEEPER(0) |
7cfbb4ab PJ |
239 | ldr w0, [x1] /* Filter 0 Gate Keeper Register */ |
240 | orr w0, w0, #1 << 0 /* Set open_request for Filter 0 */ | |
241 | str w0, [x1] | |
9c66ce66 | 242 | |
9c66ce66 | 243 | ldr x1, =TZASC_REGION_ATTRIBUTES_0(0) |
7cfbb4ab PJ |
244 | ldr w0, [x1] /* Region-0 Attributes Register */ |
245 | orr w0, w0, #1 << 31 /* Set Sec global write en, Bit[31] */ | |
246 | orr w0, w0, #1 << 30 /* Set Sec global read en, Bit[30] */ | |
247 | str w0, [x1] | |
9c66ce66 | 248 | |
85a9a14e A |
249 | ldr x1, =TZASC_REGION_ID_ACCESS_0(0) |
250 | ldr w0, [x1] /* Region-0 Access Register */ | |
251 | mov w0, #0xFFFFFFFF /* Set nsaid_wr_en and nsaid_rd_en */ | |
252 | str w0, [x1] | |
253 | #endif | |
254 | #ifdef CONFIG_FSL_TZASC_2 | |
255 | ldr x1, =TZASC_GATE_KEEPER(1) | |
256 | ldr w0, [x1] /* Filter 0 Gate Keeper Register */ | |
257 | orr w0, w0, #1 << 0 /* Set open_request for Filter 0 */ | |
258 | str w0, [x1] | |
259 | ||
9c66ce66 | 260 | ldr x1, =TZASC_REGION_ATTRIBUTES_0(1) |
7cfbb4ab PJ |
261 | ldr w0, [x1] /* Region-1 Attributes Register */ |
262 | orr w0, w0, #1 << 31 /* Set Sec global write en, Bit[31] */ | |
263 | orr w0, w0, #1 << 30 /* Set Sec global read en, Bit[30] */ | |
264 | str w0, [x1] | |
9c66ce66 | 265 | |
9c66ce66 BS |
266 | ldr x1, =TZASC_REGION_ID_ACCESS_0(1) |
267 | ldr w0, [x1] /* Region-1 Attributes Register */ | |
268 | mov w0, #0xFFFFFFFF /* Set nsaid_wr_en and nsaid_rd_en */ | |
269 | str w0, [x1] | |
85a9a14e | 270 | #endif |
9c66ce66 BS |
271 | isb |
272 | dsb sy | |
273 | #endif | |
399e2bb6 | 274 | 100: |
d5df606d | 275 | 1: |
da28e58a | 276 | #ifdef CONFIG_ARCH_LS1046A |
399e2bb6 YS |
277 | switch_el x1, 1f, 100f, 100f /* skip if not in EL3 */ |
278 | 1: | |
13f79880 MH |
279 | /* Initialize the L2 RAM latency */ |
280 | mrs x1, S3_1_c11_c0_2 | |
281 | mov x0, #0x1C7 | |
282 | /* Clear L2 Tag RAM latency and L2 Data RAM latency */ | |
283 | bic x1, x1, x0 | |
284 | /* Set L2 data ram latency bits [2:0] */ | |
285 | orr x1, x1, #0x2 | |
286 | /* set L2 tag ram latency bits [8:6] */ | |
287 | orr x1, x1, #0x80 | |
288 | msr S3_1_c11_c0_2, x1 | |
289 | isb | |
399e2bb6 | 290 | 100: |
13f79880 MH |
291 | #endif |
292 | ||
3b6bf811 HZ |
293 | #if defined(CONFIG_FSL_LSCH2) && !defined(CONFIG_SPL_BUILD) |
294 | bl fsl_ocram_init | |
295 | #endif | |
296 | ||
40f8dec5 YS |
297 | mov lr, x29 /* Restore LR */ |
298 | ret | |
299 | ENDPROC(lowlevel_init) | |
300 | ||
3b6bf811 HZ |
301 | #if defined(CONFIG_FSL_LSCH2) && !defined(CONFIG_SPL_BUILD) |
302 | ENTRY(fsl_ocram_init) | |
303 | mov x28, lr /* Save LR */ | |
304 | bl fsl_clear_ocram | |
305 | bl fsl_ocram_clear_ecc_err | |
306 | mov lr, x28 /* Restore LR */ | |
307 | ret | |
308 | ENDPROC(fsl_ocram_init) | |
309 | ||
310 | ENTRY(fsl_clear_ocram) | |
311 | /* Clear OCRAM */ | |
312 | ldr x0, =CONFIG_SYS_FSL_OCRAM_BASE | |
313 | ldr x1, =(CONFIG_SYS_FSL_OCRAM_BASE + CONFIG_SYS_FSL_OCRAM_SIZE) | |
314 | mov x2, #0 | |
315 | clear_loop: | |
316 | str x2, [x0] | |
317 | add x0, x0, #8 | |
318 | cmp x0, x1 | |
319 | b.lo clear_loop | |
320 | ret | |
321 | ENDPROC(fsl_clear_ocram) | |
322 | ||
323 | ENTRY(fsl_ocram_clear_ecc_err) | |
324 | /* OCRAM1/2 ECC status bit */ | |
325 | mov w1, #0x60 | |
326 | ldr x0, =DCSR_DCFG_SBEESR2 | |
327 | str w1, [x0] | |
328 | ldr x0, =DCSR_DCFG_MBEESR2 | |
329 | str w1, [x0] | |
330 | ret | |
331 | ENDPROC(fsl_ocram_init) | |
332 | #endif | |
333 | ||
b7f2bbff | 334 | #ifdef CONFIG_FSL_LSCH3 |
f6a70b3a PJ |
335 | .globl get_svr |
336 | get_svr: | |
337 | ldr x1, =FSL_LSCH3_SVR | |
338 | ldr w0, [x1] | |
339 | ret | |
c055cee1 | 340 | #endif |
f6a70b3a | 341 | |
c055cee1 | 342 | #ifdef CONFIG_SYS_FSL_HAS_CCN504 |
dcd468b8 YS |
343 | hnf_pstate_poll: |
344 | /* x0 has the desired status, return 0 for success, 1 for timeout | |
345 | * clobber x1, x2, x3, x4, x6, x7 | |
346 | */ | |
347 | mov x1, x0 | |
348 | mov x7, #0 /* flag for timeout */ | |
349 | mrs x3, cntpct_el0 /* read timer */ | |
350 | add x3, x3, #1200 /* timeout after 100 microseconds */ | |
351 | mov x0, #0x18 | |
352 | movk x0, #0x420, lsl #16 /* HNF0_PSTATE_STATUS */ | |
353 | mov w6, #8 /* HN-F node count */ | |
354 | 1: | |
355 | ldr x2, [x0] | |
356 | cmp x2, x1 /* check status */ | |
357 | b.eq 2f | |
358 | mrs x4, cntpct_el0 | |
359 | cmp x4, x3 | |
360 | b.ls 1b | |
361 | mov x7, #1 /* timeout */ | |
362 | b 3f | |
363 | 2: | |
364 | add x0, x0, #0x10000 /* move to next node */ | |
365 | subs w6, w6, #1 | |
366 | cbnz w6, 1b | |
367 | 3: | |
368 | mov x0, x7 | |
369 | ret | |
370 | ||
371 | hnf_set_pstate: | |
372 | /* x0 has the desired state, clobber x1, x2, x6 */ | |
373 | mov x1, x0 | |
374 | /* power state to SFONLY */ | |
375 | mov w6, #8 /* HN-F node count */ | |
376 | mov x0, #0x10 | |
377 | movk x0, #0x420, lsl #16 /* HNF0_PSTATE_REQ */ | |
378 | 1: /* set pstate to sfonly */ | |
379 | ldr x2, [x0] | |
380 | and x2, x2, #0xfffffffffffffffc /* & HNFPSTAT_MASK */ | |
381 | orr x2, x2, x1 | |
382 | str x2, [x0] | |
383 | add x0, x0, #0x10000 /* move to next node */ | |
384 | subs w6, w6, #1 | |
385 | cbnz w6, 1b | |
386 | ||
387 | ret | |
388 | ||
1ab557a0 | 389 | ENTRY(__asm_flush_l3_dcache) |
dcd468b8 YS |
390 | /* |
391 | * Return status in x0 | |
392 | * success 0 | |
399e2bb6 | 393 | * timeout 1 for setting SFONLY, 2 for FAM, 3 for both |
dcd468b8 YS |
394 | */ |
395 | mov x29, lr | |
396 | mov x8, #0 | |
397 | ||
398 | dsb sy | |
399 | mov x0, #0x1 /* HNFPSTAT_SFONLY */ | |
400 | bl hnf_set_pstate | |
401 | ||
402 | mov x0, #0x4 /* SFONLY status */ | |
403 | bl hnf_pstate_poll | |
404 | cbz x0, 1f | |
405 | mov x8, #1 /* timeout */ | |
406 | 1: | |
407 | dsb sy | |
408 | mov x0, #0x3 /* HNFPSTAT_FAM */ | |
409 | bl hnf_set_pstate | |
410 | ||
411 | mov x0, #0xc /* FAM status */ | |
412 | bl hnf_pstate_poll | |
413 | cbz x0, 1f | |
414 | add x8, x8, #0x2 | |
415 | 1: | |
416 | mov x0, x8 | |
417 | mov lr, x29 | |
418 | ret | |
1ab557a0 | 419 | ENDPROC(__asm_flush_l3_dcache) |
c055cee1 | 420 | #endif /* CONFIG_SYS_FSL_HAS_CCN504 */ |
dcd468b8 | 421 | |
9f3183d2 | 422 | #ifdef CONFIG_MP |
40f8dec5 YS |
423 | /* Keep literals not used by the secondary boot code outside it */ |
424 | .ltorg | |
425 | ||
426 | /* Using 64 bit alignment since the spin table is accessed as data */ | |
427 | .align 4 | |
428 | .global secondary_boot_code | |
429 | /* Secondary Boot Code starts here */ | |
430 | secondary_boot_code: | |
431 | .global __spin_table | |
432 | __spin_table: | |
433 | .space CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE | |
434 | ||
435 | .align 2 | |
436 | ENTRY(secondary_boot_func) | |
2f78eae5 | 437 | /* |
40f8dec5 YS |
438 | * MPIDR_EL1 Fields: |
439 | * MPIDR[1:0] = AFF0_CPUID <- Core ID (0,1) | |
440 | * MPIDR[7:2] = AFF0_RES | |
441 | * MPIDR[15:8] = AFF1_CLUSTERID <- Cluster ID (0,1,2,3) | |
442 | * MPIDR[23:16] = AFF2_CLUSTERID | |
443 | * MPIDR[24] = MT | |
444 | * MPIDR[29:25] = RES0 | |
445 | * MPIDR[30] = U | |
446 | * MPIDR[31] = ME | |
447 | * MPIDR[39:32] = AFF3 | |
448 | * | |
449 | * Linear Processor ID (LPID) calculation from MPIDR_EL1: | |
450 | * (We only use AFF0_CPUID and AFF1_CLUSTERID for now | |
451 | * until AFF2_CLUSTERID and AFF3 have non-zero values) | |
452 | * | |
453 | * LPID = MPIDR[15:8] | MPIDR[1:0] | |
2f78eae5 | 454 | */ |
40f8dec5 YS |
455 | mrs x0, mpidr_el1 |
456 | ubfm x1, x0, #8, #15 | |
457 | ubfm x2, x0, #0, #1 | |
458 | orr x10, x2, x1, lsl #2 /* x10 has LPID */ | |
459 | ubfm x9, x0, #0, #15 /* x9 contains MPIDR[15:0] */ | |
2f78eae5 | 460 | /* |
40f8dec5 YS |
461 | * offset of the spin table element for this core from start of spin |
462 | * table (each elem is padded to 64 bytes) | |
2f78eae5 | 463 | */ |
40f8dec5 YS |
464 | lsl x1, x10, #6 |
465 | ldr x0, =__spin_table | |
466 | /* physical address of this cpus spin table element */ | |
467 | add x11, x1, x0 | |
468 | ||
207774b2 YS |
469 | ldr x0, =__real_cntfrq |
470 | ldr x0, [x0] | |
471 | msr cntfrq_el0, x0 /* set with real frequency */ | |
40f8dec5 YS |
472 | str x9, [x11, #16] /* LPID */ |
473 | mov x4, #1 | |
474 | str x4, [x11, #8] /* STATUS */ | |
475 | dsb sy | |
476 | #if defined(CONFIG_GICV3) | |
477 | gic_wait_for_interrupt_m x0 | |
478 | #elif defined(CONFIG_GICV2) | |
fa18ed76 WS |
479 | bl get_gic_offset |
480 | mov x0, x1 | |
40f8dec5 YS |
481 | gic_wait_for_interrupt_m x0, w1 |
482 | #endif | |
483 | ||
40f8dec5 YS |
484 | slave_cpu: |
485 | wfe | |
486 | ldr x0, [x11] | |
487 | cbz x0, slave_cpu | |
488 | #ifndef CONFIG_ARMV8_SWITCH_TO_EL1 | |
489 | mrs x1, sctlr_el2 | |
490 | #else | |
491 | mrs x1, sctlr_el1 | |
492 | #endif | |
493 | tbz x1, #25, cpu_is_le | |
494 | rev x0, x0 /* BE to LE conversion */ | |
495 | cpu_is_le: | |
ec6617c3 | 496 | ldr x5, [x11, #24] |
020b3ce8 | 497 | cbz x5, 1f |
ec6617c3 AW |
498 | |
499 | #ifdef CONFIG_ARMV8_SWITCH_TO_EL1 | |
7c5e1feb AW |
500 | adr x4, secondary_switch_to_el1 |
501 | ldr x5, =ES_TO_AARCH64 | |
ec6617c3 | 502 | #else |
7c5e1feb AW |
503 | ldr x4, [x11] |
504 | ldr x5, =ES_TO_AARCH32 | |
ec6617c3 AW |
505 | #endif |
506 | bl secondary_switch_to_el2 | |
507 | ||
508 | 1: | |
509 | #ifdef CONFIG_ARMV8_SWITCH_TO_EL1 | |
7c5e1feb | 510 | adr x4, secondary_switch_to_el1 |
ec6617c3 | 511 | #else |
7c5e1feb | 512 | ldr x4, [x11] |
ec6617c3 | 513 | #endif |
7c5e1feb | 514 | ldr x5, =ES_TO_AARCH64 |
ec6617c3 AW |
515 | bl secondary_switch_to_el2 |
516 | ||
40f8dec5 YS |
517 | ENDPROC(secondary_boot_func) |
518 | ||
519 | ENTRY(secondary_switch_to_el2) | |
7c5e1feb | 520 | switch_el x6, 1f, 0f, 0f |
40f8dec5 | 521 | 0: ret |
7c5e1feb | 522 | 1: armv8_switch_to_el2_m x4, x5, x6 |
40f8dec5 YS |
523 | ENDPROC(secondary_switch_to_el2) |
524 | ||
525 | ENTRY(secondary_switch_to_el1) | |
ec6617c3 AW |
526 | mrs x0, mpidr_el1 |
527 | ubfm x1, x0, #8, #15 | |
528 | ubfm x2, x0, #0, #1 | |
529 | orr x10, x2, x1, lsl #2 /* x10 has LPID */ | |
530 | ||
531 | lsl x1, x10, #6 | |
532 | ldr x0, =__spin_table | |
533 | /* physical address of this cpus spin table element */ | |
534 | add x11, x1, x0 | |
535 | ||
7c5e1feb | 536 | ldr x4, [x11] |
ec6617c3 AW |
537 | |
538 | ldr x5, [x11, #24] | |
020b3ce8 | 539 | cbz x5, 2f |
ec6617c3 | 540 | |
7c5e1feb | 541 | ldr x5, =ES_TO_AARCH32 |
ec6617c3 AW |
542 | bl switch_to_el1 |
543 | ||
7c5e1feb | 544 | 2: ldr x5, =ES_TO_AARCH64 |
ec6617c3 AW |
545 | |
546 | switch_to_el1: | |
7c5e1feb | 547 | switch_el x6, 0f, 1f, 0f |
40f8dec5 | 548 | 0: ret |
7c5e1feb | 549 | 1: armv8_switch_to_el1_m x4, x5, x6 |
40f8dec5 YS |
550 | ENDPROC(secondary_switch_to_el1) |
551 | ||
552 | /* Ensure that the literals used by the secondary boot code are | |
553 | * assembled within it (this is required so that we can protect | |
554 | * this area with a single memreserve region | |
555 | */ | |
556 | .ltorg | |
557 | ||
558 | /* 64 bit alignment for elements accessed as data */ | |
559 | .align 4 | |
207774b2 YS |
560 | .global __real_cntfrq |
561 | __real_cntfrq: | |
562 | .quad COUNTER_FREQUENCY | |
40f8dec5 YS |
563 | .globl __secondary_boot_code_size |
564 | .type __secondary_boot_code_size, %object | |
565 | /* Secondary Boot Code ends here */ | |
566 | __secondary_boot_code_size: | |
567 | .quad .-secondary_boot_code | |
9f3183d2 | 568 | #endif |