2 * (C) Copyright 2014 Freescale Semiconductor
4 * SPDX-License-Identifier: GPL-2.0+
6 * Extracted from armv8/start.S
10 #include <linux/linkage.h>
12 #include <asm/macro.h>
16 mov x29, lr /* Save LR */
18 /* Add fully-coherent masters to DVM domain */
20 ldr x2, [x1, #CCI_MN_RNF_NODEID_LIST]
21 str x2, [x1, #CCI_MN_DVM_DOMAIN_CTL_SET]
22 1: ldr x3, [x1, #CCI_MN_DVM_DOMAIN_CTL_SET]
24 tst x0, x3 /* Wait for domain addition to complete */
27 /* Set the SMMU page size in the sACR register */
30 orr w0, w0, #1 << 16 /* set sACR.pagesize to indicate 64K page */
33 /* Initialize GIC Secure Bank Status */
34 #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
35 branch_if_slave x0, 1f
41 bl gic_init_secure_percpu
42 #elif defined(CONFIG_GICV2)
45 bl gic_init_secure_percpu
49 branch_if_master x0, x1, 2f
51 ldr x0, =secondary_boot_func
55 #ifdef CONFIG_FSL_TZPC_BP147
56 /* Set Non Secure access for all devices protected via TZPC */
57 ldr x1, =TZPCDECPROT_0_SET_BASE /* Decode Protection-0 Set Reg */
58 orr w0, w0, #1 << 3 /* DCFG_RESET is accessible from NS world */
65 #ifdef CONFIG_FSL_TZASC_400
67 * a. We use only Region0 whose global secure write/read is EN
68 * b. We use only Region0 whose NSAID write/read is EN
70 * NOTE: As per the CCSR map doc, TZASC 3 and TZASC 4 are just
73 ldr x1, =TZASC_GATE_KEEPER(0)
74 ldr x0, [x1] /* Filter 0 Gate Keeper Register */
75 orr x0, x0, #1 << 0 /* Set open_request for Filter 0 */
78 ldr x1, =TZASC_GATE_KEEPER(1)
79 ldr x0, [x1] /* Filter 0 Gate Keeper Register */
80 orr x0, x0, #1 << 0 /* Set open_request for Filter 0 */
83 ldr x1, =TZASC_REGION_ATTRIBUTES_0(0)
84 ldr x0, [x1] /* Region-0 Attributes Register */
85 orr x0, x0, #1 << 31 /* Set Sec global write en, Bit[31] */
86 orr x0, x0, #1 << 30 /* Set Sec global read en, Bit[30] */
89 ldr x1, =TZASC_REGION_ATTRIBUTES_0(1)
90 ldr x0, [x1] /* Region-1 Attributes Register */
91 orr x0, x0, #1 << 31 /* Set Sec global write en, Bit[31] */
92 orr x0, x0, #1 << 30 /* Set Sec global read en, Bit[30] */
95 ldr x1, =TZASC_REGION_ID_ACCESS_0(0)
96 ldr w0, [x1] /* Region-0 Access Register */
97 mov w0, #0xFFFFFFFF /* Set nsaid_wr_en and nsaid_rd_en */
100 ldr x1, =TZASC_REGION_ID_ACCESS_0(1)
101 ldr w0, [x1] /* Region-1 Attributes Register */
102 mov w0, #0xFFFFFFFF /* Set nsaid_wr_en and nsaid_rd_en */
108 mov lr, x29 /* Restore LR */
110 ENDPROC(lowlevel_init)
113 /* x0 has the desired status, return 0 for success, 1 for timeout
114 * clobber x1, x2, x3, x4, x6, x7
117 mov x7, #0 /* flag for timeout */
118 mrs x3, cntpct_el0 /* read timer */
119 add x3, x3, #1200 /* timeout after 100 microseconds */
121 movk x0, #0x420, lsl #16 /* HNF0_PSTATE_STATUS */
122 mov w6, #8 /* HN-F node count */
125 cmp x2, x1 /* check status */
130 mov x7, #1 /* timeout */
133 add x0, x0, #0x10000 /* move to next node */
141 /* x0 has the desired state, clobber x1, x2, x6 */
143 /* power state to SFONLY */
144 mov w6, #8 /* HN-F node count */
146 movk x0, #0x420, lsl #16 /* HNF0_PSTATE_REQ */
147 1: /* set pstate to sfonly */
149 and x2, x2, #0xfffffffffffffffc /* & HNFPSTAT_MASK */
152 add x0, x0, #0x10000 /* move to next node */
158 ENTRY(__asm_flush_l3_cache)
160 * Return status in x0
162 * tmeout 1 for setting SFONLY, 2 for FAM, 3 for both
168 mov x0, #0x1 /* HNFPSTAT_SFONLY */
171 mov x0, #0x4 /* SFONLY status */
174 mov x8, #1 /* timeout */
177 mov x0, #0x3 /* HNFPSTAT_FAM */
180 mov x0, #0xc /* FAM status */
188 ENDPROC(__asm_flush_l3_cache)
190 /* Keep literals not used by the secondary boot code outside it */
193 /* Using 64 bit alignment since the spin table is accessed as data */
195 .global secondary_boot_code
196 /* Secondary Boot Code starts here */
200 .space CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE
203 ENTRY(secondary_boot_func)
206 * MPIDR[1:0] = AFF0_CPUID <- Core ID (0,1)
207 * MPIDR[7:2] = AFF0_RES
208 * MPIDR[15:8] = AFF1_CLUSTERID <- Cluster ID (0,1,2,3)
209 * MPIDR[23:16] = AFF2_CLUSTERID
211 * MPIDR[29:25] = RES0
214 * MPIDR[39:32] = AFF3
216 * Linear Processor ID (LPID) calculation from MPIDR_EL1:
217 * (We only use AFF0_CPUID and AFF1_CLUSTERID for now
218 * until AFF2_CLUSTERID and AFF3 have non-zero values)
220 * LPID = MPIDR[15:8] | MPIDR[1:0]
225 orr x10, x2, x1, lsl #2 /* x10 has LPID */
226 ubfm x9, x0, #0, #15 /* x9 contains MPIDR[15:0] */
228 * offset of the spin table element for this core from start of spin
229 * table (each elem is padded to 64 bytes)
232 ldr x0, =__spin_table
233 /* physical address of this cpus spin table element */
236 ldr x0, =__real_cntfrq
238 msr cntfrq_el0, x0 /* set with real frequency */
239 str x9, [x11, #16] /* LPID */
241 str x4, [x11, #8] /* STATUS */
243 #if defined(CONFIG_GICV3)
244 gic_wait_for_interrupt_m x0
245 #elif defined(CONFIG_GICV2)
247 gic_wait_for_interrupt_m x0, w1
250 bl secondary_switch_to_el2
251 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
252 bl secondary_switch_to_el1
259 #ifndef CONFIG_ARMV8_SWITCH_TO_EL1
264 tbz x1, #25, cpu_is_le
265 rev x0, x0 /* BE to LE conversion */
267 br x0 /* branch to the given address */
268 ENDPROC(secondary_boot_func)
270 ENTRY(secondary_switch_to_el2)
271 switch_el x0, 1f, 0f, 0f
273 1: armv8_switch_to_el2_m x0
274 ENDPROC(secondary_switch_to_el2)
276 ENTRY(secondary_switch_to_el1)
277 switch_el x0, 0f, 1f, 0f
279 1: armv8_switch_to_el1_m x0, x1
280 ENDPROC(secondary_switch_to_el1)
282 /* Ensure that the literals used by the secondary boot code are
283 * assembled within it (this is required so that we can protect
284 * this area with a single memreserve region
288 /* 64 bit alignment for elements accessed as data */
290 .global __real_cntfrq
292 .quad COUNTER_FREQUENCY
293 .globl __secondary_boot_code_size
294 .type __secondary_boot_code_size, %object
295 /* Secondary Boot Code ends here */
296 __secondary_boot_code_size:
297 .quad .-secondary_boot_code