108438e24SVarun Wadekar/* 208438e24SVarun Wadekar * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. 308438e24SVarun Wadekar * 408438e24SVarun Wadekar * Redistribution and use in source and binary forms, with or without 508438e24SVarun Wadekar * modification, are permitted provided that the following conditions are met: 608438e24SVarun Wadekar * 708438e24SVarun Wadekar * Redistributions of source code must retain the above copyright notice, this 808438e24SVarun Wadekar * list of conditions and the following disclaimer. 908438e24SVarun Wadekar * 1008438e24SVarun Wadekar * Redistributions in binary form must reproduce the above copyright notice, 1108438e24SVarun Wadekar * this list of conditions and the following disclaimer in the documentation 1208438e24SVarun Wadekar * and/or other materials provided with the distribution. 1308438e24SVarun Wadekar * 1408438e24SVarun Wadekar * Neither the name of ARM nor the names of its contributors may be used 1508438e24SVarun Wadekar * to endorse or promote products derived from this software without specific 1608438e24SVarun Wadekar * prior written permission. 1708438e24SVarun Wadekar * 1808438e24SVarun Wadekar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1908438e24SVarun Wadekar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2008438e24SVarun Wadekar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2108438e24SVarun Wadekar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2208438e24SVarun Wadekar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2308438e24SVarun Wadekar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2408438e24SVarun Wadekar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2508438e24SVarun Wadekar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2608438e24SVarun Wadekar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2708438e24SVarun Wadekar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2808438e24SVarun Wadekar * POSSIBILITY OF SUCH DAMAGE. 2908438e24SVarun Wadekar */ 3008438e24SVarun Wadekar#include <arch.h> 3108438e24SVarun Wadekar#include <asm_macros.S> 3208438e24SVarun Wadekar#include <assert_macros.S> 3308438e24SVarun Wadekar#include <cpu_macros.S> 3408438e24SVarun Wadekar#include <cortex_a57.h> 3508438e24SVarun Wadekar#include <cortex_a53.h> 3608438e24SVarun Wadekar#include <tegra_def.h> 3708438e24SVarun Wadekar 3808438e24SVarun Wadekar /* Global functions */ 3971cb26eaSVarun Wadekar .globl plat_is_my_cpu_primary 4071cb26eaSVarun Wadekar .globl plat_my_core_pos 4171cb26eaSVarun Wadekar .globl plat_get_my_entrypoint 4208438e24SVarun Wadekar .globl plat_secondary_cold_boot_setup 4308438e24SVarun Wadekar .globl platform_mem_init 4408438e24SVarun Wadekar .globl plat_crash_console_init 4508438e24SVarun Wadekar .globl plat_crash_console_putc 4608438e24SVarun Wadekar .globl tegra_secure_entrypoint 4708438e24SVarun Wadekar .globl plat_reset_handler 4808438e24SVarun Wadekar 4908438e24SVarun Wadekar /* Global variables */ 5071cb26eaSVarun Wadekar .globl tegra_sec_entry_point 5108438e24SVarun Wadekar .globl ns_image_entrypoint 5208438e24SVarun Wadekar .globl tegra_bl31_phys_base 5308438e24SVarun Wadekar 5408438e24SVarun Wadekar /* --------------------- 5508438e24SVarun Wadekar * Common CPU init code 5608438e24SVarun Wadekar * --------------------- 5708438e24SVarun Wadekar */ 5808438e24SVarun Wadekar.macro cpu_init_common 5908438e24SVarun Wadekar 60b42192bcSVarun Wadekar#if ENABLE_L2_DYNAMIC_RETENTION 61b42192bcSVarun Wadekar /* --------------------------- 62b42192bcSVarun Wadekar * Enable processor retention 63b42192bcSVarun Wadekar * --------------------------- 64b42192bcSVarun Wadekar */ 65b42192bcSVarun Wadekar mrs x0, L2ECTLR_EL1 66b42192bcSVarun Wadekar mov x1, #RETENTION_ENTRY_TICKS_512 << L2ECTLR_RET_CTRL_SHIFT 67b42192bcSVarun Wadekar bic x0, x0, #L2ECTLR_RET_CTRL_MASK 68b42192bcSVarun Wadekar orr x0, x0, x1 69b42192bcSVarun Wadekar msr L2ECTLR_EL1, x0 70b42192bcSVarun Wadekar isb 71b42192bcSVarun Wadekar#endif 72b42192bcSVarun Wadekar 73b42192bcSVarun Wadekar#if ENABLE_CPU_DYNAMIC_RETENTION 74b42192bcSVarun Wadekar mrs x0, CPUECTLR_EL1 75b42192bcSVarun Wadekar mov x1, #RETENTION_ENTRY_TICKS_512 << CPUECTLR_CPU_RET_CTRL_SHIFT 76b42192bcSVarun Wadekar bic x0, x0, #CPUECTLR_CPU_RET_CTRL_MASK 77b42192bcSVarun Wadekar orr x0, x0, x1 78b42192bcSVarun Wadekar msr CPUECTLR_EL1, x0 79b42192bcSVarun Wadekar isb 80b42192bcSVarun Wadekar#endif 81b42192bcSVarun Wadekar 828061a973SVarun Wadekar#if ENABLE_NS_L2_CPUECTRL_RW_ACCESS 8308438e24SVarun Wadekar /* ------------------------------------------------------- 8408438e24SVarun Wadekar * Enable L2 and CPU ECTLR RW access from non-secure world 8508438e24SVarun Wadekar * ------------------------------------------------------- 8608438e24SVarun Wadekar */ 8708438e24SVarun Wadekar mov x0, #ACTLR_EL3_ENABLE_ALL_ACCESS 8808438e24SVarun Wadekar msr actlr_el3, x0 8908438e24SVarun Wadekar msr actlr_el2, x0 9008438e24SVarun Wadekar isb 918061a973SVarun Wadekar#endif 9208438e24SVarun Wadekar 9308438e24SVarun Wadekar /* -------------------------------- 9408438e24SVarun Wadekar * Enable the cycle count register 9508438e24SVarun Wadekar * -------------------------------- 9608438e24SVarun Wadekar */ 9708438e24SVarun Wadekar mrs x0, pmcr_el0 9808438e24SVarun Wadekar ubfx x0, x0, #11, #5 // read PMCR.N field 9908438e24SVarun Wadekar mov x1, #1 10008438e24SVarun Wadekar lsl x0, x1, x0 10108438e24SVarun Wadekar sub x0, x0, #1 // mask of event counters 10208438e24SVarun Wadekar orr x0, x0, #0x80000000 // disable overflow intrs 10308438e24SVarun Wadekar msr pmintenclr_el1, x0 10408438e24SVarun Wadekar msr pmuserenr_el0, x1 // enable user mode access 10508438e24SVarun Wadekar 10608438e24SVarun Wadekar /* ---------------------------------------------------------------- 10708438e24SVarun Wadekar * Allow non-privileged access to CNTVCT: Set CNTKCTL (Kernel Count 10808438e24SVarun Wadekar * register), bit 1 (EL0VCTEN) to enable access to CNTVCT/CNTFRQ 10908438e24SVarun Wadekar * registers from EL0. 11008438e24SVarun Wadekar * ---------------------------------------------------------------- 11108438e24SVarun Wadekar */ 11208438e24SVarun Wadekar mrs x0, cntkctl_el1 11308438e24SVarun Wadekar orr x0, x0, #EL0VCTEN_BIT 11408438e24SVarun Wadekar msr cntkctl_el1, x0 11508438e24SVarun Wadekar.endm 11608438e24SVarun Wadekar 11708438e24SVarun Wadekar /* ----------------------------------------------------- 11871cb26eaSVarun Wadekar * unsigned int plat_is_my_cpu_primary(void); 11908438e24SVarun Wadekar * 12008438e24SVarun Wadekar * This function checks if this is the Primary CPU 12108438e24SVarun Wadekar * ----------------------------------------------------- 12208438e24SVarun Wadekar */ 12371cb26eaSVarun Wadekarfunc plat_is_my_cpu_primary 12471cb26eaSVarun Wadekar mrs x0, mpidr_el1 12508438e24SVarun Wadekar and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) 12608438e24SVarun Wadekar cmp x0, #TEGRA_PRIMARY_CPU 12708438e24SVarun Wadekar cset x0, eq 12808438e24SVarun Wadekar ret 12971cb26eaSVarun Wadekarendfunc plat_is_my_cpu_primary 13008438e24SVarun Wadekar 13108438e24SVarun Wadekar /* ----------------------------------------------------- 13271cb26eaSVarun Wadekar * unsigned int plat_my_core_pos(void); 13308438e24SVarun Wadekar * 13471cb26eaSVarun Wadekar * result: CorePos = CoreId + (ClusterId << 2) 13508438e24SVarun Wadekar * ----------------------------------------------------- 13608438e24SVarun Wadekar */ 13771cb26eaSVarun Wadekarfunc plat_my_core_pos 13871cb26eaSVarun Wadekar mrs x0, mpidr_el1 13971cb26eaSVarun Wadekar and x1, x0, #MPIDR_CPU_MASK 14071cb26eaSVarun Wadekar and x0, x0, #MPIDR_CLUSTER_MASK 14171cb26eaSVarun Wadekar add x0, x1, x0, LSR #6 14208438e24SVarun Wadekar ret 14371cb26eaSVarun Wadekarendfunc plat_my_core_pos 14471cb26eaSVarun Wadekar 14571cb26eaSVarun Wadekar /* ----------------------------------------------------- 14671cb26eaSVarun Wadekar * unsigned long plat_get_my_entrypoint (void); 14771cb26eaSVarun Wadekar * 14871cb26eaSVarun Wadekar * Main job of this routine is to distinguish between 14971cb26eaSVarun Wadekar * a cold and warm boot. If the tegra_sec_entry_point for 15071cb26eaSVarun Wadekar * this CPU is present, then it's a warm boot. 15171cb26eaSVarun Wadekar * 15271cb26eaSVarun Wadekar * ----------------------------------------------------- 15371cb26eaSVarun Wadekar */ 15471cb26eaSVarun Wadekarfunc plat_get_my_entrypoint 15571cb26eaSVarun Wadekar adr x1, tegra_sec_entry_point 15671cb26eaSVarun Wadekar ldr x0, [x1] 15771cb26eaSVarun Wadekar ret 15871cb26eaSVarun Wadekarendfunc plat_get_my_entrypoint 15908438e24SVarun Wadekar 16008438e24SVarun Wadekar /* ----------------------------------------------------- 16108438e24SVarun Wadekar * void plat_secondary_cold_boot_setup (void); 16208438e24SVarun Wadekar * 16308438e24SVarun Wadekar * This function performs any platform specific actions 16408438e24SVarun Wadekar * needed for a secondary cpu after a cold reset. Right 16508438e24SVarun Wadekar * now this is a stub function. 16608438e24SVarun Wadekar * ----------------------------------------------------- 16708438e24SVarun Wadekar */ 16808438e24SVarun Wadekarfunc plat_secondary_cold_boot_setup 16908438e24SVarun Wadekar mov x0, #0 17008438e24SVarun Wadekar ret 17108438e24SVarun Wadekarendfunc plat_secondary_cold_boot_setup 17208438e24SVarun Wadekar 17308438e24SVarun Wadekar /* -------------------------------------------------------- 17408438e24SVarun Wadekar * void platform_mem_init (void); 17508438e24SVarun Wadekar * 17608438e24SVarun Wadekar * Any memory init, relocation to be done before the 17708438e24SVarun Wadekar * platform boots. Called very early in the boot process. 17808438e24SVarun Wadekar * -------------------------------------------------------- 17908438e24SVarun Wadekar */ 18008438e24SVarun Wadekarfunc platform_mem_init 18108438e24SVarun Wadekar mov x0, #0 18208438e24SVarun Wadekar ret 18308438e24SVarun Wadekarendfunc platform_mem_init 18408438e24SVarun Wadekar 18508438e24SVarun Wadekar /* --------------------------------------------- 18608438e24SVarun Wadekar * int plat_crash_console_init(void) 18708438e24SVarun Wadekar * Function to initialize the crash console 18808438e24SVarun Wadekar * without a C Runtime to print crash report. 189*9400b40eSJuan Castillo * Clobber list : x0 - x4 19008438e24SVarun Wadekar * --------------------------------------------- 19108438e24SVarun Wadekar */ 19208438e24SVarun Wadekarfunc plat_crash_console_init 19308438e24SVarun Wadekar mov_imm x0, TEGRA_BOOT_UART_BASE 19408438e24SVarun Wadekar mov_imm x1, TEGRA_BOOT_UART_CLK_IN_HZ 19508438e24SVarun Wadekar mov_imm x2, TEGRA_CONSOLE_BAUDRATE 19608438e24SVarun Wadekar b console_core_init 19708438e24SVarun Wadekarendfunc plat_crash_console_init 19808438e24SVarun Wadekar 19908438e24SVarun Wadekar /* --------------------------------------------- 20008438e24SVarun Wadekar * int plat_crash_console_putc(void) 20108438e24SVarun Wadekar * Function to print a character on the crash 20208438e24SVarun Wadekar * console without a C Runtime. 20308438e24SVarun Wadekar * Clobber list : x1, x2 20408438e24SVarun Wadekar * --------------------------------------------- 20508438e24SVarun Wadekar */ 20608438e24SVarun Wadekarfunc plat_crash_console_putc 20708438e24SVarun Wadekar mov_imm x1, TEGRA_BOOT_UART_BASE 20808438e24SVarun Wadekar b console_core_putc 20908438e24SVarun Wadekarendfunc plat_crash_console_putc 21008438e24SVarun Wadekar 21108438e24SVarun Wadekar /* --------------------------------------------------- 21208438e24SVarun Wadekar * Function to handle a platform reset and store 21308438e24SVarun Wadekar * input parameters passed by BL2. 21408438e24SVarun Wadekar * --------------------------------------------------- 21508438e24SVarun Wadekar */ 21608438e24SVarun Wadekarfunc plat_reset_handler 21708438e24SVarun Wadekar 21808438e24SVarun Wadekar /* ----------------------------------- 21908438e24SVarun Wadekar * derive and save the phys_base addr 22008438e24SVarun Wadekar * ----------------------------------- 22108438e24SVarun Wadekar */ 22208438e24SVarun Wadekar adr x17, tegra_bl31_phys_base 22308438e24SVarun Wadekar ldr x18, [x17] 22408438e24SVarun Wadekar cbnz x18, 1f 22508438e24SVarun Wadekar adr x18, bl31_entrypoint 22608438e24SVarun Wadekar str x18, [x17] 22708438e24SVarun Wadekar 22808438e24SVarun Wadekar1: cpu_init_common 22908438e24SVarun Wadekar 23008438e24SVarun Wadekar ret 23108438e24SVarun Wadekarendfunc plat_reset_handler 23208438e24SVarun Wadekar 23308438e24SVarun Wadekar /* ---------------------------------------- 23408438e24SVarun Wadekar * Secure entrypoint function for CPU boot 23508438e24SVarun Wadekar * ---------------------------------------- 23608438e24SVarun Wadekar */ 23708438e24SVarun Wadekar .align 6 23808438e24SVarun Wadekarfunc tegra_secure_entrypoint 23908438e24SVarun Wadekar 24008438e24SVarun Wadekar#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT 24108438e24SVarun Wadekar 24208438e24SVarun Wadekar /* ------------------------------------------------------- 24308438e24SVarun Wadekar * Invalidate BTB along with I$ to remove any stale 24408438e24SVarun Wadekar * entries from the branch predictor array. 24508438e24SVarun Wadekar * ------------------------------------------------------- 24608438e24SVarun Wadekar */ 24708438e24SVarun Wadekar mrs x0, CPUACTLR_EL1 24808438e24SVarun Wadekar orr x0, x0, #1 24908438e24SVarun Wadekar msr CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */ 25008438e24SVarun Wadekar dsb sy 25108438e24SVarun Wadekar isb 25208438e24SVarun Wadekar ic iallu /* actual invalidate */ 25308438e24SVarun Wadekar dsb sy 25408438e24SVarun Wadekar isb 25508438e24SVarun Wadekar 25608438e24SVarun Wadekar mrs x0, CPUACTLR_EL1 25708438e24SVarun Wadekar bic x0, x0, #1 25808438e24SVarun Wadekar msr CPUACTLR_EL1, X0 /* restore original CPUACTLR_EL1 */ 25908438e24SVarun Wadekar dsb sy 26008438e24SVarun Wadekar isb 26108438e24SVarun Wadekar 26208438e24SVarun Wadekar .rept 7 26308438e24SVarun Wadekar nop /* wait */ 26408438e24SVarun Wadekar .endr 26508438e24SVarun Wadekar 26608438e24SVarun Wadekar /* ----------------------------------------------- 26708438e24SVarun Wadekar * Extract OSLK bit and check if it is '1'. This 26808438e24SVarun Wadekar * bit remains '0' for A53 on warm-resets. If '1', 26908438e24SVarun Wadekar * turn off regional clock gating and request warm 27008438e24SVarun Wadekar * reset. 27108438e24SVarun Wadekar * ----------------------------------------------- 27208438e24SVarun Wadekar */ 27308438e24SVarun Wadekar mrs x0, oslsr_el1 27408438e24SVarun Wadekar and x0, x0, #2 27508438e24SVarun Wadekar mrs x1, mpidr_el1 27608438e24SVarun Wadekar bics xzr, x0, x1, lsr #7 /* 0 = slow cluster or warm reset */ 27708438e24SVarun Wadekar b.eq restore_oslock 27808438e24SVarun Wadekar mov x0, xzr 27908438e24SVarun Wadekar msr oslar_el1, x0 /* os lock stays 0 across warm reset */ 28008438e24SVarun Wadekar mov x3, #3 28108438e24SVarun Wadekar movz x4, #0x8000, lsl #48 28208438e24SVarun Wadekar msr CPUACTLR_EL1, x4 /* turn off RCG */ 28308438e24SVarun Wadekar isb 28408438e24SVarun Wadekar msr rmr_el3, x3 /* request warm reset */ 28508438e24SVarun Wadekar isb 28608438e24SVarun Wadekar dsb sy 28708438e24SVarun Wadekar1: wfi 28808438e24SVarun Wadekar b 1b 28908438e24SVarun Wadekar 29008438e24SVarun Wadekar /* -------------------------------------------------- 29108438e24SVarun Wadekar * These nops are here so that speculative execution 29208438e24SVarun Wadekar * won't harm us before we are done with warm reset. 29308438e24SVarun Wadekar * -------------------------------------------------- 29408438e24SVarun Wadekar */ 29508438e24SVarun Wadekar .rept 65 29608438e24SVarun Wadekar nop 29708438e24SVarun Wadekar .endr 29808438e24SVarun Wadekar 29908438e24SVarun Wadekar /* -------------------------------------------------- 30008438e24SVarun Wadekar * Do not insert instructions here 30108438e24SVarun Wadekar * -------------------------------------------------- 30208438e24SVarun Wadekar */ 30308438e24SVarun Wadekar#endif 30408438e24SVarun Wadekar 30508438e24SVarun Wadekar /* -------------------------------------------------- 30608438e24SVarun Wadekar * Restore OS Lock bit 30708438e24SVarun Wadekar * -------------------------------------------------- 30808438e24SVarun Wadekar */ 30908438e24SVarun Wadekarrestore_oslock: 31008438e24SVarun Wadekar mov x0, #1 31108438e24SVarun Wadekar msr oslar_el1, x0 31208438e24SVarun Wadekar 31308438e24SVarun Wadekar cpu_init_common 31408438e24SVarun Wadekar 31508438e24SVarun Wadekar /* --------------------------------------------------------------------- 31608438e24SVarun Wadekar * The initial state of the Architectural feature trap register 31708438e24SVarun Wadekar * (CPTR_EL3) is unknown and it must be set to a known state. All 31808438e24SVarun Wadekar * feature traps are disabled. Some bits in this register are marked as 31908438e24SVarun Wadekar * Reserved and should not be modified. 32008438e24SVarun Wadekar * 32108438e24SVarun Wadekar * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1 32208438e24SVarun Wadekar * or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2. 32308438e24SVarun Wadekar * CPTR_EL3.TTA: This causes access to the Trace functionality to trap 32408438e24SVarun Wadekar * to EL3 when executed from EL0, EL1, EL2, or EL3. If system register 32508438e24SVarun Wadekar * access to trace functionality is not supported, this bit is RES0. 32608438e24SVarun Wadekar * CPTR_EL3.TFP: This causes instructions that access the registers 32708438e24SVarun Wadekar * associated with Floating Point and Advanced SIMD execution to trap 32808438e24SVarun Wadekar * to EL3 when executed from any exception level, unless trapped to EL1 32908438e24SVarun Wadekar * or EL2. 33008438e24SVarun Wadekar * --------------------------------------------------------------------- 33108438e24SVarun Wadekar */ 33208438e24SVarun Wadekar mrs x1, cptr_el3 33308438e24SVarun Wadekar bic w1, w1, #TCPAC_BIT 33408438e24SVarun Wadekar bic w1, w1, #TTA_BIT 33508438e24SVarun Wadekar bic w1, w1, #TFP_BIT 33608438e24SVarun Wadekar msr cptr_el3, x1 33708438e24SVarun Wadekar 33808438e24SVarun Wadekar /* -------------------------------------------------- 33908438e24SVarun Wadekar * Get secure world's entry point and jump to it 34008438e24SVarun Wadekar * -------------------------------------------------- 34108438e24SVarun Wadekar */ 34271cb26eaSVarun Wadekar bl plat_get_my_entrypoint 34308438e24SVarun Wadekar br x0 34408438e24SVarun Wadekarendfunc tegra_secure_entrypoint 34508438e24SVarun Wadekar 34608438e24SVarun Wadekar .data 34708438e24SVarun Wadekar .align 3 34808438e24SVarun Wadekar 34908438e24SVarun Wadekar /* -------------------------------------------------- 35071cb26eaSVarun Wadekar * CPU Secure entry point - resume from suspend 35108438e24SVarun Wadekar * -------------------------------------------------- 35208438e24SVarun Wadekar */ 35371cb26eaSVarun Wadekartegra_sec_entry_point: 35408438e24SVarun Wadekar .quad 0 35508438e24SVarun Wadekar 35608438e24SVarun Wadekar /* -------------------------------------------------- 35708438e24SVarun Wadekar * NS world's cold boot entry point 35808438e24SVarun Wadekar * -------------------------------------------------- 35908438e24SVarun Wadekar */ 36008438e24SVarun Wadekarns_image_entrypoint: 36108438e24SVarun Wadekar .quad 0 36208438e24SVarun Wadekar 36308438e24SVarun Wadekar /* -------------------------------------------------- 36408438e24SVarun Wadekar * BL31's physical base address 36508438e24SVarun Wadekar * -------------------------------------------------- 36608438e24SVarun Wadekar */ 36708438e24SVarun Wadekartegra_bl31_phys_base: 36808438e24SVarun Wadekar .quad 0 369