Merge branch 'master' of git://git.denx.de/u-boot-net
[oweals/u-boot.git] / arch / arm / cpu / armv8 / start.S
index 4b11aa4f22272cfa1766b0482ff8b1797e15db6e..2ee60d60f123b9e5f86729c16088a225b086a4fa 100644 (file)
@@ -7,7 +7,6 @@
 
 #include <asm-offsets.h>
 #include <config.h>
-#include <version.h>
 #include <linux/linkage.h>
 #include <asm/macro.h>
 #include <asm/armv8/mmu.h>
@@ -44,6 +43,9 @@ _bss_end_ofs:
        .quad   __bss_end - _start
 
 reset:
+#ifdef CONFIG_SYS_RESET_SCTRL
+       bl reset_sctrl
+#endif
        /*
         * Could be EL3/EL2/EL1, Initial State:
         * Little Endian, MMU Disabled, i/dCache Disabled
@@ -55,8 +57,10 @@ reset:
        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
@@ -67,6 +71,9 @@ reset:
        msr     cpacr_el1, x0                   /* Enable FP/SIMD */
 0:
 
+       /* Apply ARM core specific erratas */
+       bl      apply_core_errata
+
        /*
         * Cache/BPB/TLB Invalidate
         * i-cache is invalidated before enabled in icache_enable()
@@ -77,6 +84,7 @@ reset:
        /* Processor specific initialization */
        bl      lowlevel_init
 
+#ifdef CONFIG_ARMV8_MULTIENTRY
        branch_if_master x0, x1, master_cpu
 
        /*
@@ -88,18 +96,101 @@ slave_cpu:
        ldr     x0, [x1]
        cbz     x0, slave_cpu
        br      x0                      /* branch to the given address */
-
-       /*
-        * Master CPU
-        */
 master_cpu:
+       /* On the master CPU */
+#endif /* CONFIG_ARMV8_MULTIENTRY */
+
        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_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)
        mov     x29, lr                 /* Save LR */
 
+#ifndef CONFIG_ARMV8_MULTIENTRY
+       /*
+        * For single-entry systems the lowlevel init is very simple.
+        */
+       ldr     x0, =GICD_BASE
+       bl      gic_init_secure
+
+#else /* CONFIG_ARMV8_MULTIENTRY is set */
+
 #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
        branch_if_slave x0, 1f
        ldr     x0, =GICD_BASE
@@ -137,6 +228,8 @@ WEAK(lowlevel_init)
        bl      armv8_switch_to_el1
 #endif
 
+#endif /* CONFIG_ARMV8_MULTIENTRY */
+
 2:
        mov     lr, x29                 /* Restore LR */
        ret