1*08438e24SVarun Wadekar/* 2*08438e24SVarun Wadekar * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. 3*08438e24SVarun Wadekar * 4*08438e24SVarun Wadekar * Redistribution and use in source and binary forms, with or without 5*08438e24SVarun Wadekar * modification, are permitted provided that the following conditions are met: 6*08438e24SVarun Wadekar * 7*08438e24SVarun Wadekar * Redistributions of source code must retain the above copyright notice, this 8*08438e24SVarun Wadekar * list of conditions and the following disclaimer. 9*08438e24SVarun Wadekar * 10*08438e24SVarun Wadekar * Redistributions in binary form must reproduce the above copyright notice, 11*08438e24SVarun Wadekar * this list of conditions and the following disclaimer in the documentation 12*08438e24SVarun Wadekar * and/or other materials provided with the distribution. 13*08438e24SVarun Wadekar * 14*08438e24SVarun Wadekar * Neither the name of ARM nor the names of its contributors may be used 15*08438e24SVarun Wadekar * to endorse or promote products derived from this software without specific 16*08438e24SVarun Wadekar * prior written permission. 17*08438e24SVarun Wadekar * 18*08438e24SVarun Wadekar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19*08438e24SVarun Wadekar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*08438e24SVarun Wadekar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*08438e24SVarun Wadekar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22*08438e24SVarun Wadekar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*08438e24SVarun Wadekar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*08438e24SVarun Wadekar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*08438e24SVarun Wadekar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*08438e24SVarun Wadekar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*08438e24SVarun Wadekar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*08438e24SVarun Wadekar * POSSIBILITY OF SUCH DAMAGE. 29*08438e24SVarun Wadekar */ 30*08438e24SVarun Wadekar#include <arch.h> 31*08438e24SVarun Wadekar#include <asm_macros.S> 32*08438e24SVarun Wadekar#include <assert_macros.S> 33*08438e24SVarun Wadekar#include <cpu_macros.S> 34*08438e24SVarun Wadekar#include <cortex_a57.h> 35*08438e24SVarun Wadekar#include <cortex_a53.h> 36*08438e24SVarun Wadekar#include <tegra_def.h> 37*08438e24SVarun Wadekar 38*08438e24SVarun Wadekar /* Global functions */ 39*08438e24SVarun Wadekar .globl platform_is_primary_cpu 40*08438e24SVarun Wadekar .globl platform_get_core_pos 41*08438e24SVarun Wadekar .globl platform_get_entrypoint 42*08438e24SVarun Wadekar .globl plat_secondary_cold_boot_setup 43*08438e24SVarun Wadekar .globl platform_mem_init 44*08438e24SVarun Wadekar .globl plat_crash_console_init 45*08438e24SVarun Wadekar .globl plat_crash_console_putc 46*08438e24SVarun Wadekar .globl tegra_secure_entrypoint 47*08438e24SVarun Wadekar .globl plat_reset_handler 48*08438e24SVarun Wadekar 49*08438e24SVarun Wadekar /* Global variables */ 50*08438e24SVarun Wadekar .globl sec_entry_point 51*08438e24SVarun Wadekar .globl ns_image_entrypoint 52*08438e24SVarun Wadekar .globl tegra_bl31_phys_base 53*08438e24SVarun Wadekar 54*08438e24SVarun Wadekar /* --------------------- 55*08438e24SVarun Wadekar * Common CPU init code 56*08438e24SVarun Wadekar * --------------------- 57*08438e24SVarun Wadekar */ 58*08438e24SVarun Wadekar.macro cpu_init_common 59*08438e24SVarun Wadekar 60*08438e24SVarun Wadekar /* ------------------------------------------------------- 61*08438e24SVarun Wadekar * Enable L2 and CPU ECTLR RW access from non-secure world 62*08438e24SVarun Wadekar * ------------------------------------------------------- 63*08438e24SVarun Wadekar */ 64*08438e24SVarun Wadekar mov x0, #ACTLR_EL3_ENABLE_ALL_ACCESS 65*08438e24SVarun Wadekar msr actlr_el3, x0 66*08438e24SVarun Wadekar msr actlr_el2, x0 67*08438e24SVarun Wadekar isb 68*08438e24SVarun Wadekar 69*08438e24SVarun Wadekar /* -------------------------------- 70*08438e24SVarun Wadekar * Enable the cycle count register 71*08438e24SVarun Wadekar * -------------------------------- 72*08438e24SVarun Wadekar */ 73*08438e24SVarun Wadekar mrs x0, pmcr_el0 74*08438e24SVarun Wadekar ubfx x0, x0, #11, #5 // read PMCR.N field 75*08438e24SVarun Wadekar mov x1, #1 76*08438e24SVarun Wadekar lsl x0, x1, x0 77*08438e24SVarun Wadekar sub x0, x0, #1 // mask of event counters 78*08438e24SVarun Wadekar orr x0, x0, #0x80000000 // disable overflow intrs 79*08438e24SVarun Wadekar msr pmintenclr_el1, x0 80*08438e24SVarun Wadekar msr pmuserenr_el0, x1 // enable user mode access 81*08438e24SVarun Wadekar 82*08438e24SVarun Wadekar /* ---------------------------------------------------------------- 83*08438e24SVarun Wadekar * Allow non-privileged access to CNTVCT: Set CNTKCTL (Kernel Count 84*08438e24SVarun Wadekar * register), bit 1 (EL0VCTEN) to enable access to CNTVCT/CNTFRQ 85*08438e24SVarun Wadekar * registers from EL0. 86*08438e24SVarun Wadekar * ---------------------------------------------------------------- 87*08438e24SVarun Wadekar */ 88*08438e24SVarun Wadekar mrs x0, cntkctl_el1 89*08438e24SVarun Wadekar orr x0, x0, #EL0VCTEN_BIT 90*08438e24SVarun Wadekar msr cntkctl_el1, x0 91*08438e24SVarun Wadekar.endm 92*08438e24SVarun Wadekar 93*08438e24SVarun Wadekar /* ----------------------------------------------------- 94*08438e24SVarun Wadekar * int platform_is_primary_cpu(int mpidr); 95*08438e24SVarun Wadekar * 96*08438e24SVarun Wadekar * This function checks if this is the Primary CPU 97*08438e24SVarun Wadekar * ----------------------------------------------------- 98*08438e24SVarun Wadekar */ 99*08438e24SVarun Wadekarfunc platform_is_primary_cpu 100*08438e24SVarun Wadekar and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) 101*08438e24SVarun Wadekar cmp x0, #TEGRA_PRIMARY_CPU 102*08438e24SVarun Wadekar cset x0, eq 103*08438e24SVarun Wadekar ret 104*08438e24SVarun Wadekarendfunc platform_is_primary_cpu 105*08438e24SVarun Wadekar 106*08438e24SVarun Wadekar /* ----------------------------------------------------- 107*08438e24SVarun Wadekar * int platform_get_core_pos(int mpidr); 108*08438e24SVarun Wadekar * 109*08438e24SVarun Wadekar * With this function: CorePos = CoreId 110*08438e24SVarun Wadekar * ----------------------------------------------------- 111*08438e24SVarun Wadekar */ 112*08438e24SVarun Wadekarfunc platform_get_core_pos 113*08438e24SVarun Wadekar and x0, x0, #MPIDR_CPU_MASK 114*08438e24SVarun Wadekar ret 115*08438e24SVarun Wadekarendfunc platform_get_core_pos 116*08438e24SVarun Wadekar 117*08438e24SVarun Wadekar /* ----------------------------------------------------- 118*08438e24SVarun Wadekar * void plat_secondary_cold_boot_setup (void); 119*08438e24SVarun Wadekar * 120*08438e24SVarun Wadekar * This function performs any platform specific actions 121*08438e24SVarun Wadekar * needed for a secondary cpu after a cold reset. Right 122*08438e24SVarun Wadekar * now this is a stub function. 123*08438e24SVarun Wadekar * ----------------------------------------------------- 124*08438e24SVarun Wadekar */ 125*08438e24SVarun Wadekarfunc plat_secondary_cold_boot_setup 126*08438e24SVarun Wadekar mov x0, #0 127*08438e24SVarun Wadekar ret 128*08438e24SVarun Wadekarendfunc plat_secondary_cold_boot_setup 129*08438e24SVarun Wadekar 130*08438e24SVarun Wadekar /* ----------------------------------------------------- 131*08438e24SVarun Wadekar * void platform_get_entrypoint (unsigned int mpidr); 132*08438e24SVarun Wadekar * 133*08438e24SVarun Wadekar * Main job of this routine is to distinguish between 134*08438e24SVarun Wadekar * a cold and warm boot. If the sec_entry_point for 135*08438e24SVarun Wadekar * this CPU is present, then it's a warm boot. 136*08438e24SVarun Wadekar * 137*08438e24SVarun Wadekar * ----------------------------------------------------- 138*08438e24SVarun Wadekar */ 139*08438e24SVarun Wadekarfunc platform_get_entrypoint 140*08438e24SVarun Wadekar and x0, x0, #MPIDR_CPU_MASK 141*08438e24SVarun Wadekar adr x1, sec_entry_point 142*08438e24SVarun Wadekar ldr x0, [x1, x0, lsl #3] 143*08438e24SVarun Wadekar ret 144*08438e24SVarun Wadekarendfunc platform_get_entrypoint 145*08438e24SVarun Wadekar 146*08438e24SVarun Wadekar /* -------------------------------------------------------- 147*08438e24SVarun Wadekar * void platform_mem_init (void); 148*08438e24SVarun Wadekar * 149*08438e24SVarun Wadekar * Any memory init, relocation to be done before the 150*08438e24SVarun Wadekar * platform boots. Called very early in the boot process. 151*08438e24SVarun Wadekar * -------------------------------------------------------- 152*08438e24SVarun Wadekar */ 153*08438e24SVarun Wadekarfunc platform_mem_init 154*08438e24SVarun Wadekar mov x0, #0 155*08438e24SVarun Wadekar ret 156*08438e24SVarun Wadekarendfunc platform_mem_init 157*08438e24SVarun Wadekar 158*08438e24SVarun Wadekar /* --------------------------------------------- 159*08438e24SVarun Wadekar * int plat_crash_console_init(void) 160*08438e24SVarun Wadekar * Function to initialize the crash console 161*08438e24SVarun Wadekar * without a C Runtime to print crash report. 162*08438e24SVarun Wadekar * Clobber list : x0, x1, x2 163*08438e24SVarun Wadekar * --------------------------------------------- 164*08438e24SVarun Wadekar */ 165*08438e24SVarun Wadekarfunc plat_crash_console_init 166*08438e24SVarun Wadekar mov_imm x0, TEGRA_BOOT_UART_BASE 167*08438e24SVarun Wadekar mov_imm x1, TEGRA_BOOT_UART_CLK_IN_HZ 168*08438e24SVarun Wadekar mov_imm x2, TEGRA_CONSOLE_BAUDRATE 169*08438e24SVarun Wadekar b console_core_init 170*08438e24SVarun Wadekarendfunc plat_crash_console_init 171*08438e24SVarun Wadekar 172*08438e24SVarun Wadekar /* --------------------------------------------- 173*08438e24SVarun Wadekar * int plat_crash_console_putc(void) 174*08438e24SVarun Wadekar * Function to print a character on the crash 175*08438e24SVarun Wadekar * console without a C Runtime. 176*08438e24SVarun Wadekar * Clobber list : x1, x2 177*08438e24SVarun Wadekar * --------------------------------------------- 178*08438e24SVarun Wadekar */ 179*08438e24SVarun Wadekarfunc plat_crash_console_putc 180*08438e24SVarun Wadekar mov_imm x1, TEGRA_BOOT_UART_BASE 181*08438e24SVarun Wadekar b console_core_putc 182*08438e24SVarun Wadekarendfunc plat_crash_console_putc 183*08438e24SVarun Wadekar 184*08438e24SVarun Wadekar /* --------------------------------------------------- 185*08438e24SVarun Wadekar * Function to handle a platform reset and store 186*08438e24SVarun Wadekar * input parameters passed by BL2. 187*08438e24SVarun Wadekar * --------------------------------------------------- 188*08438e24SVarun Wadekar */ 189*08438e24SVarun Wadekarfunc plat_reset_handler 190*08438e24SVarun Wadekar 191*08438e24SVarun Wadekar /* ----------------------------------- 192*08438e24SVarun Wadekar * derive and save the phys_base addr 193*08438e24SVarun Wadekar * ----------------------------------- 194*08438e24SVarun Wadekar */ 195*08438e24SVarun Wadekar adr x17, tegra_bl31_phys_base 196*08438e24SVarun Wadekar ldr x18, [x17] 197*08438e24SVarun Wadekar cbnz x18, 1f 198*08438e24SVarun Wadekar adr x18, bl31_entrypoint 199*08438e24SVarun Wadekar str x18, [x17] 200*08438e24SVarun Wadekar 201*08438e24SVarun Wadekar1: cpu_init_common 202*08438e24SVarun Wadekar 203*08438e24SVarun Wadekar ret 204*08438e24SVarun Wadekarendfunc plat_reset_handler 205*08438e24SVarun Wadekar 206*08438e24SVarun Wadekar /* ---------------------------------------- 207*08438e24SVarun Wadekar * Secure entrypoint function for CPU boot 208*08438e24SVarun Wadekar * ---------------------------------------- 209*08438e24SVarun Wadekar */ 210*08438e24SVarun Wadekar .align 6 211*08438e24SVarun Wadekarfunc tegra_secure_entrypoint 212*08438e24SVarun Wadekar 213*08438e24SVarun Wadekar#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT 214*08438e24SVarun Wadekar 215*08438e24SVarun Wadekar /* ------------------------------------------------------- 216*08438e24SVarun Wadekar * Invalidate BTB along with I$ to remove any stale 217*08438e24SVarun Wadekar * entries from the branch predictor array. 218*08438e24SVarun Wadekar * ------------------------------------------------------- 219*08438e24SVarun Wadekar */ 220*08438e24SVarun Wadekar mrs x0, CPUACTLR_EL1 221*08438e24SVarun Wadekar orr x0, x0, #1 222*08438e24SVarun Wadekar msr CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */ 223*08438e24SVarun Wadekar dsb sy 224*08438e24SVarun Wadekar isb 225*08438e24SVarun Wadekar ic iallu /* actual invalidate */ 226*08438e24SVarun Wadekar dsb sy 227*08438e24SVarun Wadekar isb 228*08438e24SVarun Wadekar 229*08438e24SVarun Wadekar mrs x0, CPUACTLR_EL1 230*08438e24SVarun Wadekar bic x0, x0, #1 231*08438e24SVarun Wadekar msr CPUACTLR_EL1, X0 /* restore original CPUACTLR_EL1 */ 232*08438e24SVarun Wadekar dsb sy 233*08438e24SVarun Wadekar isb 234*08438e24SVarun Wadekar 235*08438e24SVarun Wadekar .rept 7 236*08438e24SVarun Wadekar nop /* wait */ 237*08438e24SVarun Wadekar .endr 238*08438e24SVarun Wadekar 239*08438e24SVarun Wadekar /* ----------------------------------------------- 240*08438e24SVarun Wadekar * Extract OSLK bit and check if it is '1'. This 241*08438e24SVarun Wadekar * bit remains '0' for A53 on warm-resets. If '1', 242*08438e24SVarun Wadekar * turn off regional clock gating and request warm 243*08438e24SVarun Wadekar * reset. 244*08438e24SVarun Wadekar * ----------------------------------------------- 245*08438e24SVarun Wadekar */ 246*08438e24SVarun Wadekar mrs x0, oslsr_el1 247*08438e24SVarun Wadekar and x0, x0, #2 248*08438e24SVarun Wadekar mrs x1, mpidr_el1 249*08438e24SVarun Wadekar bics xzr, x0, x1, lsr #7 /* 0 = slow cluster or warm reset */ 250*08438e24SVarun Wadekar b.eq restore_oslock 251*08438e24SVarun Wadekar mov x0, xzr 252*08438e24SVarun Wadekar msr oslar_el1, x0 /* os lock stays 0 across warm reset */ 253*08438e24SVarun Wadekar mov x3, #3 254*08438e24SVarun Wadekar movz x4, #0x8000, lsl #48 255*08438e24SVarun Wadekar msr CPUACTLR_EL1, x4 /* turn off RCG */ 256*08438e24SVarun Wadekar isb 257*08438e24SVarun Wadekar msr rmr_el3, x3 /* request warm reset */ 258*08438e24SVarun Wadekar isb 259*08438e24SVarun Wadekar dsb sy 260*08438e24SVarun Wadekar1: wfi 261*08438e24SVarun Wadekar b 1b 262*08438e24SVarun Wadekar 263*08438e24SVarun Wadekar /* -------------------------------------------------- 264*08438e24SVarun Wadekar * These nops are here so that speculative execution 265*08438e24SVarun Wadekar * won't harm us before we are done with warm reset. 266*08438e24SVarun Wadekar * -------------------------------------------------- 267*08438e24SVarun Wadekar */ 268*08438e24SVarun Wadekar .rept 65 269*08438e24SVarun Wadekar nop 270*08438e24SVarun Wadekar .endr 271*08438e24SVarun Wadekar 272*08438e24SVarun Wadekar /* -------------------------------------------------- 273*08438e24SVarun Wadekar * Do not insert instructions here 274*08438e24SVarun Wadekar * -------------------------------------------------- 275*08438e24SVarun Wadekar */ 276*08438e24SVarun Wadekar#endif 277*08438e24SVarun Wadekar 278*08438e24SVarun Wadekar /* -------------------------------------------------- 279*08438e24SVarun Wadekar * Restore OS Lock bit 280*08438e24SVarun Wadekar * -------------------------------------------------- 281*08438e24SVarun Wadekar */ 282*08438e24SVarun Wadekarrestore_oslock: 283*08438e24SVarun Wadekar mov x0, #1 284*08438e24SVarun Wadekar msr oslar_el1, x0 285*08438e24SVarun Wadekar 286*08438e24SVarun Wadekar cpu_init_common 287*08438e24SVarun Wadekar 288*08438e24SVarun Wadekar /* --------------------------------------------------------------------- 289*08438e24SVarun Wadekar * The initial state of the Architectural feature trap register 290*08438e24SVarun Wadekar * (CPTR_EL3) is unknown and it must be set to a known state. All 291*08438e24SVarun Wadekar * feature traps are disabled. Some bits in this register are marked as 292*08438e24SVarun Wadekar * Reserved and should not be modified. 293*08438e24SVarun Wadekar * 294*08438e24SVarun Wadekar * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1 295*08438e24SVarun Wadekar * or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2. 296*08438e24SVarun Wadekar * CPTR_EL3.TTA: This causes access to the Trace functionality to trap 297*08438e24SVarun Wadekar * to EL3 when executed from EL0, EL1, EL2, or EL3. If system register 298*08438e24SVarun Wadekar * access to trace functionality is not supported, this bit is RES0. 299*08438e24SVarun Wadekar * CPTR_EL3.TFP: This causes instructions that access the registers 300*08438e24SVarun Wadekar * associated with Floating Point and Advanced SIMD execution to trap 301*08438e24SVarun Wadekar * to EL3 when executed from any exception level, unless trapped to EL1 302*08438e24SVarun Wadekar * or EL2. 303*08438e24SVarun Wadekar * --------------------------------------------------------------------- 304*08438e24SVarun Wadekar */ 305*08438e24SVarun Wadekar mrs x1, cptr_el3 306*08438e24SVarun Wadekar bic w1, w1, #TCPAC_BIT 307*08438e24SVarun Wadekar bic w1, w1, #TTA_BIT 308*08438e24SVarun Wadekar bic w1, w1, #TFP_BIT 309*08438e24SVarun Wadekar msr cptr_el3, x1 310*08438e24SVarun Wadekar 311*08438e24SVarun Wadekar /* -------------------------------------------------- 312*08438e24SVarun Wadekar * Get secure world's entry point and jump to it 313*08438e24SVarun Wadekar * -------------------------------------------------- 314*08438e24SVarun Wadekar */ 315*08438e24SVarun Wadekar mrs x0, mpidr_el1 316*08438e24SVarun Wadekar bl platform_get_entrypoint 317*08438e24SVarun Wadekar br x0 318*08438e24SVarun Wadekarendfunc tegra_secure_entrypoint 319*08438e24SVarun Wadekar 320*08438e24SVarun Wadekar .data 321*08438e24SVarun Wadekar .align 3 322*08438e24SVarun Wadekar 323*08438e24SVarun Wadekar /* -------------------------------------------------- 324*08438e24SVarun Wadekar * Per-CPU Secure entry point - resume from suspend 325*08438e24SVarun Wadekar * -------------------------------------------------- 326*08438e24SVarun Wadekar */ 327*08438e24SVarun Wadekarsec_entry_point: 328*08438e24SVarun Wadekar .rept PLATFORM_CORE_COUNT 329*08438e24SVarun Wadekar .quad 0 330*08438e24SVarun Wadekar .endr 331*08438e24SVarun Wadekar 332*08438e24SVarun Wadekar /* -------------------------------------------------- 333*08438e24SVarun Wadekar * NS world's cold boot entry point 334*08438e24SVarun Wadekar * -------------------------------------------------- 335*08438e24SVarun Wadekar */ 336*08438e24SVarun Wadekarns_image_entrypoint: 337*08438e24SVarun Wadekar .quad 0 338*08438e24SVarun Wadekar 339*08438e24SVarun Wadekar /* -------------------------------------------------- 340*08438e24SVarun Wadekar * BL31's physical base address 341*08438e24SVarun Wadekar * -------------------------------------------------- 342*08438e24SVarun Wadekar */ 343*08438e24SVarun Wadekartegra_bl31_phys_base: 344*08438e24SVarun Wadekar .quad 0 345