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