X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=arch%2Farm%2Fcpu%2Farmv8%2Fstart.S;h=62d97f7e882225a027390e8d2b6f13c4a6a606de;hb=4961eafc25d0bfa7ac5f88ec78a7f7501c202fbb;hp=e70c51d43d86fef80d86781c6363e14ad92bf5f9;hpb=83571bcab10bc8d6d73dc77b64442dbd281afc99;p=u-boot diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S index e70c51d43d..62d97f7e88 100644 --- a/arch/arm/cpu/armv8/start.S +++ b/arch/arm/cpu/armv8/start.S @@ -7,7 +7,6 @@ #include #include -#include #include #include #include @@ -20,7 +19,16 @@ .globl _start _start: +#ifdef CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK +/* + * Various SoCs need something special and SoC-specific up front in + * order to boot, allow them to set that in their boot0.h file and then + * use it here. + */ +#include +#else b reset +#endif .align 3 @@ -44,6 +52,14 @@ _bss_end_ofs: .quad __bss_end - _start reset: + /* Allow the board to save important registers */ + b save_boot_params +.globl save_boot_params_ret +save_boot_params_ret: + +#ifdef CONFIG_SYS_RESET_SCTRL + bl reset_sctrl +#endif /* * Could be EL3/EL2/EL1, Initial State: * Little Endian, MMU Disabled, i/dCache Disabled @@ -51,9 +67,14 @@ reset: adr x0, vectors switch_el x1, 3f, 2f, 1f 3: msr vbar_el3, x0 + mrs x0, scr_el3 + orr x0, x0, #0xf /* SCR_EL3.NS|IRQ|FIQ|EA */ + msr scr_el3, x0 msr cptr_el3, xzr /* Enable FP/SIMD */ +#ifdef COUNTER_FREQUENCY ldr x0, =COUNTER_FREQUENCY msr cntfrq_el0, x0 /* Initialize CNTFRQ */ +#endif b 0f 2: msr vbar_el2, x0 mov x0, #0x33ff @@ -64,14 +85,35 @@ reset: msr cpacr_el1, x0 /* Enable FP/SIMD */ 0: - /* Cache/BPB/TLB Invalidate */ - bl __asm_flush_dcache_all /* dCache clean&invalidate */ - bl __asm_invalidate_icache_all /* iCache invalidate */ - bl __asm_invalidate_tlb_all /* invalidate TLBs */ + /* + * Enalbe SMPEN bit for coherency. + * This register is not architectural but at the moment + * this bit should be set for A53/A57/A72. + */ +#ifdef CONFIG_ARMV8_SET_SMPEN + mrs x0, S3_1_c15_c2_1 /* cpuactlr_el1 */ + orr x0, x0, #0x40 + msr S3_1_c15_c2_1, x0 +#endif + + /* Apply ARM core specific erratas */ + bl apply_core_errata + + /* + * Cache/BPB/TLB Invalidate + * i-cache is invalidated before enabled in icache_enable() + * tlb is invalidated before mmu is enabled in dcache_enable() + * d-cache is invalidated before enabled in dcache_enable() + */ /* Processor specific initialization */ bl lowlevel_init +#if defined(CONFIG_ARMV8_SPIN_TABLE) && !defined(CONFIG_SPL_BUILD) + branch_if_master x0, x1, master_cpu + b spin_table_secondary_jump + /* never return */ +#elif defined(CONFIG_ARMV8_MULTIENTRY) branch_if_master x0, x1, master_cpu /* @@ -83,42 +125,171 @@ slave_cpu: ldr x0, [x1] cbz x0, slave_cpu br x0 /* branch to the given address */ - - /* - * Master CPU - */ +#endif /* CONFIG_ARMV8_MULTIENTRY */ master_cpu: bl _main +#ifdef CONFIG_SYS_RESET_SCTRL +reset_sctrl: + switch_el x1, 3f, 2f, 1f +3: + mrs x0, sctlr_el3 + b 0f +2: + mrs x0, sctlr_el2 + b 0f +1: + mrs x0, sctlr_el1 + +0: + ldr x1, =0xfdfffffa + and x0, x0, x1 + + switch_el x1, 6f, 5f, 4f +6: + msr sctlr_el3, x0 + b 7f +5: + msr sctlr_el2, x0 + b 7f +4: + msr sctlr_el1, x0 + +7: + dsb sy + isb + b __asm_invalidate_tlb_all + ret +#endif + +/*-----------------------------------------------------------------------*/ + +WEAK(apply_core_errata) + + mov x29, lr /* Save LR */ + /* For now, we support Cortex-A57 specific errata only */ + + /* Check if we are running on a Cortex-A57 core */ + branch_if_a57_core x0, apply_a57_core_errata +0: + mov lr, x29 /* Restore LR */ + ret + +apply_a57_core_errata: + +#ifdef CONFIG_ARM_ERRATA_828024 + mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */ + /* Disable non-allocate hint of w-b-n-a memory type */ + orr x0, x0, #1 << 49 + /* Disable write streaming no L1-allocate threshold */ + orr x0, x0, #3 << 25 + /* Disable write streaming no-allocate threshold */ + orr x0, x0, #3 << 27 + msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */ +#endif + +#ifdef CONFIG_ARM_ERRATA_826974 + mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */ + /* Disable speculative load execution ahead of a DMB */ + orr x0, x0, #1 << 59 + msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */ +#endif + +#ifdef CONFIG_ARM_ERRATA_833471 + mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */ + /* FPSCR write flush. + * Note that in some cases where a flush is unnecessary this + could impact performance. */ + orr x0, x0, #1 << 38 + msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */ +#endif + +#ifdef CONFIG_ARM_ERRATA_829520 + mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */ + /* Disable Indirect Predictor bit will prevent this erratum + from occurring + * Note that in some cases where a flush is unnecessary this + could impact performance. */ + orr x0, x0, #1 << 4 + msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */ +#endif + +#ifdef CONFIG_ARM_ERRATA_833069 + mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */ + /* Disable Enable Invalidates of BTB bit */ + and x0, x0, #0xE + msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */ +#endif + b 0b +ENDPROC(apply_core_errata) + /*-----------------------------------------------------------------------*/ WEAK(lowlevel_init) - /* Initialize GIC Secure Bank Status */ mov x29, lr /* Save LR */ - bl gic_init - branch_if_master x0, x1, 1f +#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3) + branch_if_slave x0, 1f + ldr x0, =GICD_BASE + bl gic_init_secure +1: +#if defined(CONFIG_GICV3) + ldr x0, =GICR_BASE + bl gic_init_secure_percpu +#elif defined(CONFIG_GICV2) + ldr x0, =GICD_BASE + ldr x1, =GICC_BASE + bl gic_init_secure_percpu +#endif +#endif + +#ifdef CONFIG_ARMV8_MULTIENTRY + branch_if_master x0, x1, 2f /* * Slave should wait for master clearing spin table. * This sync prevent salves observing incorrect * value of spin table and jumping to wrong place. */ - bl wait_for_wakeup +#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3) +#ifdef CONFIG_GICV2 + ldr x0, =GICC_BASE +#endif + bl gic_wait_for_interrupt +#endif /* - * All processors will enter EL2 and optionally EL1. + * All slaves will enter EL2 and optionally EL1. */ + adr x4, lowlevel_in_el2 + ldr x5, =ES_TO_AARCH64 bl armv8_switch_to_el2 + +lowlevel_in_el2: #ifdef CONFIG_ARMV8_SWITCH_TO_EL1 + adr x4, lowlevel_in_el1 + ldr x5, =ES_TO_AARCH64 bl armv8_switch_to_el1 + +lowlevel_in_el1: #endif -1: +#endif /* CONFIG_ARMV8_MULTIENTRY */ + +2: mov lr, x29 /* Restore LR */ ret ENDPROC(lowlevel_init) +WEAK(smp_kick_all_cpus) + /* Kick secondary cpus up by SGI 0 interrupt */ +#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3) + ldr x0, =GICD_BASE + b gic_kick_secondary_cpus +#endif + ret +ENDPROC(smp_kick_all_cpus) + /*-----------------------------------------------------------------------*/ ENTRY(c_runtime_cpu_setup) @@ -134,3 +305,7 @@ ENTRY(c_runtime_cpu_setup) ret ENDPROC(c_runtime_cpu_setup) + +WEAK(save_boot_params) + b save_boot_params_ret /* back to my caller */ +ENDPROC(save_boot_params)