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 70 /* --------------------- 71 * Common CPU init code 72 * --------------------- 73 */ 74.macro cpu_init_common 75 76 /* ------------------------------------------------ 77 * We enable procesor retention and L2/CPUECTLR NS 78 * access for A57 CPUs only. 79 * ------------------------------------------------ 80 */ 81 mrs x0, midr_el1 82 mov x1, #(MIDR_PN_MASK << MIDR_PN_SHIFT) 83 and x0, x0, x1 84 lsr x0, x0, #MIDR_PN_SHIFT 85 cmp x0, #MIDR_PN_CORTEX_A57 86 b.ne 1f 87 88 /* --------------------------- 89 * Enable processor retention 90 * --------------------------- 91 */ 92 mrs x0, L2ECTLR_EL1 93 mov x1, #RETENTION_ENTRY_TICKS_512 << L2ECTLR_RET_CTRL_SHIFT 94 bic x0, x0, #L2ECTLR_RET_CTRL_MASK 95 orr x0, x0, x1 96 msr L2ECTLR_EL1, x0 97 isb 98 99 mrs x0, CPUECTLR_EL1 100 mov x1, #RETENTION_ENTRY_TICKS_512 << CPUECTLR_CPU_RET_CTRL_SHIFT 101 bic x0, x0, #CPUECTLR_CPU_RET_CTRL_MASK 102 orr x0, x0, x1 103 msr CPUECTLR_EL1, x0 104 isb 105 106 /* ------------------------------------------------------- 107 * Enable L2 and CPU ECTLR RW access from non-secure world 108 * ------------------------------------------------------- 109 */ 110 mov x0, #ACTLR_EL3_ENABLE_ALL_ACCESS 111 msr actlr_el3, x0 112 msr actlr_el2, x0 113 isb 114 115 /* -------------------------------- 116 * Enable the cycle count register 117 * -------------------------------- 118 */ 1191: mrs x0, pmcr_el0 120 ubfx x0, x0, #11, #5 // read PMCR.N field 121 mov x1, #1 122 lsl x0, x1, x0 123 sub x0, x0, #1 // mask of event counters 124 orr x0, x0, #0x80000000 // disable overflow intrs 125 msr pmintenclr_el1, x0 126 msr pmuserenr_el0, x1 // enable user mode access 127 128 /* ---------------------------------------------------------------- 129 * Allow non-privileged access to CNTVCT: Set CNTKCTL (Kernel Count 130 * register), bit 1 (EL0VCTEN) to enable access to CNTVCT/CNTFRQ 131 * registers from EL0. 132 * ---------------------------------------------------------------- 133 */ 134 mrs x0, cntkctl_el1 135 orr x0, x0, #EL0VCTEN_BIT 136 msr cntkctl_el1, x0 137.endm 138 139 /* ----------------------------------------------------- 140 * unsigned int plat_is_my_cpu_primary(void); 141 * 142 * This function checks if this is the Primary CPU 143 * ----------------------------------------------------- 144 */ 145func plat_is_my_cpu_primary 146 mrs x0, mpidr_el1 147 and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) 148 cmp x0, #TEGRA_PRIMARY_CPU 149 cset x0, eq 150 ret 151endfunc plat_is_my_cpu_primary 152 153 /* ----------------------------------------------------- 154 * unsigned int plat_my_core_pos(void); 155 * 156 * result: CorePos = CoreId + (ClusterId << 2) 157 * ----------------------------------------------------- 158 */ 159func plat_my_core_pos 160 mrs x0, mpidr_el1 161 and x1, x0, #MPIDR_CPU_MASK 162 and x0, x0, #MPIDR_CLUSTER_MASK 163 add x0, x1, x0, LSR #6 164 ret 165endfunc plat_my_core_pos 166 167 /* ----------------------------------------------------- 168 * unsigned long plat_get_my_entrypoint (void); 169 * 170 * Main job of this routine is to distinguish between 171 * a cold and warm boot. If the tegra_sec_entry_point for 172 * this CPU is present, then it's a warm boot. 173 * 174 * ----------------------------------------------------- 175 */ 176func plat_get_my_entrypoint 177 adr x1, tegra_sec_entry_point 178 ldr x0, [x1] 179 ret 180endfunc plat_get_my_entrypoint 181 182 /* ----------------------------------------------------- 183 * int platform_get_core_pos(int mpidr); 184 * 185 * With this function: CorePos = (ClusterId * 4) + 186 * CoreId 187 * ----------------------------------------------------- 188 */ 189func platform_get_core_pos 190 and x1, x0, #MPIDR_CPU_MASK 191 and x0, x0, #MPIDR_CLUSTER_MASK 192 add x0, x1, x0, LSR #6 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 * int plat_crash_console_init(void) 223 * Function to initialize the crash console 224 * without a C Runtime to print crash report. 225 * Clobber list : x0 - x4 226 * --------------------------------------------- 227 */ 228func plat_crash_console_init 229 mov_imm x0, TEGRA_BOOT_UART_BASE 230 mov_imm x1, TEGRA_BOOT_UART_CLK_IN_HZ 231 mov_imm x2, TEGRA_CONSOLE_BAUDRATE 232 b console_core_init 233endfunc plat_crash_console_init 234 235 /* --------------------------------------------- 236 * int plat_crash_console_putc(void) 237 * Function to print a character on the crash 238 * console without a C Runtime. 239 * Clobber list : x1, x2 240 * --------------------------------------------- 241 */ 242func plat_crash_console_putc 243 mov_imm x1, TEGRA_BOOT_UART_BASE 244 b console_core_putc 245endfunc plat_crash_console_putc 246 247 /* --------------------------------------------------- 248 * Function to handle a platform reset and store 249 * input parameters passed by BL2. 250 * --------------------------------------------------- 251 */ 252func plat_reset_handler 253 254 /* ----------------------------------- 255 * derive and save the phys_base addr 256 * ----------------------------------- 257 */ 258 adr x17, tegra_bl31_phys_base 259 ldr x18, [x17] 260 cbnz x18, 1f 261 adr x18, bl31_entrypoint 262 str x18, [x17] 263 2641: cpu_init_common 265 266 ret 267endfunc plat_reset_handler 268 269 /* ---------------------------------------- 270 * Secure entrypoint function for CPU boot 271 * ---------------------------------------- 272 */ 273 .align 6 274func tegra_secure_entrypoint 275 276#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT 277 278 /* ------------------------------------------------------- 279 * Invalidate BTB along with I$ to remove any stale 280 * entries from the branch predictor array. 281 * ------------------------------------------------------- 282 */ 283 mrs x0, CPUACTLR_EL1 284 orr x0, x0, #1 285 msr CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */ 286 dsb sy 287 isb 288 ic iallu /* actual invalidate */ 289 dsb sy 290 isb 291 292 mrs x0, CPUACTLR_EL1 293 bic x0, x0, #1 294 msr CPUACTLR_EL1, X0 /* restore original CPUACTLR_EL1 */ 295 dsb sy 296 isb 297 298 .rept 7 299 nop /* wait */ 300 .endr 301 302 /* ----------------------------------------------- 303 * Extract OSLK bit and check if it is '1'. This 304 * bit remains '0' for A53 on warm-resets. If '1', 305 * turn off regional clock gating and request warm 306 * reset. 307 * ----------------------------------------------- 308 */ 309 mrs x0, oslsr_el1 310 and x0, x0, #2 311 mrs x1, mpidr_el1 312 bics xzr, x0, x1, lsr #7 /* 0 = slow cluster or warm reset */ 313 b.eq restore_oslock 314 mov x0, xzr 315 msr oslar_el1, x0 /* os lock stays 0 across warm reset */ 316 mov x3, #3 317 movz x4, #0x8000, lsl #48 318 msr CPUACTLR_EL1, x4 /* turn off RCG */ 319 isb 320 msr rmr_el3, x3 /* request warm reset */ 321 isb 322 dsb sy 3231: wfi 324 b 1b 325 326 /* -------------------------------------------------- 327 * These nops are here so that speculative execution 328 * won't harm us before we are done with warm reset. 329 * -------------------------------------------------- 330 */ 331 .rept 65 332 nop 333 .endr 334 335 /* -------------------------------------------------- 336 * Do not insert instructions here 337 * -------------------------------------------------- 338 */ 339#endif 340 341 /* -------------------------------------------------- 342 * Restore OS Lock bit 343 * -------------------------------------------------- 344 */ 345restore_oslock: 346 mov x0, #1 347 msr oslar_el1, x0 348 349 cpu_init_common 350 351 /* --------------------------------------------------------------------- 352 * The initial state of the Architectural feature trap register 353 * (CPTR_EL3) is unknown and it must be set to a known state. All 354 * feature traps are disabled. Some bits in this register are marked as 355 * Reserved and should not be modified. 356 * 357 * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1 358 * or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2. 359 * CPTR_EL3.TTA: This causes access to the Trace functionality to trap 360 * to EL3 when executed from EL0, EL1, EL2, or EL3. If system register 361 * access to trace functionality is not supported, this bit is RES0. 362 * CPTR_EL3.TFP: This causes instructions that access the registers 363 * associated with Floating Point and Advanced SIMD execution to trap 364 * to EL3 when executed from any exception level, unless trapped to EL1 365 * or EL2. 366 * --------------------------------------------------------------------- 367 */ 368 mrs x1, cptr_el3 369 bic w1, w1, #TCPAC_BIT 370 bic w1, w1, #TTA_BIT 371 bic w1, w1, #TFP_BIT 372 msr cptr_el3, x1 373 374 /* -------------------------------------------------- 375 * Get secure world's entry point and jump to it 376 * -------------------------------------------------- 377 */ 378 bl plat_get_my_entrypoint 379 br x0 380endfunc tegra_secure_entrypoint 381 382 .data 383 .align 3 384 385 /* -------------------------------------------------- 386 * CPU Secure entry point - resume from suspend 387 * -------------------------------------------------- 388 */ 389tegra_sec_entry_point: 390 .quad 0 391 392 /* -------------------------------------------------- 393 * NS world's cold boot entry point 394 * -------------------------------------------------- 395 */ 396ns_image_entrypoint: 397 .quad 0 398 399 /* -------------------------------------------------- 400 * BL31's physical base address 401 * -------------------------------------------------- 402 */ 403tegra_bl31_phys_base: 404 .quad 0 405