mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 00:45:24 +00:00
[NTOS:KE] Remove all checks for x87 not being present
This commit is contained in:
parent
1aca6937ff
commit
99a6667bd9
4 changed files with 151 additions and 335 deletions
|
@ -24,7 +24,7 @@ UCHAR KiNMITSS[KTSS_IO_MAPS];
|
|||
ULONG KeI386CpuType;
|
||||
ULONG KeI386CpuStep;
|
||||
ULONG KiFastSystemCallDisable = 0;
|
||||
ULONG KeI386NpxPresent = 0;
|
||||
ULONG KeI386NpxPresent = TRUE;
|
||||
ULONG KiMXCsrMask = 0;
|
||||
ULONG MxcsrFeatureMask = 0;
|
||||
ULONG KeI386XMMIPresent = 0;
|
||||
|
@ -90,66 +90,30 @@ VOID
|
|||
NTAPI
|
||||
KiSetProcessorType(VOID)
|
||||
{
|
||||
ULONG EFlags, NewEFlags;
|
||||
CPU_INFO CpuInfo;
|
||||
ULONG Stepping, Type;
|
||||
|
||||
/* Start by assuming no CPUID data */
|
||||
KeGetCurrentPrcb()->CpuID = 0;
|
||||
/* Do CPUID 1 now */
|
||||
KiCpuId(&CpuInfo, 1);
|
||||
|
||||
/* Save EFlags */
|
||||
EFlags = __readeflags();
|
||||
/*
|
||||
* Get the Stepping and Type. The stepping contains both the
|
||||
* Model and the Step, while the Type contains the returned Type.
|
||||
* We ignore the family.
|
||||
*
|
||||
* For the stepping, we convert this: zzzzzzxy into this: x0y
|
||||
*/
|
||||
Stepping = CpuInfo.Eax & 0xF0;
|
||||
Stepping <<= 4;
|
||||
Stepping += (CpuInfo.Eax & 0xFF);
|
||||
Stepping &= 0xF0F;
|
||||
Type = CpuInfo.Eax & 0xF00;
|
||||
Type >>= 8;
|
||||
|
||||
/* XOR out the ID bit and update EFlags */
|
||||
NewEFlags = EFlags ^ EFLAGS_ID;
|
||||
__writeeflags(NewEFlags);
|
||||
|
||||
/* Get them back and see if they were modified */
|
||||
NewEFlags = __readeflags();
|
||||
if (NewEFlags != EFlags)
|
||||
{
|
||||
/* The modification worked, so CPUID exists. Set the ID Bit again. */
|
||||
EFlags |= EFLAGS_ID;
|
||||
__writeeflags(EFlags);
|
||||
|
||||
/* Peform CPUID 0 to see if CPUID 1 is supported */
|
||||
KiCpuId(&CpuInfo, 0);
|
||||
if (CpuInfo.Eax > 0)
|
||||
{
|
||||
/* Do CPUID 1 now */
|
||||
KiCpuId(&CpuInfo, 1);
|
||||
|
||||
/*
|
||||
* Get the Stepping and Type. The stepping contains both the
|
||||
* Model and the Step, while the Type contains the returned Type.
|
||||
* We ignore the family.
|
||||
*
|
||||
* For the stepping, we convert this: zzzzzzxy into this: x0y
|
||||
*/
|
||||
Stepping = CpuInfo.Eax & 0xF0;
|
||||
Stepping <<= 4;
|
||||
Stepping += (CpuInfo.Eax & 0xFF);
|
||||
Stepping &= 0xF0F;
|
||||
Type = CpuInfo.Eax & 0xF00;
|
||||
Type >>= 8;
|
||||
|
||||
/* Save them in the PRCB */
|
||||
KeGetCurrentPrcb()->CpuID = TRUE;
|
||||
KeGetCurrentPrcb()->CpuType = (UCHAR)Type;
|
||||
KeGetCurrentPrcb()->CpuStep = (USHORT)Stepping;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("CPUID Support lacking\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("CPUID Support lacking\n");
|
||||
}
|
||||
|
||||
/* Restore EFLAGS */
|
||||
__writeeflags(EFlags);
|
||||
/* Save them in the PRCB */
|
||||
KeGetCurrentPrcb()->CpuID = TRUE;
|
||||
KeGetCurrentPrcb()->CpuType = (UCHAR)Type;
|
||||
KeGetCurrentPrcb()->CpuStep = (USHORT)Stepping;
|
||||
}
|
||||
|
||||
CODE_SEG("INIT")
|
||||
|
@ -160,10 +124,6 @@ KiGetCpuVendor(VOID)
|
|||
PKPRCB Prcb = KeGetCurrentPrcb();
|
||||
CPU_INFO CpuInfo;
|
||||
|
||||
/* Assume no Vendor ID and fail if no CPUID Support. */
|
||||
Prcb->VendorString[0] = 0;
|
||||
if (!Prcb->CpuID) return 0;
|
||||
|
||||
/* Get the Vendor ID */
|
||||
KiCpuId(&CpuInfo, 0);
|
||||
|
||||
|
@ -465,7 +425,6 @@ NTAPI
|
|||
KiGetCacheInformation(VOID)
|
||||
{
|
||||
PKIPCR Pcr = (PKIPCR)KeGetPcr();
|
||||
ULONG Vendor;
|
||||
CPU_INFO CpuInfo;
|
||||
ULONG CacheRequests = 0, i;
|
||||
ULONG CurrentRegister;
|
||||
|
@ -476,12 +435,8 @@ KiGetCacheInformation(VOID)
|
|||
/* Set default L2 size */
|
||||
Pcr->SecondLevelCacheSize = 0;
|
||||
|
||||
/* Get the Vendor ID and make sure we support CPUID */
|
||||
Vendor = KiGetCpuVendor();
|
||||
if (!Vendor) return;
|
||||
|
||||
/* Check the Vendor ID */
|
||||
switch (Vendor)
|
||||
switch (KiGetCpuVendor())
|
||||
{
|
||||
/* Handle Intel case */
|
||||
case CPU_INTEL:
|
||||
|
@ -1158,47 +1113,6 @@ KiSaveProcessorState(IN PKTRAP_FRAME TrapFrame,
|
|||
KiSaveProcessorControlState(&Prcb->ProcessorState);
|
||||
}
|
||||
|
||||
CODE_SEG("INIT")
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KiIsNpxPresent(VOID)
|
||||
{
|
||||
ULONG Cr0;
|
||||
USHORT Magic;
|
||||
|
||||
/* Set magic */
|
||||
Magic = 0xFFFF;
|
||||
|
||||
/* Read CR0 and mask out FPU flags */
|
||||
Cr0 = __readcr0() & ~(CR0_MP | CR0_TS | CR0_EM | CR0_ET);
|
||||
|
||||
/* Store on FPU stack */
|
||||
#ifdef _MSC_VER
|
||||
__asm fninit;
|
||||
__asm fnstsw Magic;
|
||||
#else
|
||||
asm volatile ("fninit;" "fnstsw %0" : "+m"(Magic));
|
||||
#endif
|
||||
|
||||
/* Magic should now be cleared */
|
||||
if (Magic & 0xFF)
|
||||
{
|
||||
/* You don't have an FPU -- enable emulation for now */
|
||||
__writecr0(Cr0 | CR0_EM | CR0_TS);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* You have an FPU, enable it */
|
||||
Cr0 |= CR0_ET;
|
||||
|
||||
/* Enable INT 16 on 486 and higher */
|
||||
if (KeGetCurrentPrcb()->CpuType >= 3) Cr0 |= CR0_NE;
|
||||
|
||||
/* Set FPU state */
|
||||
__writecr0(Cr0 | CR0_EM | CR0_TS);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
CODE_SEG("INIT")
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
|
@ -1208,8 +1122,8 @@ KiIsNpxErrataPresent(VOID)
|
|||
INT ErrataPresent;
|
||||
ULONG Cr0;
|
||||
|
||||
/* Disable interrupts */
|
||||
_disable();
|
||||
/* Interrupts have to be disabled here. */
|
||||
ASSERT(!(__readeflags() & EFLAGS_INTERRUPT_MASK));
|
||||
|
||||
/* Read CR0 and remove FPU flags */
|
||||
Cr0 = __readcr0();
|
||||
|
@ -1247,9 +1161,6 @@ KiIsNpxErrataPresent(VOID)
|
|||
/* Restore CR0 */
|
||||
__writecr0(Cr0);
|
||||
|
||||
/* Enable interrupts */
|
||||
_enable();
|
||||
|
||||
/* Return if there's an errata */
|
||||
return ErrataPresent != 0;
|
||||
}
|
||||
|
@ -1370,9 +1281,6 @@ KeSaveFloatingPointState(OUT PKFLOATING_SAVE Save)
|
|||
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
|
||||
UNIMPLEMENTED_ONCE;
|
||||
|
||||
/* check if we are doing software emulation */
|
||||
if (!KeI386NpxPresent) return STATUS_ILLEGAL_FLOAT_CONTEXT;
|
||||
|
||||
FpState = ExAllocatePool(NonPagedPool, sizeof (FNSAVE_FORMAT));
|
||||
if (!FpState) return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
|
|
|
@ -434,30 +434,25 @@ KeContextToTrapFrame(IN PCONTEXT Context,
|
|||
/* Get the FX Area */
|
||||
FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
|
||||
|
||||
/* Check if NPX is present */
|
||||
if (KeI386NpxPresent)
|
||||
/* Flush the NPX State */
|
||||
KiFlushNPXState(NULL);
|
||||
|
||||
/* Copy the FX State */
|
||||
RtlCopyMemory(&FxSaveArea->U.FxArea,
|
||||
&Context->ExtendedRegisters[0],
|
||||
MAXIMUM_SUPPORTED_EXTENSION);
|
||||
|
||||
/* Remove reserved bits from MXCSR */
|
||||
FxSaveArea->U.FxArea.MXCsr &= KiMXCsrMask;
|
||||
|
||||
/* Mask out any invalid flags */
|
||||
FxSaveArea->Cr0NpxState &= ~(CR0_EM | CR0_MP | CR0_TS);
|
||||
|
||||
/* Check if this is a VDM app */
|
||||
if (PsGetCurrentProcess()->VdmObjects)
|
||||
{
|
||||
/* Flush the NPX State */
|
||||
KiFlushNPXState(NULL);
|
||||
|
||||
/* Copy the FX State */
|
||||
RtlCopyMemory(&FxSaveArea->U.FxArea,
|
||||
&Context->ExtendedRegisters[0],
|
||||
MAXIMUM_SUPPORTED_EXTENSION);
|
||||
|
||||
/* Remove reserved bits from MXCSR */
|
||||
FxSaveArea->U.FxArea.MXCsr &= KiMXCsrMask;
|
||||
|
||||
/* Mask out any invalid flags */
|
||||
FxSaveArea->Cr0NpxState &= ~(CR0_EM | CR0_MP | CR0_TS);
|
||||
|
||||
/* Check if this is a VDM app */
|
||||
if (PsGetCurrentProcess()->VdmObjects)
|
||||
{
|
||||
/* Allow the EM flag */
|
||||
FxSaveArea->Cr0NpxState |= Context->FloatSave.Cr0NpxState &
|
||||
(CR0_EM | CR0_MP);
|
||||
}
|
||||
/* Allow the EM flag */
|
||||
FxSaveArea->Cr0NpxState |= Context->FloatSave.Cr0NpxState & (CR0_EM | CR0_MP);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -468,88 +463,63 @@ KeContextToTrapFrame(IN PCONTEXT Context,
|
|||
/* Get the FX Area */
|
||||
FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
|
||||
|
||||
/* Check if NPX is present */
|
||||
if (KeI386NpxPresent)
|
||||
/* Flush the NPX State */
|
||||
KiFlushNPXState(NULL);
|
||||
|
||||
/* Check if we have Fxsr support */
|
||||
if (KeI386FxsrPresent)
|
||||
{
|
||||
/* Flush the NPX State */
|
||||
KiFlushNPXState(NULL);
|
||||
/* Convert the Fn Floating Point state to Fx */
|
||||
FxSaveArea->U.FxArea.ControlWord = (USHORT)Context->FloatSave.ControlWord;
|
||||
FxSaveArea->U.FxArea.StatusWord = (USHORT)Context->FloatSave.StatusWord;
|
||||
FxSaveArea->U.FxArea.TagWord =
|
||||
KiTagWordFnsaveToFxsave((USHORT)Context->FloatSave.TagWord);
|
||||
FxSaveArea->U.FxArea.ErrorOpcode =
|
||||
(USHORT)((Context->FloatSave.ErrorSelector >> 16) & 0xFFFF);
|
||||
FxSaveArea->U.FxArea.ErrorOffset = Context->FloatSave.ErrorOffset;
|
||||
FxSaveArea->U.FxArea.ErrorSelector = Context->FloatSave.ErrorSelector & 0xFFFF;
|
||||
FxSaveArea->U.FxArea.DataOffset = Context->FloatSave.DataOffset;
|
||||
FxSaveArea->U.FxArea.DataSelector = Context->FloatSave.DataSelector;
|
||||
|
||||
/* Check if we have Fxsr support */
|
||||
if (KeI386FxsrPresent)
|
||||
/* Clear out the Register Area */
|
||||
RtlZeroMemory(&FxSaveArea->U.FxArea.RegisterArea[0], SIZE_OF_FX_REGISTERS);
|
||||
|
||||
/* Loop the 8 floating point registers */
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
/* Convert the Fn Floating Point state to Fx */
|
||||
FxSaveArea->U.FxArea.ControlWord =
|
||||
(USHORT)Context->FloatSave.ControlWord;
|
||||
FxSaveArea->U.FxArea.StatusWord =
|
||||
(USHORT)Context->FloatSave.StatusWord;
|
||||
FxSaveArea->U.FxArea.TagWord =
|
||||
KiTagWordFnsaveToFxsave((USHORT)Context->FloatSave.TagWord);
|
||||
FxSaveArea->U.FxArea.ErrorOpcode =
|
||||
(USHORT)((Context->FloatSave.ErrorSelector >> 16) & 0xFFFF);
|
||||
FxSaveArea->U.FxArea.ErrorOffset =
|
||||
Context->FloatSave.ErrorOffset;
|
||||
FxSaveArea->U.FxArea.ErrorSelector =
|
||||
Context->FloatSave.ErrorSelector & 0xFFFF;
|
||||
FxSaveArea->U.FxArea.DataOffset =
|
||||
Context->FloatSave.DataOffset;
|
||||
FxSaveArea->U.FxArea.DataSelector =
|
||||
Context->FloatSave.DataSelector;
|
||||
|
||||
/* Clear out the Register Area */
|
||||
RtlZeroMemory(&FxSaveArea->U.FxArea.RegisterArea[0],
|
||||
SIZE_OF_FX_REGISTERS);
|
||||
|
||||
/* Loop the 8 floating point registers */
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
/* Copy from Fn to Fx */
|
||||
RtlCopyMemory(FxSaveArea->U.FxArea.RegisterArea + (i * 16),
|
||||
Context->FloatSave.RegisterArea + (i * 10),
|
||||
10);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy the structure */
|
||||
FxSaveArea->U.FnArea.ControlWord = Context->FloatSave.
|
||||
ControlWord;
|
||||
FxSaveArea->U.FnArea.StatusWord = Context->FloatSave.
|
||||
StatusWord;
|
||||
FxSaveArea->U.FnArea.TagWord = Context->FloatSave.TagWord;
|
||||
FxSaveArea->U.FnArea.ErrorOffset = Context->FloatSave.
|
||||
ErrorOffset;
|
||||
FxSaveArea->U.FnArea.ErrorSelector = Context->FloatSave.
|
||||
ErrorSelector;
|
||||
FxSaveArea->U.FnArea.DataOffset = Context->FloatSave.
|
||||
DataOffset;
|
||||
FxSaveArea->U.FnArea.DataSelector = Context->FloatSave.
|
||||
DataSelector;
|
||||
|
||||
/* Loop registers */
|
||||
for (i = 0; i < SIZE_OF_80387_REGISTERS; i++)
|
||||
{
|
||||
/* Copy registers */
|
||||
FxSaveArea->U.FnArea.RegisterArea[i] =
|
||||
Context->FloatSave.RegisterArea[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Mask out any invalid flags */
|
||||
FxSaveArea->Cr0NpxState &= ~(CR0_EM | CR0_MP | CR0_TS);
|
||||
|
||||
/* Check if this is a VDM app */
|
||||
if (PsGetCurrentProcess()->VdmObjects)
|
||||
{
|
||||
/* Allow the EM flag */
|
||||
FxSaveArea->Cr0NpxState |= Context->FloatSave.Cr0NpxState &
|
||||
(CR0_EM | CR0_MP);
|
||||
/* Copy from Fn to Fx */
|
||||
RtlCopyMemory(FxSaveArea->U.FxArea.RegisterArea + (i * 16),
|
||||
Context->FloatSave.RegisterArea + (i * 10),
|
||||
10);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: Handle FPU Emulation */
|
||||
//ASSERT(FALSE);
|
||||
UNIMPLEMENTED;
|
||||
/* Copy the structure */
|
||||
FxSaveArea->U.FnArea.ControlWord = Context->FloatSave.ControlWord;
|
||||
FxSaveArea->U.FnArea.StatusWord = Context->FloatSave.StatusWord;
|
||||
FxSaveArea->U.FnArea.TagWord = Context->FloatSave.TagWord;
|
||||
FxSaveArea->U.FnArea.ErrorOffset = Context->FloatSave.ErrorOffset;
|
||||
FxSaveArea->U.FnArea.ErrorSelector = Context->FloatSave.ErrorSelector;
|
||||
FxSaveArea->U.FnArea.DataOffset = Context->FloatSave.DataOffset;
|
||||
FxSaveArea->U.FnArea.DataSelector = Context->FloatSave.DataSelector;
|
||||
|
||||
/* Loop registers */
|
||||
for (i = 0; i < SIZE_OF_80387_REGISTERS; i++)
|
||||
{
|
||||
/* Copy registers */
|
||||
FxSaveArea->U.FnArea.RegisterArea[i] = Context->FloatSave.RegisterArea[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Mask out any invalid flags */
|
||||
FxSaveArea->Cr0NpxState &= ~(CR0_EM | CR0_MP | CR0_TS);
|
||||
|
||||
/* Check if this is a VDM app */
|
||||
if (PsGetCurrentProcess()->VdmObjects)
|
||||
{
|
||||
/* Allow the EM flag */
|
||||
FxSaveArea->Cr0NpxState |= Context->FloatSave.Cr0NpxState & (CR0_EM | CR0_MP);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -698,17 +668,13 @@ KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
|
|||
/* Get the FX Save Area */
|
||||
FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
|
||||
|
||||
/* Make sure NPX is present */
|
||||
if (KeI386NpxPresent)
|
||||
{
|
||||
/* Flush the NPX State */
|
||||
KiFlushNPXState(NULL);
|
||||
/* Flush the NPX State */
|
||||
KiFlushNPXState(NULL);
|
||||
|
||||
/* Copy the registers */
|
||||
RtlCopyMemory(&Context->ExtendedRegisters[0],
|
||||
&FxSaveArea->U.FxArea,
|
||||
MAXIMUM_SUPPORTED_EXTENSION);
|
||||
}
|
||||
/* Copy the registers */
|
||||
RtlCopyMemory(&Context->ExtendedRegisters[0],
|
||||
&FxSaveArea->U.FxArea,
|
||||
MAXIMUM_SUPPORTED_EXTENSION);
|
||||
}
|
||||
|
||||
/* Handle Floating Point */
|
||||
|
@ -718,49 +684,38 @@ KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
|
|||
/* Get the FX Save Area */
|
||||
FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
|
||||
|
||||
/* Make sure we have an NPX */
|
||||
if (KeI386NpxPresent)
|
||||
{
|
||||
/* Check if we have Fxsr support */
|
||||
if (KeI386FxsrPresent)
|
||||
{
|
||||
/* Align the floating area to 16-bytes */
|
||||
FloatSaveArea = (FLOATING_SAVE_AREA*)
|
||||
((ULONG_PTR)&FloatSaveBuffer.UnalignedArea &~ 0xF);
|
||||
/* Check if we have Fxsr support */
|
||||
if (KeI386FxsrPresent)
|
||||
{
|
||||
/* Align the floating area to 16-bytes */
|
||||
FloatSaveArea = (FLOATING_SAVE_AREA*)((ULONG_PTR)&FloatSaveBuffer.UnalignedArea &~ 0xF);
|
||||
|
||||
/* Get the State */
|
||||
KiFlushNPXState(FloatSaveArea);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We don't, use the FN area and flush the NPX State */
|
||||
FloatSaveArea = (FLOATING_SAVE_AREA*)&FxSaveArea->U.FnArea;
|
||||
KiFlushNPXState(NULL);
|
||||
}
|
||||
/* Get the State */
|
||||
KiFlushNPXState(FloatSaveArea);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We don't, use the FN area and flush the NPX State */
|
||||
FloatSaveArea = (FLOATING_SAVE_AREA*)&FxSaveArea->U.FnArea;
|
||||
KiFlushNPXState(NULL);
|
||||
}
|
||||
|
||||
/* Copy structure */
|
||||
Context->FloatSave.ControlWord = FloatSaveArea->ControlWord;
|
||||
Context->FloatSave.StatusWord = FloatSaveArea->StatusWord;
|
||||
Context->FloatSave.TagWord = FloatSaveArea->TagWord;
|
||||
Context->FloatSave.ErrorOffset = FloatSaveArea->ErrorOffset;
|
||||
Context->FloatSave.ErrorSelector = FloatSaveArea->ErrorSelector;
|
||||
Context->FloatSave.DataOffset = FloatSaveArea->DataOffset;
|
||||
Context->FloatSave.DataSelector = FloatSaveArea->DataSelector;
|
||||
Context->FloatSave.Cr0NpxState = FxSaveArea->Cr0NpxState;
|
||||
/* Copy structure */
|
||||
Context->FloatSave.ControlWord = FloatSaveArea->ControlWord;
|
||||
Context->FloatSave.StatusWord = FloatSaveArea->StatusWord;
|
||||
Context->FloatSave.TagWord = FloatSaveArea->TagWord;
|
||||
Context->FloatSave.ErrorOffset = FloatSaveArea->ErrorOffset;
|
||||
Context->FloatSave.ErrorSelector = FloatSaveArea->ErrorSelector;
|
||||
Context->FloatSave.DataOffset = FloatSaveArea->DataOffset;
|
||||
Context->FloatSave.DataSelector = FloatSaveArea->DataSelector;
|
||||
Context->FloatSave.Cr0NpxState = FxSaveArea->Cr0NpxState;
|
||||
|
||||
/* Loop registers */
|
||||
for (i = 0; i < SIZE_OF_80387_REGISTERS; i++)
|
||||
{
|
||||
/* Copy them */
|
||||
Context->FloatSave.RegisterArea[i] =
|
||||
FloatSaveArea->RegisterArea[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: Handle Emulation */
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
/* Loop registers */
|
||||
for (i = 0; i < SIZE_OF_80387_REGISTERS; i++)
|
||||
{
|
||||
/* Copy them */
|
||||
Context->FloatSave.RegisterArea[i] = FloatSaveArea->RegisterArea[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle debug registers */
|
||||
|
|
|
@ -85,58 +85,6 @@ KiInitMachineDependent(VOID)
|
|||
/* Check for PAT support and enable it */
|
||||
if (KeFeatureBits & KF_PAT) KiInitializePAT();
|
||||
|
||||
/* Assume no errata for now */
|
||||
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = 0;
|
||||
|
||||
/* Check if we have an NPX */
|
||||
if (KeI386NpxPresent)
|
||||
{
|
||||
/* Loop every CPU */
|
||||
i = KeActiveProcessors;
|
||||
for (Affinity = 1; i; Affinity <<= 1)
|
||||
{
|
||||
/* Check if this is part of the set */
|
||||
if (i & Affinity)
|
||||
{
|
||||
/* Run on this CPU */
|
||||
i &= ~Affinity;
|
||||
KeSetSystemAffinityThread(Affinity);
|
||||
|
||||
/* Detect FPU errata */
|
||||
if (KiIsNpxErrataPresent())
|
||||
{
|
||||
/* Disable NPX support */
|
||||
KeI386NpxPresent = FALSE;
|
||||
SharedUserData->
|
||||
ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] =
|
||||
TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If there's no NPX, then we're emulating the FPU */
|
||||
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] =
|
||||
!KeI386NpxPresent;
|
||||
|
||||
/* Check if there's no NPX, so that we can disable associated features */
|
||||
if (!KeI386NpxPresent)
|
||||
{
|
||||
/* Remove NPX-related bits */
|
||||
KeFeatureBits &= ~(KF_XMMI64 | KF_XMMI | KF_FXSR | KF_MMX);
|
||||
|
||||
/* Disable kernel flags */
|
||||
KeI386FxsrPresent = KeI386XMMIPresent = FALSE;
|
||||
|
||||
/* Disable processor features that might've been set until now */
|
||||
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] =
|
||||
SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] =
|
||||
SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] =
|
||||
SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] =
|
||||
SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] = 0;
|
||||
}
|
||||
|
||||
/* Check for CR4 support */
|
||||
if (KeFeatureBits & KF_CR4)
|
||||
{
|
||||
|
@ -459,6 +407,21 @@ KiVerifyCpuFeatures(PKPRCB Prcb)
|
|||
KeBugCheckEx(UNSUPPORTED_PROCESSOR, 0x2, 0x00000001, 0, 0);
|
||||
}
|
||||
|
||||
// Set up FPU-related CR0 flags.
|
||||
ULONG Cr0 = __readcr0();
|
||||
// Disable emulation and monitoring.
|
||||
Cr0 &= ~(CR0_EM | CR0_MP);
|
||||
// Enable FPU exceptions.
|
||||
Cr0 |= CR0_NE;
|
||||
|
||||
__writecr0(Cr0);
|
||||
|
||||
// Check for Pentium FPU bug.
|
||||
if (KiIsNpxErrataPresent())
|
||||
{
|
||||
KeBugCheckEx(UNSUPPORTED_PROCESSOR, 0x2, 0x00000001, 0, 0);
|
||||
}
|
||||
|
||||
// 5. Save feature bits.
|
||||
Prcb->FeatureBits = FeatureBits;
|
||||
}
|
||||
|
@ -590,6 +553,7 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
|
|||
((PETHREAD)InitThread)->ThreadsProcess = (PEPROCESS)InitProcess;
|
||||
|
||||
/* Set basic CPU Features that user mode can read */
|
||||
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = FALSE;
|
||||
SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] =
|
||||
(KeFeatureBits & KF_MMX) ? TRUE: FALSE;
|
||||
SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] =
|
||||
|
|
|
@ -152,28 +152,17 @@ KiInitializeContextThread(IN PKTHREAD Thread,
|
|||
Context->FloatSave.DataSelector = 0;
|
||||
}
|
||||
|
||||
/* Check if the CPU has NPX */
|
||||
if (KeI386NpxPresent)
|
||||
{
|
||||
/* Set an intial NPX State */
|
||||
Context->FloatSave.Cr0NpxState = 0;
|
||||
FxSaveArea->Cr0NpxState = 0;
|
||||
FxSaveArea->NpxSavedCpu = 0;
|
||||
/* Set an intial NPX State */
|
||||
Context->FloatSave.Cr0NpxState = 0;
|
||||
FxSaveArea->Cr0NpxState = 0;
|
||||
FxSaveArea->NpxSavedCpu = 0;
|
||||
|
||||
/* Now set the context flags depending on XMM support */
|
||||
ContextFlags |= (KeI386FxsrPresent) ? CONTEXT_EXTENDED_REGISTERS :
|
||||
CONTEXT_FLOATING_POINT;
|
||||
/* Now set the context flags depending on XMM support */
|
||||
ContextFlags |= (KeI386FxsrPresent) ? CONTEXT_EXTENDED_REGISTERS : CONTEXT_FLOATING_POINT;
|
||||
|
||||
/* Set the Thread's NPX State */
|
||||
Thread->NpxState = NPX_STATE_NOT_LOADED;
|
||||
Thread->Header.NpxIrql = PASSIVE_LEVEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We'll use emulation */
|
||||
FxSaveArea->Cr0NpxState = CR0_EM;
|
||||
Thread->NpxState = NPX_STATE_NOT_LOADED &~ CR0_MP;
|
||||
}
|
||||
/* Set the Thread's NPX State */
|
||||
Thread->NpxState = NPX_STATE_NOT_LOADED;
|
||||
Thread->Header.NpxIrql = PASSIVE_LEVEL;
|
||||
|
||||
/* Disable any debug registers */
|
||||
Context->ContextFlags &= ~CONTEXT_DEBUG_REGISTERS;
|
||||
|
|
Loading…
Reference in a new issue