summaryrefslogtreecommitdiffstats
path: root/arch/riscv
diff options
context:
space:
mode:
authorMarco Felsch <m.felsch@pengutronix.de>2022-10-05 13:12:11 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2022-10-07 10:29:53 +0200
commitc986c565b023b245d11d7aefe56d9d28ea412395 (patch)
treecdf1ffba41ad9a430e0e516708eedcf781a28204 /arch/riscv
parent82338055f49d9f71a264a207e89211aeaed34482 (diff)
downloadbarebox-c986c565b023b245d11d7aefe56d9d28ea412395.tar.gz
barebox-c986c565b023b245d11d7aefe56d9d28ea412395.tar.xz
RISC-V: use m/sscratch registers for barebox_riscv_pbl_flags
Use the dedicated scratch register for setting the pbl flags. Each mode has it's own scratch register so we are not conflicting with M-mode running firmware e.g. OpenSBI. Using the scratch register has two main advantages: 1st) It can be used in PBL and non-PBL use-case. 2nd) It is not affected by the relocation code. This commit prepares barebox to add support for the special cache ops used by several T-Head CPUs. Signed-off-by: Marco Felsch <m.felsch@pengutronix.de> Link: https://lore.barebox.org/20221005111214.148844-4-m.felsch@pengutronix.de Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/riscv')
-rw-r--r--arch/riscv/boot/entry.c3
-rw-r--r--arch/riscv/boot/entry.h6
-rw-r--r--arch/riscv/boot/start.c13
-rw-r--r--arch/riscv/boot/uncompress.c8
-rw-r--r--arch/riscv/include/asm/system.h63
5 files changed, 51 insertions, 42 deletions
diff --git a/arch/riscv/boot/entry.c b/arch/riscv/boot/entry.c
index e4a5c2208d..f5a536fc78 100644
--- a/arch/riscv/boot/entry.c
+++ b/arch/riscv/boot/entry.c
@@ -25,6 +25,7 @@ void __noreturn __naked barebox_riscv_entry(unsigned long membase,
{
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, flags);
+ riscv_set_flags(flags);
+ barebox_pbl_start(membase, memsize, boarddata);
}
diff --git a/arch/riscv/boot/entry.h b/arch/riscv/boot/entry.h
index fb4af5eae5..b3a24d2783 100644
--- a/arch/riscv/boot/entry.h
+++ b/arch/riscv/boot/entry.h
@@ -6,12 +6,10 @@
void __noreturn barebox_non_pbl_start(unsigned long membase,
unsigned long memsize,
- void *boarddata,
- unsigned flags);
+ void *boarddata);
void __noreturn barebox_pbl_start(unsigned long membase,
unsigned long memsize,
- void *boarddata,
- unsigned flags);
+ void *boarddata);
#endif
diff --git a/arch/riscv/boot/start.c b/arch/riscv/boot/start.c
index 8b4c8bb2f0..27d9066243 100644
--- a/arch/riscv/boot/start.c
+++ b/arch/riscv/boot/start.c
@@ -27,7 +27,6 @@ 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)
{
@@ -108,7 +107,7 @@ device_initcall(barebox_memory_areas_init);
*/
__noreturn __no_sanitize_address __section(.text_entry)
void barebox_non_pbl_start(unsigned long membase, unsigned long memsize,
- void *boarddata, unsigned flags)
+ void *boarddata)
{
unsigned long endmem = membase + memsize;
unsigned long malloc_start, malloc_end;
@@ -121,7 +120,7 @@ void barebox_non_pbl_start(unsigned long membase, unsigned long memsize,
barrier();
- irq_init_vector(__riscv_mode(flags));
+ irq_init_vector(riscv_mode());
pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize);
@@ -171,20 +170,18 @@ void barebox_non_pbl_start(unsigned long membase, unsigned long memsize,
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, unsigned flags);
+void start(unsigned long membase, unsigned long memsize, void *boarddata);
/*
* 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 flags)
+ unsigned long memsize, void *boarddata)
{
- barebox_non_pbl_start(membase, memsize, boarddata, flags);
+ barebox_non_pbl_start(membase, memsize, boarddata);
}
diff --git a/arch/riscv/boot/uncompress.c b/arch/riscv/boot/uncompress.c
index 4ed9b4d371..ee24f81e01 100644
--- a/arch/riscv/boot/uncompress.c
+++ b/arch/riscv/boot/uncompress.c
@@ -24,16 +24,16 @@ unsigned long free_mem_ptr;
unsigned long free_mem_end_ptr;
void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
- void *fdt, unsigned flags)
+ void *fdt)
{
uint32_t pg_len, uncompressed_len;
- void __noreturn (*barebox)(unsigned long, unsigned long, void *, unsigned);
+ void __noreturn (*barebox)(unsigned long, unsigned long, void *);
unsigned long endmem = membase + memsize;
unsigned long barebox_base;
void *pg_start, *pg_end;
unsigned long pc = get_pc();
- irq_init_vector(__riscv_mode(flags));
+ irq_init_vector(riscv_mode());
/* piggy data is not relocated, so determine the bounds now */
pg_start = input_data + get_runtime_offset();
@@ -72,5 +72,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, flags);
+ barebox(membase, memsize, fdt);
}
diff --git a/arch/riscv/include/asm/system.h b/arch/riscv/include/asm/system.h
index 89516f075b..f0b6bf2945 100644
--- a/arch/riscv/include/asm/system.h
+++ b/arch/riscv/include/asm/system.h
@@ -15,7 +15,39 @@ enum riscv_mode {
RISCV_M_MODE = 3,
};
-static inline enum riscv_mode __riscv_mode(u32 flags)
+static inline void riscv_set_flags(unsigned flags)
+{
+ switch (flags & RISCV_MODE_MASK) {
+ case RISCV_S_MODE:
+ __asm__ volatile("csrw sscratch, %0" : : "r"(flags));
+ break;
+ case RISCV_M_MODE:
+ __asm__ volatile("csrw mscratch, %0" : : "r"(flags));
+ break;
+ default:
+ /* Other modes are not implemented yet */
+ break;
+ }
+}
+
+static inline u32 riscv_get_flags(void)
+{
+ u32 flags = 0;
+
+ if (IS_ENABLED(CONFIG_RISCV_S_MODE))
+ __asm__ volatile("csrr %0, sscratch" : "=r"(flags));
+
+ /*
+ * Since we always set the scratch register on the very beginning, a
+ * empty flags indicates that we are running in M-mode.
+ */
+ if (!flags)
+ __asm__ volatile("csrr %0, mscratch" : "=r"(flags));
+
+ return 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)) {
@@ -25,14 +57,14 @@ static inline enum riscv_mode __riscv_mode(u32 flags)
return RISCV_S_MODE;
}
- return flags & RISCV_MODE_MASK;
+ return riscv_get_flags() & RISCV_MODE_MASK;
}
-static inline long __riscv_hartid(u32 flags)
+static inline long riscv_hartid(void)
{
long hartid = -1;
- switch (__riscv_mode(flags)) {
+ switch (riscv_mode()) {
case RISCV_S_MODE:
__asm__ volatile("mv %0, tp\n" : "=r"(hartid) :);
break;
@@ -44,12 +76,12 @@ static inline long __riscv_hartid(u32 flags)
return hartid;
}
-static inline long __riscv_vendor_id(u32 flags)
+static inline long riscv_vendor_id(void)
{
struct sbiret ret;
long id;
- switch (__riscv_mode(flags)) {
+ switch (riscv_mode()) {
case RISCV_M_MODE:
__asm__ volatile("csrr %0, mvendorid\n" : "=r"(id));
return id;
@@ -68,25 +100,6 @@ static inline long __riscv_vendor_id(u32 flags)
}
}
-#ifndef __PBL__
-extern unsigned barebox_riscv_pbl_flags;
-
-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);
-}
-
-static inline long riscv_vendor_id(void)
-{
- return __riscv_vendor_id(barebox_riscv_pbl_flags);
-}
-#endif
-
#endif
#endif