> > Subject: [PATCH v5 1/4] riscv: Add kconfig option to run U-Boot in S-mode > > > > This patch adds kconfig option RISCV_SMODE to run U-Boot in S-mode. When > > this > > opition is enabled we use s<xyz> CSRs instead of m<xyz> CSRs. > > > > It is important to note that there is no equivalent S-mode CSR for misa and > > mhartid CSRs so we expect M-mode runtime firmware (BBL or equivalent) to > > emulate misa and mhartid CSR read. > > > > In-future, we will have more patches to avoid accessing misa and mhartid > > CSRs > > from S-mode. > > > > Signed-off-by: Anup Patel <a...@brainfault.org> > > Reviewed-by: Bin Meng <bmeng...@gmail.com> > > Tested-by: Bin Meng <bmeng...@gmail.com> > > Reviewed-by: Lukas Auer <lukas.a...@aisec.fraunhofer.de> > > --- > > arch/riscv/Kconfig | 5 +++++ > > arch/riscv/cpu/start.S | 33 ++++++++++++++++++++++++++++ > > arch/riscv/include/asm/encoding.h | 2 ++ > > arch/riscv/lib/interrupts.c | 36 +++++++++++++++++++++++-------- > > 4 files changed, 67 insertions(+), 9 deletions(-) > > > > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index > > 3e0af55e71..732a357a99 > > 100644 > > --- a/arch/riscv/Kconfig > > +++ b/arch/riscv/Kconfig > > @@ -55,6 +55,11 @@ config RISCV_ISA_C > > config RISCV_ISA_A > > def_bool y > > > > +config RISCV_SMODE > > + bool "Run in S-Mode" > > + help > > + Enable this option to build U-Boot for RISC-V S-Mode > > + > > config 32BIT > > bool > > > > diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index > > 15e1b8199a..704190f946 100644 > > --- a/arch/riscv/cpu/start.S > > +++ b/arch/riscv/cpu/start.S > > @@ -41,10 +41,18 @@ _start: > > li t0, CONFIG_SYS_SDRAM_BASE > > SREG a2, 0(t0) > > la t0, trap_entry > > +#ifdef CONFIG_RISCV_SMODE > > + csrw stvec, t0 > > +#else > > csrw mtvec, t0 > > +#endif > > > > /* mask all interrupts */ > > +#ifdef CONFIG_RISCV_SMODE > > + csrw sie, zero > > +#else > > csrw mie, zero > > +#endif > > > > /* Enable cache */ > > jal icache_enable > > @@ -166,7 +174,11 @@ fix_rela_dyn: > > */ > > la t0, trap_entry > > add t0, t0, t6 > > +#ifdef CONFIG_RISCV_SMODE > > + csrw stvec, t0 > > +#else > > csrw mtvec, t0 > > +#endif > > > > clear_bss: > > la t0, __bss_start /* t0 <- rel __bss_start in FLASH */ > > @@ -238,17 +250,34 @@ trap_entry: > > SREG x29, 29*REGBYTES(sp) > > SREG x30, 30*REGBYTES(sp) > > SREG x31, 31*REGBYTES(sp) > > +#ifdef CONFIG_RISCV_SMODE > > + csrr a0, scause > > + csrr a1, sepc > > +#else > > csrr a0, mcause > > csrr a1, mepc > > +#endif > > mv a2, sp > > jal handle_trap > > +#ifdef CONFIG_RISCV_SMODE > > + csrw sepc, a0 > > +#else > > csrw mepc, a0 > > +#endif > > > > +#ifdef CONFIG_RISCV_SMODE > > +/* > > + * Remain in S-mode after sret > > + */ > > + li t0, SSTATUS_SPP > > + csrs sstatus, t0 > > +#else > > /* > > * Remain in M-mode after mret > > */ > > li t0, MSTATUS_MPP > > csrs mstatus, t0 > > +#endif
It only the difference between s and m in csr. The code seem to be duplicate too much. Can you implement it in macro ? or consider to separate it in different .S file It may too complex to maintain in the future. B.R Rick > > LREG x1, 1*REGBYTES(sp) > > LREG x2, 2*REGBYTES(sp) > > LREG x3, 3*REGBYTES(sp) > > @@ -281,4 +310,8 @@ trap_entry: > > LREG x30, 30*REGBYTES(sp) > > LREG x31, 31*REGBYTES(sp) > > addi sp, sp, 32*REGBYTES > > +#ifdef CONFIG_RISCV_SMODE > > + sret > > +#else > > mret > > +#endif > > diff --git a/arch/riscv/include/asm/encoding.h > > b/arch/riscv/include/asm/encoding.h > > index 9ea50ce640..153f5af2ff 100644 > > --- a/arch/riscv/include/asm/encoding.h > > +++ b/arch/riscv/include/asm/encoding.h > > @@ -143,6 +143,8 @@ > > # define MCAUSE_CAUSE MCAUSE32_CAUSE > > #endif > > > > +#define SCAUSE_INT MCAUSE_INT > > + > > #define RISCV_PGSHIFT 12 > > #define RISCV_PGSIZE BIT(RISCV_PGSHIFT) > > > > diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c index > > 903a1c4cd5..8793f233d0 100644 > > --- a/arch/riscv/lib/interrupts.c > > +++ b/arch/riscv/lib/interrupts.c > > @@ -34,17 +34,35 @@ int disable_interrupts(void) > > return 0; > > } > > > > -ulong handle_trap(ulong mcause, ulong epc, struct pt_regs *regs) > > +ulong handle_trap(ulong cause, ulong epc, struct pt_regs *regs) > > { > > - ulong is_int; > > + ulong is_irq, irq; > > > > - is_int = (mcause & MCAUSE_INT); > > - if ((is_int) && ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT)) > > - external_interrupt(0); /* handle_m_ext_interrupt */ > > - else if ((is_int) && ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER)) > > - timer_interrupt(0); /* handle_m_timer_interrupt */ > > - else > > - _exit_trap(mcause, epc, regs); > > +#ifdef CONFIG_RISCV_SMODE > > + is_irq = (cause & SCAUSE_INT); > > + irq = (cause & ~SCAUSE_INT); > > +#else > > + is_irq = (cause & MCAUSE_INT); > > + irq = (cause & ~MCAUSE_INT); > > +#endif > > + > > + if (is_irq) { > > + switch (irq) { > > + case IRQ_M_EXT: > > + case IRQ_S_EXT: > > + external_interrupt(0); /* handle external interrupt > > */ > > + break; > > + case IRQ_M_TIMER: > > + case IRQ_S_TIMER: > > + timer_interrupt(0); /* handle timer interrupt */ > > + break; > > + default: > > + _exit_trap(cause, epc, regs); > > + break; > > + }; > > + } else { > > + _exit_trap(cause, epc, regs); > > + } > > > > return epc; > > } > > -- > > 2.17.1 > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot