Changeset View
Changeset View
Standalone View
Standalone View
head/sys/amd64/amd64/fpu.c
Show First 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | xsave(char *addr, uint64_t mask) | ||||
uint32_t low, hi; | uint32_t low, hi; | ||||
low = mask; | low = mask; | ||||
hi = mask >> 32; | hi = mask >> 32; | ||||
__asm __volatile("xsave %0" : "=m" (*addr) : "a" (low), "d" (hi) : | __asm __volatile("xsave %0" : "=m" (*addr) : "a" (low), "d" (hi) : | ||||
"memory"); | "memory"); | ||||
} | } | ||||
static __inline void | |||||
xsaveopt(char *addr, uint64_t mask) | |||||
{ | |||||
uint32_t low, hi; | |||||
low = mask; | |||||
hi = mask >> 32; | |||||
__asm __volatile("xsaveopt %0" : "=m" (*addr) : "a" (low), "d" (hi) : | |||||
"memory"); | |||||
} | |||||
#else /* !(__GNUCLIKE_ASM && !lint) */ | #else /* !(__GNUCLIKE_ASM && !lint) */ | ||||
void fldcw(u_short cw); | void fldcw(u_short cw); | ||||
void fnclex(void); | void fnclex(void); | ||||
void fninit(void); | void fninit(void); | ||||
void fnstcw(caddr_t addr); | void fnstcw(caddr_t addr); | ||||
void fnstsw(caddr_t addr); | void fnstsw(caddr_t addr); | ||||
void fxsave(caddr_t addr); | void fxsave(caddr_t addr); | ||||
void fxrstor(caddr_t addr); | void fxrstor(caddr_t addr); | ||||
void ldmxcsr(u_int csr); | void ldmxcsr(u_int csr); | ||||
void stmxcsr(u_int *csr); | void stmxcsr(u_int *csr); | ||||
void xrstor(char *addr, uint64_t mask); | void xrstor(char *addr, uint64_t mask); | ||||
void xsave(char *addr, uint64_t mask); | void xsave(char *addr, uint64_t mask); | ||||
void xsaveopt(char *addr, uint64_t mask); | |||||
#endif /* __GNUCLIKE_ASM && !lint */ | #endif /* __GNUCLIKE_ASM && !lint */ | ||||
#define start_emulating() load_cr0(rcr0() | CR0_TS) | #define start_emulating() load_cr0(rcr0() | CR0_TS) | ||||
#define stop_emulating() clts() | #define stop_emulating() clts() | ||||
CTASSERT(sizeof(struct savefpu) == 512); | CTASSERT(sizeof(struct savefpu) == 512); | ||||
CTASSERT(sizeof(struct xstate_hdr) == 64); | CTASSERT(sizeof(struct xstate_hdr) == 64); | ||||
Show All 29 Lines | |||||
static struct savefpu *fpu_initialstate; | static struct savefpu *fpu_initialstate; | ||||
struct xsave_area_elm_descr { | struct xsave_area_elm_descr { | ||||
u_int offset; | u_int offset; | ||||
u_int size; | u_int size; | ||||
} *xsave_area_desc; | } *xsave_area_desc; | ||||
static void | static void | ||||
fpusave_xsaveopt(void *addr) | |||||
{ | |||||
xsaveopt((char *)addr, xsave_mask); | |||||
} | |||||
static void | |||||
fpusave_xsave(void *addr) | fpusave_xsave(void *addr) | ||||
{ | { | ||||
xsave((char *)addr, xsave_mask); | xsave((char *)addr, xsave_mask); | ||||
} | } | ||||
static void | static void | ||||
fpurestore_xrstor(void *addr) | fpurestore_xrstor(void *addr) | ||||
Show All 27 Lines | init_xsave(void) | ||||
use_xsave = 1; | use_xsave = 1; | ||||
TUNABLE_INT_FETCH("hw.use_xsave", &use_xsave); | TUNABLE_INT_FETCH("hw.use_xsave", &use_xsave); | ||||
} | } | ||||
DEFINE_IFUNC(, void, fpusave, (void *), static) | DEFINE_IFUNC(, void, fpusave, (void *), static) | ||||
{ | { | ||||
init_xsave(); | init_xsave(); | ||||
return (use_xsave ? fpusave_xsave : fpusave_fxsave); | if (use_xsave) | ||||
return ((cpu_stdext_feature & CPUID_EXTSTATE_XSAVEOPT) != 0 ? | |||||
fpusave_xsaveopt : fpusave_xsave); | |||||
return (fpusave_fxsave); | |||||
} | } | ||||
DEFINE_IFUNC(, void, fpurestore, (void *), static) | DEFINE_IFUNC(, void, fpurestore, (void *), static) | ||||
{ | { | ||||
init_xsave(); | init_xsave(); | ||||
return (use_xsave ? fpurestore_xrstor : fpurestore_fxrstor); | return (use_xsave ? fpurestore_xrstor : fpurestore_fxrstor); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 138 Lines • ▼ Show 20 Lines | fpuinitstate(void *arg __unused) | ||||
register_t saveintr; | register_t saveintr; | ||||
int cp[4], i, max_ext_n; | int cp[4], i, max_ext_n; | ||||
fpu_initialstate = malloc(cpu_max_ext_state_size, M_DEVBUF, | fpu_initialstate = malloc(cpu_max_ext_state_size, M_DEVBUF, | ||||
M_WAITOK | M_ZERO); | M_WAITOK | M_ZERO); | ||||
saveintr = intr_disable(); | saveintr = intr_disable(); | ||||
stop_emulating(); | stop_emulating(); | ||||
fpusave(fpu_initialstate); | fpusave_fxsave(fpu_initialstate); | ||||
if (fpu_initialstate->sv_env.en_mxcsr_mask) | if (fpu_initialstate->sv_env.en_mxcsr_mask) | ||||
cpu_mxcsr_mask = fpu_initialstate->sv_env.en_mxcsr_mask; | cpu_mxcsr_mask = fpu_initialstate->sv_env.en_mxcsr_mask; | ||||
else | else | ||||
cpu_mxcsr_mask = 0xFFBF; | cpu_mxcsr_mask = 0xFFBF; | ||||
/* | /* | ||||
* The fninit instruction does not modify XMM registers or x87 | * The fninit instruction does not modify XMM registers or x87 | ||||
* registers (MM/ST). The fpusave call dumped the garbage | * registers (MM/ST). The fpusave call dumped the garbage | ||||
▲ Show 20 Lines • Show All 821 Lines • Show Last 20 Lines |