* [PATCH linux-evl v3 1/2] riscv: Add EVL core
2026-07-28 11:13 [PATCH linux-evl v3 0/2] Add RISC-V support to EVL Tobias Schaffner
@ 2026-07-28 11:13 ` Tobias Schaffner
2026-07-30 13:27 ` Philippe Gerum
2026-07-28 11:13 ` [PATCH linux-evl v3 2/2] riscv: Add FPU register test support Tobias Schaffner
1 sibling, 1 reply; 4+ messages in thread
From: Tobias Schaffner @ 2026-07-28 11:13 UTC (permalink / raw)
To: xenomai; +Cc: rpm, florian.bezdeka, jan.kiszka, Tobias Schaffner
Signed-off-by: Tobias Schaffner <tobias.schaffner@siemens.com>
---
arch/riscv/Kconfig | 2 ++
arch/riscv/include/asm/evl/calibration.h | 12 +++++++++++
arch/riscv/include/asm/evl/fptest.h | 22 ++++++++++++++++++++
arch/riscv/include/asm/evl/syscall.h | 25 +++++++++++++++++++++++
arch/riscv/include/asm/evl/thread.h | 12 +++++++++++
arch/riscv/include/dovetail/irq.h | 11 ++++++++++
arch/riscv/include/dovetail/mm_info.h | 11 ++++++++++
arch/riscv/include/dovetail/net.h | 11 ++++++++++
arch/riscv/include/dovetail/netdevice.h | 11 ++++++++++
arch/riscv/include/dovetail/poll.h | 11 ++++++++++
arch/riscv/include/dovetail/skbuff.h | 11 ++++++++++
arch/riscv/include/dovetail/thread_info.h | 11 ++++++++++
arch/riscv/include/uapi/asm/evl/fptest.h | 16 +++++++++++++++
13 files changed, 166 insertions(+)
create mode 100644 arch/riscv/include/asm/evl/calibration.h
create mode 100644 arch/riscv/include/asm/evl/fptest.h
create mode 100644 arch/riscv/include/asm/evl/syscall.h
create mode 100644 arch/riscv/include/asm/evl/thread.h
create mode 100644 arch/riscv/include/dovetail/irq.h
create mode 100644 arch/riscv/include/dovetail/mm_info.h
create mode 100644 arch/riscv/include/dovetail/net.h
create mode 100644 arch/riscv/include/dovetail/netdevice.h
create mode 100644 arch/riscv/include/dovetail/poll.h
create mode 100644 arch/riscv/include/dovetail/skbuff.h
create mode 100644 arch/riscv/include/dovetail/thread_info.h
create mode 100644 arch/riscv/include/uapi/asm/evl/fptest.h
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 912aada80962..cd5aba11360d 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -152,6 +152,7 @@ config RISCV
select HAVE_ARCH_VMAP_STACK if MMU && 64BIT
select HAVE_IRQ_PIPELINE
select HAVE_DOVETAIL
+ select HAVE_ARCH_EVL
select HAVE_ASM_MODVERSIONS
select HAVE_CONTEXT_TRACKING_USER
select HAVE_DEBUG_KMEMLEAK
@@ -378,6 +379,7 @@ config AS_HAS_OPTION_ARCH
source "arch/riscv/Kconfig.socs"
source "arch/riscv/Kconfig.errata"
source "kernel/Kconfig.dovetail"
+source "kernel/Kconfig.evl"
menu "Platform type"
diff --git a/arch/riscv/include/asm/evl/calibration.h b/arch/riscv/include/asm/evl/calibration.h
new file mode 100644
index 000000000000..4da81f33ce3c
--- /dev/null
+++ b/arch/riscv/include/asm/evl/calibration.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _EVL_RISCV_ASM_CALIBRATION_H
+#define _EVL_RISCV_ASM_CALIBRATION_H
+
+#include <linux/kconfig.h>
+
+static inline unsigned int evl_get_default_clock_gravity(void)
+{
+ return IS_ENABLED(CONFIG_SMP) ? 6000 : 3000;
+}
+
+#endif /* !_EVL_RISCV_ASM_CALIBRATION_H */
diff --git a/arch/riscv/include/asm/evl/fptest.h b/arch/riscv/include/asm/evl/fptest.h
new file mode 100644
index 000000000000..76a8092af702
--- /dev/null
+++ b/arch/riscv/include/asm/evl/fptest.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _EVL_RISCV_ASM_FPTEST_H
+#define _EVL_RISCV_ASM_FPTEST_H
+
+#include <linux/cpufeature.h>
+#include <uapi/asm/evl/fptest.h>
+
+static inline bool evl_begin_fpu(void)
+{
+ return false;
+}
+
+static inline void evl_end_fpu(void) { }
+
+static inline u32 evl_detect_fpu(void)
+{
+ u32 features = 0;
+
+ return features;
+}
+
+#endif /* _EVL_RISCV_ASM_FPTEST_H */
diff --git a/arch/riscv/include/asm/evl/syscall.h b/arch/riscv/include/asm/evl/syscall.h
new file mode 100644
index 000000000000..1ef2d008934f
--- /dev/null
+++ b/arch/riscv/include/asm/evl/syscall.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _EVL_RISC_ASM_SYSCALL_H
+#define _EVL_RISC_ASM_SYSCALL_H
+
+#include <linux/uaccess.h>
+#include <asm/unistd.h>
+#include <asm/ptrace.h>
+#include <asm/syscall.h>
+#include <uapi/asm-generic/dovetail.h>
+
+#define raw_put_user(src, dst) __put_user(src, dst)
+#define raw_get_user(dst, src) __get_user(dst, src)
+
+static inline bool
+is_valid_inband_syscall(unsigned int nr)
+{
+ return nr < NR_syscalls;
+}
+
+static inline bool is_compat_oob_call(void)
+{
+ return false;
+}
+
+#endif /* !_EVL_RISC_ASM_SYSCALL_H */
diff --git a/arch/riscv/include/asm/evl/thread.h b/arch/riscv/include/asm/evl/thread.h
new file mode 100644
index 000000000000..70a07d5bfdbb
--- /dev/null
+++ b/arch/riscv/include/asm/evl/thread.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _EVL_RISCV_ASM_THREAD_H
+#define _EVL_RISCV_ASM_THREAD_H
+
+#include <asm/csr.h>
+
+static inline bool evl_is_breakpoint(int trapnr)
+{
+ return trapnr == EXC_BREAKPOINT;
+}
+
+#endif /* !_EVL_RISCV_ASM_THREAD_H */
diff --git a/arch/riscv/include/dovetail/irq.h b/arch/riscv/include/dovetail/irq.h
new file mode 100644
index 000000000000..f214e2f6ee2b
--- /dev/null
+++ b/arch/riscv/include/dovetail/irq.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _EVL_DOVETAIL_IRQ_H
+#define _EVL_DOVETAIL_IRQ_H
+
+#ifdef CONFIG_EVL
+#include <asm-generic/evl/irq.h>
+#else
+#include_next <dovetail/irq.h>
+#endif
+
+#endif /* !_EVL_DOVETAIL_IRQ_H */
diff --git a/arch/riscv/include/dovetail/mm_info.h b/arch/riscv/include/dovetail/mm_info.h
new file mode 100644
index 000000000000..e38b97d1f50f
--- /dev/null
+++ b/arch/riscv/include/dovetail/mm_info.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _EVL_DOVETAIL_MM_INFO_H
+#define _EVL_DOVETAIL_MM_INFO_H
+
+#ifdef CONFIG_EVL
+#include <asm-generic/evl/mm_info.h>
+#else
+#include_next <dovetail/mm_info.h>
+#endif
+
+#endif /* !_EVL_DOVETAIL_MM_INFO_H */
diff --git a/arch/riscv/include/dovetail/net.h b/arch/riscv/include/dovetail/net.h
new file mode 100644
index 000000000000..34062fd4dd13
--- /dev/null
+++ b/arch/riscv/include/dovetail/net.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _EVL_DOVETAIL_NET_H
+#define _EVL_DOVETAIL_NET_H
+
+#ifdef CONFIG_NET_OOB
+#include <asm-generic/evl/net.h>
+#else
+#include_next <dovetail/net.h>
+#endif
+
+#endif /* !_EVL_DOVETAIL_NET_H */
diff --git a/arch/riscv/include/dovetail/netdevice.h b/arch/riscv/include/dovetail/netdevice.h
new file mode 100644
index 000000000000..ad3e7e99f1c0
--- /dev/null
+++ b/arch/riscv/include/dovetail/netdevice.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _EVL_DOVETAIL_NETDEVICE_H
+#define _EVL_DOVETAIL_NETDEVICE_H
+
+#ifdef CONFIG_NET_OOB
+#include <asm-generic/evl/netdevice.h>
+#else
+#include_next <dovetail/netdevice.h>
+#endif
+
+#endif /* !_EVL_DOVETAIL_NETDEVICE_H */
diff --git a/arch/riscv/include/dovetail/poll.h b/arch/riscv/include/dovetail/poll.h
new file mode 100644
index 000000000000..7196d625d0d9
--- /dev/null
+++ b/arch/riscv/include/dovetail/poll.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _EVL_DOVETAIL_POLL_H
+#define _EVL_DOVETAIL_POLL_H
+
+#ifdef CONFIG_EVL
+#include <asm-generic/evl/poll.h>
+#else
+#include_next <dovetail/poll.h>
+#endif
+
+#endif /* !_EVL_DOVETAIL_POLL_H */
diff --git a/arch/riscv/include/dovetail/skbuff.h b/arch/riscv/include/dovetail/skbuff.h
new file mode 100644
index 000000000000..c6ee9016a37a
--- /dev/null
+++ b/arch/riscv/include/dovetail/skbuff.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _EVL_DOVETAIL_SKBUFF_H
+#define _EVL_DOVETAIL_SKBUFF_H
+
+#ifdef CONFIG_NET_OOB
+#include <asm-generic/evl/skbuff.h>
+#else
+#include_next <dovetail/skbuff.h>
+#endif
+
+#endif /* !_EVL_DOVETAIL_SKBUFF_H */
diff --git a/arch/riscv/include/dovetail/thread_info.h b/arch/riscv/include/dovetail/thread_info.h
new file mode 100644
index 000000000000..bfef01471f0c
--- /dev/null
+++ b/arch/riscv/include/dovetail/thread_info.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _EVL_DOVETAIL_THREAD_INFO_H
+#define _EVL_DOVETAIL_THREAD_INFO_H
+
+#ifdef CONFIG_EVL
+#include <asm-generic/evl/thread_info.h>
+#else
+#include_next <dovetail/thread_info.h>
+#endif
+
+#endif /* !_EVL_DOVETAIL_THREAD_INFO_H */
diff --git a/arch/riscv/include/uapi/asm/evl/fptest.h b/arch/riscv/include/uapi/asm/evl/fptest.h
new file mode 100644
index 000000000000..1b1f4f0ce373
--- /dev/null
+++ b/arch/riscv/include/uapi/asm/evl/fptest.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+ *
+ * Derived from Xenomai Cobalt, https://xenomai.org/
+ * Copyright (C) 2006 Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>.
+ */
+#ifndef _EVL_RISCV_ASM_UAPI_FPTEST_H
+#define _EVL_RISCV_ASM_UAPI_FPTEST_H
+
+#include <linux/types.h>
+
+#define evl_riscv_fp 0x1
+
+#define evl_set_fpregs(__features, __val)
+#define evl_check_fpregs(__features, __val, __bad) 0
+
+#endif /* !_EVL_RISCV_ASM_UAPI_FPTEST_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH linux-evl v3 2/2] riscv: Add FPU register test support
2026-07-28 11:13 [PATCH linux-evl v3 0/2] Add RISC-V support to EVL Tobias Schaffner
2026-07-28 11:13 ` [PATCH linux-evl v3 1/2] riscv: Add EVL core Tobias Schaffner
@ 2026-07-28 11:13 ` Tobias Schaffner
1 sibling, 0 replies; 4+ messages in thread
From: Tobias Schaffner @ 2026-07-28 11:13 UTC (permalink / raw)
To: xenomai; +Cc: rpm, florian.bezdeka, jan.kiszka, Tobias Schaffner
Define evl_set_fpregs() and evl_check_fpregs(), allowing low-level
manipulation and validation of FPU register state.
Signed-off-by: Tobias Schaffner <tobias.schaffner@siemens.com>
---
arch/riscv/include/asm/evl/fptest.h | 13 ++-
arch/riscv/include/uapi/asm/evl/fptest.h | 127 ++++++++++++++++++++++-
2 files changed, 135 insertions(+), 5 deletions(-)
diff --git a/arch/riscv/include/asm/evl/fptest.h b/arch/riscv/include/asm/evl/fptest.h
index 76a8092af702..abbfe67055e5 100644
--- a/arch/riscv/include/asm/evl/fptest.h
+++ b/arch/riscv/include/asm/evl/fptest.h
@@ -3,19 +3,28 @@
#define _EVL_RISCV_ASM_FPTEST_H
#include <linux/cpufeature.h>
+#include <asm/fpu.h>
#include <uapi/asm/evl/fptest.h>
static inline bool evl_begin_fpu(void)
{
- return false;
+ kernel_fpu_begin();
+
+ return true;
}
-static inline void evl_end_fpu(void) { }
+static inline void evl_end_fpu(void)
+{
+ kernel_fpu_end();
+}
static inline u32 evl_detect_fpu(void)
{
u32 features = 0;
+ if (has_fpu())
+ features = evl_riscv_fpsimd;
+
return features;
}
diff --git a/arch/riscv/include/uapi/asm/evl/fptest.h b/arch/riscv/include/uapi/asm/evl/fptest.h
index 1b1f4f0ce373..1c9358005f0c 100644
--- a/arch/riscv/include/uapi/asm/evl/fptest.h
+++ b/arch/riscv/include/uapi/asm/evl/fptest.h
@@ -8,9 +8,130 @@
#include <linux/types.h>
-#define evl_riscv_fp 0x1
+#define evl_riscv_fpsimd 0x1
+#define evl_riscv_sve 0x2
-#define evl_set_fpregs(__features, __val)
-#define evl_check_fpregs(__features, __val, __bad) 0
+/*
+ * CAUTION: keep this code strictly inlined in macros: we don't want
+ * GCC to apply any callee-saved logic to fpsimd registers in
+ * evl_set_fpregs() before evl_check_fpregs() can verify their
+ * contents, but we still want GCC to know about the registers we have
+ * clobbered.
+ */
+
+#define evl_set_fpregs(__features, __val) \
+ do { \
+ unsigned int __i; \
+ __u64 __e[32]; \
+ \
+ if (__features & evl_riscv_fpsimd) { \
+ for (__i = 0; __i < 32; __i++) \
+ __e[__i] = (__val); \
+ __asm__ __volatile__( \
+ ".option push\n" \
+ ".option arch, +d\n" \
+ "fld f0, 0(%0)\n" \
+ "fld f1, 8(%0)\n" \
+ "fld f2, 16(%0)\n" \
+ "fld f3, 24(%0)\n" \
+ "fld f4, 32(%0)\n" \
+ "fld f5, 40(%0)\n" \
+ "fld f6, 48(%0)\n" \
+ "fld f7, 56(%0)\n" \
+ "fld f8, 64(%0)\n" \
+ "fld f9, 72(%0)\n" \
+ "fld f10, 80(%0)\n" \
+ "fld f11, 88(%0)\n" \
+ "fld f12, 96(%0)\n" \
+ "fld f13, 104(%0)\n" \
+ "fld f14, 112(%0)\n" \
+ "fld f15, 120(%0)\n" \
+ "fld f16, 128(%0)\n" \
+ "fld f17, 136(%0)\n" \
+ "fld f18, 144(%0)\n" \
+ "fld f19, 152(%0)\n" \
+ "fld f20, 160(%0)\n" \
+ "fld f21, 168(%0)\n" \
+ "fld f22, 176(%0)\n" \
+ "fld f23, 184(%0)\n" \
+ "fld f24, 192(%0)\n" \
+ "fld f25, 200(%0)\n" \
+ "fld f26, 208(%0)\n" \
+ "fld f27, 216(%0)\n" \
+ "fld f28, 224(%0)\n" \
+ "fld f29, 232(%0)\n" \
+ "fld f30, 240(%0)\n" \
+ "fld f31, 248(%0)\n" \
+ : /* No outputs. */ \
+ : "r"(&__e[0]) \
+ : "f0", "f1", "f2", "f3", "f4", "f5", \
+ "f6", "f7", "f8", "f9", "f10", "f11", \
+ "f12", "f13", "f14", "f15", "f16", \
+ "f17", "f18", "f19", "f20", "f21", \
+ "f22", "f23", "f24", "f25", "f26", \
+ "f27", "f28", "f29", "f30", "f31", \
+ "memory"); \
+ } \
+ } while (0)
+
+
+#define evl_check_fpregs(__features, __val, __bad) \
+ ({ \
+ unsigned int __result = (__val), __i; \
+ __u64 __e[32]; \
+ \
+ if (__features & evl_riscv_fpsimd) { \
+ for (__i = 0; __i < 32; __i++) \
+ __e[__i] = __val; \
+ \
+ __asm__ __volatile__( \
+ ".option push\n" \
+ ".option arch, +d\n" \
+ "fsd f0, 0(%0)\n" \
+ "fsd f1, 8(%0)\n" \
+ "fsd f2, 16(%0)\n" \
+ "fsd f3, 24(%0)\n" \
+ "fsd f4, 32(%0)\n" \
+ "fsd f5, 40(%0)\n" \
+ "fsd f6, 48(%0)\n" \
+ "fsd f7, 56(%0)\n" \
+ "fsd f8, 64(%0)\n" \
+ "fsd f9, 72(%0)\n" \
+ "fsd f10, 80(%0)\n" \
+ "fsd f11, 88(%0)\n" \
+ "fsd f12, 96(%0)\n" \
+ "fsd f13, 104(%0)\n" \
+ "fsd f14, 112(%0)\n" \
+ "fsd f15, 120(%0)\n" \
+ "fsd f16, 128(%0)\n" \
+ "fsd f17, 136(%0)\n" \
+ "fsd f18, 144(%0)\n" \
+ "fsd f19, 152(%0)\n" \
+ "fsd f20, 160(%0)\n" \
+ "fsd f21, 168(%0)\n" \
+ "fsd f22, 176(%0)\n" \
+ "fsd f23, 184(%0)\n" \
+ "fsd f24, 192(%0)\n" \
+ "fsd f25, 200(%0)\n" \
+ "fsd f26, 208(%0)\n" \
+ "fsd f27, 216(%0)\n" \
+ "fsd f28, 224(%0)\n" \
+ "fsd f29, 232(%0)\n" \
+ "fsd f30, 240(%0)\n" \
+ "fsd f31, 248(%0)\n" \
+ : /* No outputs */ \
+ : "r"(&__e[0]) \
+ : "memory"); \
+ \
+ for (__i = 0; __i < 32; __i++) { \
+ if (__e[__i] != __val) { \
+ __result = __e[__i]; \
+ (__bad) = __i; \
+ break; \
+ } \
+ } \
+ } \
+ __result; \
+ })
#endif /* !_EVL_RISCV_ASM_UAPI_FPTEST_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread