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