#include #include #include #include void vfp_save_state(struct vcpu *v) { v->arch.vfp.fpexc = READ_CP32(FPEXC); WRITE_CP32(v->arch.vfp.fpexc | FPEXC_EN, FPEXC); v->arch.vfp.fpscr = READ_CP32(FPSCR); if ( v->arch.vfp.fpexc & FPEXC_EX ) /* Check for sub-architecture */ { v->arch.vfp.fpinst = READ_CP32(FPINST); if ( v->arch.vfp.fpexc & FPEXC_FP2V ) v->arch.vfp.fpinst2 = READ_CP32(FPINST2); /* Disable FPEXC_EX */ WRITE_CP32((v->arch.vfp.fpexc | FPEXC_EN) & ~FPEXC_EX, FPEXC); } /* Save {d0-d15} */ asm volatile("stc p11, cr0, [%1], #32*4" : "=Q" (*v->arch.vfp.fpregs1) : "r" (v->arch.vfp.fpregs1)); /* 32 x 64 bits registers? */ if ( (READ_CP32(MVFR0) & MVFR0_A_SIMD_MASK) == 2 ) { /* Save {d16-d31} */ asm volatile("stcl p11, cr0, [%1], #32*4" : "=Q" (*v->arch.vfp.fpregs2) : "r" (v->arch.vfp.fpregs2)); } WRITE_CP32(v->arch.vfp.fpexc & ~(FPEXC_EN), FPEXC); } void vfp_restore_state(struct vcpu *v) { //uint64_t test[16]; WRITE_CP32(READ_CP32(FPEXC) | FPEXC_EN, FPEXC); /* Restore {d0-d15} */ asm volatile("ldc p11, cr0, [%1], #32*4" : : "Q" (*v->arch.vfp.fpregs1), "r" (v->arch.vfp.fpregs1)); /* 32 x 64 bits registers? */ if ( (READ_CP32(MVFR0) & MVFR0_A_SIMD_MASK) == 2 ) /* 32 x 64 bits registers */ /* Restore {d16-d31} */ asm volatile("ldcl p11, cr0, [%1], #32*4" : : "Q" (*v->arch.vfp.fpregs2), "r" (v->arch.vfp.fpregs2)); if ( v->arch.vfp.fpexc & FPEXC_EX ) { WRITE_CP32(v->arch.vfp.fpinst, FPINST); if ( v->arch.vfp.fpexc & FPEXC_FP2V ) WRITE_CP32(v->arch.vfp.fpinst2, FPINST2); } WRITE_CP32(v->arch.vfp.fpscr, FPSCR); WRITE_CP32(v->arch.vfp.fpexc, FPEXC); } static __init int vfp_init(void) { unsigned int vfpsid; unsigned int vfparch; vfpsid = READ_CP32(FPSID); printk("VFP implementer 0x%02x architecture %d part 0x%02x variant 0x%x " "rev 0x%x\n", (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT, (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT, (vfpsid & FPSID_PART_MASK) >> FPSID_PART_BIT, (vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT, (vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT); vfparch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; if ( vfparch < 2 ) panic("Xen only support VFP 3\n"); return 0; } presmp_initcall(vfp_init); /* * Local variables: * mode: C * c-file-style: "BSD" * c-basic-offset: 4 * indent-tabs-mode: nil * End: */