[PATCH v2 1/5] RISC-V: extend multi-image to support both S- and M-Mode

Ahmad Fatoum a.fatoum at pengutronix.de
Mon Jun 7 00:42:29 PDT 2021


Hi,

On 31.05.21 09:03, Ahmad Fatoum wrote:
> We can't currently mix S-Mode and M-Mode images in the same build
> and there's no straight-forward way to determine which mode we are in.
> 
> Move the decision on which mode barebox is targeted at out of Kconfig
> and into the PBL. PBL code can call either barebox_riscv_supervisor_entry
> or barebox_riscv_machine_entry to signal to barebox proper which mode
> it's running in. Currently the only user of this information is the
> RISC-V timer clocksource driver.
> 
> Any new code that does IS_ENABLED(CONFIG_RISCV_SBI) or
> IS_ENABLED(CONFIG_RISCV_M_MODE) should also be adapted to use riscv_mode().
> 
> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
> ---

sbi_init() should only run for S-Mode, but it doesn't. I will send a v3.

> v1 -> v2:
>   - make riscv_mode a pure static inline function for single-mode
>     builds, so e.g. building only erizo can discard code for other modes
> ---
>  arch/riscv/Kconfig                     | 14 ++++++++-----
>  arch/riscv/Kconfig.socs                |  2 ++
>  arch/riscv/boards/erizo/lowlevel.c     |  6 ++++--
>  arch/riscv/boards/hifive/lowlevel.c    | 17 ++++++++--------
>  arch/riscv/boot/board-dt-2nd.c         |  2 +-
>  arch/riscv/boot/entry.c                |  5 +++--
>  arch/riscv/boot/entry.h                |  6 ++++--
>  arch/riscv/boot/start.c                | 12 +++++++----
>  arch/riscv/boot/uncompress.c           |  6 +++---
>  arch/riscv/include/asm/barebox-riscv.h | 10 ++++++++-
>  arch/riscv/include/asm/system.h        | 28 ++++++++++++++++++++++++++
>  drivers/clocksource/timer-riscv.c      |  3 ++-
>  12 files changed, 82 insertions(+), 29 deletions(-)
>  create mode 100644 arch/riscv/include/asm/system.h
> 
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index a4aa799acf01..bbafdea1b959 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -97,14 +97,18 @@ config NMON_HELP
>  	  Say yes here to get the nmon commands message on
>  	  every nmon start.
>  
> -# set if we run in machine mode, cleared if we run in supervisor mode
> +# selected by boards where barebox runs in machine mode
>  config RISCV_M_MODE
>  	bool
>  
> -# set if we are running in S-mode and can use SBI calls
> -config RISCV_SBI
> +# selected by boards where barebox runs in supervisor mode
> +config RISCV_S_MODE
>  	bool
> -	depends on !RISCV_M_MODE
> -	default y
> +
> +config RISCV_MULTI_MODE
> +	def_bool RISCV_S_MODE && RISCV_M_MODE
> +
> +config RISCV_SBI
> +	def_bool RISCV_S_MODE
>  
>  endmenu
> diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
> index c6875738d05c..67d19caeb3b0 100644
> --- a/arch/riscv/Kconfig.socs
> +++ b/arch/riscv/Kconfig.socs
> @@ -15,6 +15,7 @@ config BOARD_ERIZO_GENERIC
>  
>  config SOC_VIRT
>  	bool "QEMU Virt Machine"
> +	select RISCV_S_MODE
>  	select BOARD_RISCV_GENERIC_DT
>  	select CLINT_TIMER
>  	help
> @@ -23,6 +24,7 @@ config SOC_VIRT
>  
>  config SOC_SIFIVE
>  	bool "SiFive SoCs"
> +	select RISCV_S_MODE
>  	select CLK_SIFIVE
>  	select CLK_SIFIVE_PRCI
>  	select RISCV_TIMER
> diff --git a/arch/riscv/boards/erizo/lowlevel.c b/arch/riscv/boards/erizo/lowlevel.c
> index 6acf15931cdf..fc262ed61b56 100644
> --- a/arch/riscv/boards/erizo/lowlevel.c
> +++ b/arch/riscv/boards/erizo/lowlevel.c
> @@ -7,12 +7,14 @@
>  ENTRY_FUNCTION(start_erizo_generic, a0, a1, a2)
>  {
>  	extern char __dtb_z_erizo_generic_start[];
> +	void *fdt;
>  
>  	debug_ll_init();
>  	putc_ll('>');
>  
>  	/* On POR, we are running from read-only memory here. */
>  
> -	barebox_riscv_entry(0x80000000, SZ_8M,
> -			    __dtb_z_erizo_generic_start + get_runtime_offset());
> +	fdt = __dtb_z_erizo_generic_start + get_runtime_offset();
> +
> +	barebox_riscv_machine_entry(0x80000000, SZ_8M, fdt);
>  }
> diff --git a/arch/riscv/boards/hifive/lowlevel.c b/arch/riscv/boards/hifive/lowlevel.c
> index 1de13cac1688..8a20f3c51d40 100644
> --- a/arch/riscv/boards/hifive/lowlevel.c
> +++ b/arch/riscv/boards/hifive/lowlevel.c
> @@ -4,22 +4,23 @@
>  #include <asm/barebox-riscv.h>
>  #include <debug_ll.h>
>  
> +static __always_inline void start_hifive(void *fdt)
> +{
> +	putc_ll('>');
> +
> +	barebox_riscv_supervisor_entry(0x80000000, SZ_128M, fdt);
> +}
> +
>  ENTRY_FUNCTION(start_hifive_unmatched, a0, a1, a2)
>  {
>  	extern char __dtb_z_hifive_unmatched_a00_start[];
>  
> -	putc_ll('>');
> -
> -	barebox_riscv_entry(0x80000000, SZ_128M,
> -			    __dtb_z_hifive_unmatched_a00_start + get_runtime_offset());
> +	start_hifive(__dtb_z_hifive_unmatched_a00_start + get_runtime_offset());
>  }
>  
>  ENTRY_FUNCTION(start_hifive_unleashed, a0, a1, a2)
>  {
>  	extern char __dtb_z_hifive_unleashed_a00_start[];
>  
> -	putc_ll('>');
> -
> -	barebox_riscv_entry(0x80000000, SZ_128M,
> -			    __dtb_z_hifive_unleashed_a00_start + get_runtime_offset());
> +	start_hifive(__dtb_z_hifive_unleashed_a00_start + get_runtime_offset());
>  }
> diff --git a/arch/riscv/boot/board-dt-2nd.c b/arch/riscv/boot/board-dt-2nd.c
> index e9810f8add97..48cb23ae5e92 100644
> --- a/arch/riscv/boot/board-dt-2nd.c
> +++ b/arch/riscv/boot/board-dt-2nd.c
> @@ -73,5 +73,5 @@ ENTRY_FUNCTION(start_dt_2nd, a0, _fdt, a2)
>  	    _fdt < riscv_mem_stack_top(membase, endmem))
>  		memsize = ALIGN_DOWN(_fdt - membase, SZ_1M);
>  
> -	barebox_riscv_entry(membase, memsize, fdt);
> +	barebox_riscv_supervisor_entry(membase, memsize, fdt);
>  }
> diff --git a/arch/riscv/boot/entry.c b/arch/riscv/boot/entry.c
> index eb286423d875..e4a5c2208df3 100644
> --- a/arch/riscv/boot/entry.c
> +++ b/arch/riscv/boot/entry.c
> @@ -20,10 +20,11 @@
>   */
>  
>  void __noreturn __naked barebox_riscv_entry(unsigned long membase,
> -					    unsigned long memsize, void *boarddata)
> +					    unsigned long memsize, void *boarddata,
> +					    unsigned flags)
>  {
>  	unsigned long stack_top = riscv_mem_stack_top(membase, membase + memsize);
>  	asm volatile ("move sp, %0" : : "r"(stack_top));
> -	barebox_pbl_start(membase, memsize, boarddata);
> +	barebox_pbl_start(membase, memsize, boarddata, flags);
>  }
>  
> diff --git a/arch/riscv/boot/entry.h b/arch/riscv/boot/entry.h
> index b3a24d2783f7..fb4af5eae558 100644
> --- a/arch/riscv/boot/entry.h
> +++ b/arch/riscv/boot/entry.h
> @@ -6,10 +6,12 @@
>  
>  void __noreturn barebox_non_pbl_start(unsigned long membase,
>  				      unsigned long memsize,
> -				      void *boarddata);
> +				      void *boarddata,
> +				      unsigned flags);
>  
>  void __noreturn barebox_pbl_start(unsigned long membase,
>  				  unsigned long memsize,
> -				  void *boarddata);
> +				  void *boarddata,
> +				  unsigned flags);
>  
>  #endif
> diff --git a/arch/riscv/boot/start.c b/arch/riscv/boot/start.c
> index 05f6c6231f7e..82bd02d0a0d0 100644
> --- a/arch/riscv/boot/start.c
> +++ b/arch/riscv/boot/start.c
> @@ -26,6 +26,7 @@ static unsigned long riscv_barebox_size;
>  static unsigned long riscv_endmem;
>  static void *barebox_boarddata;
>  static unsigned long barebox_boarddata_size;
> +unsigned barebox_riscv_pbl_flags;
>  
>  void *barebox_riscv_boot_dtb(void)
>  {
> @@ -107,7 +108,8 @@ device_initcall(barebox_memory_areas_init);
>   * the pbl. The stack already has been set up by the pbl.
>   */
>  __noreturn __no_sanitize_address __section(.text_entry)
> -void barebox_non_pbl_start(unsigned long membase, unsigned long memsize, void *boarddata)
> +void barebox_non_pbl_start(unsigned long membase, unsigned long memsize,
> +			   void *boarddata, unsigned flags)
>  {
>  	unsigned long endmem = membase + memsize;
>  	unsigned long malloc_start, malloc_end;
> @@ -168,18 +170,20 @@ void barebox_non_pbl_start(unsigned long membase, unsigned long memsize, void *b
>  
>  	mem_malloc_init((void *)malloc_start, (void *)malloc_end - 1);
>  
> +	barebox_riscv_pbl_flags = flags;
> +
>  	pr_debug("starting barebox...\n");
>  
>  	start_barebox();
>  }
>  
> -void start(unsigned long membase, unsigned long memsize, void *boarddata);
> +void start(unsigned long membase, unsigned long memsize, void *boarddata, unsigned flags);
>  /*
>   * First function in the uncompressed image. We get here from
>   * the pbl. The stack already has been set up by the pbl.
>   */
>  void __no_sanitize_address __section(.text_entry) start(unsigned long membase,
> -		unsigned long memsize, void *boarddata)
> +		unsigned long memsize, void *boarddata, unsigned flags)
>  {
> -	barebox_non_pbl_start(membase, memsize, boarddata);
> +	barebox_non_pbl_start(membase, memsize, boarddata, flags);
>  }
> diff --git a/arch/riscv/boot/uncompress.c b/arch/riscv/boot/uncompress.c
> index b4e010998a4a..35a91e8cb62a 100644
> --- a/arch/riscv/boot/uncompress.c
> +++ b/arch/riscv/boot/uncompress.c
> @@ -23,10 +23,10 @@ unsigned long free_mem_ptr;
>  unsigned long free_mem_end_ptr;
>  
>  void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
> -				  void *fdt)
> +				  void *fdt, unsigned flags)
>  {
>  	uint32_t pg_len, uncompressed_len;
> -	void __noreturn (*barebox)(unsigned long, unsigned long, void *);
> +	void __noreturn (*barebox)(unsigned long, unsigned long, void *, unsigned);
>  	unsigned long endmem = membase + memsize;
>  	unsigned long barebox_base;
>  	void *pg_start, *pg_end;
> @@ -67,5 +67,5 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
>  
>  	pr_debug("jumping to uncompressed image at 0x%p. dtb=0x%p\n", barebox, fdt);
>  
> -	barebox(membase, memsize, fdt);
> +	barebox(membase, memsize, fdt, flags);
>  }
> diff --git a/arch/riscv/include/asm/barebox-riscv.h b/arch/riscv/include/asm/barebox-riscv.h
> index bb1d15308b48..f4081a71f00e 100644
> --- a/arch/riscv/include/asm/barebox-riscv.h
> +++ b/arch/riscv/include/asm/barebox-riscv.h
> @@ -19,14 +19,22 @@
>  #include <linux/compiler.h>
>  #include <asm/sections.h>
>  #include <asm/barebox-riscv-head.h>
> +#include <asm/system.h>
>  
>  unsigned long get_runtime_offset(void);
>  
>  void setup_c(void);
>  void relocate_to_current_adr(void);
>  void relocate_to_adr(unsigned long target);
> +
>  void __noreturn __naked barebox_riscv_entry(unsigned long membase, unsigned long memsize,
> -					    void *boarddata);
> +					    void *boarddata, unsigned int flags);
> +
> +#define barebox_riscv_machine_entry(membase, memsize, boarddata) \
> +	barebox_riscv_entry(membase, memsize, boarddata, RISCV_M_MODE)
> +
> +#define barebox_riscv_supervisor_entry(membase, memsize, boarddata) \
> +	barebox_riscv_entry(membase, memsize, boarddata, RISCV_S_MODE)
>  
>  unsigned long riscv_mem_ramoops_get(void);
>  unsigned long riscv_mem_endmem_get(void);
> diff --git a/arch/riscv/include/asm/system.h b/arch/riscv/include/asm/system.h
> new file mode 100644
> index 000000000000..95a22fb88062
> --- /dev/null
> +++ b/arch/riscv/include/asm/system.h
> @@ -0,0 +1,28 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#ifndef __ASM_SYSTEM_H_
> +
> +#define RISCV_MODE_MASK 0x3
> +enum riscv_mode {
> +    RISCV_U_MODE	= 0,
> +    RISCV_S_MODE	= 1,
> +    RISCV_HS_MODE	= 2,
> +    RISCV_M_MODE	= 3,
> +};
> +
> +extern unsigned barebox_riscv_pbl_flags;
> +
> +static inline enum riscv_mode riscv_mode(void)
> +{
> +	/* allow non-LTO builds to discard code for unused modes */
> +	if (!IS_ENABLED(CONFIG_RISCV_MULTI_MODE)) {
> +		if (IS_ENABLED(CONFIG_RISCV_M_MODE))
> +			return RISCV_M_MODE;
> +		if (IS_ENABLED(CONFIG_RISCV_S_MODE))
> +			return RISCV_S_MODE;
> +	}
> +
> +	return barebox_riscv_pbl_flags & RISCV_MODE_MASK;
> +}
> +
> +#endif
> diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
> index ef67cff47555..cbbe18d9a693 100644
> --- a/drivers/clocksource/timer-riscv.c
> +++ b/drivers/clocksource/timer-riscv.c
> @@ -12,6 +12,7 @@
>  #include <clock.h>
>  #include <asm/timer.h>
>  #include <asm/csr.h>
> +#include <asm/system.h>
>  
>  static u64 notrace riscv_timer_get_count_sbi(void)
>  {
> @@ -45,7 +46,7 @@ static u64 notrace riscv_timer_get_count_rdcycle(void)
>  
>  static u64 notrace riscv_timer_get_count(void)
>  {
> -	if (IS_ENABLED(CONFIG_RISCV_SBI))
> +	if (riscv_mode() == RISCV_S_MODE)
>  		return riscv_timer_get_count_sbi();
>  	else
>  		return riscv_timer_get_count_rdcycle();
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



More information about the barebox mailing list