X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=arch%2Farm%2Fcpu%2Farmv8%2Fstart.S;h=62d97f7e882225a027390e8d2b6f13c4a6a606de;hb=4961eafc25d0bfa7ac5f88ec78a7f7501c202fbb;hp=33d3f3688ae83bc45f13a79e12c84a0848d20d05;hpb=c71645ad2bd5179ad21e2501c26f574e9688f02a;p=u-boot diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S index 33d3f3688a..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,19 +52,29 @@ _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 */ adr x0, vectors switch_el x1, 3f, 2f, 1f -3: mrs x0, scr_el3 +3: msr vbar_el3, x0 + mrs x0, scr_el3 orr x0, x0, #0xf /* SCR_EL3.NS|IRQ|FIQ|EA */ msr scr_el3, x0 - msr vbar_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 @@ -67,6 +85,20 @@ reset: msr cpacr_el1, x0 /* Enable FP/SIMD */ 0: + /* + * 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() @@ -77,6 +109,11 @@ reset: /* 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 /* @@ -88,13 +125,104 @@ 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) @@ -115,6 +243,7 @@ WEAK(lowlevel_init) #endif #endif +#ifdef CONFIG_ARMV8_MULTIENTRY branch_if_master x0, x1, 2f /* @@ -132,11 +261,21 @@ WEAK(lowlevel_init) /* * 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 +#endif /* CONFIG_ARMV8_MULTIENTRY */ + 2: mov lr, x29 /* Restore LR */ ret @@ -144,12 +283,10 @@ ENDPROC(lowlevel_init) WEAK(smp_kick_all_cpus) /* Kick secondary cpus up by SGI 0 interrupt */ - mov x29, lr /* Save LR */ #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3) ldr x0, =GICD_BASE - bl gic_kick_secondary_cpus + b gic_kick_secondary_cpus #endif - mov lr, x29 /* Restore LR */ ret ENDPROC(smp_kick_all_cpus) @@ -168,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)