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 05/29] RISC-V: S-Mode: propagate Hart ID
Date: Sat, 19 Jun 2021 06:50:31 +0200	[thread overview]
Message-ID: <20210619045055.779-6-a.fatoum@pengutronix.de> (raw)
In-Reply-To: <20210619045055.779-1-a.fatoum@pengutronix.de>

Unlike other architectures we support, Linux must apparently be
booted on all cores by the bootloader. To achieve this, the bootloaders
running on the multiple cores synchronize via IPIs.

We will get there eventually, but for now, let's restrict barebox
to boot Linux on a single core. S-Mode firmware is passed hart (core) id
in a0. This is propagated via the thread pointer register, which is
unused by GCC and made available as:

 - cpuinfo output when running in S-Mode
 - $global.hartid
 - a0 when booting via bootm
 - /chosen/boot-hartid fixup: will come in handy when we gain EFI
   loading support
 - single /cpus/*/reg: All other CPU nodes are deleted via fixup

For M-Mode, we can query hart id via CSR. It's unknown whether erizo
supports it and we don't yet have exception support to handle it not
being available, so changes are only done for S-Mode for now.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/riscv/boards/hifive/lowlevel.c    |  8 +++----
 arch/riscv/boot/board-dt-2nd.c         |  4 ++--
 arch/riscv/cpu/core.c                  | 33 +++++++++++++++++++++++++-
 arch/riscv/include/asm/barebox-riscv.h |  6 +++--
 arch/riscv/include/asm/system.h        | 20 ++++++++++++++++
 arch/riscv/lib/bootm.c                 |  4 +++-
 arch/riscv/lib/cpuinfo.c               |  1 +
 common/globalvar.c                     | 21 ++++++++++++++++
 common/oftree.c                        | 19 ++++++++++++++-
 include/globalvar.h                    |  8 +++++++
 10 files changed, 113 insertions(+), 11 deletions(-)

diff --git a/arch/riscv/boards/hifive/lowlevel.c b/arch/riscv/boards/hifive/lowlevel.c
index 8a20f3c51d40..5e8969bef1da 100644
--- a/arch/riscv/boards/hifive/lowlevel.c
+++ b/arch/riscv/boards/hifive/lowlevel.c
@@ -4,23 +4,23 @@
 #include <asm/barebox-riscv.h>
 #include <debug_ll.h>
 
-static __always_inline void start_hifive(void *fdt)
+static __always_inline void start_hifive(unsigned long hartid, void *fdt)
 {
 	putc_ll('>');
 
-	barebox_riscv_supervisor_entry(0x80000000, SZ_128M, fdt);
+	barebox_riscv_supervisor_entry(0x80000000, SZ_128M, hartid, fdt);
 }
 
 ENTRY_FUNCTION(start_hifive_unmatched, a0, a1, a2)
 {
 	extern char __dtb_z_hifive_unmatched_a00_start[];
 
-	start_hifive(__dtb_z_hifive_unmatched_a00_start + get_runtime_offset());
+	start_hifive(a0, __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[];
 
-	start_hifive(__dtb_z_hifive_unleashed_a00_start + get_runtime_offset());
+	start_hifive(a0, __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 48cb23ae5e92..f31c48a906c2 100644
--- a/arch/riscv/boot/board-dt-2nd.c
+++ b/arch/riscv/boot/board-dt-2nd.c
@@ -40,7 +40,7 @@ static const struct fdt_device_id console_ids[] = {
 	{ /* sentinel */ }
 };
 
-ENTRY_FUNCTION(start_dt_2nd, a0, _fdt, a2)
+ENTRY_FUNCTION(start_dt_2nd, hartid, _fdt, a2)
 {
 	unsigned long membase, memsize, endmem, endfdt, uncompressed_len;
 	struct fdt_header *fdt = (void *)_fdt;
@@ -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_supervisor_entry(membase, memsize, fdt);
+	barebox_riscv_supervisor_entry(membase, memsize, hartid, fdt);
 }
diff --git a/arch/riscv/cpu/core.c b/arch/riscv/cpu/core.c
index 982d378eddec..62eb0ca87164 100644
--- a/arch/riscv/cpu/core.c
+++ b/arch/riscv/cpu/core.c
@@ -19,6 +19,8 @@
 #include <linux/err.h>
 #include <memory.h>
 #include <asm-generic/memory_layout.h>
+#include <globalvar.h>
+#include <magicvar.h>
 #include <io.h>
 
 static int riscv_request_stack(void)
@@ -30,6 +32,31 @@ coredevice_initcall(riscv_request_stack);
 
 static struct device_d timer_dev;
 
+static s64 hartid;
+
+BAREBOX_MAGICVAR(global.hartid, "RISC-V hartid");
+
+static int riscv_fixup_cpus(struct device_node *root, void *context)
+{
+	struct device_node *cpus_node, *np, *tmp;
+
+	cpus_node = of_find_node_by_name(root, "cpus");
+	if (!cpus_node)
+		return 0;
+
+	for_each_child_of_node_safe(cpus_node, tmp, np) {
+		u32 cpu_index;
+
+		if (of_property_read_u32(np, "reg", &cpu_index))
+			continue;
+
+		if (cpu_index != hartid)
+			of_delete_node(np);
+	}
+
+	return 0;
+}
+
 static int riscv_probe(struct device_d *parent)
 {
 	int ret;
@@ -46,7 +73,11 @@ static int riscv_probe(struct device_d *parent)
 			return ret;
 	}
 
-	return 0;
+	hartid = riscv_hartid();
+	if (hartid >= 0)
+		globalvar_add_simple_uint64("hartid", &hartid, "%llu");
+
+	return of_register_fixup(riscv_fixup_cpus, NULL);
 }
 
 static struct of_device_id riscv_dt_ids[] = {
diff --git a/arch/riscv/include/asm/barebox-riscv.h b/arch/riscv/include/asm/barebox-riscv.h
index f4081a71f00e..bbe6cd040642 100644
--- a/arch/riscv/include/asm/barebox-riscv.h
+++ b/arch/riscv/include/asm/barebox-riscv.h
@@ -33,8 +33,10 @@ void __noreturn __naked barebox_riscv_entry(unsigned long membase, unsigned long
 #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)
+#define barebox_riscv_supervisor_entry(membase, memsize, hartid, boarddata) do { \
+	__asm__ volatile("mv tp, %0\n" : : "r"(hartid)); \
+	barebox_riscv_entry(membase, memsize, boarddata, RISCV_S_MODE); \
+} while (0)
 
 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
index 3d57a7d191f6..adf856f9e99b 100644
--- a/arch/riscv/include/asm/system.h
+++ b/arch/riscv/include/asm/system.h
@@ -26,6 +26,22 @@ static inline enum riscv_mode __riscv_mode(u32 flags)
 	return flags & RISCV_MODE_MASK;
 }
 
+static inline long __riscv_hartid(u32 flags)
+{
+	long hartid = -1;
+
+	switch (__riscv_mode(flags)) {
+	case RISCV_S_MODE:
+		__asm__ volatile("mv %0, tp\n" : "=r"(hartid) :);
+		break;
+	default:
+		/* unimplemented */
+		break;
+	}
+
+	return hartid;
+}
+
 #ifndef __PBL__
 extern unsigned barebox_riscv_pbl_flags;
 
@@ -34,6 +50,10 @@ static inline enum riscv_mode riscv_mode(void)
 	return __riscv_mode(barebox_riscv_pbl_flags);
 }
 
+static inline long riscv_hartid(void)
+{
+	return __riscv_hartid(barebox_riscv_pbl_flags);
+}
 #endif
 
 #endif
diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c
index b3e41de4a890..835ff345e347 100644
--- a/arch/riscv/lib/bootm.c
+++ b/arch/riscv/lib/bootm.c
@@ -3,11 +3,13 @@
 
 #include <common.h>
 #include <bootm.h>
+#include <asm/system.h>
 
 static int do_bootm_linux(struct image_data *data)
 {
 	void (*fn)(unsigned long a0, unsigned long dtb, unsigned long a2);
 	phys_addr_t devicetree;
+	long hartid = riscv_hartid();
 
 	fn = booti_load_image(data, &devicetree);
 	if (IS_ERR(fn))
@@ -15,7 +17,7 @@ static int do_bootm_linux(struct image_data *data)
 
 	shutdown_barebox();
 
-	fn(0, devicetree, 0);
+	fn(hartid >= 0 ? hartid : 0, devicetree, 0);
 
 	return -EINVAL;
 }
diff --git a/arch/riscv/lib/cpuinfo.c b/arch/riscv/lib/cpuinfo.c
index 16305e6c4d96..2d9cee2a6270 100644
--- a/arch/riscv/lib/cpuinfo.c
+++ b/arch/riscv/lib/cpuinfo.c
@@ -34,6 +34,7 @@ static int do_cpuinfo(int argc, char *argv[])
 
 	switch (mode) {
 	case RISCV_S_MODE:
+		printf("Hart ID=%lu\n", riscv_hartid());
 		if (!IS_ENABLED(CONFIG_RISCV_SBI))
 			break;
 		printf("SBI specification v%lu.%lu detected\n",
diff --git a/common/globalvar.c b/common/globalvar.c
index 8bb5015ce4e8..9e5a99f79353 100644
--- a/common/globalvar.c
+++ b/common/globalvar.c
@@ -565,6 +565,27 @@ int globalvar_add_simple_int(const char *name, int *value,
 	return 0;
 }
 
+int globalvar_add_simple_uint64(const char *name, u64 *value,
+				const char *format)
+{
+	struct param_d *p;
+	int ret;
+
+	ret = globalvar_remove_unqualified(name);
+	if (ret)
+		return ret;
+
+	p = dev_add_param_uint64(&global_device, name, NULL, NULL,
+		value, format, NULL);
+
+	if (IS_ERR(p))
+		return PTR_ERR(p);
+
+	globalvar_nv_sync(name);
+
+	return 0;
+}
+
 int globalvar_add_bool(const char *name,
 		       int (*set)(struct param_d *, void *),
 		       int *value, void *priv)
diff --git a/common/oftree.c b/common/oftree.c
index 5eaa63ad7ebc..1fcc5277c58d 100644
--- a/common/oftree.c
+++ b/common/oftree.c
@@ -232,7 +232,24 @@ static int of_fixup_bootargs(struct device_node *root, void *unused)
 			return err;
 	}
 
-	return of_fixup_bootargs_bootsource(root, node);
+	err = of_fixup_bootargs_bootsource(root, node);
+	if (err)
+		return err;
+
+	if (IS_ENABLED(CONFIG_RISCV)) {
+		const char *hartid;
+
+		hartid = getenv("global.hartid");
+		if (hartid) {
+			unsigned long id;
+
+			err = kstrtoul(hartid, 10, &id);
+			if (!err)
+				err = of_property_write_u32(node, "boot-hartid", id);
+		}
+	}
+
+	return err;
 }
 
 static int of_register_bootargs_fixup(void)
diff --git a/include/globalvar.h b/include/globalvar.h
index 84bee9102cf3..476bb920f3e1 100644
--- a/include/globalvar.h
+++ b/include/globalvar.h
@@ -20,6 +20,8 @@ void globalvar_set(const char *name, const char *val);
 int globalvar_add_simple_string(const char *name, char **value);
 int globalvar_add_simple_int(const char *name, int *value,
 			     const char *format);
+int globalvar_add_simple_uint64(const char *name, u64 *value,
+				const char *format);
 int globalvar_add_bool(const char *name,
 		       int (*set)(struct param_d *, void *),
 		       int *value, void *priv);
@@ -55,6 +57,12 @@ static inline int globalvar_add_simple_int(const char *name,
 	return 0;
 }
 
+static inline int globalvar_add_simple_uint64(const char *name,
+		u64 *value, const char *format)
+{
+	return 0;
+}
+
 static inline int globalvar_add_bool(const char *name,
 		int (*set)(struct param_d *, void *),
 		int *value, void *priv)
-- 
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:53 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 ` [PATCH v2 03/29] RISC-V: extend multi-image to support both S- and M-Mode Ahmad Fatoum
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 ` Ahmad Fatoum [this message]
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-6-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