[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH v3 4/7] 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 | 72 +++++++++++++++++++++++++++++ plat/common/include/arm/arm64/cpu.h | 46 +++++++++++++++++- 2 files changed, 116 insertions(+), 2 deletions(-) diff --git a/plat/common/arm/thread_start64.S b/plat/common/arm/thread_start64.S index 9a80f62..495040c 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,74 @@ restore_point: add sp, x2, #__CALLEE_SAVED_SIZE ret ENDPROC(asm_sw_ctx_switch) + +#ifdef CONFIG_FLOAT_POINT +/* + * Save the FP registers. + * + * x0 - pointer to struct fpsimd_state + */ +ENTRY(fpsimd_save_state) + stp q0, q1, [x0, #16 * 0] + stp q2, q3, [x0, #16 * 2] + stp q4, q5, [x0, #16 * 4] + stp q6, q7, [x0, #16 * 6] + stp q8, q9, [x0, #16 * 8] + stp q10, q11, [x0, #16 * 10] + stp q12, q13, [x0, #16 * 12] + stp q14, q15, [x0, #16 * 14] + stp q16, q17, [x0, #16 * 16] + stp q18, q19, [x0, #16 * 18] + stp q20, q21, [x0, #16 * 20] + stp q22, q23, [x0, #16 * 22] + stp q24, q25, [x0, #16 * 24] + stp q26, q27, [x0, #16 * 26] + stp q28, q29, [x0, #16 * 28] + stp q30, q31, [x0, #16 * 30]! + mrs x8, fpsr + str w8, [x0, #16 * 2] + mrs x8, fpcr + str w8, [x0, #16 * 2 + 4] + + ret +ENDPROC(fpsimd_save_state) + +/* + * Load the FP registers. + * + * x0 - pointer to struct fpsimd_state + */ +ENTRY(fpsimd_restore_state) + ldp q0, q1, [x0, #16 * 0] + ldp q2, q3, [x0, #16 * 2] + ldp q4, q5, [x0, #16 * 4] + ldp q6, q7, [x0, #16 * 6] + ldp q8, q9, [x0, #16 * 8] + ldp q10, q11, [x0, #16 * 10] + ldp q12, q13, [x0, #16 * 12] + ldp q14, q15, [x0, #16 * 14] + ldp q16, q17, [x0, #16 * 16] + ldp q18, q19, [x0, #16 * 18] + ldp q20, q21, [x0, #16 * 20] + ldp q22, q23, [x0, #16 * 22] + ldp q24, q25, [x0, #16 * 24] + ldp q26, q27, [x0, #16 * 26] + ldp q28, q29, [x0, #16 * 28] + ldp q30, q31, [x0, #16 * 30]! + ldr w8, [x0, #16 * 2] + msr fpsr, x8 + ldr w8, [x0, #16 * 2 + 4] + + /* + * Writes to fpcr may be self-synchronising, so avoid restoring + * the register if it hasn't changed. + */ + mrs x0, fpcr + cmp x0, x8 + b.eq 9999f + msr fpcr, x8 + +9999: + 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 |