1/* 2 * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6#include <arch.h> 7#include <asm_macros.S> 8#include <assert_macros.S> 9#include <cpu_macros.S> 10#include <cortex_a57.h> 11#include <cortex_a53.h> 12#include <platform_def.h> 13#include <tegra_def.h> 14 15#define MIDR_PN_CORTEX_A57 0xD07 16 17/******************************************************************************* 18 * Implementation defined ACTLR_EL3 bit definitions 19 ******************************************************************************/ 20#define ACTLR_EL3_L2ACTLR_BIT (1 << 6) 21#define ACTLR_EL3_L2ECTLR_BIT (1 << 5) 22#define ACTLR_EL3_L2CTLR_BIT (1 << 4) 23#define ACTLR_EL3_CPUECTLR_BIT (1 << 1) 24#define ACTLR_EL3_CPUACTLR_BIT (1 << 0) 25#define ACTLR_EL3_ENABLE_ALL_ACCESS (ACTLR_EL3_L2ACTLR_BIT | \ 26 ACTLR_EL3_L2ECTLR_BIT | \ 27 ACTLR_EL3_L2CTLR_BIT | \ 28 ACTLR_EL3_CPUECTLR_BIT | \ 29 ACTLR_EL3_CPUACTLR_BIT) 30 31 /* Global functions */ 32 .globl plat_is_my_cpu_primary 33 .globl plat_my_core_pos 34 .globl plat_get_my_entrypoint 35 .globl plat_secondary_cold_boot_setup 36 .globl platform_mem_init 37 .globl plat_crash_console_init 38 .globl plat_crash_console_putc 39 .globl tegra_secure_entrypoint 40 .globl plat_reset_handler 41 42 /* Global variables */ 43 .globl tegra_sec_entry_point 44 .globl ns_image_entrypoint 45 .globl tegra_bl31_phys_base 46 .globl tegra_console_base 47 .globl tegra_enable_l2_ecc_parity_prot 48 49 /* --------------------- 50 * Common CPU init code 51 * --------------------- 52 */ 53.macro cpu_init_common 54 55 /* ------------------------------------------------ 56 * We enable procesor retention, L2/CPUECTLR NS 57 * access and ECC/Parity protection for A57 CPUs 58 * ------------------------------------------------ 59 */ 60 mrs x0, midr_el1 61 mov x1, #(MIDR_PN_MASK << MIDR_PN_SHIFT) 62 and x0, x0, x1 63 lsr x0, x0, #MIDR_PN_SHIFT 64 cmp x0, #MIDR_PN_CORTEX_A57 65 b.ne 1f 66 67 /* --------------------------- 68 * Enable processor retention 69 * --------------------------- 70 */ 71 mrs x0, L2ECTLR_EL1 72 mov x1, #RETENTION_ENTRY_TICKS_512 << L2ECTLR_RET_CTRL_SHIFT 73 bic x0, x0, #L2ECTLR_RET_CTRL_MASK 74 orr x0, x0, x1 75 msr L2ECTLR_EL1, x0 76 isb 77 78 mrs x0, CPUECTLR_EL1 79 mov x1, #RETENTION_ENTRY_TICKS_512 << CPUECTLR_CPU_RET_CTRL_SHIFT 80 bic x0, x0, #CPUECTLR_CPU_RET_CTRL_MASK 81 orr x0, x0, x1 82 msr CPUECTLR_EL1, x0 83 isb 84 85 /* ------------------------------------------------------- 86 * Enable L2 and CPU ECTLR RW access from non-secure world 87 * ------------------------------------------------------- 88 */ 89 mov x0, #ACTLR_EL3_ENABLE_ALL_ACCESS 90 msr actlr_el3, x0 91 msr actlr_el2, x0 92 isb 93 94 /* ------------------------------------------------------- 95 * Enable L2 ECC and Parity Protection 96 * ------------------------------------------------------- 97 */ 98 adr x0, tegra_enable_l2_ecc_parity_prot 99 ldr x0, [x0] 100 cbz x0, 1f 101 mrs x0, L2CTLR_EL1 102 and x1, x0, #L2_ECC_PARITY_PROTECTION_BIT 103 cbnz x1, 1f 104 orr x0, x0, #L2_ECC_PARITY_PROTECTION_BIT 105 msr L2CTLR_EL1, x0 106 isb 107 108 /* -------------------------------- 109 * Enable the cycle count register 110 * -------------------------------- 111 */ 1121: mrs x0, pmcr_el0 113 ubfx x0, x0, #11, #5 // read PMCR.N field 114 mov x1, #1 115 lsl x0, x1, x0 116 sub x0, x0, #1 // mask of event counters 117 orr x0, x0, #0x80000000 // disable overflow intrs 118 msr pmintenclr_el1, x0 119 msr pmuserenr_el0, x1 // enable user mode access 120 121 /* ---------------------------------------------------------------- 122 * Allow non-privileged access to CNTVCT: Set CNTKCTL (Kernel Count 123 * register), bit 1 (EL0VCTEN) to enable access to CNTVCT/CNTFRQ 124 * registers from EL0. 125 * ---------------------------------------------------------------- 126 */ 127 mrs x0, cntkctl_el1 128 orr x0, x0, #EL0VCTEN_BIT 129 msr cntkctl_el1, x0 130.endm 131 132 /* ----------------------------------------------------- 133 * unsigned int plat_is_my_cpu_primary(void); 134 * 135 * This function checks if this is the Primary CPU 136 * ----------------------------------------------------- 137 */ 138func plat_is_my_cpu_primary 139 mrs x0, mpidr_el1 140 and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) 141 cmp x0, #TEGRA_PRIMARY_CPU 142 cset x0, eq 143 ret 144endfunc plat_is_my_cpu_primary 145 146 /* ----------------------------------------------------- 147 * unsigned int plat_my_core_pos(void); 148 * 149 * result: CorePos = CoreId + (ClusterId << 2) 150 * ----------------------------------------------------- 151 */ 152func plat_my_core_pos 153 mrs x0, mpidr_el1 154 and x1, x0, #MPIDR_CPU_MASK 155 and x0, x0, #MPIDR_CLUSTER_MASK 156 add x0, x1, x0, LSR #6 157 ret 158endfunc plat_my_core_pos 159 160 /* ----------------------------------------------------- 161 * unsigned long plat_get_my_entrypoint (void); 162 * 163 * Main job of this routine is to distinguish between 164 * a cold and warm boot. If the tegra_sec_entry_point for 165 * this CPU is present, then it's a warm boot. 166 * 167 * ----------------------------------------------------- 168 */ 169func plat_get_my_entrypoint 170 adr x1, tegra_sec_entry_point 171 ldr x0, [x1] 172 ret 173endfunc plat_get_my_entrypoint 174 175 /* ----------------------------------------------------- 176 * int platform_get_core_pos(int mpidr); 177 * 178 * With this function: CorePos = (ClusterId * 4) + 179 * CoreId 180 * ----------------------------------------------------- 181 */ 182func platform_get_core_pos 183 and x1, x0, #MPIDR_CPU_MASK 184 and x0, x0, #MPIDR_CLUSTER_MASK 185 add x0, x1, x0, LSR #6 186 ret 187endfunc platform_get_core_pos 188 189 /* ----------------------------------------------------- 190 * void plat_secondary_cold_boot_setup (void); 191 * 192 * This function performs any platform specific actions 193 * needed for a secondary cpu after a cold reset. Right 194 * now this is a stub function. 195 * ----------------------------------------------------- 196 */ 197func plat_secondary_cold_boot_setup 198 mov x0, #0 199 ret 200endfunc plat_secondary_cold_boot_setup 201 202 /* -------------------------------------------------------- 203 * void platform_mem_init (void); 204 * 205 * Any memory init, relocation to be done before the 206 * platform boots. Called very early in the boot process. 207 * -------------------------------------------------------- 208 */ 209func platform_mem_init 210 mov x0, #0 211 ret 212endfunc platform_mem_init 213 214 /* --------------------------------------------- 215 * int plat_crash_console_init(void) 216 * Function to initialize the crash console 217 * without a C Runtime to print crash report. 218 * Clobber list : x0 - x4 219 * --------------------------------------------- 220 */ 221func plat_crash_console_init 222 mov x0, #0 223 adr x1, tegra_console_base 224 ldr x1, [x1] 225 cbz x1, 1f 226 mov w0, #1 2271: ret 228endfunc plat_crash_console_init 229 230 /* --------------------------------------------- 231 * int plat_crash_console_putc(void) 232 * Function to print a character on the crash 233 * console without a C Runtime. 234 * Clobber list : x1, x2 235 * --------------------------------------------- 236 */ 237func plat_crash_console_putc 238 adr x1, tegra_console_base 239 ldr x1, [x1] 240 b console_core_putc 241endfunc plat_crash_console_putc 242 243 /* --------------------------------------------------- 244 * Function to handle a platform reset and store 245 * input parameters passed by BL2. 246 * --------------------------------------------------- 247 */ 248func plat_reset_handler 249 250 /* ---------------------------------------------------- 251 * Verify if we are running from BL31_BASE address 252 * ---------------------------------------------------- 253 */ 254 adr x18, bl31_entrypoint 255 mov x17, #BL31_BASE 256 cmp x18, x17 257 b.eq 1f 258 259 /* ---------------------------------------------------- 260 * Copy the entire BL31 code to BL31_BASE if we are not 261 * running from it already 262 * ---------------------------------------------------- 263 */ 264 mov x0, x17 265 mov x1, x18 266 mov x2, #BL31_SIZE 267_loop16: 268 cmp x2, #16 269 b.lo _loop1 270 ldp x3, x4, [x1], #16 271 stp x3, x4, [x0], #16 272 sub x2, x2, #16 273 b _loop16 274 /* copy byte per byte */ 275_loop1: 276 cbz x2, _end 277 ldrb w3, [x1], #1 278 strb w3, [x0], #1 279 subs x2, x2, #1 280 b.ne _loop1 281 282 /* ---------------------------------------------------- 283 * Jump to BL31_BASE and start execution again 284 * ---------------------------------------------------- 285 */ 286_end: mov x0, x20 287 mov x1, x21 288 br x17 2891: 290 291 /* ----------------------------------- 292 * derive and save the phys_base addr 293 * ----------------------------------- 294 */ 295 adr x17, tegra_bl31_phys_base 296 ldr x18, [x17] 297 cbnz x18, 1f 298 adr x18, bl31_entrypoint 299 str x18, [x17] 300 3011: cpu_init_common 302 303 ret 304endfunc plat_reset_handler 305 306 /* ---------------------------------------- 307 * Secure entrypoint function for CPU boot 308 * ---------------------------------------- 309 */ 310 .align 6 311func tegra_secure_entrypoint 312 313#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT 314 315 /* ------------------------------------------------------- 316 * Invalidate BTB along with I$ to remove any stale 317 * entries from the branch predictor array. 318 * ------------------------------------------------------- 319 */ 320 mrs x0, CPUACTLR_EL1 321 orr x0, x0, #1 322 msr CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */ 323 dsb sy 324 isb 325 ic iallu /* actual invalidate */ 326 dsb sy 327 isb 328 329 mrs x0, CPUACTLR_EL1 330 bic x0, x0, #1 331 msr CPUACTLR_EL1, X0 /* restore original CPUACTLR_EL1 */ 332 dsb sy 333 isb 334 335 .rept 7 336 nop /* wait */ 337 .endr 338 339 /* ----------------------------------------------- 340 * Extract OSLK bit and check if it is '1'. This 341 * bit remains '0' for A53 on warm-resets. If '1', 342 * turn off regional clock gating and request warm 343 * reset. 344 * ----------------------------------------------- 345 */ 346 mrs x0, oslsr_el1 347 and x0, x0, #2 348 mrs x1, mpidr_el1 349 bics xzr, x0, x1, lsr #7 /* 0 = slow cluster or warm reset */ 350 b.eq restore_oslock 351 mov x0, xzr 352 msr oslar_el1, x0 /* os lock stays 0 across warm reset */ 353 mov x3, #3 354 movz x4, #0x8000, lsl #48 355 msr CPUACTLR_EL1, x4 /* turn off RCG */ 356 isb 357 msr rmr_el3, x3 /* request warm reset */ 358 isb 359 dsb sy 3601: wfi 361 b 1b 362 363 /* -------------------------------------------------- 364 * These nops are here so that speculative execution 365 * won't harm us before we are done with warm reset. 366 * -------------------------------------------------- 367 */ 368 .rept 65 369 nop 370 .endr 371 372 /* -------------------------------------------------- 373 * Do not insert instructions here 374 * -------------------------------------------------- 375 */ 376#endif 377 378 /* -------------------------------------------------- 379 * Restore OS Lock bit 380 * -------------------------------------------------- 381 */ 382restore_oslock: 383 mov x0, #1 384 msr oslar_el1, x0 385 386 cpu_init_common 387 388 /* --------------------------------------------------------------------- 389 * The initial state of the Architectural feature trap register 390 * (CPTR_EL3) is unknown and it must be set to a known state. All 391 * feature traps are disabled. Some bits in this register are marked as 392 * Reserved and should not be modified. 393 * 394 * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1 395 * or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2. 396 * CPTR_EL3.TTA: This causes access to the Trace functionality to trap 397 * to EL3 when executed from EL0, EL1, EL2, or EL3. If system register 398 * access to trace functionality is not supported, this bit is RES0. 399 * CPTR_EL3.TFP: This causes instructions that access the registers 400 * associated with Floating Point and Advanced SIMD execution to trap 401 * to EL3 when executed from any exception level, unless trapped to EL1 402 * or EL2. 403 * --------------------------------------------------------------------- 404 */ 405 mrs x1, cptr_el3 406 bic w1, w1, #TCPAC_BIT 407 bic w1, w1, #TTA_BIT 408 bic w1, w1, #TFP_BIT 409 msr cptr_el3, x1 410 411 /* -------------------------------------------------- 412 * Get secure world's entry point and jump to it 413 * -------------------------------------------------- 414 */ 415 bl plat_get_my_entrypoint 416 br x0 417endfunc tegra_secure_entrypoint 418 419 .data 420 .align 3 421 422 /* -------------------------------------------------- 423 * CPU Secure entry point - resume from suspend 424 * -------------------------------------------------- 425 */ 426tegra_sec_entry_point: 427 .quad 0 428 429 /* -------------------------------------------------- 430 * NS world's cold boot entry point 431 * -------------------------------------------------- 432 */ 433ns_image_entrypoint: 434 .quad 0 435 436 /* -------------------------------------------------- 437 * BL31's physical base address 438 * -------------------------------------------------- 439 */ 440tegra_bl31_phys_base: 441 .quad 0 442 443 /* -------------------------------------------------- 444 * UART controller base for console init 445 * -------------------------------------------------- 446 */ 447tegra_console_base: 448 .quad 0 449 450 /* -------------------------------------------------- 451 * Enable L2 ECC and Parity Protection 452 * -------------------------------------------------- 453 */ 454tegra_enable_l2_ecc_parity_prot: 455 .quad 0 456