From: Dave Patel <[email protected]>
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 <[email protected]>
---
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
--
opensbi mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/opensbi
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.