https://git.reactos.org/?p=reactos.git;a=commitdiff;h=99a6667bd911ad7dec92bfacdfa10cb702b37793

commit 99a6667bd911ad7dec92bfacdfa10cb702b37793
Author:     Victor Perevertkin <[email protected]>
AuthorDate: Sat Jan 15 04:15:05 2022 +0300
Commit:     Victor Perevertkin <[email protected]>
CommitDate: Tue Jan 25 02:12:33 2022 +0300

    [NTOS:KE] Remove all checks for x87 not being present
---
 ntoskrnl/ke/i386/cpu.c     | 140 +++++---------------------
 ntoskrnl/ke/i386/exp.c     | 245 ++++++++++++++++++---------------------------
 ntoskrnl/ke/i386/kiinit.c  |  68 +++----------
 ntoskrnl/ke/i386/thrdini.c |  33 ++----
 4 files changed, 151 insertions(+), 335 deletions(-)

diff --git a/ntoskrnl/ke/i386/cpu.c b/ntoskrnl/ke/i386/cpu.c
index 03bd33d465b..e627efe228a 100644
--- a/ntoskrnl/ke/i386/cpu.c
+++ b/ntoskrnl/ke/i386/cpu.c
@@ -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;
-
-    /* Save EFlags */
-    EFlags = __readeflags();
-
-    /* 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");
-    }
+    /* Do CPUID 1 now */
+    KiCpuId(&CpuInfo, 1);
 
-    /* Restore EFLAGS */
-    __writeeflags(EFlags);
+    /*
+     * 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;
 }
 
 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;
 
diff --git a/ntoskrnl/ke/i386/exp.c b/ntoskrnl/ke/i386/exp.c
index a64faa1d60c..7ed82f72017 100644
--- a/ntoskrnl/ke/i386/exp.c
+++ b/ntoskrnl/ke/i386/exp.c
@@ -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);
+        /* Flush the NPX State */
+        KiFlushNPXState(NULL);
 
-            /* Copy the FX State */
-            RtlCopyMemory(&FxSaveArea->U.FxArea,
-                          &Context->ExtendedRegisters[0],
-                          MAXIMUM_SUPPORTED_EXTENSION);
+        /* Copy the FX State */
+        RtlCopyMemory(&FxSaveArea->U.FxArea,
+                      &Context->ExtendedRegisters[0],
+                      MAXIMUM_SUPPORTED_EXTENSION);
 
-            /* Remove reserved bits from MXCSR */
-            FxSaveArea->U.FxArea.MXCsr &= KiMXCsrMask;
+        /* Remove reserved bits from MXCSR */
+        FxSaveArea->U.FxArea.MXCsr &= KiMXCsrMask;
 
-            /* Mask out any invalid flags */
-            FxSaveArea->Cr0NpxState &= ~(CR0_EM | CR0_MP | CR0_TS);
+        /* 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);
-            }
+        /* Check if this is a VDM app */
+        if (PsGetCurrentProcess()->VdmObjects)
+        {
+            /* 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);
+        /* Flush the NPX State */
+        KiFlushNPXState(NULL);
 
-            /* Check if we have Fxsr support */
-            if (KeI386FxsrPresent)
-            {
-                /* 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
+        /* Check if we have Fxsr support */
+        if (KeI386FxsrPresent)
+        {
+            /* 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 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];
-                }
+                /* 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;
 
-            /* Mask out any invalid flags */
-            FxSaveArea->Cr0NpxState &= ~(CR0_EM | CR0_MP | CR0_TS);
-
-            /* Check if this is a VDM app */
-            if (PsGetCurrentProcess()->VdmObjects)
+            /* Loop registers */
+            for (i = 0; i < SIZE_OF_80387_REGISTERS; i++)
             {
-                /* Allow the EM flag */
-                FxSaveArea->Cr0NpxState |= Context->FloatSave.Cr0NpxState &
-                    (CR0_EM | CR0_MP);
+                /* Copy registers */
+                FxSaveArea->U.FnArea.RegisterArea[i] = 
Context->FloatSave.RegisterArea[i];
             }
         }
-        else
+
+        /* Mask out any invalid flags */
+        FxSaveArea->Cr0NpxState &= ~(CR0_EM | CR0_MP | CR0_TS);
+
+        /* Check if this is a VDM app */
+        if (PsGetCurrentProcess()->VdmObjects)
         {
-            /* FIXME: Handle FPU Emulation */
-            //ASSERT(FALSE);
-            UNIMPLEMENTED;
+            /* 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);
-
-                /* 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);
-            }
+        /* Check if we have Fxsr support */
+        if (KeI386FxsrPresent)
+        {
+            /* Align the floating area to 16-bytes */
+            FloatSaveArea = 
(FLOATING_SAVE_AREA*)((ULONG_PTR)&FloatSaveBuffer.UnalignedArea &~ 0xF);
 
-            /* 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;
+            /* 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);
+        }
 
-            /* 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);
-         }
+        /* 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];
+        }
     }
 
     /* Handle debug registers */
diff --git a/ntoskrnl/ke/i386/kiinit.c b/ntoskrnl/ke/i386/kiinit.c
index 10889c0195c..7f0651e260a 100644
--- a/ntoskrnl/ke/i386/kiinit.c
+++ b/ntoskrnl/ke/i386/kiinit.c
@@ -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] =
diff --git a/ntoskrnl/ke/i386/thrdini.c b/ntoskrnl/ke/i386/thrdini.c
index 11bf02de2fb..ae9a599a8e2 100644
--- a/ntoskrnl/ke/i386/thrdini.c
+++ b/ntoskrnl/ke/i386/thrdini.c
@@ -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;
-
-            /* 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 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;
+
+        /* 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;

Reply via email to