10ae76531SDavid Feng/* 20ae76531SDavid Feng * (C) Copyright 2013 30ae76531SDavid Feng * David Feng <fenghua@phytium.com.cn> 40ae76531SDavid Feng * 50ae76531SDavid Feng * SPDX-License-Identifier: GPL-2.0+ 60ae76531SDavid Feng */ 70ae76531SDavid Feng 80ae76531SDavid Feng#include <asm-offsets.h> 90ae76531SDavid Feng#include <config.h> 100ae76531SDavid Feng#include <linux/linkage.h> 110ae76531SDavid Feng#include <asm/macro.h> 120ae76531SDavid Feng#include <asm/armv8/mmu.h> 130ae76531SDavid Feng 140ae76531SDavid Feng/************************************************************************* 150ae76531SDavid Feng * 160ae76531SDavid Feng * Startup Code (reset vector) 170ae76531SDavid Feng * 180ae76531SDavid Feng *************************************************************************/ 190ae76531SDavid Feng 200ae76531SDavid Feng.globl _start 210ae76531SDavid Feng_start: 220ae76531SDavid Feng b reset 230ae76531SDavid Feng 24*cdaa633fSAndre Przywara#ifdef CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK 25*cdaa633fSAndre Przywara/* 26*cdaa633fSAndre Przywara * Various SoCs need something special and SoC-specific up front in 27*cdaa633fSAndre Przywara * order to boot, allow them to set that in their boot0.h file and then 28*cdaa633fSAndre Przywara * use it here. 29*cdaa633fSAndre Przywara */ 30*cdaa633fSAndre Przywara#include <asm/arch/boot0.h> 31*cdaa633fSAndre PrzywaraARM_SOC_BOOT0_HOOK 32*cdaa633fSAndre Przywara#endif 33*cdaa633fSAndre Przywara 340ae76531SDavid Feng .align 3 350ae76531SDavid Feng 360ae76531SDavid Feng.globl _TEXT_BASE 370ae76531SDavid Feng_TEXT_BASE: 380ae76531SDavid Feng .quad CONFIG_SYS_TEXT_BASE 390ae76531SDavid Feng 400ae76531SDavid Feng/* 410ae76531SDavid Feng * These are defined in the linker script. 420ae76531SDavid Feng */ 430ae76531SDavid Feng.globl _end_ofs 440ae76531SDavid Feng_end_ofs: 450ae76531SDavid Feng .quad _end - _start 460ae76531SDavid Feng 470ae76531SDavid Feng.globl _bss_start_ofs 480ae76531SDavid Feng_bss_start_ofs: 490ae76531SDavid Feng .quad __bss_start - _start 500ae76531SDavid Feng 510ae76531SDavid Feng.globl _bss_end_ofs 520ae76531SDavid Feng_bss_end_ofs: 530ae76531SDavid Feng .quad __bss_end - _start 540ae76531SDavid Feng 550ae76531SDavid Fengreset: 5694f7ff36SSergey Temerkhanov#ifdef CONFIG_SYS_RESET_SCTRL 5794f7ff36SSergey Temerkhanov bl reset_sctrl 5894f7ff36SSergey Temerkhanov#endif 590ae76531SDavid Feng /* 600ae76531SDavid Feng * Could be EL3/EL2/EL1, Initial State: 610ae76531SDavid Feng * Little Endian, MMU Disabled, i/dCache Disabled 620ae76531SDavid Feng */ 630ae76531SDavid Feng adr x0, vectors 640ae76531SDavid Feng switch_el x1, 3f, 2f, 1f 651277bac0SDavid Feng3: msr vbar_el3, x0 661277bac0SDavid Feng mrs x0, scr_el3 67c71645adSDavid Feng orr x0, x0, #0xf /* SCR_EL3.NS|IRQ|FIQ|EA */ 68c71645adSDavid Feng msr scr_el3, x0 690ae76531SDavid Feng msr cptr_el3, xzr /* Enable FP/SIMD */ 7070bcb43eSThierry Reding#ifdef COUNTER_FREQUENCY 710ae76531SDavid Feng ldr x0, =COUNTER_FREQUENCY 720ae76531SDavid Feng msr cntfrq_el0, x0 /* Initialize CNTFRQ */ 7370bcb43eSThierry Reding#endif 740ae76531SDavid Feng b 0f 750ae76531SDavid Feng2: msr vbar_el2, x0 760ae76531SDavid Feng mov x0, #0x33ff 770ae76531SDavid Feng msr cptr_el2, x0 /* Enable FP/SIMD */ 780ae76531SDavid Feng b 0f 790ae76531SDavid Feng1: msr vbar_el1, x0 800ae76531SDavid Feng mov x0, #3 << 20 810ae76531SDavid Feng msr cpacr_el1, x0 /* Enable FP/SIMD */ 820ae76531SDavid Feng0: 830ae76531SDavid Feng 8437118fb2SBhupesh Sharma /* Apply ARM core specific erratas */ 8537118fb2SBhupesh Sharma bl apply_core_errata 8637118fb2SBhupesh Sharma 871e6ad55cSYork Sun /* 881e6ad55cSYork Sun * Cache/BPB/TLB Invalidate 891e6ad55cSYork Sun * i-cache is invalidated before enabled in icache_enable() 901e6ad55cSYork Sun * tlb is invalidated before mmu is enabled in dcache_enable() 911e6ad55cSYork Sun * d-cache is invalidated before enabled in dcache_enable() 921e6ad55cSYork Sun */ 930ae76531SDavid Feng 940ae76531SDavid Feng /* Processor specific initialization */ 950ae76531SDavid Feng bl lowlevel_init 960ae76531SDavid Feng 9723b5877cSLinus Walleij#ifdef CONFIG_ARMV8_MULTIENTRY 980ae76531SDavid Feng branch_if_master x0, x1, master_cpu 990ae76531SDavid Feng 1000ae76531SDavid Feng /* 1010ae76531SDavid Feng * Slave CPUs 1020ae76531SDavid Feng */ 1030ae76531SDavid Fengslave_cpu: 1040ae76531SDavid Feng wfe 1050ae76531SDavid Feng ldr x1, =CPU_RELEASE_ADDR 1060ae76531SDavid Feng ldr x0, [x1] 1070ae76531SDavid Feng cbz x0, slave_cpu 1080ae76531SDavid Feng br x0 /* branch to the given address */ 1090ae76531SDavid Fengmaster_cpu: 11023b5877cSLinus Walleij /* On the master CPU */ 11123b5877cSLinus Walleij#endif /* CONFIG_ARMV8_MULTIENTRY */ 11223b5877cSLinus Walleij 1130ae76531SDavid Feng bl _main 1140ae76531SDavid Feng 11594f7ff36SSergey Temerkhanov#ifdef CONFIG_SYS_RESET_SCTRL 11694f7ff36SSergey Temerkhanovreset_sctrl: 11794f7ff36SSergey Temerkhanov switch_el x1, 3f, 2f, 1f 11894f7ff36SSergey Temerkhanov3: 11994f7ff36SSergey Temerkhanov mrs x0, sctlr_el3 12094f7ff36SSergey Temerkhanov b 0f 12194f7ff36SSergey Temerkhanov2: 12294f7ff36SSergey Temerkhanov mrs x0, sctlr_el2 12394f7ff36SSergey Temerkhanov b 0f 12494f7ff36SSergey Temerkhanov1: 12594f7ff36SSergey Temerkhanov mrs x0, sctlr_el1 12694f7ff36SSergey Temerkhanov 12794f7ff36SSergey Temerkhanov0: 12894f7ff36SSergey Temerkhanov ldr x1, =0xfdfffffa 12994f7ff36SSergey Temerkhanov and x0, x0, x1 13094f7ff36SSergey Temerkhanov 13194f7ff36SSergey Temerkhanov switch_el x1, 6f, 5f, 4f 13294f7ff36SSergey Temerkhanov6: 13394f7ff36SSergey Temerkhanov msr sctlr_el3, x0 13494f7ff36SSergey Temerkhanov b 7f 13594f7ff36SSergey Temerkhanov5: 13694f7ff36SSergey Temerkhanov msr sctlr_el2, x0 13794f7ff36SSergey Temerkhanov b 7f 13894f7ff36SSergey Temerkhanov4: 13994f7ff36SSergey Temerkhanov msr sctlr_el1, x0 14094f7ff36SSergey Temerkhanov 14194f7ff36SSergey Temerkhanov7: 14294f7ff36SSergey Temerkhanov dsb sy 14394f7ff36SSergey Temerkhanov isb 14494f7ff36SSergey Temerkhanov b __asm_invalidate_tlb_all 14594f7ff36SSergey Temerkhanov ret 14694f7ff36SSergey Temerkhanov#endif 14794f7ff36SSergey Temerkhanov 1480ae76531SDavid Feng/*-----------------------------------------------------------------------*/ 1490ae76531SDavid Feng 15037118fb2SBhupesh SharmaWEAK(apply_core_errata) 15137118fb2SBhupesh Sharma 15237118fb2SBhupesh Sharma mov x29, lr /* Save LR */ 15337118fb2SBhupesh Sharma /* For now, we support Cortex-A57 specific errata only */ 15437118fb2SBhupesh Sharma 15537118fb2SBhupesh Sharma /* Check if we are running on a Cortex-A57 core */ 15637118fb2SBhupesh Sharma branch_if_a57_core x0, apply_a57_core_errata 15737118fb2SBhupesh Sharma0: 15837118fb2SBhupesh Sharma mov lr, x29 /* Restore LR */ 15937118fb2SBhupesh Sharma ret 16037118fb2SBhupesh Sharma 16137118fb2SBhupesh Sharmaapply_a57_core_errata: 16237118fb2SBhupesh Sharma 16337118fb2SBhupesh Sharma#ifdef CONFIG_ARM_ERRATA_828024 16437118fb2SBhupesh Sharma mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */ 16537118fb2SBhupesh Sharma /* Disable non-allocate hint of w-b-n-a memory type */ 166f299b5b0SBhupesh Sharma orr x0, x0, #1 << 49 16737118fb2SBhupesh Sharma /* Disable write streaming no L1-allocate threshold */ 168f299b5b0SBhupesh Sharma orr x0, x0, #3 << 25 16937118fb2SBhupesh Sharma /* Disable write streaming no-allocate threshold */ 170f299b5b0SBhupesh Sharma orr x0, x0, #3 << 27 17137118fb2SBhupesh Sharma msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */ 17237118fb2SBhupesh Sharma#endif 17337118fb2SBhupesh Sharma 17437118fb2SBhupesh Sharma#ifdef CONFIG_ARM_ERRATA_826974 17537118fb2SBhupesh Sharma mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */ 17637118fb2SBhupesh Sharma /* Disable speculative load execution ahead of a DMB */ 177f299b5b0SBhupesh Sharma orr x0, x0, #1 << 59 17837118fb2SBhupesh Sharma msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */ 17937118fb2SBhupesh Sharma#endif 18037118fb2SBhupesh Sharma 1812ea3a448SAshish kumar#ifdef CONFIG_ARM_ERRATA_833471 1822ea3a448SAshish kumar mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */ 1832ea3a448SAshish kumar /* FPSCR write flush. 1842ea3a448SAshish kumar * Note that in some cases where a flush is unnecessary this 1852ea3a448SAshish kumar could impact performance. */ 1862ea3a448SAshish kumar orr x0, x0, #1 << 38 1872ea3a448SAshish kumar msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */ 1882ea3a448SAshish kumar#endif 1892ea3a448SAshish kumar 1902ea3a448SAshish kumar#ifdef CONFIG_ARM_ERRATA_829520 1912ea3a448SAshish kumar mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */ 1922ea3a448SAshish kumar /* Disable Indirect Predictor bit will prevent this erratum 1932ea3a448SAshish kumar from occurring 1942ea3a448SAshish kumar * Note that in some cases where a flush is unnecessary this 1952ea3a448SAshish kumar could impact performance. */ 1962ea3a448SAshish kumar orr x0, x0, #1 << 4 1972ea3a448SAshish kumar msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */ 1982ea3a448SAshish kumar#endif 1992ea3a448SAshish kumar 20037118fb2SBhupesh Sharma#ifdef CONFIG_ARM_ERRATA_833069 20137118fb2SBhupesh Sharma mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */ 20237118fb2SBhupesh Sharma /* Disable Enable Invalidates of BTB bit */ 20337118fb2SBhupesh Sharma and x0, x0, #0xE 20437118fb2SBhupesh Sharma msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */ 20537118fb2SBhupesh Sharma#endif 20637118fb2SBhupesh Sharma b 0b 20737118fb2SBhupesh SharmaENDPROC(apply_core_errata) 20837118fb2SBhupesh Sharma 20937118fb2SBhupesh Sharma/*-----------------------------------------------------------------------*/ 21037118fb2SBhupesh Sharma 2110ae76531SDavid FengWEAK(lowlevel_init) 2120ae76531SDavid Feng mov x29, lr /* Save LR */ 2130ae76531SDavid Feng 214c71645adSDavid Feng#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3) 215c71645adSDavid Feng branch_if_slave x0, 1f 216c71645adSDavid Feng ldr x0, =GICD_BASE 217c71645adSDavid Feng bl gic_init_secure 218c71645adSDavid Feng1: 219c71645adSDavid Feng#if defined(CONFIG_GICV3) 220c71645adSDavid Feng ldr x0, =GICR_BASE 221c71645adSDavid Feng bl gic_init_secure_percpu 222c71645adSDavid Feng#elif defined(CONFIG_GICV2) 223c71645adSDavid Feng ldr x0, =GICD_BASE 224c71645adSDavid Feng ldr x1, =GICC_BASE 225c71645adSDavid Feng bl gic_init_secure_percpu 226c71645adSDavid Feng#endif 22711661193SStephen Warren#endif 228c71645adSDavid Feng 229d38fca40SMasahiro Yamada#ifdef CONFIG_ARMV8_MULTIENTRY 230c71645adSDavid Feng branch_if_master x0, x1, 2f 2310ae76531SDavid Feng 2320ae76531SDavid Feng /* 2330ae76531SDavid Feng * Slave should wait for master clearing spin table. 2340ae76531SDavid Feng * This sync prevent salves observing incorrect 2350ae76531SDavid Feng * value of spin table and jumping to wrong place. 2360ae76531SDavid Feng */ 237c71645adSDavid Feng#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3) 238c71645adSDavid Feng#ifdef CONFIG_GICV2 239c71645adSDavid Feng ldr x0, =GICC_BASE 240c71645adSDavid Feng#endif 241c71645adSDavid Feng bl gic_wait_for_interrupt 242c71645adSDavid Feng#endif 2430ae76531SDavid Feng 2440ae76531SDavid Feng /* 245c71645adSDavid Feng * All slaves will enter EL2 and optionally EL1. 2460ae76531SDavid Feng */ 2470ae76531SDavid Feng bl armv8_switch_to_el2 2480ae76531SDavid Feng#ifdef CONFIG_ARMV8_SWITCH_TO_EL1 2490ae76531SDavid Feng bl armv8_switch_to_el1 2500ae76531SDavid Feng#endif 2510ae76531SDavid Feng 25223b5877cSLinus Walleij#endif /* CONFIG_ARMV8_MULTIENTRY */ 25323b5877cSLinus Walleij 254c71645adSDavid Feng2: 2550ae76531SDavid Feng mov lr, x29 /* Restore LR */ 2560ae76531SDavid Feng ret 2570ae76531SDavid FengENDPROC(lowlevel_init) 2580ae76531SDavid Feng 259c71645adSDavid FengWEAK(smp_kick_all_cpus) 260c71645adSDavid Feng /* Kick secondary cpus up by SGI 0 interrupt */ 261c71645adSDavid Feng mov x29, lr /* Save LR */ 262c71645adSDavid Feng#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3) 263c71645adSDavid Feng ldr x0, =GICD_BASE 264c71645adSDavid Feng bl gic_kick_secondary_cpus 265c71645adSDavid Feng#endif 266c71645adSDavid Feng mov lr, x29 /* Restore LR */ 267c71645adSDavid Feng ret 268c71645adSDavid FengENDPROC(smp_kick_all_cpus) 269c71645adSDavid Feng 2700ae76531SDavid Feng/*-----------------------------------------------------------------------*/ 2710ae76531SDavid Feng 2720ae76531SDavid FengENTRY(c_runtime_cpu_setup) 2730ae76531SDavid Feng /* Relocate vBAR */ 2740ae76531SDavid Feng adr x0, vectors 2750ae76531SDavid Feng switch_el x1, 3f, 2f, 1f 2760ae76531SDavid Feng3: msr vbar_el3, x0 2770ae76531SDavid Feng b 0f 2780ae76531SDavid Feng2: msr vbar_el2, x0 2790ae76531SDavid Feng b 0f 2800ae76531SDavid Feng1: msr vbar_el1, x0 2810ae76531SDavid Feng0: 2820ae76531SDavid Feng 2830ae76531SDavid Feng ret 2840ae76531SDavid FengENDPROC(c_runtime_cpu_setup) 285