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