[ros-diffs] [ion] 24386: - Add KF_XMMI64 feature flag for SSE2 and detect it. - Detect Hyper-Threading and set Local APIC ID (put back Thomas's code that he added in an old revision and that I had accidentally removed and forgotten to re-convert into the new KiGetFeatureBits function). - Add code to set the kernel MX Csr Mask in the FX Save Area. - Startup the sysenter handler on the DPC stack. - Detect and notify users with broken Pentiums. - Do some NPX checks to forcefully disable any FPU flags that might be set (SSE, MMX, 3DNOW) if the NPX is disabled.

ion at svn.reactos.org ion at svn.reactos.org
Wed Oct 4 07:29:31 CEST 2006


Author: ion
Date: Wed Oct  4 09:29:30 2006
New Revision: 24386

URL: http://svn.reactos.org/svn/reactos?rev=24386&view=rev
Log:
- Add KF_XMMI64 feature flag for SSE2 and detect it.
- Detect Hyper-Threading and set Local APIC ID (put back Thomas's code that he added in an old revision and that I had accidentally removed and forgotten to re-convert into the new KiGetFeatureBits function).
- Add code to set the kernel MX Csr Mask in the FX Save Area.
- Startup the sysenter handler on the DPC stack.
- Detect and notify users with broken Pentiums.
- Do some NPX checks to forcefully disable any FPU flags that might be set (SSE, MMX, 3DNOW) if the NPX is disabled.

Modified:
    trunk/reactos/include/ndk/ketypes.h
    trunk/reactos/ntoskrnl/include/internal/ke.h
    trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h
    trunk/reactos/ntoskrnl/ke/clock.c
    trunk/reactos/ntoskrnl/ke/i386/cpu.c
    trunk/reactos/ntoskrnl/ke/i386/kiinit.c
    trunk/reactos/ntoskrnl/ke/i386/trap.s

Modified: trunk/reactos/include/ndk/ketypes.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/ketypes.h?rev=24386&r1=24385&r2=24386&view=diff
==============================================================================
--- trunk/reactos/include/ndk/ketypes.h (original)
+++ trunk/reactos/include/ndk/ketypes.h Wed Oct  4 09:29:30 2006
@@ -86,6 +86,7 @@
 #define KF_XMMI                         0x00002000
 #define KF_3DNOW                        0x00004000
 #define KF_AMDK6MTRR                    0x00008000
+#define KF_XMMI64                       0x00010000
 
 //
 // KPCR Access for non-IA64 builds

Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/ke.h?rev=24386&r1=24385&r2=24386&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ke.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h Wed Oct  4 09:29:30 2006
@@ -82,6 +82,7 @@
 extern ULONG KeI386NpxPresent;
 extern ULONG KeI386XMMIPresent;
 extern ULONG KeI386FxsrPresent;
+extern ULONG KiMXCsrMask;
 extern ULONG KeI386CpuType;
 extern ULONG KeI386CpuStep;
 extern ULONG KeProcessorArchitecture;
@@ -89,6 +90,7 @@
 extern ULONG KeProcessorRevision;
 extern ULONG KeFeatureBits;
 extern ULONG Ke386GlobalPagesEnabled;
+extern BOOLEAN KiI386PentiumLockErrataPresent;
 extern KNODE KiNode0;
 extern PKNODE KeNodeBlock[1];
 extern UCHAR KeNumberNodes;
@@ -119,6 +121,7 @@
 extern BOOLEAN KeThreadDpcEnable;
 extern LARGE_INTEGER KiTimeIncrementReciprocal;
 extern UCHAR KiTimeIncrementShiftCount;
+extern ULONG KiTimeLimitIsrMicroseconds;
 extern LIST_ENTRY BugcheckCallbackListHead, BugcheckReasonCallbackListHead;
 extern KSPIN_LOCK BugCheckCallbackLock;
 extern KDPC KiExpireTimerDpc;
@@ -861,6 +864,10 @@
 KiInitMachineDependent(VOID);
 
 VOID
+NTAPI
+KiI386PentiumLockErrataFixup(VOID);
+
+VOID
 WRMSR(
     IN ULONG Register,
     IN LONGLONG Value

Modified: trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h?rev=24386&r1=24385&r2=24386&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h Wed Oct  4 09:29:30 2006
@@ -318,6 +318,7 @@
 C_ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, NpxThread) == KPCR_NPX_THREAD);
 C_ASSERT(FIELD_OFFSET(KTSS, Esp0) == KTSS_ESP0);
 C_ASSERT(FIELD_OFFSET(KTSS, IoMapBase) == KTSS_IOMAPBASE);
+C_ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, DpcStack) == KPCR_PRCB_DPC_STACK);
 C_ASSERT(sizeof(FX_SAVE_AREA) == SIZEOF_FX_SAVE_AREA);
 
 #endif /* INCLUDE_INTERNAL_NTOSKRNL_H */

Modified: trunk/reactos/ntoskrnl/ke/clock.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/clock.c?rev=24386&r1=24385&r2=24386&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/clock.c (original)
+++ trunk/reactos/ntoskrnl/ke/clock.c Wed Oct  4 09:29:30 2006
@@ -37,7 +37,7 @@
 
 KDPC KiExpireTimerDpc;
 BOOLEAN KiClockSetupComplete = FALSE;
-
+ULONG KiTimeLimitIsrMicroseconds;
 
 /*
  * Number of timer interrupts since initialisation

Modified: trunk/reactos/ntoskrnl/ke/i386/cpu.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/cpu.c?rev=24386&r1=24385&r2=24386&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/cpu.c (original)
+++ trunk/reactos/ntoskrnl/ke/i386/cpu.c Wed Oct  4 09:29:30 2006
@@ -58,19 +58,21 @@
 ULONG KeFeatureBits;
 ULONG KiFastSystemCallDisable = 1;
 ULONG KeI386NpxPresent = 0;
+ULONG KiMXCsrMask = 0;
 ULONG MxcsrFeatureMask = 0;
 ULONG KeI386XMMIPresent = 0;
 ULONG KeI386FxsrPresent = 0;
 ULONG KeI386MachineType;
 ULONG Ke386Pae = FALSE;
 ULONG Ke386NoExecute = FALSE;
-BOOLEAN KiI386PentiumLockErrataPresent;
 ULONG KeLargestCacheLine = 0x40;
 ULONG KeDcacheFlushCount = 0;
 ULONG KeIcacheFlushCount = 0;
 ULONG KiDmaIoCoherency = 0;
 CHAR KeNumberProcessors;
 KAFFINITY KeActiveProcessors = 1;
+BOOLEAN KiI386PentiumLockErrataPresent;
+BOOLEAN KiSMTProcessorsPresent;
 
 /* CPU Signatures */
 CHAR CmpIntelID[]       = "GenuineIntel";
@@ -255,6 +257,9 @@
     /* Get the CPUID Info. Features are in Reg[3]. */
     CPUID(Reg, 1);
 
+    /* Set the initial APIC ID */
+    Prcb->InitialApicId = (UCHAR)(Reg[1] >> 24);
+
     /* Check for AMD CPU */
     if (Vendor == CPU_AMD)
     {
@@ -351,6 +356,24 @@
     if (CpuFeatures & 0x00800000) FeatureBits |= KF_MMX;
     if (CpuFeatures & 0x01000000) FeatureBits |= KF_FXSR;
     if (CpuFeatures & 0x02000000) FeatureBits |= KF_XMMI;
+    if (CpuFeatures & 0x04000000) FeatureBits |= KF_XMMI64;
+
+    /* Check if the CPU has hyper-threading */
+    if (CpuFeatures & 0x10000000)
+    {
+        /* Set the number of logical CPUs */
+        Prcb->LogicalProcessorsPerPhysicalProcessor = (UCHAR)(Reg[1] >> 16);
+        if (Prcb->LogicalProcessorsPerPhysicalProcessor > 1)
+        {
+            /* We're on dual-core */
+            KiSMTProcessorsPresent = TRUE;
+        }
+    }
+    else
+    {
+        /* We only have a single CPU */
+        Prcb->LogicalProcessorsPerPhysicalProcessor = 1;
+    }
 
     /* Check if CPUID 0x80000000 is supported */
     if (ExtendedCPUID)
@@ -765,7 +788,7 @@
 {
     /* Set CS and ESP */
     Ke386Wrmsr(0x174, KGDT_R0_CODE, 0);
-    Ke386Wrmsr(0x175, 0, 0);
+    Ke386Wrmsr(0x175, KeGetCurrentPrcb()->DpcStack, 0);
 
     /* Set LSTAR */
     Ke386Wrmsr(0x176, KiFastCallEntry, 0);
@@ -811,6 +834,14 @@
     /* FIXME: Support this */
     DPRINT1("Your machine supports XMMI exceptions but ReactOS doesn't\n");
     return 0;
+}
+
+VOID
+NTAPI
+KiI386PentiumLockErrataFixup(VOID)
+{
+    /* FIXME: Support this */
+    DPRINT1("WARNING: Your machine has a CPU bug that ReactOS can't bypass!\n");
 }
 
 /* PUBLIC FUNCTIONS **********************************************************/

Modified: trunk/reactos/ntoskrnl/ke/i386/kiinit.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/kiinit.c?rev=24386&r1=24385&r2=24386&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/kiinit.c (original)
+++ trunk/reactos/ntoskrnl/ke/i386/kiinit.c Wed Oct  4 09:29:30 2006
@@ -30,6 +30,8 @@
     NTSTATUS Status;
     //ULONG ReturnLength;
     ULONG i, Affinity;
+    PFX_SAVE_AREA FxSaveArea;
+    ULONG MXCsrMask = 0xFFBF, NewMask;
 
     /* Check for large page support */
     if (KeFeatureBits & KF_LARGE_PAGE)
@@ -69,6 +71,30 @@
     /* 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;
+
+    /* 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)
     {
@@ -143,12 +169,67 @@
             /* Check if we have AMD MTRR and initialize it for the CPU */
             if (KeFeatureBits & KF_AMDK6MTRR) KiAmdK6InitializeMTRR();
 
-            /* FIXME: Apply P5 LOCK Errata fixups */
+            /* Check if this is a buggy Pentium and apply the fixup if so */
+            if (KiI386PentiumLockErrataPresent) KiI386PentiumLockErrataFixup();
+
+            /* Get the current thread NPX state */
+            FxSaveArea = (PVOID)
+                         ((ULONG_PTR)KeGetCurrentThread()->InitialStack -
+                         NPX_FRAME_LENGTH);
+
+            /* Clear initial MXCsr mask */
+            FxSaveArea->U.FxArea.MXCsrMask = 0;
+
+            /* Save the current NPX State */
+#ifdef __GNUC__
+            asm volatile("fxsave %0\n\t" : "=m" (*FxSaveArea));
+#else
+            __asm fxsave [FxSaveArea]
+#endif
+            /* Check if the current mask doesn't match the reserved bits */
+            if (FxSaveArea->U.FxArea.MXCsrMask != MXCsrMask)
+            {
+                /* Then use whatever it's holding */
+                MXCsrMask = FxSaveArea->U.FxArea.MXCsrMask;
+            }
+
+            /* Check if nobody set the kernel-wide mask */
+            if (!KiMXCsrMask)
+            {
+                /* Then use the one we calculated above */
+                NewMask = MXCsrMask;
+            }
+            else
+            {
+                /* Use the existing mask */
+                NewMask = KiMXCsrMask;
+
+                /* Was it set to the same value we found now? */
+                if (NewMask != MXCsrMask)
+                {
+                    /* No, something is definitely wrong */
+                    KEBUGCHECKEX(MULTIPROCESSOR_CONFIGURATION_NOT_SUPPORTED,
+                                 KF_FXSR,
+                                 NewMask,
+                                 MXCsrMask,
+                                 0);
+                }
+            }
+
+            /* Now set the kernel mask */
+            KiMXCsrMask = NewMask & MXCsrMask;
         }
     }
 
     /* Return affinity back to where it was */
     KeRevertToUserAffinityThread();
+
+    /* NT allows limiting the duration of an ISR with a registry key */
+    if (KiTimeLimitIsrMicroseconds)
+    {
+        /* FIXME: TODO */
+        DPRINT1("ISR Time Limit not yet supported\n");
+    }
 }
 
 VOID
@@ -519,11 +600,17 @@
 
     /* Align stack and make space for the trap frame and NPX frame */
     InitialStack &= ~KTRAP_FRAME_ALIGN;
+#ifdef __GNUC__
     __asm__ __volatile__("movl %0,%%esp" : :"r" (InitialStack));
     __asm__ __volatile__("subl %0,%%esp" : :"r" (NPX_FRAME_LENGTH +
                                                  KTRAP_FRAME_LENGTH +
                                                  KTRAP_FRAME_ALIGN));
     __asm__ __volatile__("push %0" : :"r" (CR0_EM + CR0_TS + CR0_MP));
+#else
+    __asm mov esp, InitialStack;
+    __asm sub esp, NPX_FRAME_LENGTH + KTRAP_FRAME_ALIGN + KTRAP_FRAME_LENGTH;
+    __asm push CR0_EM + CR0_TS + CR0_MP
+#endif
 
     /* Call main kernel initialization */
     KiInitializeKernel(&KiInitialProcess.Pcb,

Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/trap.s?rev=24386&r1=24385&r2=24386&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/trap.s (original)
+++ trunk/reactos/ntoskrnl/ke/i386/trap.s Wed Oct  4 09:29:30 2006
@@ -111,9 +111,13 @@
     /* Set FS to PCR */
     mov ecx, KGDT_R0_PCR
     mov fs, cx
+    //push KGDT_R0_PCR
+    //pop fs
+
+    /* Set user selector */
+    mov ecx, KGDT_R3_DATA | RPL_MASK
 
     /* Set DS/ES to User Selector */
-    mov ecx, KGDT_R3_DATA | RPL_MASK
     mov ds, cx
     mov es, cx
 




More information about the Ros-diffs mailing list