Message ID | 20190813154747.24256-14-hch@lst.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [01/15] irqchip/sifive-plic: set max threshold for ignored handlers | expand |
Hi Christoph, On Tue, Aug 13, 2019 at 05:47:45PM +0200, Christoph Hellwig 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. Sure. > +#ifdef CONFIG_FPU But it doesn't really mean that the running system has an FPU given CONFIG_FPU enabled. Normally the existence of an FPU is checked in riscv_fill_hwcap by searching device tree, where the code looks like bool has_fpu = false; // this one is global ... #ifdef CONFIG_FPU if (elf_hwcap & (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D)) has_fpu = true; #endif Or does CONFIG_FPU have a more intuitive meaning when CONFIG_M_MODE is enabled? > + 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 */
Please ignore the previous mail, I must have missed this part of the patch, > > > + csrr t0, CSR_MISA > > + andi t0, t0, (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D) > > + bnez t0, .Lreset_regs_done > > + In S-mode we were not able to obtain the ISA information in misa, but now the nommu port is in M-mode so this is rather straightforward.
On Wed, Aug 14, 2019 at 09:00:14AM +0800, Alan Kao wrote: > But it doesn't really mean that the running system has an FPU given CONFIG_FPU > enabled. Normally the existence of an FPU is checked in riscv_fill_hwcap by > searching device tree, where the code looks like > > > bool has_fpu = false; // this one is global > ... > #ifdef CONFIG_FPU > if (elf_hwcap & (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D)) > has_fpu = true; > #endif > > > Or does CONFIG_FPU have a more intuitive meaning when CONFIG_M_MODE is enabled? No, it doesn't.. > > > + csrr t0, CSR_MISA > > + andi t0, t0, (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D) > > + bnez t0, .Lreset_regs_done ... which is why we have these few lines of code that check the caps returns from the misa CSR, similar to the elf_caps check quoted above.
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
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 | 86 ++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+)