1/* 2 * Copyright (c) 2015-2017, 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_a53.h> 11#include <cortex_a57.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, CORTEX_A57_L2ECTLR_EL1 72 mov x1, #RETENTION_ENTRY_TICKS_512 73 bic x0, x0, #CORTEX_A57_L2ECTLR_RET_CTRL_MASK 74 orr x0, x0, x1 75 msr CORTEX_A57_L2ECTLR_EL1, x0 76 isb 77 78 mrs x0, CORTEX_A57_ECTLR_EL1 79 mov x1, #RETENTION_ENTRY_TICKS_512 80 bic x0, x0, #CORTEX_A57_ECTLR_CPU_RET_CTRL_MASK 81 orr x0, x0, x1 82 msr CORTEX_A57_ECTLR_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, CORTEX_A57_L2CTLR_EL1 102 and x1, x0, #CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT 103 cbnz x1, 1f 104 orr x0, x0, #CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT 105 msr CORTEX_A57_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 */ 310func tegra_secure_entrypoint _align=6 311 312#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT 313 314 /* ------------------------------------------------------- 315 * Invalidate BTB along with I$ to remove any stale 316 * entries from the branch predictor array. 317 * ------------------------------------------------------- 318 */ 319 mrs x0, CORTEX_A57_CPUACTLR_EL1 320 orr x0, x0, #1 321 msr CORTEX_A57_CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */ 322 dsb sy 323 isb 324 ic iallu /* actual invalidate */ 325 dsb sy 326 isb 327 328 mrs x0, CORTEX_A57_CPUACTLR_EL1 329 bic x0, x0, #1 330 msr CORTEX_A57_CPUACTLR_EL1, X0 /* restore original CPUACTLR_EL1 */ 331 dsb sy 332 isb 333 334 .rept 7 335 nop /* wait */ 336 .endr 337 338 /* ----------------------------------------------- 339 * Extract OSLK bit and check if it is '1'. This 340 * bit remains '0' for A53 on warm-resets. If '1', 341 * turn off regional clock gating and request warm 342 * reset. 343 * ----------------------------------------------- 344 */ 345 mrs x0, oslsr_el1 346 and x0, x0, #2 347 mrs x1, mpidr_el1 348 bics xzr, x0, x1, lsr #7 /* 0 = slow cluster or warm reset */ 349 b.eq restore_oslock 350 mov x0, xzr 351 msr oslar_el1, x0 /* os lock stays 0 across warm reset */ 352 mov x3, #3 353 movz x4, #0x8000, lsl #48 354 msr CORTEX_A57_CPUACTLR_EL1, x4 /* turn off RCG */ 355 isb 356 msr rmr_el3, x3 /* request warm reset */ 357 isb 358 dsb sy 3591: wfi 360 b 1b 361 362 /* -------------------------------------------------- 363 * These nops are here so that speculative execution 364 * won't harm us before we are done with warm reset. 365 * -------------------------------------------------- 366 */ 367 .rept 65 368 nop 369 .endr 370 371 /* -------------------------------------------------- 372 * Do not insert instructions here 373 * -------------------------------------------------- 374 */ 375#endif 376 377 /* -------------------------------------------------- 378 * Restore OS Lock bit 379 * -------------------------------------------------- 380 */ 381restore_oslock: 382 mov x0, #1 383 msr oslar_el1, x0 384 385 cpu_init_common 386 387 /* --------------------------------------------------------------------- 388 * The initial state of the Architectural feature trap register 389 * (CPTR_EL3) is unknown and it must be set to a known state. All 390 * feature traps are disabled. Some bits in this register are marked as 391 * Reserved and should not be modified. 392 * 393 * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1 394 * or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2. 395 * CPTR_EL3.TTA: This causes access to the Trace functionality to trap 396 * to EL3 when executed from EL0, EL1, EL2, or EL3. If system register 397 * access to trace functionality is not supported, this bit is RES0. 398 * CPTR_EL3.TFP: This causes instructions that access the registers 399 * associated with Floating Point and Advanced SIMD execution to trap 400 * to EL3 when executed from any exception level, unless trapped to EL1 401 * or EL2. 402 * --------------------------------------------------------------------- 403 */ 404 mrs x1, cptr_el3 405 bic w1, w1, #TCPAC_BIT 406 bic w1, w1, #TTA_BIT 407 bic w1, w1, #TFP_BIT 408 msr cptr_el3, x1 409 410 /* -------------------------------------------------- 411 * Get secure world's entry point and jump to it 412 * -------------------------------------------------- 413 */ 414 bl plat_get_my_entrypoint 415 br x0 416endfunc tegra_secure_entrypoint 417 418 .data 419 .align 3 420 421 /* -------------------------------------------------- 422 * CPU Secure entry point - resume from suspend 423 * -------------------------------------------------- 424 */ 425tegra_sec_entry_point: 426 .quad 0 427 428 /* -------------------------------------------------- 429 * NS world's cold boot entry point 430 * -------------------------------------------------- 431 */ 432ns_image_entrypoint: 433 .quad 0 434 435 /* -------------------------------------------------- 436 * BL31's physical base address 437 * -------------------------------------------------- 438 */ 439tegra_bl31_phys_base: 440 .quad 0 441 442 /* -------------------------------------------------- 443 * UART controller base for console init 444 * -------------------------------------------------- 445 */ 446tegra_console_base: 447 .quad 0 448 449 /* -------------------------------------------------- 450 * Enable L2 ECC and Parity Protection 451 * -------------------------------------------------- 452 */ 453tegra_enable_l2_ecc_parity_prot: 454 .quad 0 455