mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2026-05-23 14:21:32 +01:00
lib: sbi: Add floating-point context save/restore support.
Add support for saving and restoring RISC-V floating-point (F/D) extension state in OpenSBI. This introduces a floating-point context structure and helper routines to perform full context save and restore. The floating-point context includes storage for all 32 FPi registers (f0–f31) along with the fcsr control and status register. The register state is saved and restored using double-precision load/store instructions (fsd/fld), and single-precision load/store instructions (fsw/flw) on an RV64 system with F and D-extension support. The implementation follows an eager context switching model where the entire FP state is saved and restored on every context switch. This avoids the need for trap-based lazy management and keeps the design simple and deterministic. Signed-off-by: Dave Patel <dave.patel@riscstar.com> Signed-off-by: Anup Patel <anup.patel@oss.qualcomm.com> Link: https://lore.kernel.org/r/20260518083023.997323-3-anup.patel@oss.qualcomm.com Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2026 RISCstar Solutions.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Dave Patel <dave.patel@riscstar.com>
|
||||||
|
*/
|
||||||
|
#ifndef __SBI_FP_H__
|
||||||
|
#define __SBI_FP_H__
|
||||||
|
|
||||||
|
#include <sbi/sbi_types.h>
|
||||||
|
|
||||||
|
struct sbi_fp_context {
|
||||||
|
#if __riscv_d
|
||||||
|
uint64_t f[32];
|
||||||
|
#else
|
||||||
|
uint32_t f[32];
|
||||||
|
#endif
|
||||||
|
unsigned long fcsr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(__riscv_f) || defined(__riscv_d)
|
||||||
|
void sbi_fp_save(struct sbi_fp_context *dst);
|
||||||
|
void sbi_fp_restore(const struct sbi_fp_context *src);
|
||||||
|
#else
|
||||||
|
static inline void sbi_fp_save(struct sbi_fp_context *dst)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
static inline void sbi_fp_restore(const struct sbi_fp_context *src)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif /* __riscv_f || __riscv_d */
|
||||||
|
|
||||||
|
#endif /*__SBI_FP_H__ */
|
||||||
@@ -103,3 +103,4 @@ libsbi-objs-y += sbi_unpriv.o
|
|||||||
libsbi-objs-y += sbi_expected_trap.o
|
libsbi-objs-y += sbi_expected_trap.o
|
||||||
libsbi-objs-y += sbi_cppc.o
|
libsbi-objs-y += sbi_cppc.o
|
||||||
libsbi-objs-$(CC_SUPPORT_VECTOR) += sbi_vector.o
|
libsbi-objs-$(CC_SUPPORT_VECTOR) += sbi_vector.o
|
||||||
|
libsbi-objs-y += sbi_fp.o
|
||||||
|
|||||||
@@ -0,0 +1,192 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2026 RISCstar Solutions.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Dave Patel <dave.patel@riscstar.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sbi/riscv_asm.h>
|
||||||
|
#include <sbi/riscv_encoding.h>
|
||||||
|
#include <sbi/sbi_fp.h>
|
||||||
|
|
||||||
|
#if defined(__riscv_f) || defined(__riscv_d)
|
||||||
|
|
||||||
|
void sbi_fp_save(struct sbi_fp_context *dst)
|
||||||
|
{
|
||||||
|
unsigned long mstatus_orig;
|
||||||
|
|
||||||
|
if (!dst)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mstatus_orig = csr_read_set(CSR_MSTATUS, MSTATUS_VS);
|
||||||
|
|
||||||
|
asm volatile(
|
||||||
|
#if defined(__riscv_d)
|
||||||
|
"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"
|
||||||
|
#else
|
||||||
|
"fsw f0, 0(%0)\n"
|
||||||
|
"fsw f1, 4(%0)\n"
|
||||||
|
"fsw f2, 8(%0)\n"
|
||||||
|
"fsw f3, 12(%0)\n"
|
||||||
|
"fsw f4, 16(%0)\n"
|
||||||
|
"fsw f5, 20(%0)\n"
|
||||||
|
"fsw f6, 24(%0)\n"
|
||||||
|
"fsw f7, 28(%0)\n"
|
||||||
|
"fsw f8, 32(%0)\n"
|
||||||
|
"fsw f9, 36(%0)\n"
|
||||||
|
"fsw f10, 40(%0)\n"
|
||||||
|
"fsw f11, 44(%0)\n"
|
||||||
|
"fsw f12, 48(%0)\n"
|
||||||
|
"fsw f13, 52(%0)\n"
|
||||||
|
"fsw f14, 56(%0)\n"
|
||||||
|
"fsw f15, 60(%0)\n"
|
||||||
|
"fsw f16, 64(%0)\n"
|
||||||
|
"fsw f17, 68(%0)\n"
|
||||||
|
"fsw f18, 72(%0)\n"
|
||||||
|
"fsw f19, 76(%0)\n"
|
||||||
|
"fsw f20, 80(%0)\n"
|
||||||
|
"fsw f21, 84(%0)\n"
|
||||||
|
"fsw f22, 88(%0)\n"
|
||||||
|
"fsw f23, 92(%0)\n"
|
||||||
|
"fsw f24, 96(%0)\n"
|
||||||
|
"fsw f25, 100(%0)\n"
|
||||||
|
"fsw f26, 104(%0)\n"
|
||||||
|
"fsw f27, 108(%0)\n"
|
||||||
|
"fsw f28, 112(%0)\n"
|
||||||
|
"fsw f29, 116(%0)\n"
|
||||||
|
"fsw f30, 120(%0)\n"
|
||||||
|
"fsw f31, 124(%0)\n"
|
||||||
|
#endif /* __riscv_d */
|
||||||
|
:
|
||||||
|
: "r"(dst->f)
|
||||||
|
: "memory"
|
||||||
|
);
|
||||||
|
|
||||||
|
dst->fcsr = csr_read(CSR_FCSR);
|
||||||
|
|
||||||
|
/* Restore original mstatus LAST */
|
||||||
|
csr_write(CSR_MSTATUS, mstatus_orig);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sbi_fp_restore(const struct sbi_fp_context *src)
|
||||||
|
{
|
||||||
|
unsigned long mstatus_orig;
|
||||||
|
|
||||||
|
if (!src)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Save original mstatus */
|
||||||
|
mstatus_orig = csr_read_set(CSR_MSTATUS, MSTATUS_FS);
|
||||||
|
|
||||||
|
asm volatile(
|
||||||
|
#if defined(__riscv_d)
|
||||||
|
"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"
|
||||||
|
#else
|
||||||
|
"flw f0, 0(%0)\n"
|
||||||
|
"flw f1, 4(%0)\n"
|
||||||
|
"flw f2, 8(%0)\n"
|
||||||
|
"flw f3, 12(%0)\n"
|
||||||
|
"flw f4, 16(%0)\n"
|
||||||
|
"flw f5, 20(%0)\n"
|
||||||
|
"flw f6, 24(%0)\n"
|
||||||
|
"flw f7, 28(%0)\n"
|
||||||
|
"flw f8, 32(%0)\n"
|
||||||
|
"flw f9, 36(%0)\n"
|
||||||
|
"flw f10, 40(%0)\n"
|
||||||
|
"flw f11, 44(%0)\n"
|
||||||
|
"flw f12, 48(%0)\n"
|
||||||
|
"flw f13, 52(%0)\n"
|
||||||
|
"flw f14, 56(%0)\n"
|
||||||
|
"flw f15, 60(%0)\n"
|
||||||
|
"flw f16, 64(%0)\n"
|
||||||
|
"flw f17, 68(%0)\n"
|
||||||
|
"flw f18, 72(%0)\n"
|
||||||
|
"flw f19, 76(%0)\n"
|
||||||
|
"flw f20, 80(%0)\n"
|
||||||
|
"flw f21, 84(%0)\n"
|
||||||
|
"flw f22, 88(%0)\n"
|
||||||
|
"flw f23, 92(%0)\n"
|
||||||
|
"flw f24, 96(%0)\n"
|
||||||
|
"flw f25, 100(%0)\n"
|
||||||
|
"flw f26, 104(%0)\n"
|
||||||
|
"flw f27, 108(%0)\n"
|
||||||
|
"flw f28, 112(%0)\n"
|
||||||
|
"flw f29, 116(%0)\n"
|
||||||
|
"flw f30, 120(%0)\n"
|
||||||
|
"flw f31, 124(%0)\n"
|
||||||
|
#endif /* __riscv_d */
|
||||||
|
:
|
||||||
|
: "r"(src->f)
|
||||||
|
: "memory"
|
||||||
|
);
|
||||||
|
|
||||||
|
csr_write(CSR_FCSR, src->fcsr);
|
||||||
|
|
||||||
|
/* Restore original mstatus LAST */
|
||||||
|
csr_write(CSR_MSTATUS, mstatus_orig);
|
||||||
|
}
|
||||||
|
#endif /* __riscv_f || __riscv_d */
|
||||||
Reference in New Issue
Block a user