* [PATCH 1/2] riscv: Add CSR detection support
@ 2026-03-19 8:29 Leo Yu-Chi Liang via qemu development
2026-03-19 8:29 ` [PATCH 2/2] riscv: andes: Add Smstateen extension support Leo Yu-Chi Liang via qemu development
2026-03-24 18:55 ` [PATCH 1/2] riscv: Add CSR detection support Heinrich Schuchardt
0 siblings, 2 replies; 6+ messages in thread
From: Leo Yu-Chi Liang via qemu development @ 2026-03-19 8:29 UTC (permalink / raw)
To: u-boot; +Cc: rick, ycliang, trini, me, anshuld, xypron.glpk, qemu-devel
Add a lightweight mechanism to safely probe CSRs that may not exist
on the current hart. This is useful for detecting optional extensions
(e.g. Smstateen) without relying on MARCHID or ISA string parsing.
The implementation consists of:
- A minimal expected trap handler (__riscv_expected_trap) that advances
past the faulting instruction and signals the trap via register a4.
- csr_read_allowed() and csr_write_allowed() macros that temporarily
swap the trap vector, attempt the CSR access, and report whether it
trapped.
Ported from OpenSBI's sbi_csr_detect.h mechanism.
Signed-off-by: Leo Yu-Chi Liang <ycliang@andestech.com>
---
arch/riscv/include/asm/csr_detect.h | 90 +++++++++++++++++++++++++++++
arch/riscv/lib/Makefile | 1 +
arch/riscv/lib/csr_detect.S | 23 ++++++++
3 files changed, 114 insertions(+)
create mode 100644 arch/riscv/include/asm/csr_detect.h
create mode 100644 arch/riscv/lib/csr_detect.S
diff --git a/arch/riscv/include/asm/csr_detect.h b/arch/riscv/include/asm/csr_detect.h
new file mode 100644
index 00000000000..c058b6b85ea
--- /dev/null
+++ b/arch/riscv/include/asm/csr_detect.h
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2026 Andes Technology Corporation
+ * Leo Yu-Chi Liang <ycliang@andestech.com>
+ *
+ * RISC-V CSR detection support
+ *
+ * Provides macros to safely probe CSRs that may not exist on the
+ * current hart. Uses a lightweight trap handler that simply advances
+ * past the faulting instruction and sets a flag.
+ *
+ * Ported from OpenSBI's sbi_csr_detect.h.
+ */
+
+#ifndef _ASM_RISCV_CSR_DETECT_H
+#define _ASM_RISCV_CSR_DETECT_H
+
+#include <asm/csr.h>
+
+#ifndef __ASSEMBLY__
+
+/* Two-level stringification so CSR macros are expanded before quoting */
+#define __CSR_DETECT_XSTR(x) #x
+#define __CSR_DETECT_STR(x) __CSR_DETECT_XSTR(x)
+
+#if CONFIG_IS_ENABLED(RISCV_SMODE)
+#define CSR_XTVEC CSR_STVEC
+#else
+#define CSR_XTVEC CSR_MTVEC
+#endif
+
+void __riscv_expected_trap(void);
+
+/**
+ * csr_read_allowed() - Read a CSR, detecting illegal-instruction traps.
+ * @csr_num: CSR number (must be a compile-time constant).
+ * @trap: lvalue that is set to 1 if the access trapped, 0 otherwise.
+ *
+ * Returns the CSR value on success, or 0 if the CSR does not exist.
+ *
+ * This works by temporarily installing a minimal trap handler that
+ * skips the faulting instruction and sets register a4 to 1. Interrupts
+ * must be disabled when calling this macro (they normally are during
+ * early init).
+ */
+#define csr_read_allowed(csr_num, trap) \
+({ \
+ register unsigned long __mtvec = \
+ (unsigned long)__riscv_expected_trap; \
+ register unsigned long __trap asm("a4") = 0; \
+ register unsigned long __ret = 0; \
+ __asm__ __volatile__( \
+ "csrrw %[mtvec], " \
+ __CSR_DETECT_STR(CSR_XTVEC) ", %[mtvec]\n" \
+ "csrr %[ret], " __ASM_STR(csr_num) "\n" \
+ "csrw " __CSR_DETECT_STR(CSR_XTVEC) ", %[mtvec]" \
+ : [mtvec] "+&r"(__mtvec), [ret] "=&r"(__ret), \
+ [trap] "+&r"(__trap) \
+ : \
+ : "memory"); \
+ trap = __trap; \
+ __ret; \
+})
+
+/**
+ * csr_write_allowed() - Write a CSR, detecting illegal-instruction traps.
+ * @csr_num: CSR number (must be a compile-time constant).
+ * @trap: lvalue that is set to 1 if the access trapped, 0 otherwise.
+ * @value: Value to write.
+ */
+#define csr_write_allowed(csr_num, trap, value) \
+({ \
+ register unsigned long __mtvec = \
+ (unsigned long)__riscv_expected_trap; \
+ register unsigned long __trap asm("a4") = 0; \
+ register unsigned long __val = (unsigned long)(value); \
+ __asm__ __volatile__( \
+ "csrrw %[mtvec], " \
+ __CSR_DETECT_STR(CSR_XTVEC) ", %[mtvec]\n" \
+ "csrw " __ASM_STR(csr_num) ", %[val]\n" \
+ "csrw " __CSR_DETECT_STR(CSR_XTVEC) ", %[mtvec]" \
+ : [mtvec] "+&r"(__mtvec), [trap] "+&r"(__trap) \
+ : [val] "rK"(__val) \
+ : "memory"); \
+ trap = __trap; \
+})
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_RISCV_CSR_DETECT_H */
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index a527b3e9ae3..42463b8bed0 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_$(PHASE_)LIB_BOOTM) += bootm.o
obj-$(CONFIG_$(PHASE_)LIB_BOOTI) += image.o
obj-$(CONFIG_CMD_GO) += boot.o
obj-y += cache.o
+obj-y += csr_detect.o
obj-$(CONFIG_SIFIVE_CACHE) += sifive_cache.o
obj-$(CONFIG_SYS_CACHE_THEAD_CMO) += thead_cmo.o
ifeq ($(CONFIG_$(PHASE_)RISCV_MMODE),y)
diff --git a/arch/riscv/lib/csr_detect.S b/arch/riscv/lib/csr_detect.S
new file mode 100644
index 00000000000..69c4b8e7933
--- /dev/null
+++ b/arch/riscv/lib/csr_detect.S
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * RISC-V CSR detection support
+ *
+ * Copyright (C) 2025 Andes Technology Corporation
+ * Leo Yu-Chi Liang <ycliang@andestech.com>
+ *
+ * Ported from OpenSBI's expected trap mechanism.
+ */
+
+#include <asm/encoding.h>
+
+ .text
+ .align 2
+ .global __riscv_expected_trap
+__riscv_expected_trap:
+ /* Advance past the faulting instruction */
+ csrr a4, MODE_PREFIX(epc)
+ addi a4, a4, 4
+ csrw MODE_PREFIX(epc), a4
+ /* Set a4 = 1 to signal that a trap occurred */
+ li a4, 1
+ MODE_PREFIX(ret)
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/2] riscv: andes: Add Smstateen extension support
2026-03-19 8:29 [PATCH 1/2] riscv: Add CSR detection support Leo Yu-Chi Liang via qemu development
@ 2026-03-19 8:29 ` Leo Yu-Chi Liang via qemu development
2026-03-24 19:03 ` Heinrich Schuchardt
2026-03-24 18:55 ` [PATCH 1/2] riscv: Add CSR detection support Heinrich Schuchardt
1 sibling, 1 reply; 6+ messages in thread
From: Leo Yu-Chi Liang via qemu development @ 2026-03-19 8:29 UTC (permalink / raw)
To: u-boot; +Cc: rick, ycliang, trini, me, anshuld, xypron.glpk, qemu-devel
Use the CSR detection mechanism to probe for the Smstateen extension
and initialize mstateen0/sstateen0 CSRs when present.
The mstateen0 register is configured to allow S-mode access to fcsr,
AIA, IMSIC, indirect CSR access, environment configuration, and
sstateen0. The sstateen0 register enables U-mode access to compressed
extension state and fcsr.
Supports both RV32 (using MSTATEEN0/MSTATEEN0H split) and RV64.
Signed-off-by: Leo Yu-Chi Liang <ycliang@andestech.com>
---
arch/riscv/cpu/andes/cpu.c | 29 +++++++++++++++++++++++++++++
arch/riscv/include/asm/csr.h | 15 +++++++++++++++
2 files changed, 44 insertions(+)
diff --git a/arch/riscv/cpu/andes/cpu.c b/arch/riscv/cpu/andes/cpu.c
index d25ecba0e88..feb755a4f0d 100644
--- a/arch/riscv/cpu/andes/cpu.c
+++ b/arch/riscv/cpu/andes/cpu.c
@@ -9,6 +9,7 @@
#include <irq_func.h>
#include <asm/cache.h>
#include <asm/csr.h>
+#include <asm/csr_detect.h>
#include <asm/arch-andes/csr.h>
/*
@@ -60,5 +61,33 @@ void harts_early_init(void)
mmisc_ctl_val |= MMISC_CTL_NON_BLOCKING_EN;
csr_write(CSR_MMISC_CTL, mmisc_ctl_val);
+
+ /* Initialize Smstateen if the extension is present */
+ {
+ int trap = 0;
+ unsigned long long mstateen0;
+
+ mstateen0 = csr_read_allowed(CSR_MSTATEEN0, trap);
+ if (!trap) {
+#if __riscv_xlen == 32
+ mstateen0 |= (unsigned long long)
+ csr_read(CSR_MSTATEEN0H) << 32;
+#endif
+ mstateen0 |= SMSTATEEN0_CS | SMSTATEEN0_FCSR |
+ SMSTATEEN0_CONTEXT |
+ SMSTATEEN0_IMSIC |
+ SMSTATEEN0_AIA |
+ SMSTATEEN0_CSRIND |
+ SMSTATEEN0_ENVCFG |
+ SMSTATEEN0_SE0;
+ csr_write(CSR_MSTATEEN0, mstateen0);
+#if __riscv_xlen == 32
+ csr_write(CSR_MSTATEEN0H, mstateen0 >> 32);
+#endif
+ csr_write(CSR_SSTATEEN0,
+ csr_read(CSR_SSTATEEN0) |
+ SMSTATEEN0_CS | SMSTATEEN0_FCSR);
+ }
+ }
}
}
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index 986f951c31a..cef0fd906da 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -97,6 +97,18 @@
#define SIE_STIE (_AC(0x1, UL) << IRQ_S_TIMER)
#define SIE_SEIE (_AC(0x1, UL) << IRQ_S_EXT)
+/* Smstateen: mstateen0 / sstateen0 bit definitions */
+#define SMSTATEEN0_CS (_AC(0x1, ULL) << 0)
+#define SMSTATEEN0_FCSR (_AC(0x1, ULL) << 1)
+#define SMSTATEEN0_JVT (_AC(0x1, ULL) << 2)
+#define SMSTATEEN0_CONTEXT (_AC(0x1, ULL) << 57)
+#define SMSTATEEN0_IMSIC (_AC(0x1, ULL) << 58)
+#define SMSTATEEN0_AIA (_AC(0x1, ULL) << 59)
+#define SMSTATEEN0_CSRIND (_AC(0x1, ULL) << 60)
+#define SMSTATEEN0_P1P13 (_AC(0x1, ULL) << 61)
+#define SMSTATEEN0_ENVCFG (_AC(0x1, ULL) << 62)
+#define SMSTATEEN0_SE0 (_AC(0x1, ULL) << 63)
+
#define CSR_FCSR 0x003
#define CSR_CYCLE 0xc00
#define CSR_TIME 0xc01
@@ -105,6 +117,7 @@
#define CSR_SIE 0x104
#define CSR_STVEC 0x105
#define CSR_SCOUNTEREN 0x106
+#define CSR_SSTATEEN0 0x10c
#define CSR_SSCRATCH 0x140
#define CSR_SEPC 0x141
#define CSR_SCAUSE 0x142
@@ -126,6 +139,8 @@
#else
#define CSR_MCOUNTEREN 0x306
#endif
+#define CSR_MSTATEEN0 0x30c
+#define CSR_MSTATEEN0H 0x31c
#define CSR_MSCRATCH 0x340
#define CSR_MEPC 0x341
#define CSR_MCAUSE 0x342
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 1/2] riscv: Add CSR detection support
@ 2026-03-19 8:33 Leo Yu-Chi Liang via qemu development
0 siblings, 0 replies; 6+ messages in thread
From: Leo Yu-Chi Liang via qemu development @ 2026-03-19 8:33 UTC (permalink / raw)
To: u-boot; +Cc: rick, ycliang, trini, me, anshuld, xypron.glpk, qemu-devel
Add a lightweight mechanism to safely probe CSRs that may not exist
on the current hart. This is useful for detecting optional extensions
(e.g. Smstateen) without relying on MARCHID or ISA string parsing.
The implementation consists of:
- A minimal expected trap handler (__riscv_expected_trap) that advances
past the faulting instruction and signals the trap via register a4.
- csr_read_allowed() and csr_write_allowed() macros that temporarily
swap the trap vector, attempt the CSR access, and report whether it
trapped.
Ported from OpenSBI's sbi_csr_detect.h mechanism.
Signed-off-by: Leo Yu-Chi Liang <ycliang@andestech.com>
---
arch/riscv/include/asm/csr_detect.h | 90 +++++++++++++++++++++++++++++
arch/riscv/lib/Makefile | 1 +
arch/riscv/lib/csr_detect.S | 23 ++++++++
3 files changed, 114 insertions(+)
create mode 100644 arch/riscv/include/asm/csr_detect.h
create mode 100644 arch/riscv/lib/csr_detect.S
diff --git a/arch/riscv/include/asm/csr_detect.h b/arch/riscv/include/asm/csr_detect.h
new file mode 100644
index 00000000000..c058b6b85ea
--- /dev/null
+++ b/arch/riscv/include/asm/csr_detect.h
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2026 Andes Technology Corporation
+ * Leo Yu-Chi Liang <ycliang@andestech.com>
+ *
+ * RISC-V CSR detection support
+ *
+ * Provides macros to safely probe CSRs that may not exist on the
+ * current hart. Uses a lightweight trap handler that simply advances
+ * past the faulting instruction and sets a flag.
+ *
+ * Ported from OpenSBI's sbi_csr_detect.h.
+ */
+
+#ifndef _ASM_RISCV_CSR_DETECT_H
+#define _ASM_RISCV_CSR_DETECT_H
+
+#include <asm/csr.h>
+
+#ifndef __ASSEMBLY__
+
+/* Two-level stringification so CSR macros are expanded before quoting */
+#define __CSR_DETECT_XSTR(x) #x
+#define __CSR_DETECT_STR(x) __CSR_DETECT_XSTR(x)
+
+#if CONFIG_IS_ENABLED(RISCV_SMODE)
+#define CSR_XTVEC CSR_STVEC
+#else
+#define CSR_XTVEC CSR_MTVEC
+#endif
+
+void __riscv_expected_trap(void);
+
+/**
+ * csr_read_allowed() - Read a CSR, detecting illegal-instruction traps.
+ * @csr_num: CSR number (must be a compile-time constant).
+ * @trap: lvalue that is set to 1 if the access trapped, 0 otherwise.
+ *
+ * Returns the CSR value on success, or 0 if the CSR does not exist.
+ *
+ * This works by temporarily installing a minimal trap handler that
+ * skips the faulting instruction and sets register a4 to 1. Interrupts
+ * must be disabled when calling this macro (they normally are during
+ * early init).
+ */
+#define csr_read_allowed(csr_num, trap) \
+({ \
+ register unsigned long __mtvec = \
+ (unsigned long)__riscv_expected_trap; \
+ register unsigned long __trap asm("a4") = 0; \
+ register unsigned long __ret = 0; \
+ __asm__ __volatile__( \
+ "csrrw %[mtvec], " \
+ __CSR_DETECT_STR(CSR_XTVEC) ", %[mtvec]\n" \
+ "csrr %[ret], " __ASM_STR(csr_num) "\n" \
+ "csrw " __CSR_DETECT_STR(CSR_XTVEC) ", %[mtvec]" \
+ : [mtvec] "+&r"(__mtvec), [ret] "=&r"(__ret), \
+ [trap] "+&r"(__trap) \
+ : \
+ : "memory"); \
+ trap = __trap; \
+ __ret; \
+})
+
+/**
+ * csr_write_allowed() - Write a CSR, detecting illegal-instruction traps.
+ * @csr_num: CSR number (must be a compile-time constant).
+ * @trap: lvalue that is set to 1 if the access trapped, 0 otherwise.
+ * @value: Value to write.
+ */
+#define csr_write_allowed(csr_num, trap, value) \
+({ \
+ register unsigned long __mtvec = \
+ (unsigned long)__riscv_expected_trap; \
+ register unsigned long __trap asm("a4") = 0; \
+ register unsigned long __val = (unsigned long)(value); \
+ __asm__ __volatile__( \
+ "csrrw %[mtvec], " \
+ __CSR_DETECT_STR(CSR_XTVEC) ", %[mtvec]\n" \
+ "csrw " __ASM_STR(csr_num) ", %[val]\n" \
+ "csrw " __CSR_DETECT_STR(CSR_XTVEC) ", %[mtvec]" \
+ : [mtvec] "+&r"(__mtvec), [trap] "+&r"(__trap) \
+ : [val] "rK"(__val) \
+ : "memory"); \
+ trap = __trap; \
+})
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_RISCV_CSR_DETECT_H */
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index a527b3e9ae3..42463b8bed0 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_$(PHASE_)LIB_BOOTM) += bootm.o
obj-$(CONFIG_$(PHASE_)LIB_BOOTI) += image.o
obj-$(CONFIG_CMD_GO) += boot.o
obj-y += cache.o
+obj-y += csr_detect.o
obj-$(CONFIG_SIFIVE_CACHE) += sifive_cache.o
obj-$(CONFIG_SYS_CACHE_THEAD_CMO) += thead_cmo.o
ifeq ($(CONFIG_$(PHASE_)RISCV_MMODE),y)
diff --git a/arch/riscv/lib/csr_detect.S b/arch/riscv/lib/csr_detect.S
new file mode 100644
index 00000000000..69c4b8e7933
--- /dev/null
+++ b/arch/riscv/lib/csr_detect.S
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * RISC-V CSR detection support
+ *
+ * Copyright (C) 2025 Andes Technology Corporation
+ * Leo Yu-Chi Liang <ycliang@andestech.com>
+ *
+ * Ported from OpenSBI's expected trap mechanism.
+ */
+
+#include <asm/encoding.h>
+
+ .text
+ .align 2
+ .global __riscv_expected_trap
+__riscv_expected_trap:
+ /* Advance past the faulting instruction */
+ csrr a4, MODE_PREFIX(epc)
+ addi a4, a4, 4
+ csrw MODE_PREFIX(epc), a4
+ /* Set a4 = 1 to signal that a trap occurred */
+ li a4, 1
+ MODE_PREFIX(ret)
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] riscv: Add CSR detection support
2026-03-19 8:29 [PATCH 1/2] riscv: Add CSR detection support Leo Yu-Chi Liang via qemu development
2026-03-19 8:29 ` [PATCH 2/2] riscv: andes: Add Smstateen extension support Leo Yu-Chi Liang via qemu development
@ 2026-03-24 18:55 ` Heinrich Schuchardt
1 sibling, 0 replies; 6+ messages in thread
From: Heinrich Schuchardt @ 2026-03-24 18:55 UTC (permalink / raw)
To: Leo Yu-Chi Liang, u-boot; +Cc: rick, ycliang, trini, me, anshuld, qemu-devel
Am 19. März 2026 09:29:10 MEZ schrieb Leo Yu-Chi Liang <ycliang@andestech.com>:
>Add a lightweight mechanism to safely probe CSRs that may not exist
>on the current hart. This is useful for detecting optional extensions
>(e.g. Smstateen) without relying on MARCHID or ISA string parsing.
>
>The implementation consists of:
>- A minimal expected trap handler (__riscv_expected_trap) that advances
> past the faulting instruction and signals the trap via register a4.
>- csr_read_allowed() and csr_write_allowed() macros that temporarily
> swap the trap vector, attempt the CSR access, and report whether it
> trapped.
>
>Ported from OpenSBI's sbi_csr_detect.h mechanism.
We already have a more generic mechanism for catching exceptions on RISC-V. See functions riscv_zkr_bind() and set_resume().
Do we really need a second mechanism?
Best regards
Heinrich
>
>Signed-off-by: Leo Yu-Chi Liang <ycliang@andestech.com>
>---
> arch/riscv/include/asm/csr_detect.h | 90 +++++++++++++++++++++++++++++
> arch/riscv/lib/Makefile | 1 +
> arch/riscv/lib/csr_detect.S | 23 ++++++++
> 3 files changed, 114 insertions(+)
> create mode 100644 arch/riscv/include/asm/csr_detect.h
> create mode 100644 arch/riscv/lib/csr_detect.S
>
>diff --git a/arch/riscv/include/asm/csr_detect.h b/arch/riscv/include/asm/csr_detect.h
>new file mode 100644
>index 00000000000..c058b6b85ea
>--- /dev/null
>+++ b/arch/riscv/include/asm/csr_detect.h
>@@ -0,0 +1,90 @@
>+/* SPDX-License-Identifier: GPL-2.0+ */
>+/*
>+ * Copyright (C) 2026 Andes Technology Corporation
>+ * Leo Yu-Chi Liang <ycliang@andestech.com>
>+ *
>+ * RISC-V CSR detection support
>+ *
>+ * Provides macros to safely probe CSRs that may not exist on the
>+ * current hart. Uses a lightweight trap handler that simply advances
>+ * past the faulting instruction and sets a flag.
>+ *
>+ * Ported from OpenSBI's sbi_csr_detect.h.
>+ */
>+
>+#ifndef _ASM_RISCV_CSR_DETECT_H
>+#define _ASM_RISCV_CSR_DETECT_H
>+
>+#include <asm/csr.h>
>+
>+#ifndef __ASSEMBLY__
>+
>+/* Two-level stringification so CSR macros are expanded before quoting */
>+#define __CSR_DETECT_XSTR(x) #x
>+#define __CSR_DETECT_STR(x) __CSR_DETECT_XSTR(x)
>+
>+#if CONFIG_IS_ENABLED(RISCV_SMODE)
>+#define CSR_XTVEC CSR_STVEC
>+#else
>+#define CSR_XTVEC CSR_MTVEC
>+#endif
>+
>+void __riscv_expected_trap(void);
>+
>+/**
>+ * csr_read_allowed() - Read a CSR, detecting illegal-instruction traps.
>+ * @csr_num: CSR number (must be a compile-time constant).
>+ * @trap: lvalue that is set to 1 if the access trapped, 0 otherwise.
>+ *
>+ * Returns the CSR value on success, or 0 if the CSR does not exist.
>+ *
>+ * This works by temporarily installing a minimal trap handler that
>+ * skips the faulting instruction and sets register a4 to 1. Interrupts
>+ * must be disabled when calling this macro (they normally are during
>+ * early init).
>+ */
>+#define csr_read_allowed(csr_num, trap) \
>+({ \
>+ register unsigned long __mtvec = \
>+ (unsigned long)__riscv_expected_trap; \
>+ register unsigned long __trap asm("a4") = 0; \
>+ register unsigned long __ret = 0; \
>+ __asm__ __volatile__( \
>+ "csrrw %[mtvec], " \
>+ __CSR_DETECT_STR(CSR_XTVEC) ", %[mtvec]\n" \
>+ "csrr %[ret], " __ASM_STR(csr_num) "\n" \
>+ "csrw " __CSR_DETECT_STR(CSR_XTVEC) ", %[mtvec]" \
>+ : [mtvec] "+&r"(__mtvec), [ret] "=&r"(__ret), \
>+ [trap] "+&r"(__trap) \
>+ : \
>+ : "memory"); \
>+ trap = __trap; \
>+ __ret; \
>+})
>+
>+/**
>+ * csr_write_allowed() - Write a CSR, detecting illegal-instruction traps.
>+ * @csr_num: CSR number (must be a compile-time constant).
>+ * @trap: lvalue that is set to 1 if the access trapped, 0 otherwise.
>+ * @value: Value to write.
>+ */
>+#define csr_write_allowed(csr_num, trap, value) \
>+({ \
>+ register unsigned long __mtvec = \
>+ (unsigned long)__riscv_expected_trap; \
>+ register unsigned long __trap asm("a4") = 0; \
>+ register unsigned long __val = (unsigned long)(value); \
>+ __asm__ __volatile__( \
>+ "csrrw %[mtvec], " \
>+ __CSR_DETECT_STR(CSR_XTVEC) ", %[mtvec]\n" \
>+ "csrw " __ASM_STR(csr_num) ", %[val]\n" \
>+ "csrw " __CSR_DETECT_STR(CSR_XTVEC) ", %[mtvec]" \
>+ : [mtvec] "+&r"(__mtvec), [trap] "+&r"(__trap) \
>+ : [val] "rK"(__val) \
>+ : "memory"); \
>+ trap = __trap; \
>+})
>+
>+#endif /* !__ASSEMBLY__ */
>+
>+#endif /* _ASM_RISCV_CSR_DETECT_H */
>diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
>index a527b3e9ae3..42463b8bed0 100644
>--- a/arch/riscv/lib/Makefile
>+++ b/arch/riscv/lib/Makefile
>@@ -12,6 +12,7 @@ obj-$(CONFIG_$(PHASE_)LIB_BOOTM) += bootm.o
> obj-$(CONFIG_$(PHASE_)LIB_BOOTI) += image.o
> obj-$(CONFIG_CMD_GO) += boot.o
> obj-y += cache.o
>+obj-y += csr_detect.o
> obj-$(CONFIG_SIFIVE_CACHE) += sifive_cache.o
> obj-$(CONFIG_SYS_CACHE_THEAD_CMO) += thead_cmo.o
> ifeq ($(CONFIG_$(PHASE_)RISCV_MMODE),y)
>diff --git a/arch/riscv/lib/csr_detect.S b/arch/riscv/lib/csr_detect.S
>new file mode 100644
>index 00000000000..69c4b8e7933
>--- /dev/null
>+++ b/arch/riscv/lib/csr_detect.S
>@@ -0,0 +1,23 @@
>+/* SPDX-License-Identifier: GPL-2.0+ */
>+/*
>+ * RISC-V CSR detection support
>+ *
>+ * Copyright (C) 2025 Andes Technology Corporation
>+ * Leo Yu-Chi Liang <ycliang@andestech.com>
>+ *
>+ * Ported from OpenSBI's expected trap mechanism.
>+ */
>+
>+#include <asm/encoding.h>
>+
>+ .text
>+ .align 2
>+ .global __riscv_expected_trap
>+__riscv_expected_trap:
>+ /* Advance past the faulting instruction */
>+ csrr a4, MODE_PREFIX(epc)
>+ addi a4, a4, 4
>+ csrw MODE_PREFIX(epc), a4
>+ /* Set a4 = 1 to signal that a trap occurred */
>+ li a4, 1
>+ MODE_PREFIX(ret)
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] riscv: andes: Add Smstateen extension support
2026-03-19 8:29 ` [PATCH 2/2] riscv: andes: Add Smstateen extension support Leo Yu-Chi Liang via qemu development
@ 2026-03-24 19:03 ` Heinrich Schuchardt
2026-03-24 19:06 ` Heinrich Schuchardt
0 siblings, 1 reply; 6+ messages in thread
From: Heinrich Schuchardt @ 2026-03-24 19:03 UTC (permalink / raw)
To: Leo Yu-Chi Liang, u-boot; +Cc: rick, ycliang, trini, me, anshuld, qemu-devel
Am 19. März 2026 09:29:11 MEZ schrieb Leo Yu-Chi Liang <ycliang@andestech.com>:
>Use the CSR detection mechanism to probe for the Smstateen extension
>and initialize mstateen0/sstateen0 CSRs when present.
>
>The mstateen0 register is configured to allow S-mode access to fcsr,
>AIA, IMSIC, indirect CSR access, environment configuration, and
>sstateen0. The sstateen0 register enables U-mode access to compressed
>extension state and fcsr.
>
>Supports both RV32 (using MSTATEEN0/MSTATEEN0H split) and RV64.
Why is this change needed in U-Boot?
Does EDK II do the same?
Isn't this the kernel's job?
Best regards
Heinrich
>
>Signed-off-by: Leo Yu-Chi Liang <ycliang@andestech.com>
>---
> arch/riscv/cpu/andes/cpu.c | 29 +++++++++++++++++++++++++++++
> arch/riscv/include/asm/csr.h | 15 +++++++++++++++
> 2 files changed, 44 insertions(+)
>
>diff --git a/arch/riscv/cpu/andes/cpu.c b/arch/riscv/cpu/andes/cpu.c
>index d25ecba0e88..feb755a4f0d 100644
>--- a/arch/riscv/cpu/andes/cpu.c
>+++ b/arch/riscv/cpu/andes/cpu.c
>@@ -9,6 +9,7 @@
> #include <irq_func.h>
> #include <asm/cache.h>
> #include <asm/csr.h>
>+#include <asm/csr_detect.h>
> #include <asm/arch-andes/csr.h>
>
> /*
>@@ -60,5 +61,33 @@ void harts_early_init(void)
> mmisc_ctl_val |= MMISC_CTL_NON_BLOCKING_EN;
>
> csr_write(CSR_MMISC_CTL, mmisc_ctl_val);
>+
>+ /* Initialize Smstateen if the extension is present */
>+ {
>+ int trap = 0;
>+ unsigned long long mstateen0;
>+
>+ mstateen0 = csr_read_allowed(CSR_MSTATEEN0, trap);
>+ if (!trap) {
>+#if __riscv_xlen == 32
>+ mstateen0 |= (unsigned long long)
>+ csr_read(CSR_MSTATEEN0H) << 32;
>+#endif
>+ mstateen0 |= SMSTATEEN0_CS | SMSTATEEN0_FCSR |
>+ SMSTATEEN0_CONTEXT |
>+ SMSTATEEN0_IMSIC |
>+ SMSTATEEN0_AIA |
>+ SMSTATEEN0_CSRIND |
>+ SMSTATEEN0_ENVCFG |
>+ SMSTATEEN0_SE0;
>+ csr_write(CSR_MSTATEEN0, mstateen0);
>+#if __riscv_xlen == 32
>+ csr_write(CSR_MSTATEEN0H, mstateen0 >> 32);
>+#endif
>+ csr_write(CSR_SSTATEEN0,
>+ csr_read(CSR_SSTATEEN0) |
>+ SMSTATEEN0_CS | SMSTATEEN0_FCSR);
>+ }
>+ }
> }
> }
>diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
>index 986f951c31a..cef0fd906da 100644
>--- a/arch/riscv/include/asm/csr.h
>+++ b/arch/riscv/include/asm/csr.h
>@@ -97,6 +97,18 @@
> #define SIE_STIE (_AC(0x1, UL) << IRQ_S_TIMER)
> #define SIE_SEIE (_AC(0x1, UL) << IRQ_S_EXT)
>
>+/* Smstateen: mstateen0 / sstateen0 bit definitions */
>+#define SMSTATEEN0_CS (_AC(0x1, ULL) << 0)
>+#define SMSTATEEN0_FCSR (_AC(0x1, ULL) << 1)
>+#define SMSTATEEN0_JVT (_AC(0x1, ULL) << 2)
>+#define SMSTATEEN0_CONTEXT (_AC(0x1, ULL) << 57)
>+#define SMSTATEEN0_IMSIC (_AC(0x1, ULL) << 58)
>+#define SMSTATEEN0_AIA (_AC(0x1, ULL) << 59)
>+#define SMSTATEEN0_CSRIND (_AC(0x1, ULL) << 60)
>+#define SMSTATEEN0_P1P13 (_AC(0x1, ULL) << 61)
>+#define SMSTATEEN0_ENVCFG (_AC(0x1, ULL) << 62)
>+#define SMSTATEEN0_SE0 (_AC(0x1, ULL) << 63)
>+
> #define CSR_FCSR 0x003
> #define CSR_CYCLE 0xc00
> #define CSR_TIME 0xc01
>@@ -105,6 +117,7 @@
> #define CSR_SIE 0x104
> #define CSR_STVEC 0x105
> #define CSR_SCOUNTEREN 0x106
>+#define CSR_SSTATEEN0 0x10c
> #define CSR_SSCRATCH 0x140
> #define CSR_SEPC 0x141
> #define CSR_SCAUSE 0x142
>@@ -126,6 +139,8 @@
> #else
> #define CSR_MCOUNTEREN 0x306
> #endif
>+#define CSR_MSTATEEN0 0x30c
>+#define CSR_MSTATEEN0H 0x31c
> #define CSR_MSCRATCH 0x340
> #define CSR_MEPC 0x341
> #define CSR_MCAUSE 0x342
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] riscv: andes: Add Smstateen extension support
2026-03-24 19:03 ` Heinrich Schuchardt
@ 2026-03-24 19:06 ` Heinrich Schuchardt
0 siblings, 0 replies; 6+ messages in thread
From: Heinrich Schuchardt @ 2026-03-24 19:06 UTC (permalink / raw)
To: Leo Yu-Chi Liang, u-boot; +Cc: rick, ycliang, trini, me, anshuld, qemu-devel
Am 24. März 2026 20:03:48 MEZ schrieb Heinrich Schuchardt <xypron.glpk@gmx.de>:
>Am 19. März 2026 09:29:11 MEZ schrieb Leo Yu-Chi Liang <ycliang@andestech.com>:
>>Use the CSR detection mechanism to probe for the Smstateen extension
>>and initialize mstateen0/sstateen0 CSRs when present.
>>
>>The mstateen0 register is configured to allow S-mode access to fcsr,
>>AIA, IMSIC, indirect CSR access, environment configuration, and
>>sstateen0. The sstateen0 register enables U-mode access to compressed
>>extension state and fcsr.
>>
>>Supports both RV32 (using MSTATEEN0/MSTATEEN0H split) and RV64.
>
>Why is this change needed in U-Boot?
>Does EDK II do the same?
>Isn't this the kernel's job?
And why add this in Andes code and not in the generic code?
>
>Best regards
>
>Heinrich
>
>>
>>Signed-off-by: Leo Yu-Chi Liang <ycliang@andestech.com>
>>---
>> arch/riscv/cpu/andes/cpu.c | 29 +++++++++++++++++++++++++++++
>> arch/riscv/include/asm/csr.h | 15 +++++++++++++++
>> 2 files changed, 44 insertions(+)
>>
>>diff --git a/arch/riscv/cpu/andes/cpu.c b/arch/riscv/cpu/andes/cpu.c
>>index d25ecba0e88..feb755a4f0d 100644
>>--- a/arch/riscv/cpu/andes/cpu.c
>>+++ b/arch/riscv/cpu/andes/cpu.c
>>@@ -9,6 +9,7 @@
>> #include <irq_func.h>
>> #include <asm/cache.h>
>> #include <asm/csr.h>
>>+#include <asm/csr_detect.h>
>> #include <asm/arch-andes/csr.h>
>>
>> /*
>>@@ -60,5 +61,33 @@ void harts_early_init(void)
>> mmisc_ctl_val |= MMISC_CTL_NON_BLOCKING_EN;
>>
>> csr_write(CSR_MMISC_CTL, mmisc_ctl_val);
>>+
>>+ /* Initialize Smstateen if the extension is present */
>>+ {
>>+ int trap = 0;
>>+ unsigned long long mstateen0;
>>+
>>+ mstateen0 = csr_read_allowed(CSR_MSTATEEN0, trap);
>>+ if (!trap) {
>>+#if __riscv_xlen == 32
>>+ mstateen0 |= (unsigned long long)
>>+ csr_read(CSR_MSTATEEN0H) << 32;
>>+#endif
>>+ mstateen0 |= SMSTATEEN0_CS | SMSTATEEN0_FCSR |
>>+ SMSTATEEN0_CONTEXT |
>>+ SMSTATEEN0_IMSIC |
>>+ SMSTATEEN0_AIA |
>>+ SMSTATEEN0_CSRIND |
>>+ SMSTATEEN0_ENVCFG |
>>+ SMSTATEEN0_SE0;
>>+ csr_write(CSR_MSTATEEN0, mstateen0);
>>+#if __riscv_xlen == 32
>>+ csr_write(CSR_MSTATEEN0H, mstateen0 >> 32);
>>+#endif
>>+ csr_write(CSR_SSTATEEN0,
>>+ csr_read(CSR_SSTATEEN0) |
>>+ SMSTATEEN0_CS | SMSTATEEN0_FCSR);
>>+ }
>>+ }
>> }
>> }
>>diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
>>index 986f951c31a..cef0fd906da 100644
>>--- a/arch/riscv/include/asm/csr.h
>>+++ b/arch/riscv/include/asm/csr.h
>>@@ -97,6 +97,18 @@
>> #define SIE_STIE (_AC(0x1, UL) << IRQ_S_TIMER)
>> #define SIE_SEIE (_AC(0x1, UL) << IRQ_S_EXT)
>>
>>+/* Smstateen: mstateen0 / sstateen0 bit definitions */
>>+#define SMSTATEEN0_CS (_AC(0x1, ULL) << 0)
>>+#define SMSTATEEN0_FCSR (_AC(0x1, ULL) << 1)
>>+#define SMSTATEEN0_JVT (_AC(0x1, ULL) << 2)
>>+#define SMSTATEEN0_CONTEXT (_AC(0x1, ULL) << 57)
>>+#define SMSTATEEN0_IMSIC (_AC(0x1, ULL) << 58)
>>+#define SMSTATEEN0_AIA (_AC(0x1, ULL) << 59)
>>+#define SMSTATEEN0_CSRIND (_AC(0x1, ULL) << 60)
>>+#define SMSTATEEN0_P1P13 (_AC(0x1, ULL) << 61)
>>+#define SMSTATEEN0_ENVCFG (_AC(0x1, ULL) << 62)
>>+#define SMSTATEEN0_SE0 (_AC(0x1, ULL) << 63)
>>+
>> #define CSR_FCSR 0x003
>> #define CSR_CYCLE 0xc00
>> #define CSR_TIME 0xc01
>>@@ -105,6 +117,7 @@
>> #define CSR_SIE 0x104
>> #define CSR_STVEC 0x105
>> #define CSR_SCOUNTEREN 0x106
>>+#define CSR_SSTATEEN0 0x10c
>> #define CSR_SSCRATCH 0x140
>> #define CSR_SEPC 0x141
>> #define CSR_SCAUSE 0x142
>>@@ -126,6 +139,8 @@
>> #else
>> #define CSR_MCOUNTEREN 0x306
>> #endif
>>+#define CSR_MSTATEEN0 0x30c
>>+#define CSR_MSTATEEN0H 0x31c
>> #define CSR_MSCRATCH 0x340
>> #define CSR_MEPC 0x341
>> #define CSR_MCAUSE 0x342
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-03-24 19:06 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-19 8:29 [PATCH 1/2] riscv: Add CSR detection support Leo Yu-Chi Liang via qemu development
2026-03-19 8:29 ` [PATCH 2/2] riscv: andes: Add Smstateen extension support Leo Yu-Chi Liang via qemu development
2026-03-24 19:03 ` Heinrich Schuchardt
2026-03-24 19:06 ` Heinrich Schuchardt
2026-03-24 18:55 ` [PATCH 1/2] riscv: Add CSR detection support Heinrich Schuchardt
-- strict thread matches above, loose matches on Subject: below --
2026-03-19 8:33 Leo Yu-Chi Liang via qemu development
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox