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 * derive and save the phys_base addr 259 * ----------------------------------- 260 */ 261 adr x17, tegra_bl31_phys_base 262 ldr x18, [x17] 263 cbnz x18, 1f 264 adr x18, bl31_entrypoint 265 str x18, [x17] 266 2671: cpu_init_common 268 269 ret 270endfunc plat_reset_handler 271 272 /* ---------------------------------------- 273 * Secure entrypoint function for CPU boot 274 * ---------------------------------------- 275 */ 276 .align 6 277func tegra_secure_entrypoint 278 279#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT 280 281 /* ------------------------------------------------------- 282 * Invalidate BTB along with I$ to remove any stale 283 * entries from the branch predictor array. 284 * ------------------------------------------------------- 285 */ 286 mrs x0, CPUACTLR_EL1 287 orr x0, x0, #1 288 msr CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */ 289 dsb sy 290 isb 291 ic iallu /* actual invalidate */ 292 dsb sy 293 isb 294 295 mrs x0, CPUACTLR_EL1 296 bic x0, x0, #1 297 msr CPUACTLR_EL1, X0 /* restore original CPUACTLR_EL1 */ 298 dsb sy 299 isb 300 301 .rept 7 302 nop /* wait */ 303 .endr 304 305 /* ----------------------------------------------- 306 * Extract OSLK bit and check if it is '1'. This 307 * bit remains '0' for A53 on warm-resets. If '1', 308 * turn off regional clock gating and request warm 309 * reset. 310 * ----------------------------------------------- 311 */ 312 mrs x0, oslsr_el1 313 and x0, x0, #2 314 mrs x1, mpidr_el1 315 bics xzr, x0, x1, lsr #7 /* 0 = slow cluster or warm reset */ 316 b.eq restore_oslock 317 mov x0, xzr 318 msr oslar_el1, x0 /* os lock stays 0 across warm reset */ 319 mov x3, #3 320 movz x4, #0x8000, lsl #48 321 msr CPUACTLR_EL1, x4 /* turn off RCG */ 322 isb 323 msr rmr_el3, x3 /* request warm reset */ 324 isb 325 dsb sy 3261: wfi 327 b 1b 328 329 /* -------------------------------------------------- 330 * These nops are here so that speculative execution 331 * won't harm us before we are done with warm reset. 332 * -------------------------------------------------- 333 */ 334 .rept 65 335 nop 336 .endr 337 338 /* -------------------------------------------------- 339 * Do not insert instructions here 340 * -------------------------------------------------- 341 */ 342#endif 343 344 /* -------------------------------------------------- 345 * Restore OS Lock bit 346 * -------------------------------------------------- 347 */ 348restore_oslock: 349 mov x0, #1 350 msr oslar_el1, x0 351 352 cpu_init_common 353 354 /* --------------------------------------------------------------------- 355 * The initial state of the Architectural feature trap register 356 * (CPTR_EL3) is unknown and it must be set to a known state. All 357 * feature traps are disabled. Some bits in this register are marked as 358 * Reserved and should not be modified. 359 * 360 * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1 361 * or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2. 362 * CPTR_EL3.TTA: This causes access to the Trace functionality to trap 363 * to EL3 when executed from EL0, EL1, EL2, or EL3. If system register 364 * access to trace functionality is not supported, this bit is RES0. 365 * CPTR_EL3.TFP: This causes instructions that access the registers 366 * associated with Floating Point and Advanced SIMD execution to trap 367 * to EL3 when executed from any exception level, unless trapped to EL1 368 * or EL2. 369 * --------------------------------------------------------------------- 370 */ 371 mrs x1, cptr_el3 372 bic w1, w1, #TCPAC_BIT 373 bic w1, w1, #TTA_BIT 374 bic w1, w1, #TFP_BIT 375 msr cptr_el3, x1 376 377 /* -------------------------------------------------- 378 * Get secure world's entry point and jump to it 379 * -------------------------------------------------- 380 */ 381 bl plat_get_my_entrypoint 382 br x0 383endfunc tegra_secure_entrypoint 384 385 .data 386 .align 3 387 388 /* -------------------------------------------------- 389 * CPU Secure entry point - resume from suspend 390 * -------------------------------------------------- 391 */ 392tegra_sec_entry_point: 393 .quad 0 394 395 /* -------------------------------------------------- 396 * NS world's cold boot entry point 397 * -------------------------------------------------- 398 */ 399ns_image_entrypoint: 400 .quad 0 401 402 /* -------------------------------------------------- 403 * BL31's physical base address 404 * -------------------------------------------------- 405 */ 406tegra_bl31_phys_base: 407 .quad 0 408 409 /* -------------------------------------------------- 410 * UART controller base for console init 411 * -------------------------------------------------- 412 */ 413tegra_console_base: 414 .quad 0 415