diff mbox series

[12/15] riscv: clear the instruction cache and all registers when booting

Message ID 20191017173743.5430-13-hch@lst.de (mailing list archive)
State New, archived
Headers show
Series [01/15] riscv: cleanup <asm/bug.h> | expand

Commit Message

Christoph Hellwig Oct. 17, 2019, 5:37 p.m. UTC
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 <hch@lst.de>
---
 arch/riscv/include/asm/csr.h |  1 +
 arch/riscv/kernel/head.S     | 88 +++++++++++++++++++++++++++++++++++-
 2 files changed, 88 insertions(+), 1 deletion(-)

Comments

Anup Patel Oct. 18, 2019, 3:05 a.m. UTC | #1
On Thu, Oct 17, 2019 at 11:08 PM Christoph Hellwig <hch@lst.de> wrote:
>
> 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 <hch@lst.de>
> ---
>  arch/riscv/include/asm/csr.h |  1 +
>  arch/riscv/kernel/head.S     | 88 +++++++++++++++++++++++++++++++++++-
>  2 files changed, 88 insertions(+), 1 deletion(-)
>
> diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
> index d0b5113e1a54..ee0101278608 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 583784cb3a32..25867b99cc95 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,12 +52,18 @@ _start_kernel:
>         csrw CSR_XIP, 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_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_RISCV_M_MODE */
> +
>  __PAGE_ALIGNED_BSS
>         /* Empty zero page */
>         .balign PAGE_SIZE
> --
> 2.20.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Regards,
Anup
diff mbox series

Patch

diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index d0b5113e1a54..ee0101278608 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 583784cb3a32..25867b99cc95 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,12 +52,18 @@  _start_kernel:
 	csrw CSR_XIP, 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_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_RISCV_M_MODE */
+
 __PAGE_ALIGNED_BSS
 	/* Empty zero page */
 	.balign PAGE_SIZE