riscv: clear the instruction cache and all registers when booting
[sfrench/cifs-2.6.git] / arch / riscv / kernel / head.S
index fc99730869466f6652007dec7db645dc36bf85da..64eb8beb228ee7884aeae462ee1939deabe296d5 100644 (file)
@@ -11,6 +11,7 @@
 #include <asm/thread_info.h>
 #include <asm/page.h>
 #include <asm/csr.h>
+#include <asm/hwcap.h>
 #include <asm/image.h>
 
 __INIT
@@ -51,12 +52,18 @@ _start_kernel:
        csrw CSR_IP, zero
 
 #ifdef CONFIG_RISCV_M_MODE
+       /* flush the instruction cache */
+       fence.i
+
+       /* Reset all registers except ra, a0, a1 */
+       call reset_regs
+
        /*
         * The hartid in a0 is expected later on, and we have no firmware
         * to hand it to us.
         */
        csrr a0, CSR_MHARTID
-#endif
+#endif /* CONFIG_RISCV_M_MODE */
 
        /* Load the global pointer */
 .option push
@@ -203,6 +210,85 @@ relocate:
        j .Lsecondary_park
 END(_start)
 
+#ifdef CONFIG_RISCV_M_MODE
+ENTRY(reset_regs)
+       li      sp, 0
+       li      gp, 0
+       li      tp, 0
+       li      t0, 0
+       li      t1, 0
+       li      t2, 0
+       li      s0, 0
+       li      s1, 0
+       li      a2, 0
+       li      a3, 0
+       li      a4, 0
+       li      a5, 0
+       li      a6, 0
+       li      a7, 0
+       li      s2, 0
+       li      s3, 0
+       li      s4, 0
+       li      s5, 0
+       li      s6, 0
+       li      s7, 0
+       li      s8, 0
+       li      s9, 0
+       li      s10, 0
+       li      s11, 0
+       li      t3, 0
+       li      t4, 0
+       li      t5, 0
+       li      t6, 0
+       csrw    sscratch, 0
+
+#ifdef CONFIG_FPU
+       csrr    t0, CSR_MISA
+       andi    t0, t0, (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D)
+       bnez    t0, .Lreset_regs_done
+
+       li      t1, SR_FS
+       csrs    CSR_STATUS, t1
+       fmv.s.x f0, zero
+       fmv.s.x f1, zero
+       fmv.s.x f2, zero
+       fmv.s.x f3, zero
+       fmv.s.x f4, zero
+       fmv.s.x f5, zero
+       fmv.s.x f6, zero
+       fmv.s.x f7, zero
+       fmv.s.x f8, zero
+       fmv.s.x f9, zero
+       fmv.s.x f10, zero
+       fmv.s.x f11, zero
+       fmv.s.x f12, zero
+       fmv.s.x f13, zero
+       fmv.s.x f14, zero
+       fmv.s.x f15, zero
+       fmv.s.x f16, zero
+       fmv.s.x f17, zero
+       fmv.s.x f18, zero
+       fmv.s.x f19, zero
+       fmv.s.x f20, zero
+       fmv.s.x f21, zero
+       fmv.s.x f22, zero
+       fmv.s.x f23, zero
+       fmv.s.x f24, zero
+       fmv.s.x f25, zero
+       fmv.s.x f26, zero
+       fmv.s.x f27, zero
+       fmv.s.x f28, zero
+       fmv.s.x f29, zero
+       fmv.s.x f30, zero
+       fmv.s.x f31, zero
+       csrw    fcsr, 0
+       /* note that the caller must clear SR_FS */
+#endif /* CONFIG_FPU */
+.Lreset_regs_done:
+       ret
+END(reset_regs)
+#endif /* CONFIG_RISCV_M_MODE */
+
 __PAGE_ALIGNED_BSS
        /* Empty zero page */
        .balign PAGE_SIZE