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