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