1/* 2 * Copyright (c) 2015-2019, 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 (U(1) << 6) 22#define ACTLR_EL3_L2ECTLR_BIT (U(1) << 5) 23#define ACTLR_EL3_L2CTLR_BIT (U(1) << 4) 24#define ACTLR_EL3_CPUECTLR_BIT (U(1) << 1) 25#define ACTLR_EL3_CPUACTLR_BIT (U(1) << 0) 26#define ACTLR_EL3_ENABLE_ALL_MASK (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#define ACTLR_EL3_ENABLE_ALL_ACCESS (ACTLR_EL3_L2ACTLR_BIT | \ 32 ACTLR_EL3_L2ECTLR_BIT | \ 33 ACTLR_EL3_L2CTLR_BIT | \ 34 ACTLR_EL3_CPUECTLR_BIT | \ 35 ACTLR_EL3_CPUACTLR_BIT) 36 37 /* Global functions */ 38 .globl plat_is_my_cpu_primary 39 .globl plat_my_core_pos 40 .globl plat_get_my_entrypoint 41 .globl plat_secondary_cold_boot_setup 42 .globl platform_mem_init 43 .globl plat_crash_console_init 44 .globl plat_crash_console_putc 45 .globl plat_crash_console_flush 46 .globl tegra_secure_entrypoint 47 .globl plat_reset_handler 48 49 /* Global variables */ 50 .globl tegra_sec_entry_point 51 .globl ns_image_entrypoint 52 .globl tegra_bl31_phys_base 53 .globl tegra_console_base 54 55 /* --------------------- 56 * Common CPU init code 57 * --------------------- 58 */ 59.macro cpu_init_common 60 61 /* ------------------------------------------------ 62 * We enable procesor retention, L2/CPUECTLR NS 63 * access and ECC/Parity protection for A57 CPUs 64 * ------------------------------------------------ 65 */ 66 mrs x0, midr_el1 67 mov x1, #(MIDR_PN_MASK << MIDR_PN_SHIFT) 68 and x0, x0, x1 69 lsr x0, x0, #MIDR_PN_SHIFT 70 cmp x0, #MIDR_PN_CORTEX_A57 71 b.ne 1f 72 73 /* --------------------------- 74 * Enable processor retention 75 * --------------------------- 76 */ 77 mrs x0, CORTEX_A57_L2ECTLR_EL1 78 mov x1, #RETENTION_ENTRY_TICKS_512 79 bic x0, x0, #CORTEX_A57_L2ECTLR_RET_CTRL_MASK 80 orr x0, x0, x1 81 msr CORTEX_A57_L2ECTLR_EL1, x0 82 isb 83 84 mrs x0, CORTEX_A57_ECTLR_EL1 85 mov x1, #RETENTION_ENTRY_TICKS_512 86 bic x0, x0, #CORTEX_A57_ECTLR_CPU_RET_CTRL_MASK 87 orr x0, x0, x1 88 msr CORTEX_A57_ECTLR_EL1, x0 89 isb 90 91 /* ------------------------------------------------------- 92 * Enable L2 and CPU ECTLR RW access from non-secure world 93 * ------------------------------------------------------- 94 */ 95 mrs x0, actlr_el3 96 mov x1, #ACTLR_EL3_ENABLE_ALL_MASK 97 bic x0, x0, x1 98 mov x1, #ACTLR_EL3_ENABLE_ALL_ACCESS 99 orr x0, x0, x1 100 msr actlr_el3, x0 101 mrs x0, actlr_el2 102 mov x1, #ACTLR_EL3_ENABLE_ALL_MASK 103 bic x0, x0, x1 104 mov x1, #ACTLR_EL3_ENABLE_ALL_ACCESS 105 orr x0, x0, x1 106 msr actlr_el2, 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 * cpus per cluster) 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 lsr x0, x0, #MPIDR_AFFINITY_BITS 158 mov x2, #PLATFORM_MAX_CPUS_PER_CLUSTER 159 mul x0, x0, x2 160 add x0, x1, x0 161 ret 162endfunc plat_my_core_pos 163 164 /* ----------------------------------------------------- 165 * unsigned long plat_get_my_entrypoint (void); 166 * 167 * Main job of this routine is to distinguish between 168 * a cold and warm boot. If the tegra_sec_entry_point for 169 * this CPU is present, then it's a warm boot. 170 * 171 * ----------------------------------------------------- 172 */ 173func plat_get_my_entrypoint 174 adr x1, tegra_sec_entry_point 175 ldr x0, [x1] 176 ret 177endfunc plat_get_my_entrypoint 178 179 /* ----------------------------------------------------- 180 * int platform_get_core_pos(int mpidr); 181 * 182 * result: CorePos = (ClusterId * cpus per cluster) + 183 * CoreId 184 * ----------------------------------------------------- 185 */ 186func platform_get_core_pos 187 and x1, x0, #MPIDR_CPU_MASK 188 and x0, x0, #MPIDR_CLUSTER_MASK 189 lsr x0, x0, #MPIDR_AFFINITY_BITS 190 mov x2, #PLATFORM_MAX_CPUS_PER_CLUSTER 191 mul x0, x0, x2 192 add x0, x1, x0 193 ret 194endfunc platform_get_core_pos 195 196 /* ----------------------------------------------------- 197 * void plat_secondary_cold_boot_setup (void); 198 * 199 * This function performs any platform specific actions 200 * needed for a secondary cpu after a cold reset. Right 201 * now this is a stub function. 202 * ----------------------------------------------------- 203 */ 204func plat_secondary_cold_boot_setup 205 mov x0, #0 206 ret 207endfunc plat_secondary_cold_boot_setup 208 209 /* -------------------------------------------------------- 210 * void platform_mem_init (void); 211 * 212 * Any memory init, relocation to be done before the 213 * platform boots. Called very early in the boot process. 214 * -------------------------------------------------------- 215 */ 216func platform_mem_init 217 mov x0, #0 218 ret 219endfunc platform_mem_init 220 221 /* --------------------------------------------------- 222 * Function to handle a platform reset and store 223 * input parameters passed by BL2. 224 * --------------------------------------------------- 225 */ 226func plat_reset_handler 227 228 /* ---------------------------------------------------- 229 * Verify if we are running from BL31_BASE address 230 * ---------------------------------------------------- 231 */ 232 adr x18, bl31_entrypoint 233 mov x17, #BL31_BASE 234 cmp x18, x17 235 b.eq 1f 236 237 /* ---------------------------------------------------- 238 * Copy the entire BL31 code to BL31_BASE if we are not 239 * running from it already 240 * ---------------------------------------------------- 241 */ 242 mov x0, x17 243 mov x1, x18 244 mov x2, #BL31_SIZE 245_loop16: 246 cmp x2, #16 247 b.lo _loop1 248 ldp x3, x4, [x1], #16 249 stp x3, x4, [x0], #16 250 sub x2, x2, #16 251 b _loop16 252 /* copy byte per byte */ 253_loop1: 254 cbz x2, _end 255 ldrb w3, [x1], #1 256 strb w3, [x0], #1 257 subs x2, x2, #1 258 b.ne _loop1 259 260 /* ---------------------------------------------------- 261 * Jump to BL31_BASE and start execution again 262 * ---------------------------------------------------- 263 */ 264_end: mov x0, x20 265 mov x1, x21 266 br x17 2671: 268 269 /* ----------------------------------- 270 * derive and save the phys_base addr 271 * ----------------------------------- 272 */ 273 adr x17, tegra_bl31_phys_base 274 ldr x18, [x17] 275 cbnz x18, 1f 276 adr x18, bl31_entrypoint 277 str x18, [x17] 278 2791: cpu_init_common 280 281 ret 282endfunc plat_reset_handler 283 284 /* ---------------------------------------- 285 * Secure entrypoint function for CPU boot 286 * ---------------------------------------- 287 */ 288func tegra_secure_entrypoint _align=6 289 290#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT 291 292 /* -------------------------------------------------------- 293 * Skip the invalidate BTB workaround for Tegra210B01 SKUs. 294 * -------------------------------------------------------- 295 */ 296 mov x0, #TEGRA_MISC_BASE 297 add x0, x0, #HARDWARE_REVISION_OFFSET 298 ldr w1, [x0] 299 lsr w1, w1, #CHIP_ID_SHIFT 300 and w1, w1, #CHIP_ID_MASK 301 cmp w1, #TEGRA_CHIPID_TEGRA21 /* T210? */ 302 b.ne 2f 303 ldr w1, [x0] 304 lsr w1, w1, #MAJOR_VERSION_SHIFT 305 and w1, w1, #MAJOR_VERSION_MASK 306 cmp w1, #0x02 /* T210 B01? */ 307 b.eq 2f 308 309 /* ------------------------------------------------------- 310 * Invalidate BTB along with I$ to remove any stale 311 * entries from the branch predictor array. 312 * ------------------------------------------------------- 313 */ 314 mrs x0, CORTEX_A57_CPUACTLR_EL1 315 orr x0, x0, #1 316 msr CORTEX_A57_CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */ 317 dsb sy 318 isb 319 ic iallu /* actual invalidate */ 320 dsb sy 321 isb 322 323 mrs x0, CORTEX_A57_CPUACTLR_EL1 324 bic x0, x0, #1 325 msr CORTEX_A57_CPUACTLR_EL1, X0 /* restore original CPUACTLR_EL1 */ 326 dsb sy 327 isb 328 329 .rept 7 330 nop /* wait */ 331 .endr 332 333 /* ----------------------------------------------- 334 * Extract OSLK bit and check if it is '1'. This 335 * bit remains '0' for A53 on warm-resets. If '1', 336 * turn off regional clock gating and request warm 337 * reset. 338 * ----------------------------------------------- 339 */ 340 mrs x0, oslsr_el1 341 and x0, x0, #2 342 mrs x1, mpidr_el1 343 bics xzr, x0, x1, lsr #7 /* 0 = slow cluster or warm reset */ 344 b.eq restore_oslock 345 mov x0, xzr 346 msr oslar_el1, x0 /* os lock stays 0 across warm reset */ 347 mov x3, #3 348 movz x4, #0x8000, lsl #48 349 msr CORTEX_A57_CPUACTLR_EL1, x4 /* turn off RCG */ 350 isb 351 msr rmr_el3, x3 /* request warm reset */ 352 isb 353 dsb sy 3541: wfi 355 b 1b 356 357 /* -------------------------------------------------- 358 * These nops are here so that speculative execution 359 * won't harm us before we are done with warm reset. 360 * -------------------------------------------------- 361 */ 362 .rept 65 363 nop 364 .endr 3652: 366 /* -------------------------------------------------- 367 * Do not insert instructions here 368 * -------------------------------------------------- 369 */ 370#endif 371 372 /* -------------------------------------------------- 373 * Restore OS Lock bit 374 * -------------------------------------------------- 375 */ 376restore_oslock: 377 mov x0, #1 378 msr oslar_el1, x0 379 380 /* -------------------------------------------------- 381 * Get secure world's entry point and jump to it 382 * -------------------------------------------------- 383 */ 384 bl plat_get_my_entrypoint 385 br x0 386endfunc tegra_secure_entrypoint 387 388 .data 389 .align 3 390 391 /* -------------------------------------------------- 392 * CPU Secure entry point - resume from suspend 393 * -------------------------------------------------- 394 */ 395tegra_sec_entry_point: 396 .quad 0 397 398 /* -------------------------------------------------- 399 * NS world's cold boot entry point 400 * -------------------------------------------------- 401 */ 402ns_image_entrypoint: 403 .quad 0 404 405 /* -------------------------------------------------- 406 * BL31's physical base address 407 * -------------------------------------------------- 408 */ 409tegra_bl31_phys_base: 410 .quad 0 411 412 /* -------------------------------------------------- 413 * UART controller base for console init 414 * -------------------------------------------------- 415 */ 416tegra_console_base: 417 .quad 0 418