summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Patel <[email protected]>2026-05-18 14:00:21 +0530
committerAnup Patel <[email protected]>2026-05-18 14:02:28 +0530
commit21461156da2be4633f53a60a77fe70da1a517db4 (patch)
treef01af7bc3bccbffdcc77aa1552ace605ebe57cec
parent79e63bc8348df12835b5c264144e50d45abe72c8 (diff)
lib: sbi: Add RISC-V vector context save/restore support
Eager context switch: Add support for saving and restoring RISC-V vector extension state in OpenSBI. This introduces a per-hart vector context structure and helper routines to perform full context save and restore. The vector context includes vcsr CSRs along with storage for all 32 vector registers. The register state is saved and restored using byte-wise vector load/store instructions (vs8r/vl8r). The implementation follows an eager context switching model where the entire vector state is saved and restored on every context switch. This provides a simple and deterministic mechanism without requiring lazy trap-based management. Signed-off-by: Dave Patel <[email protected]> Signed-off-by: Anup Patel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Anup Patel <[email protected]>
-rw-r--r--include/sbi/sbi_vector.h40
-rw-r--r--lib/sbi/objects.mk1
-rw-r--r--lib/sbi/sbi_vector.c94
3 files changed, 135 insertions, 0 deletions
diff --git a/include/sbi/sbi_vector.h b/include/sbi/sbi_vector.h
new file mode 100644
index 00000000..f00184f0
--- /dev/null
+++ b/include/sbi/sbi_vector.h
@@ -0,0 +1,40 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2026 RISCstar Solutions.
+ *
+ * Authors:
+ * Dave Patel <[email protected]>
+ */
+
+#ifndef __SBI_VECTOR_H__
+#define __SBI_VECTOR_H__
+
+#include <sbi/sbi_types.h>
+
+struct sbi_vector_context {
+ unsigned long vcsr;
+ unsigned long vstart;
+
+ /* size depends on VLEN */
+ uint8_t vregs[];
+};
+
+#ifdef OPENSBI_CC_SUPPORT_VECTOR
+void sbi_vector_save(struct sbi_vector_context *dst);
+void sbi_vector_restore(const struct sbi_vector_context *src);
+size_t sbi_vector_context_size(void);
+#else
+static inline void sbi_vector_save(struct sbi_vector_context *dst)
+{
+}
+static inline void sbi_vector_restore(const struct sbi_vector_context *src)
+{
+}
+static inline size_t sbi_vector_context_size(void)
+{
+ return 0;
+}
+#endif /* OPENSBI_CC_SUPPORT_VECTOR */
+
+#endif /* __SBI_VECTOR_H__ */
diff --git a/lib/sbi/objects.mk b/lib/sbi/objects.mk
index 07d13229..c965e86d 100644
--- a/lib/sbi/objects.mk
+++ b/lib/sbi/objects.mk
@@ -102,3 +102,4 @@ libsbi-objs-y += sbi_trap_v_ldst.o
libsbi-objs-y += sbi_unpriv.o
libsbi-objs-y += sbi_expected_trap.o
libsbi-objs-y += sbi_cppc.o
+libsbi-objs-$(CC_SUPPORT_VECTOR) += sbi_vector.o
diff --git a/lib/sbi/sbi_vector.c b/lib/sbi/sbi_vector.c
new file mode 100644
index 00000000..1f9e01cf
--- /dev/null
+++ b/lib/sbi/sbi_vector.c
@@ -0,0 +1,94 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2026 RISCstar Solutions.
+ *
+ * Authors:
+ * Dave Patel <[email protected]>
+ */
+
+#include <sbi/riscv_encoding.h>
+#include <sbi/riscv_asm.h>
+#include <sbi/sbi_vector.h>
+#include <sbi/sbi_types.h>
+#include <sbi/sbi_hart.h>
+#include <sbi/sbi_error.h>
+
+size_t sbi_vector_context_size(void)
+{
+ return sizeof(struct sbi_vector_context) + (32 * csr_read(CSR_VLENB));
+}
+
+void sbi_vector_save(struct sbi_vector_context *dst)
+{
+ unsigned long vlenb, mstatus_orig;
+
+ if (!dst)
+ return;
+
+ /* Step 1. Save original mstatus and Enable VS */
+ mstatus_orig = csr_read_set(CSR_MSTATUS, MSTATUS_VS);
+ vlenb = csr_read(CSR_VLENB);
+
+ /* Step 2: Save CSRs */
+ dst->vcsr = csr_read(vcsr);
+ dst->vstart = csr_read(vstart);
+
+ /* Step 3: Save vector registers */
+#define SAVE_VREG(i) \
+ ({ \
+ asm volatile( \
+ " .option push\n\t" \
+ " .option arch, +v\n\t" \
+ " vs8r.v v" #i ", (%0)\n\t" \
+ " .option pop\n\t" \
+ :: "r"(dst->vregs + (i) * vlenb) : "memory"); \
+ }) \
+
+ SAVE_VREG(0);
+ SAVE_VREG(8);
+ SAVE_VREG(16);
+ SAVE_VREG(24);
+
+#undef SAVE_VREG
+
+ /* Step 4. Restore original mstatus LAST */
+ csr_write(CSR_MSTATUS, mstatus_orig);
+}
+
+void sbi_vector_restore(const struct sbi_vector_context *src)
+{
+ unsigned long vlenb, mstatus_orig;
+
+ if (!src)
+ return;
+
+ /* Step 1. Save original mstatus and Enable VS */
+ mstatus_orig = csr_read_set(CSR_MSTATUS, MSTATUS_VS);
+ vlenb = csr_read(CSR_VLENB);
+
+ /* Step 2: Restore vector registers */
+#define RESTORE_VREG(i) \
+ ({ \
+ asm volatile( \
+ " .option push\n\t" \
+ " .option arch, +v\n\t" \
+ " vl8r.v v" #i ", (%0)\n\t" \
+ " .option pop\n\t" \
+ :: "r"(src->vregs + (i) * vlenb) : "memory"); \
+ }) \
+
+ RESTORE_VREG(0);
+ RESTORE_VREG(8);
+ RESTORE_VREG(16);
+ RESTORE_VREG(24);
+#undef RESTORE_VREG
+
+ /* Step 3: Restore CSR's last */
+ /* Restore CSRs first */
+ csr_write(vcsr, src->vcsr);
+ csr_write(vstart, src->vstart);
+
+ /* Step 4. Restore original mstatus LAST */
+ csr_write(CSR_MSTATUS, mstatus_orig);
+}