This patch enables building Xen for the arm64 using the Clang/LLVM compiler. Changes include: - Add explicit -march=armv8 flag for arm64 builds. - Introduce `READ_FP_SYSREG` and `WRITE_FP_SYSREG` to encapsulate the required `.arch_extension fp` directive for system fp register access. - Add ".arch_extension fp" to the inline assembly for `save_state` and `restore_state`.
Signed-off-by: Saman Dehghan <[email protected]> --- README | 2 ++ xen/arch/arm/arch.mk | 1 + xen/arch/arm/arm64/vfp.c | 30 ++++++++++++++++++++++-------- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/README b/README index 889a4ea906..67c1aa7fe6 100644 --- a/README +++ b/README @@ -45,6 +45,8 @@ provided by your OS distributor: - For ARM: - GCC 5.1 or later - GNU Binutils 2.25 or later + or + - Clang/LLVM 11 or later - For RISC-V 64-bit: - GCC 12.2 or later - GNU Binutils 2.39 or later diff --git a/xen/arch/arm/arch.mk b/xen/arch/arm/arch.mk index 9c4bedfb3b..bcf548069b 100644 --- a/xen/arch/arm/arch.mk +++ b/xen/arch/arm/arch.mk @@ -13,6 +13,7 @@ ifeq ($(CONFIG_MPU),y) CFLAGS-$(CONFIG_ARM_64) += -march=armv8-r else CFLAGS-$(CONFIG_ARM_64) += -mcpu=generic +CFLAGS-$(CONFIG_ARM_64) += -march=armv8 endif CFLAGS-$(CONFIG_ARM_64) += -mgeneral-regs-only # No fp registers etc $(call cc-option-add,CFLAGS-$(CONFIG_ARM_64),CC,-mno-outline-atomics) diff --git a/xen/arch/arm/arm64/vfp.c b/xen/arch/arm/arm64/vfp.c index c4f89c7b0e..ea75c7a2b2 100644 --- a/xen/arch/arm/arm64/vfp.c +++ b/xen/arch/arm/arm64/vfp.c @@ -6,7 +6,8 @@ static inline void save_state(uint64_t *fpregs) { - asm volatile("stp q0, q1, [%1, #16 * 0]\n\t" + asm volatile(".arch_extension fp\n\t" + "stp q0, q1, [%1, #16 * 0]\n\t" "stp q2, q3, [%1, #16 * 2]\n\t" "stp q4, q5, [%1, #16 * 4]\n\t" "stp q6, q7, [%1, #16 * 6]\n\t" @@ -27,7 +28,8 @@ static inline void save_state(uint64_t *fpregs) static inline void restore_state(const uint64_t *fpregs) { - asm volatile("ldp q0, q1, [%1, #16 * 0]\n\t" + asm volatile(".arch_extension fp\n\t" + "ldp q0, q1, [%1, #16 * 0]\n\t" "ldp q2, q3, [%1, #16 * 2]\n\t" "ldp q4, q5, [%1, #16 * 4]\n\t" "ldp q6, q7, [%1, #16 * 6]\n\t" @@ -46,6 +48,18 @@ static inline void restore_state(const uint64_t *fpregs) : : "Q" (*fpregs), "r" (fpregs)); } +#define WRITE_FP_SYSREG(v, name) do { \ + uint64_t _r = (v); \ + asm volatile(".arch_extension fp\n\t" \ + "msr "__stringify(name)", %0" : : "r" (_r)); \ +} while (0) + +#define READ_FP_SYSREG(name) ({ \ + uint64_t _r; \ + asm volatile(".arch_extension fp\n\t" \ + "mrs %0, "__stringify(name) : "=r" (_r)); \ + _r; }) + void vfp_save_state(struct vcpu *v) { if ( !cpu_has_fp ) @@ -56,10 +70,10 @@ void vfp_save_state(struct vcpu *v) else save_state(v->arch.vfp.fpregs); - v->arch.vfp.fpsr = READ_SYSREG(FPSR); - v->arch.vfp.fpcr = READ_SYSREG(FPCR); + v->arch.vfp.fpsr = READ_FP_SYSREG(FPSR); + v->arch.vfp.fpcr = READ_FP_SYSREG(FPCR); if ( is_32bit_domain(v->domain) ) - v->arch.vfp.fpexc32_el2 = READ_SYSREG(FPEXC32_EL2); + v->arch.vfp.fpexc32_el2 = READ_FP_SYSREG(FPEXC32_EL2); } void vfp_restore_state(struct vcpu *v) @@ -72,8 +86,8 @@ void vfp_restore_state(struct vcpu *v) else restore_state(v->arch.vfp.fpregs); - WRITE_SYSREG(v->arch.vfp.fpsr, FPSR); - WRITE_SYSREG(v->arch.vfp.fpcr, FPCR); + WRITE_FP_SYSREG(v->arch.vfp.fpsr, FPSR); + WRITE_FP_SYSREG(v->arch.vfp.fpcr, FPCR); if ( is_32bit_domain(v->domain) ) - WRITE_SYSREG(v->arch.vfp.fpexc32_el2, FPEXC32_EL2); + WRITE_FP_SYSREG(v->arch.vfp.fpexc32_el2, FPEXC32_EL2); } -- 2.49.0
