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