Changeset View
Changeset View
Standalone View
Standalone View
head/sys/amd64/amd64/fpu.c
Show First 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | |||||
#include <machine/intr_machdep.h> | #include <machine/intr_machdep.h> | ||||
#include <machine/md_var.h> | #include <machine/md_var.h> | ||||
#include <machine/pcb.h> | #include <machine/pcb.h> | ||||
#include <machine/psl.h> | #include <machine/psl.h> | ||||
#include <machine/resource.h> | #include <machine/resource.h> | ||||
#include <machine/specialreg.h> | #include <machine/specialreg.h> | ||||
#include <machine/segments.h> | #include <machine/segments.h> | ||||
#include <machine/ucontext.h> | #include <machine/ucontext.h> | ||||
#include <x86/ifunc.h> | |||||
/* | /* | ||||
* Floating point support. | * Floating point support. | ||||
*/ | */ | ||||
#if defined(__GNUCLIKE_ASM) && !defined(lint) | #if defined(__GNUCLIKE_ASM) && !defined(lint) | ||||
#define fldcw(cw) __asm __volatile("fldcw %0" : : "m" (cw)) | #define fldcw(cw) __asm __volatile("fldcw %0" : : "m" (cw)) | ||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | |||||
static uma_zone_t fpu_save_area_zone; | static uma_zone_t fpu_save_area_zone; | ||||
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; | ||||
void | static void | ||||
fpusave(void *addr) | fpusave_xsave(void *addr) | ||||
{ | { | ||||
if (use_xsave) | |||||
xsave((char *)addr, xsave_mask); | xsave((char *)addr, xsave_mask); | ||||
else | |||||
fxsave((char *)addr); | |||||
} | } | ||||
void | static void | ||||
fpurestore(void *addr) | fpurestore_xrstor(void *addr) | ||||
{ | { | ||||
if (use_xsave) | |||||
xrstor((char *)addr, xsave_mask); | xrstor((char *)addr, xsave_mask); | ||||
else | } | ||||
static void | |||||
fpusave_fxsave(void *addr) | |||||
{ | |||||
fxsave((char *)addr); | |||||
} | |||||
static void | |||||
fpurestore_fxrstor(void *addr) | |||||
{ | |||||
fxrstor((char *)addr); | fxrstor((char *)addr); | ||||
} | } | ||||
static void | |||||
init_xsave(void) | |||||
{ | |||||
if (use_xsave) | |||||
return; | |||||
if ((cpu_feature2 & CPUID2_XSAVE) == 0) | |||||
return; | |||||
use_xsave = 1; | |||||
TUNABLE_INT_FETCH("hw.use_xsave", &use_xsave); | |||||
} | |||||
DEFINE_IFUNC(, void, fpusave, (void *), static) | |||||
{ | |||||
init_xsave(); | |||||
return (use_xsave ? fpusave_xsave : fpusave_fxsave); | |||||
} | |||||
DEFINE_IFUNC(, void, fpurestore, (void *), static) | |||||
{ | |||||
init_xsave(); | |||||
return (use_xsave ? fpurestore_xrstor : fpurestore_fxrstor); | |||||
} | |||||
void | void | ||||
fpususpend(void *addr) | fpususpend(void *addr) | ||||
{ | { | ||||
u_long cr0; | u_long cr0; | ||||
cr0 = rcr0(); | cr0 = rcr0(); | ||||
stop_emulating(); | stop_emulating(); | ||||
fpusave(addr); | fpusave(addr); | ||||
Show All 20 Lines | |||||
*/ | */ | ||||
static void | static void | ||||
fpuinit_bsp1(void) | fpuinit_bsp1(void) | ||||
{ | { | ||||
u_int cp[4]; | u_int cp[4]; | ||||
uint64_t xsave_mask_user; | uint64_t xsave_mask_user; | ||||
bool old_wp; | bool old_wp; | ||||
if ((cpu_feature2 & CPUID2_XSAVE) != 0) { | |||||
use_xsave = 1; | |||||
TUNABLE_INT_FETCH("hw.use_xsave", &use_xsave); | |||||
} | |||||
if (!use_xsave) | if (!use_xsave) | ||||
return; | return; | ||||
cpuid_count(0xd, 0x0, cp); | cpuid_count(0xd, 0x0, cp); | ||||
xsave_mask = XFEATURE_ENABLED_X87 | XFEATURE_ENABLED_SSE; | xsave_mask = XFEATURE_ENABLED_X87 | XFEATURE_ENABLED_SSE; | ||||
if ((cp[0] & xsave_mask) != xsave_mask) | if ((cp[0] & xsave_mask) != xsave_mask) | ||||
panic("CPU0 does not support X87 or SSE: %x", cp[0]); | panic("CPU0 does not support X87 or SSE: %x", cp[0]); | ||||
xsave_mask = ((uint64_t)cp[3] << 32) | cp[0]; | xsave_mask = ((uint64_t)cp[3] << 32) | cp[0]; | ||||
xsave_mask_user = xsave_mask; | xsave_mask_user = xsave_mask; | ||||
TUNABLE_ULONG_FETCH("hw.xsave_mask", &xsave_mask_user); | TUNABLE_ULONG_FETCH("hw.xsave_mask", &xsave_mask_user); | ||||
xsave_mask_user |= XFEATURE_ENABLED_X87 | XFEATURE_ENABLED_SSE; | xsave_mask_user |= XFEATURE_ENABLED_X87 | XFEATURE_ENABLED_SSE; | ||||
▲ Show 20 Lines • Show All 897 Lines • Show Last 20 Lines |