1/* 2 * (C) Copyright 2014-2015 Freescale Semiconductor 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> 11#include <asm/gic.h> 12#include <asm/macro.h> 13#ifdef CONFIG_MP 14#include <asm/arch/mp.h> 15#endif 16 17ENTRY(lowlevel_init) 18 mov x29, lr /* Save LR */ 19 20#ifdef CONFIG_FSL_LSCH3 21 /* Add fully-coherent masters to DVM domain */ 22 ldr x0, =CCI_MN_BASE 23 ldr x1, =CCI_MN_RNF_NODEID_LIST 24 ldr x2, =CCI_MN_DVM_DOMAIN_CTL_SET 25 bl ccn504_add_masters_to_dvm 26 27 /* Set all RN-I ports to QoS of 15 */ 28 ldr x0, =CCI_S0_QOS_CONTROL_BASE(0) 29 ldr x1, =0x00FF000C 30 bl ccn504_set_qos 31 ldr x0, =CCI_S1_QOS_CONTROL_BASE(0) 32 ldr x1, =0x00FF000C 33 bl ccn504_set_qos 34 ldr x0, =CCI_S2_QOS_CONTROL_BASE(0) 35 ldr x1, =0x00FF000C 36 bl ccn504_set_qos 37 38 ldr x0, =CCI_S0_QOS_CONTROL_BASE(2) 39 ldr x1, =0x00FF000C 40 bl ccn504_set_qos 41 ldr x0, =CCI_S1_QOS_CONTROL_BASE(2) 42 ldr x1, =0x00FF000C 43 bl ccn504_set_qos 44 ldr x0, =CCI_S2_QOS_CONTROL_BASE(2) 45 ldr x1, =0x00FF000C 46 bl ccn504_set_qos 47 48 ldr x0, =CCI_S0_QOS_CONTROL_BASE(6) 49 ldr x1, =0x00FF000C 50 bl ccn504_set_qos 51 ldr x0, =CCI_S1_QOS_CONTROL_BASE(6) 52 ldr x1, =0x00FF000C 53 bl ccn504_set_qos 54 ldr x0, =CCI_S2_QOS_CONTROL_BASE(6) 55 ldr x1, =0x00FF000C 56 bl ccn504_set_qos 57 58 ldr x0, =CCI_S0_QOS_CONTROL_BASE(12) 59 ldr x1, =0x00FF000C 60 bl ccn504_set_qos 61 ldr x0, =CCI_S1_QOS_CONTROL_BASE(12) 62 ldr x1, =0x00FF000C 63 bl ccn504_set_qos 64 ldr x0, =CCI_S2_QOS_CONTROL_BASE(12) 65 ldr x1, =0x00FF000C 66 bl ccn504_set_qos 67 68 ldr x0, =CCI_S0_QOS_CONTROL_BASE(16) 69 ldr x1, =0x00FF000C 70 bl ccn504_set_qos 71 ldr x0, =CCI_S1_QOS_CONTROL_BASE(16) 72 ldr x1, =0x00FF000C 73 bl ccn504_set_qos 74 ldr x0, =CCI_S2_QOS_CONTROL_BASE(16) 75 ldr x1, =0x00FF000C 76 bl ccn504_set_qos 77 78 ldr x0, =CCI_S0_QOS_CONTROL_BASE(20) 79 ldr x1, =0x00FF000C 80 bl ccn504_set_qos 81 ldr x0, =CCI_S1_QOS_CONTROL_BASE(20) 82 ldr x1, =0x00FF000C 83 bl ccn504_set_qos 84 ldr x0, =CCI_S2_QOS_CONTROL_BASE(20) 85 ldr x1, =0x00FF000C 86 bl ccn504_set_qos 87#endif 88 89 /* Set the SMMU page size in the sACR register */ 90 ldr x1, =SMMU_BASE 91 ldr w0, [x1, #0x10] 92 orr w0, w0, #1 << 16 /* set sACR.pagesize to indicate 64K page */ 93 str w0, [x1, #0x10] 94 95 /* Initialize GIC Secure Bank Status */ 96#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3) 97 branch_if_slave x0, 1f 98 ldr x0, =GICD_BASE 99 bl gic_init_secure 1001: 101#ifdef CONFIG_GICV3 102 ldr x0, =GICR_BASE 103 bl gic_init_secure_percpu 104#elif defined(CONFIG_GICV2) 105 ldr x0, =GICD_BASE 106 ldr x1, =GICC_BASE 107 bl gic_init_secure_percpu 108#endif 109#endif 110 111 branch_if_master x0, x1, 2f 112 113#if defined(CONFIG_MP) && defined(CONFIG_ARMV8_MULTIENTRY) 114 ldr x0, =secondary_boot_func 115 blr x0 116#endif 117 1182: 119#ifdef CONFIG_FSL_TZPC_BP147 120 /* Set Non Secure access for all devices protected via TZPC */ 121 ldr x1, =TZPCDECPROT_0_SET_BASE /* Decode Protection-0 Set Reg */ 122 orr w0, w0, #1 << 3 /* DCFG_RESET is accessible from NS world */ 123 str w0, [x1] 124 125 isb 126 dsb sy 127#endif 128 129#ifdef CONFIG_FSL_TZASC_400 130 /* Set TZASC so that: 131 * a. We use only Region0 whose global secure write/read is EN 132 * b. We use only Region0 whose NSAID write/read is EN 133 * 134 * NOTE: As per the CCSR map doc, TZASC 3 and TZASC 4 are just 135 * placeholders. 136 */ 137 ldr x1, =TZASC_GATE_KEEPER(0) 138 ldr x0, [x1] /* Filter 0 Gate Keeper Register */ 139 orr x0, x0, #1 << 0 /* Set open_request for Filter 0 */ 140 str x0, [x1] 141 142 ldr x1, =TZASC_GATE_KEEPER(1) 143 ldr x0, [x1] /* Filter 0 Gate Keeper Register */ 144 orr x0, x0, #1 << 0 /* Set open_request for Filter 0 */ 145 str x0, [x1] 146 147 ldr x1, =TZASC_REGION_ATTRIBUTES_0(0) 148 ldr x0, [x1] /* Region-0 Attributes Register */ 149 orr x0, x0, #1 << 31 /* Set Sec global write en, Bit[31] */ 150 orr x0, x0, #1 << 30 /* Set Sec global read en, Bit[30] */ 151 str x0, [x1] 152 153 ldr x1, =TZASC_REGION_ATTRIBUTES_0(1) 154 ldr x0, [x1] /* Region-1 Attributes Register */ 155 orr x0, x0, #1 << 31 /* Set Sec global write en, Bit[31] */ 156 orr x0, x0, #1 << 30 /* Set Sec global read en, Bit[30] */ 157 str x0, [x1] 158 159 ldr x1, =TZASC_REGION_ID_ACCESS_0(0) 160 ldr w0, [x1] /* Region-0 Access Register */ 161 mov w0, #0xFFFFFFFF /* Set nsaid_wr_en and nsaid_rd_en */ 162 str w0, [x1] 163 164 ldr x1, =TZASC_REGION_ID_ACCESS_0(1) 165 ldr w0, [x1] /* Region-1 Attributes Register */ 166 mov w0, #0xFFFFFFFF /* Set nsaid_wr_en and nsaid_rd_en */ 167 str w0, [x1] 168 169 isb 170 dsb sy 171#endif 172 mov lr, x29 /* Restore LR */ 173 ret 174ENDPROC(lowlevel_init) 175 176hnf_pstate_poll: 177 /* x0 has the desired status, return 0 for success, 1 for timeout 178 * clobber x1, x2, x3, x4, x6, x7 179 */ 180 mov x1, x0 181 mov x7, #0 /* flag for timeout */ 182 mrs x3, cntpct_el0 /* read timer */ 183 add x3, x3, #1200 /* timeout after 100 microseconds */ 184 mov x0, #0x18 185 movk x0, #0x420, lsl #16 /* HNF0_PSTATE_STATUS */ 186 mov w6, #8 /* HN-F node count */ 1871: 188 ldr x2, [x0] 189 cmp x2, x1 /* check status */ 190 b.eq 2f 191 mrs x4, cntpct_el0 192 cmp x4, x3 193 b.ls 1b 194 mov x7, #1 /* timeout */ 195 b 3f 1962: 197 add x0, x0, #0x10000 /* move to next node */ 198 subs w6, w6, #1 199 cbnz w6, 1b 2003: 201 mov x0, x7 202 ret 203 204hnf_set_pstate: 205 /* x0 has the desired state, clobber x1, x2, x6 */ 206 mov x1, x0 207 /* power state to SFONLY */ 208 mov w6, #8 /* HN-F node count */ 209 mov x0, #0x10 210 movk x0, #0x420, lsl #16 /* HNF0_PSTATE_REQ */ 2111: /* set pstate to sfonly */ 212 ldr x2, [x0] 213 and x2, x2, #0xfffffffffffffffc /* & HNFPSTAT_MASK */ 214 orr x2, x2, x1 215 str x2, [x0] 216 add x0, x0, #0x10000 /* move to next node */ 217 subs w6, w6, #1 218 cbnz w6, 1b 219 220 ret 221 222ENTRY(__asm_flush_l3_cache) 223 /* 224 * Return status in x0 225 * success 0 226 * tmeout 1 for setting SFONLY, 2 for FAM, 3 for both 227 */ 228 mov x29, lr 229 mov x8, #0 230 231 dsb sy 232 mov x0, #0x1 /* HNFPSTAT_SFONLY */ 233 bl hnf_set_pstate 234 235 mov x0, #0x4 /* SFONLY status */ 236 bl hnf_pstate_poll 237 cbz x0, 1f 238 mov x8, #1 /* timeout */ 2391: 240 dsb sy 241 mov x0, #0x3 /* HNFPSTAT_FAM */ 242 bl hnf_set_pstate 243 244 mov x0, #0xc /* FAM status */ 245 bl hnf_pstate_poll 246 cbz x0, 1f 247 add x8, x8, #0x2 2481: 249 mov x0, x8 250 mov lr, x29 251 ret 252ENDPROC(__asm_flush_l3_cache) 253 254#ifdef CONFIG_MP 255 /* Keep literals not used by the secondary boot code outside it */ 256 .ltorg 257 258 /* Using 64 bit alignment since the spin table is accessed as data */ 259 .align 4 260 .global secondary_boot_code 261 /* Secondary Boot Code starts here */ 262secondary_boot_code: 263 .global __spin_table 264__spin_table: 265 .space CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE 266 267 .align 2 268ENTRY(secondary_boot_func) 269 /* 270 * MPIDR_EL1 Fields: 271 * MPIDR[1:0] = AFF0_CPUID <- Core ID (0,1) 272 * MPIDR[7:2] = AFF0_RES 273 * MPIDR[15:8] = AFF1_CLUSTERID <- Cluster ID (0,1,2,3) 274 * MPIDR[23:16] = AFF2_CLUSTERID 275 * MPIDR[24] = MT 276 * MPIDR[29:25] = RES0 277 * MPIDR[30] = U 278 * MPIDR[31] = ME 279 * MPIDR[39:32] = AFF3 280 * 281 * Linear Processor ID (LPID) calculation from MPIDR_EL1: 282 * (We only use AFF0_CPUID and AFF1_CLUSTERID for now 283 * until AFF2_CLUSTERID and AFF3 have non-zero values) 284 * 285 * LPID = MPIDR[15:8] | MPIDR[1:0] 286 */ 287 mrs x0, mpidr_el1 288 ubfm x1, x0, #8, #15 289 ubfm x2, x0, #0, #1 290 orr x10, x2, x1, lsl #2 /* x10 has LPID */ 291 ubfm x9, x0, #0, #15 /* x9 contains MPIDR[15:0] */ 292 /* 293 * offset of the spin table element for this core from start of spin 294 * table (each elem is padded to 64 bytes) 295 */ 296 lsl x1, x10, #6 297 ldr x0, =__spin_table 298 /* physical address of this cpus spin table element */ 299 add x11, x1, x0 300 301 ldr x0, =__real_cntfrq 302 ldr x0, [x0] 303 msr cntfrq_el0, x0 /* set with real frequency */ 304 str x9, [x11, #16] /* LPID */ 305 mov x4, #1 306 str x4, [x11, #8] /* STATUS */ 307 dsb sy 308#if defined(CONFIG_GICV3) 309 gic_wait_for_interrupt_m x0 310#elif defined(CONFIG_GICV2) 311 ldr x0, =GICC_BASE 312 gic_wait_for_interrupt_m x0, w1 313#endif 314 315 bl secondary_switch_to_el2 316#ifdef CONFIG_ARMV8_SWITCH_TO_EL1 317 bl secondary_switch_to_el1 318#endif 319 320slave_cpu: 321 wfe 322 ldr x0, [x11] 323 cbz x0, slave_cpu 324#ifndef CONFIG_ARMV8_SWITCH_TO_EL1 325 mrs x1, sctlr_el2 326#else 327 mrs x1, sctlr_el1 328#endif 329 tbz x1, #25, cpu_is_le 330 rev x0, x0 /* BE to LE conversion */ 331cpu_is_le: 332 br x0 /* branch to the given address */ 333ENDPROC(secondary_boot_func) 334 335ENTRY(secondary_switch_to_el2) 336 switch_el x0, 1f, 0f, 0f 3370: ret 3381: armv8_switch_to_el2_m x0 339ENDPROC(secondary_switch_to_el2) 340 341ENTRY(secondary_switch_to_el1) 342 switch_el x0, 0f, 1f, 0f 3430: ret 3441: armv8_switch_to_el1_m x0, x1 345ENDPROC(secondary_switch_to_el1) 346 347 /* Ensure that the literals used by the secondary boot code are 348 * assembled within it (this is required so that we can protect 349 * this area with a single memreserve region 350 */ 351 .ltorg 352 353 /* 64 bit alignment for elements accessed as data */ 354 .align 4 355 .global __real_cntfrq 356__real_cntfrq: 357 .quad COUNTER_FREQUENCY 358 .globl __secondary_boot_code_size 359 .type __secondary_boot_code_size, %object 360 /* Secondary Boot Code ends here */ 361__secondary_boot_code_size: 362 .quad .-secondary_boot_code 363#endif 364