mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@pengutronix.de>
Subject: [PATCH v2 03/29] RISC-V: extend multi-image to support both S- and M-Mode
Date: Sat, 19 Jun 2021 06:50:29 +0200	[thread overview]
Message-ID: <20210619045055.779-4-a.fatoum@pengutronix.de> (raw)
In-Reply-To: <20210619045055.779-1-a.fatoum@pengutronix.de>

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@pengutronix.de>
---
 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        | 41 ++++++++++++++++++++++++++
 arch/riscv/lib/sbi.c                   |  4 +++
 drivers/clocksource/timer-clint.c      |  5 ++--
 drivers/clocksource/timer-riscv.c      |  3 +-
 14 files changed, 102 insertions(+), 31 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 fd36745755e0..f1b431555fcd 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
 	help
 	  Generates an image tht can be be booted by QEMU. The image is called
@@ -22,6 +23,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..3d57a7d191f6
--- /dev/null
+++ b/arch/riscv/include/asm/system.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __ASM_SYSTEM_H_
+#define __ASM_SYSTEM_H_
+
+#ifndef __ASSEMBLY__
+
+#define RISCV_MODE_MASK 0x3
+enum riscv_mode {
+    RISCV_U_MODE	= 0,
+    RISCV_S_MODE	= 1,
+    RISCV_HS_MODE	= 2,
+    RISCV_M_MODE	= 3,
+};
+
+static inline enum riscv_mode __riscv_mode(u32 flags)
+{
+	/* 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 flags & RISCV_MODE_MASK;
+}
+
+#ifndef __PBL__
+extern unsigned barebox_riscv_pbl_flags;
+
+static inline enum riscv_mode riscv_mode(void)
+{
+	return __riscv_mode(barebox_riscv_pbl_flags);
+}
+
+#endif
+
+#endif
+
+#endif
diff --git a/arch/riscv/lib/sbi.c b/arch/riscv/lib/sbi.c
index 973c9d9d0f1e..45a04fb821a9 100644
--- a/arch/riscv/lib/sbi.c
+++ b/arch/riscv/lib/sbi.c
@@ -6,6 +6,7 @@
  */
 
 #include <asm/sbi.h>
+#include <asm/system.h>
 #include <linux/export.h>
 #include <errno.h>
 #include <init.h>
@@ -53,6 +54,9 @@ static int sbi_init(void)
 {
 	int ret;
 
+	if (riscv_mode() != RISCV_S_MODE)
+		return 0;
+
 	ret = sbi_get_spec_version();
 	if (ret > 0)
 		sbi_spec_version = ret;
diff --git a/drivers/clocksource/timer-clint.c b/drivers/clocksource/timer-clint.c
index 4eeb9cf7ffc9..412ce3e1e985 100644
--- a/drivers/clocksource/timer-clint.c
+++ b/drivers/clocksource/timer-clint.c
@@ -17,6 +17,7 @@
 #include <linux/err.h>
 #include <io.h>
 #include <asm/timer.h>
+#include <asm/system.h>
 
 #define CLINT_TIMER_VAL_OFF	0xbff8
 
@@ -63,8 +64,8 @@ static int clint_timer_init_dt(struct device_d* dev)
 {
 	struct resource *iores;
 
-	/* one timer is enough */
-	if (clint_timer_val)
+	/* one timer is enough. Only M-Mode */
+	if (clint_timer_val || riscv_mode() != RISCV_M_MODE)
 		return 0;
 
 	iores = dev_request_mem_resource(dev, 0);
diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
index c2d32b36bbc5..5a517fe6b43d 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();
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


  parent reply	other threads:[~2021-06-19  4:58 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 01/29] clocksource: RISC-V: demote probe success messages to debug level Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 02/29] RISC-V: virt: select only one timer Ahmad Fatoum
2021-06-19  4:50 ` Ahmad Fatoum [this message]
2021-06-19  4:50 ` [PATCH v2 04/29] RISC-V: cpuinfo: return some output for non-SBI systems as well Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 05/29] RISC-V: S-Mode: propagate Hart ID Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 06/29] RISC-V: erizo: make it easier to reuse ns16550 debug_ll Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 07/29] RISC-V: socs: add Kconfig entry for StarFive JH7100 Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 08/29] nvmem: add StarFive OTP support Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 09/29] RISC-V: dma: support multiple dma_alloc_coherent backends Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 10/29] RISC-V: add exception support Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 11/29] RISC-V: support incoherent I-Cache Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 12/29] drivers: soc: sifive: add basic L2 cache controller driver Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 13/29] soc: starfive: add support for JH7100 incoherent interconnect Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 14/29] soc: sifive: l2_cache: enable maximum available cache ways Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 15/29] net: designware: fix non-1:1 mapped 64-bit systems Ahmad Fatoum
2021-06-21  7:25   ` Sascha Hauer
2021-06-21  7:33     ` Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 16/29] net: designware: add support for IP integrated into StarFive SoC Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 17/29] mci: allocate DMA-able memory Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 18/29] mci: allocate sector_buf on demand Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 19/29] dma: allocate 32-byte aligned buffers by default Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 20/29] mci: dw_mmc: add optional reset line Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 21/29] mci: dw_mmc: match against StarFive MMC compatibles Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 22/29] clk: add initial StarFive clock support Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 23/29] reset: add StarFive reset controller driver Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 24/29] watchdog: add StarFive watchdog driver Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 25/29] hw_random: add driver for RNG on StarFive SoC Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 26/29] reset: add device_reset_all helper Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 27/29] gpio: add support for StarFive GPIO controller Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 28/29] misc: add power sequencing driver for initializing StarFive peripherals Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 29/29] RISC-V: StarFive: add board support for BeagleV Starlight Ahmad Fatoum
2021-06-21  9:11 ` [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210619045055.779-4-a.fatoum@pengutronix.de \
    --to=a.fatoum@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox