[U-Boot] [PATCH 0/3] RISC-V S-mode support

This patchset allows us runing u-boot in S-mode.
This is particularly useful on platforms where M-mode runtime firmware is an independent firmware and u-boot is used as last stage OS bootloader.
The patchset is tested on QEMU in both M-mode and S-mode.
Anup Patel (3): riscv: Add kconfig option to run u-boot in S-mode riscv: qemu: Use different SYS_TEXT_BASE for S-mode riscv: Add S-mode defconfigs for QEMU virt machine
arch/riscv/Kconfig | 6 ++++++ arch/riscv/cpu/start.S | 31 ++++++++++++++++++++++++++++ board/emulation/qemu-riscv/Kconfig | 3 ++- configs/qemu-riscv32-smode_defconfig | 7 +++++++ configs/qemu-riscv64-smode_defconfig | 8 +++++++ 5 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 configs/qemu-riscv32-smode_defconfig create mode 100644 configs/qemu-riscv64-smode_defconfig

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.
Eventually, we will have patches to avoid accessing misa and mhartid from S-mode.
Signed-off-by: Anup Patel anup@brainfault.org --- arch/riscv/Kconfig | 6 ++++++ arch/riscv/cpu/start.S | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 168ca3de7c..0ee3bcc3c5 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -37,6 +37,12 @@ config CPU_RISCV_64
endchoice
+config RISCV_SMODE + bool "Run in S-Mode" + default n + help + Enable this option to build an 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 7cd7755190..669d3bde92 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -47,9 +47,15 @@ handle_reset: li t0, CONFIG_SYS_SDRAM_BASE SREG a2, 0(t0) la t0, trap_entry +#ifdef CONFIG_RISCV_SMODE + csrw stvec, t0 + csrwi sstatus, 0 + csrwi sie, 0 +#else csrw mtvec, t0 csrwi mstatus, 0 csrwi mie, 0 +#endif
/* * Do CPU critical regs init only at reboot, @@ -171,7 +177,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 */ @@ -241,17 +251,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 LREG x1, 1*REGBYTES(sp) LREG x2, 2*REGBYTES(sp) LREG x3, 3*REGBYTES(sp) @@ -284,7 +311,11 @@ 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
#ifdef CONFIG_INIT_CRITICAL cpu_init_crit:

When u-boot runs in S-mode, the M-mode runtime firmware (BBL or equivalent) uses memory range in 0x80000000 to 0x80200000. Due to this, we cannot use 0x80000000 as SYS_TEXT_BASE when running in S-mode. Instead for S-mode, we use 0x80200000 as SYS_TEXT_BASE.
Even Linux RISC-V kernel ignores/reserves memory range 0x80000000 to 0x80200000 because it runs in S-mode.
Signed-off-by: Anup Patel anup@brainfault.org --- board/emulation/qemu-riscv/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig index 37a80db6a9..88f56f30e5 100644 --- a/board/emulation/qemu-riscv/Kconfig +++ b/board/emulation/qemu-riscv/Kconfig @@ -13,7 +13,8 @@ config SYS_CONFIG_NAME default "qemu-riscv"
config SYS_TEXT_BASE - default 0x80000000 + default 0x80000000 if !RISCV_SMODE + default 0x80200000 if RISCV_SMODE
config BOARD_SPECIFIC_OPTIONS # dummy def_bool y

This patch adds S-mode defconfigs for QEMU virt machine so that we can run u-boot in S-mode on QEMU using M-mode runtime firmware (BBL or equivalent).
Signed-off-by: Anup Patel anup@brainfault.org --- configs/qemu-riscv32-smode_defconfig | 7 +++++++ configs/qemu-riscv64-smode_defconfig | 8 ++++++++ 2 files changed, 15 insertions(+) create mode 100644 configs/qemu-riscv32-smode_defconfig create mode 100644 configs/qemu-riscv64-smode_defconfig
diff --git a/configs/qemu-riscv32-smode_defconfig b/configs/qemu-riscv32-smode_defconfig new file mode 100644 index 0000000000..902a706733 --- /dev/null +++ b/configs/qemu-riscv32-smode_defconfig @@ -0,0 +1,7 @@ +CONFIG_RISCV=y +CONFIG_TARGET_QEMU_VIRT=y +CONFIG_RISCV_SMODE=y +CONFIG_NR_DRAM_BANKS=1 +CONFIG_DISPLAY_CPUINFO=y +CONFIG_DISPLAY_BOARDINFO=y +CONFIG_OF_BOARD=y diff --git a/configs/qemu-riscv64-smode_defconfig b/configs/qemu-riscv64-smode_defconfig new file mode 100644 index 0000000000..fe830c6190 --- /dev/null +++ b/configs/qemu-riscv64-smode_defconfig @@ -0,0 +1,8 @@ +CONFIG_RISCV=y +CONFIG_TARGET_QEMU_VIRT=y +CONFIG_CPU_RISCV_64=y +CONFIG_RISCV_SMODE=y +CONFIG_NR_DRAM_BANKS=1 +CONFIG_DISPLAY_CPUINFO=y +CONFIG_DISPLAY_BOARDINFO=y +CONFIG_OF_BOARD=y

Hi All,
I will rebase this patchset upon latest RISC-V u-boot located at: git://git.denx.de/u-boot-riscv.git
I will also update cover letter to include steps for running u-boot in S-mode.
Thanks, Anup
participants (1)
-
Anup Patel