Fix KeSaveFloatingPointState. It was working once upon a time, but the fix was lost...
[reactos.git] / reactos / ntoskrnl / ke / i386 / cpu.c
index 7c548fe..b56414c 100644 (file)
@@ -23,7 +23,7 @@ UCHAR KiNMITSS[KTSS_IO_MAPS];
 /* CPU Features and Flags */
 ULONG KeI386CpuType;
 ULONG KeI386CpuStep;
-ULONG KiFastSystemCallDisable = 1;
+ULONG KiFastSystemCallDisable = 0;
 ULONG KeI386NpxPresent = 0;
 ULONG KiMXCsrMask = 0;
 ULONG MxcsrFeatureMask = 0;
@@ -794,7 +794,7 @@ KiGetCacheInformation(VOID)
 
     /* Set the cache line */
     if (CacheLine > KeLargestCacheLine) KeLargestCacheLine = CacheLine;
-    DPRINT1("Prefetch Cache: %d bytes\tL2 Cache: %d bytes\tL2 Cache Line: %d bytes\tL2 Cache Associativity: %d\n",
+    DPRINT1("Prefetch Cache: %lu bytes\tL2 Cache: %lu bytes\tL2 Cache Line: %lu bytes\tL2 Cache Associativity: %lu\n",
             KePrefetchNTAGranularity,
             Pcr->SecondLevelCacheSize,
             KeLargestCacheLine,
@@ -1064,21 +1064,21 @@ KiRestoreFastSyscallReturnState(VOID)
     if (KeFeatureBits & KF_FAST_SYSCALL)
     {
         /* Check if it has been disabled */
-        if (!KiFastSystemCallDisable)
+        if (KiFastSystemCallDisable)
+        {
+            /* Disable fast system call */
+            KeFeatureBits &= ~KF_FAST_SYSCALL;
+            KiFastCallExitHandler = KiSystemCallTrapReturn;
+            DPRINT1("Support for SYSENTER disabled.\n");
+        }
+        else
         {
             /* Do an IPI to enable it */
             KeIpiGenericCall(KiLoadFastSyscallMachineSpecificRegisters, 0);
 
             /* It's enabled, so use the proper exit stub */
             KiFastCallExitHandler = KiSystemCallSysExitReturn;
-            DPRINT1("Support for SYSENTER detected.\n");
-        }
-        else
-        {
-            /* Disable fast system call */
-            KeFeatureBits &= ~KF_FAST_SYSCALL;
-            KiFastCallExitHandler = KiSystemCallTrapReturn;
-            DPRINT1("Support for SYSENTER disabled.\n");
+            DPRINT("Support for SYSENTER detected.\n");
         }
     }
     else
@@ -1137,7 +1137,7 @@ NTAPI
 INIT_FUNCTION
 KiI386PentiumLockErrataFixup(VOID)
 {
-    KDESCRIPTOR IdtDescriptor;
+    KDESCRIPTOR IdtDescriptor = {0, 0, 0};
     PKIDTENTRY NewIdt, NewIdt2;
 
     /* Allocate memory for a new IDT */
@@ -1254,9 +1254,9 @@ NTAPI
 INIT_FUNCTION
 KiIsNpxErrataPresent(VOID)
 {
-    BOOLEAN ErrataPresent;
+    static double Value1 = 4195835.0, Value2 = 3145727.0;
+    INT ErrataPresent;
     ULONG Cr0;
-    volatile double Value1, Value2;
 
     /* Disable interrupts */
     _disable();
@@ -1269,9 +1269,30 @@ KiIsNpxErrataPresent(VOID)
     Ke386FnInit();
 
     /* Multiply the magic values and divide, we should get the result back */
-    Value1 = 4195835.0;
-    Value2 = 3145727.0;
-    ErrataPresent = (Value1 * Value2 / 3145727.0) != 4195835.0;
+#ifdef __GNUC__
+    __asm__ __volatile__
+    (
+        "fldl %1\n\t"
+        "fdivl %2\n\t"
+        "fmull %2\n\t"
+        "fldl %1\n\t"
+        "fsubp\n\t"
+        "fistpl %0\n\t"
+        : "=m" (ErrataPresent)
+        : "m" (Value1),
+          "m" (Value2)
+    );
+#else
+    __asm
+    {
+        fld Value1
+        fdiv Value2
+        fmul Value2
+        fld Value1
+        fsubp st(1), st(0)
+        fistp ErrataPresent
+    };
+#endif
 
     /* Restore CR0 */
     __writecr0(Cr0);
@@ -1280,7 +1301,7 @@ KiIsNpxErrataPresent(VOID)
     _enable();
 
     /* Return if there's an errata */
-    return ErrataPresent;
+    return ErrataPresent != 0;
 }
 
 VOID
@@ -1302,7 +1323,12 @@ KiFlushNPXState(IN PFLOATING_SAVE_AREA SaveArea)
     if (Thread->NpxState != NPX_STATE_LOADED)
     {
         /* If there's nothing to load, quit */
-        if (!SaveArea) return;
+        if (!SaveArea)
+        {
+            /* Restore interrupt state and return */
+            __writeeflags(EFlags);
+            return;
+        }
 
         /* Need FXSR support for this */
         ASSERT(KeI386FxsrPresent == TRUE);
@@ -1406,11 +1432,12 @@ KeSaveFloatingPointState(OUT PKFLOATING_SAVE Save)
 #else
     __asm
     {
-        fnsave [FpState]
+        mov eax, [FpState]
+        fnsave [eax]
     };
 #endif
 
-    KeGetCurrentThread()->DispatcherHeader.NpxIrql = KeGetCurrentIrql();
+    KeGetCurrentThread()->Header.NpxIrql = KeGetCurrentIrql();
     return STATUS_SUCCESS;
 }
 
@@ -1422,7 +1449,7 @@ NTAPI
 KeRestoreFloatingPointState(IN PKFLOATING_SAVE Save)
 {
     PFNSAVE_FORMAT FpState = *((PVOID *) Save);
-    ASSERT(KeGetCurrentThread()->DispatcherHeader.NpxIrql == KeGetCurrentIrql());
+    ASSERT(KeGetCurrentThread()->Header.NpxIrql == KeGetCurrentIrql());
     DPRINT1("%s is not really implemented\n", __FUNCTION__);
 
 #ifdef __GNUC__
@@ -1509,7 +1536,7 @@ KeFlushEntireTb(IN BOOLEAN Invalid,
     if (TargetAffinity)
     {
         /* Sanity check */
-        ASSERT(Prcb == (volatile PKPRCB)KeGetCurrentPrcb());
+        ASSERT(Prcb == KeGetCurrentPrcb());
 
         /* FIXME: TODO */
         ASSERTMSG("Not yet implemented\n", FALSE);