[PATCH v5 4/4] lib: sbi: Conditionalize FP and Vector save/restore based on extensions
dave.patel at riscstar.com
dave.patel at riscstar.com
Thu May 14 22:42:08 PDT 2026
From: Dave Patel <dave.patel at riscstar.com>
Unconditional save and restore of floating-point (FP) and Vector
registers fails on generic platform firmware. This firmware must run
on multiple platforms that may lack these extensions.
Address this by conditionally executing FP save/restore only if the
underlying hart supports the F or D extensions. Similarly, perform
Vector save/restore only if the hart supports the Vector extension.
Depend on a separate patch that introduces SBI_HART_EXT_F,
SBI_HART_EXT_D, and SBI_HART_EXT_V to enum sbi_hart_extensions and
the sbi_hart_ext[] array. Use sbi_hart_has_extension() to check for
these capabilities before performing the context switches.
Signed-off-by: Dave Patel <dave.patel at riscstar.com>
---
include/sbi/sbi_hart.h | 6 ++++++
lib/sbi/sbi_domain_context.c | 31 ++++++++++++++++++++++---------
lib/sbi/sbi_hart.c | 4 ++++
3 files changed, 32 insertions(+), 9 deletions(-)
diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h
index a788b34c..68a01b97 100644
--- a/include/sbi/sbi_hart.h
+++ b/include/sbi/sbi_hart.h
@@ -87,6 +87,12 @@ enum sbi_hart_extensions {
SBI_HART_EXT_XSIFIVE_CFLUSH_D_L1,
/** Hart has Xsfcease extension */
SBI_HART_EXT_XSIFIVE_CEASE,
+ /** Hart has V extension */
+ SBI_HART_EXT_V,
+ /** Hart has F extension */
+ SBI_HART_EXT_F,
+ /** Hart has D extension */
+ SBI_HART_EXT_D,
/** Maximum index of Hart extension */
SBI_HART_EXT_MAX,
diff --git a/lib/sbi/sbi_domain_context.c b/lib/sbi/sbi_domain_context.c
index 5e180698..1e3ca46d 100644
--- a/lib/sbi/sbi_domain_context.c
+++ b/lib/sbi/sbi_domain_context.c
@@ -155,10 +155,20 @@ static int switch_to_next_domain_context(struct hart_context *ctx,
csr_set(CSR_MSTATUS, MSTATUS_FS | MSTATUS_VS);
/* Eager context switch F and V */
- sbi_fp_save(&ctx->fp_ctx);
- sbi_fp_restore(&dom_ctx->fp_ctx);
- sbi_vector_save(ctx->vec_ctx);
- sbi_vector_restore(dom_ctx->vec_ctx);
+
+ if (sbi_hart_has_extension(sbi_scratch_thishart_ptr(),
+ SBI_HART_EXT_F) ||
+ sbi_hart_has_extension(sbi_scratch_thishart_ptr(),
+ SBI_HART_EXT_D)) {
+ sbi_fp_save(&ctx->fp_ctx);
+ sbi_fp_restore(&dom_ctx->fp_ctx);
+ }
+
+ if (sbi_hart_has_extension(sbi_scratch_thishart_ptr(),
+ SBI_HART_EXT_V)) {
+ sbi_vector_save(ctx->vec_ctx);
+ sbi_vector_restore(dom_ctx->vec_ctx);
+ }
/* Save current trap state and restore target domain's trap state */
trap_ctx = sbi_trap_get_context(scratch);
@@ -201,11 +211,14 @@ static int hart_context_init(u32 hartindex)
if (!ctx)
return SBI_ENOMEM;
- /* Allocate the vector context pointer */
- ctx->vec_ctx = sbi_zalloc(vec_size);
- if (!ctx->vec_ctx) {
- sbi_free(ctx);
- return SBI_ENOMEM;
+ if (sbi_hart_has_extension(sbi_scratch_thishart_ptr(),
+ SBI_HART_EXT_V )) {
+ /* Allocate the vector context pointer */
+ ctx->vec_ctx = sbi_zalloc(vec_size);
+ if (!ctx->vec_ctx) {
+ sbi_free(ctx);
+ return SBI_ENOMEM;
+ }
}
/* Bind context and domain */
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index 60e95bca..e7581368 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -396,6 +396,10 @@ const struct sbi_hart_ext_data sbi_hart_ext[] = {
__SBI_HART_EXT_DATA(ssstateen, SBI_HART_EXT_SSSTATEEN),
__SBI_HART_EXT_DATA(xsfcflushdlone, SBI_HART_EXT_XSIFIVE_CFLUSH_D_L1),
__SBI_HART_EXT_DATA(xsfcease, SBI_HART_EXT_XSIFIVE_CEASE),
+ __SBI_HART_EXT_DATA(v, SBI_HART_EXT_V),
+ __SBI_HART_EXT_DATA(f, SBI_HART_EXT_F),
+ __SBI_HART_EXT_DATA(d, SBI_HART_EXT_D),
+
};
_Static_assert(SBI_HART_EXT_MAX == array_size(sbi_hart_ext),
--
2.43.0
More information about the opensbi
mailing list