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