|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT RFC PATCH 5/5] plat/arm: Support fp/simd save/restore during context switch
Floating point feature is useful for some applications. We should
save/restore fp registers during context switch.
Signed-off-by: Jia He <justin.he@xxxxxxx>
---
plat/common/arm/thread_start64.S | 83 +++++++++++++++++++++++++++++
plat/common/include/arm/arm64/cpu.h | 46 +++++++++++++++-
2 files changed, 127 insertions(+), 2 deletions(-)
diff --git a/plat/common/arm/thread_start64.S b/plat/common/arm/thread_start64.S
index 9a80f62..d810704 100644
--- a/plat/common/arm/thread_start64.S
+++ b/plat/common/arm/thread_start64.S
@@ -34,6 +34,7 @@
#include <uk/plat/common/sw_ctx.h>
#include <uk/arch/lcpu.h>
#include <uk/asm.h>
+#include <uk/config.h>
/*
* Thread stack memory layout:
@@ -121,3 +122,85 @@ restore_point:
add sp, x2, #__CALLEE_SAVED_SIZE
ret
ENDPROC(asm_sw_ctx_switch)
+
+#ifdef CONFIG_FLOAT_POINT
+.macro fpsimd_save state, tmpnr
+ stp q0, q1, [\state, #16 * 0]
+ stp q2, q3, [\state, #16 * 2]
+ stp q4, q5, [\state, #16 * 4]
+ stp q6, q7, [\state, #16 * 6]
+ stp q8, q9, [\state, #16 * 8]
+ stp q10, q11, [\state, #16 * 10]
+ stp q12, q13, [\state, #16 * 12]
+ stp q14, q15, [\state, #16 * 14]
+ stp q16, q17, [\state, #16 * 16]
+ stp q18, q19, [\state, #16 * 18]
+ stp q20, q21, [\state, #16 * 20]
+ stp q22, q23, [\state, #16 * 22]
+ stp q24, q25, [\state, #16 * 24]
+ stp q26, q27, [\state, #16 * 26]
+ stp q28, q29, [\state, #16 * 28]
+ stp q30, q31, [\state, #16 * 30]!
+ mrs x\tmpnr, fpsr
+ str w\tmpnr, [\state, #16 * 2]
+ mrs x\tmpnr, fpcr
+ str w\tmpnr, [\state, #16 * 2 + 4]
+.endm
+
+.macro fpsimd_restore_fpcr state, tmp
+ /*
+ * Writes to fpcr may be self-synchronising, so avoid restoring
+ * the register if it hasn't changed.
+ */
+ mrs \tmp, fpcr
+ cmp \tmp, \state
+ b.eq 9999f
+ msr fpcr, \state
+9999:
+.endm
+
+/* Clobbers \state */
+.macro fpsimd_restore state, tmpnr
+ ldp q0, q1, [\state, #16 * 0]
+ ldp q2, q3, [\state, #16 * 2]
+ ldp q4, q5, [\state, #16 * 4]
+ ldp q6, q7, [\state, #16 * 6]
+ ldp q8, q9, [\state, #16 * 8]
+ ldp q10, q11, [\state, #16 * 10]
+ ldp q12, q13, [\state, #16 * 12]
+ ldp q14, q15, [\state, #16 * 14]
+ ldp q16, q17, [\state, #16 * 16]
+ ldp q18, q19, [\state, #16 * 18]
+ ldp q20, q21, [\state, #16 * 20]
+ ldp q22, q23, [\state, #16 * 22]
+ ldp q24, q25, [\state, #16 * 24]
+ ldp q26, q27, [\state, #16 * 26]
+ ldp q28, q29, [\state, #16 * 28]
+ ldp q30, q31, [\state, #16 * 30]!
+ ldr w\tmpnr, [\state, #16 * 2]
+ msr fpsr, x\tmpnr
+ ldr w\tmpnr, [\state, #16 * 2 + 4]
+ fpsimd_restore_fpcr x\tmpnr, \state
+.endm
+
+
+/*
+ * Save the FP registers.
+ *
+ * x0 - pointer to struct fpsimd_state
+ */
+ENTRY(fpsimd_save_state)
+ fpsimd_save x0, 8
+ ret
+ENDPROC(fpsimd_save_state)
+
+/*
+ * Load the FP registers.
+ *
+ * x0 - pointer to struct fpsimd_state
+ */
+ENTRY(fpsimd_restore_state)
+ fpsimd_restore x0, 8
+ ret
+ENDPROC(fpsimd_restore_state)
+#endif /* CONFIG_FLOAT_POINT) */
diff --git a/plat/common/include/arm/arm64/cpu.h
b/plat/common/include/arm/arm64/cpu.h
index 122727a..71090b2 100644
--- a/plat/common/include/arm/arm64/cpu.h
+++ b/plat/common/include/arm/arm64/cpu.h
@@ -116,6 +116,47 @@ void halt(void);
void reset(void);
void system_off(void);
+#ifdef CONFIG_FLOAT_POINT
+struct user_fpsimd_state {
+ __u64 vregs[32 * 2];
+ __u32 fpsr;
+ __u32 fpcr;
+ __u32 __reserved[2];
+};
+
+extern void fpsimd_save_state(uintptr_t ptr);
+extern void fpsimd_restore_state(uintptr_t ptr);
+
+static inline void save_extregs(struct sw_ctx *ctx)
+{
+ fpsimd_save_state(ctx->extregs);
+}
+
+static inline void restore_extregs(struct sw_ctx *ctx)
+{
+ fpsimd_restore_state(ctx->extregs);
+}
+
+static inline struct sw_ctx *arch_alloc_sw_ctx(struct uk_alloc *allocator)
+{
+ struct sw_ctx *ctx;
+
+ ctx = (struct sw_ctx *)uk_malloc(allocator, sizeof(struct sw_ctx));
+ if (ctx)
+ ctx->extregs = (uintptr_t)uk_malloc(allocator,
+ sizeof(struct user_fpsimd_state));
+
+ uk_pr_debug("Allocating %lu bytes for sw ctx at %p, extregs at %p\n",
+ sizeof(struct sw_ctx), ctx, (void *)ctx->extregs);
+
+ return ctx;
+}
+
+static inline void arch_init_extregs(struct sw_ctx *ctx __unused)
+{
+}
+
+#else /* !CONFIG_FLOAT_POINT */
static inline void save_extregs(struct sw_ctx *ctx __unused)
{
}
@@ -128,9 +169,9 @@ static inline struct sw_ctx *arch_alloc_sw_ctx(struct
uk_alloc *allocator)
{
struct sw_ctx *ctx;
- ctx = uk_malloc(allocator, sizeof(struct sw_ctx));
+ ctx = (struct sw_ctx *)uk_malloc(allocator, sizeof(struct sw_ctx));
uk_pr_debug("Allocating %lu bytes for sw ctx at %p\n",
- sizeof(struct sw_ctx), ctx);
+ sizeof(struct sw_ctx), ctx);
return ctx;
}
@@ -140,4 +181,5 @@ static inline void arch_init_extregs(struct sw_ctx *ctx)
ctx->extregs = (uintptr_t)ctx + sizeof(struct sw_ctx);
}
+#endif /* CONFIG_FLOAT_POINT */
#endif /* __PLAT_COMMON_ARM64_CPU_H__ */
--
2.17.1
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |