When we get booted we want a clear slate without any leaks from previous
supervisors or the firmware.  Flush the instruction cache and then clear
all registers to known good values.  This is really important for the
upcoming nommu support that runs on M-mode, but can't really harm when
running in S-mode either.  Vaguely based on the concepts from opensbi.

Signed-off-by: Christoph Hellwig <h...@lst.de>
---
 arch/riscv/include/asm/csr.h |  1 +
 arch/riscv/kernel/head.S     | 86 ++++++++++++++++++++++++++++++++++++
 2 files changed, 87 insertions(+)

diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index 64f8fe84b88f..a804272a5f19 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -83,6 +83,7 @@
 /* symbolic CSR names: */
 #define CSR_MHARTID            0xf14
 #define CSR_MSTATUS            0x300
+#define CSR_MISA               0x301
 #define CSR_MIE                        0x304
 #define CSR_MTVEC              0x305
 #define CSR_MSCRATCH           0x340
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 275c2ab1e990..b603edb29e73 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -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,6 +52,12 @@ _start_kernel:
        csrw CSR_XIP, zero
 
 #ifdef CONFIG_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.
@@ -201,6 +208,85 @@ relocate:
        j .Lsecondary_park
 END(_start)
 
+#ifdef CONFIG_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_XSTATUS, 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_M_MODE */
+
 __PAGE_ALIGNED_BSS
        /* Empty zero page */
        .balign PAGE_SIZE
-- 
2.20.1

Reply via email to