[U-Boot] [PATCH v5 1/4] riscv: Add kconfig option to run U-Boot in S-mode
Rick Chen
rickchen36 at gmail.com
Tue Nov 27 06:40:55 UTC 2018
> > 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 <anup at brainfault.org>
> > Reviewed-by: Bin Meng <bmeng.cn at gmail.com>
> > Tested-by: Bin Meng <bmeng.cn at gmail.com>
> > Reviewed-by: Lukas Auer <lukas.auer at 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
>
More information about the U-Boot
mailing list