[CMAKE]
[reactos.git] / ntoskrnl / ke / i386 / cpu.c
index e05a896..0fd2dcc 100644 (file)
@@ -41,7 +41,7 @@ ULONG KeDcacheFlushCount = 0;
 ULONG KeIcacheFlushCount = 0;
 ULONG KiDmaIoCoherency = 0;
 ULONG KePrefetchNTAGranularity = 32;
-CHAR KeNumberProcessors;
+CHAR KeNumberProcessors = 0;
 KAFFINITY KeActiveProcessors = 1;
 BOOLEAN KiI386PentiumLockErrataPresent;
 BOOLEAN KiSMTProcessorsPresent;
@@ -105,10 +105,28 @@ RDMSR(IN ULONG Register)
     return __readmsr(Register);
 }
 
+/* NSC/Cyrix CPU configuration register index */
+#define CX86_CCR1 0xc1
+
+/* NSC/Cyrix CPU indexed register access macros */
+static __inline
+ULONG
+getCx86(UCHAR reg)
+{
+    WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)0x22, reg);
+    return READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)0x23);
+}
+
+#define setCx86(reg, data) do { \
+   WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)0x22,(reg)); \
+   WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)0x23,(data)); \
+} while (0)
+
 /* FUNCTIONS *****************************************************************/
 
 VOID
 NTAPI
+INIT_FUNCTION
 KiSetProcessorType(VOID)
 {
     ULONG EFlags, NewEFlags;
@@ -175,6 +193,7 @@ KiSetProcessorType(VOID)
 
 ULONG
 NTAPI
+INIT_FUNCTION
 KiGetCpuVendor(VOID)
 {
     PKPRCB Prcb = KeGetCurrentPrcb();
@@ -236,12 +255,13 @@ KiGetCpuVendor(VOID)
 
 ULONG
 NTAPI
+INIT_FUNCTION
 KiGetFeatureBits(VOID)
 {
     PKPRCB Prcb = KeGetCurrentPrcb();
     ULONG Vendor;
     ULONG FeatureBits = KF_WORKING_PTE;
-    ULONG Reg[4], Dummy;
+    ULONG Reg[4], Dummy, Ccr1;
     BOOLEAN ExtendedCPUID = TRUE;
     ULONG CpuFeatures = 0;
 
@@ -352,7 +372,22 @@ KiGetFeatureBits(VOID)
         /* Cyrix CPUs */
         case CPU_CYRIX:
 
-            /* FIXME: CMPXCGH8B */
+            /* Workaround the "COMA" bug on 6x family of Cyrix CPUs */
+            if (Prcb->CpuType == 6 &&
+                Prcb->CpuStep <= 1)
+            {
+                /* Get CCR1 value */
+                Ccr1 = getCx86(CX86_CCR1);
+
+                /* Enable the NO_LOCK bit */
+                Ccr1 |= 0x10;
+
+                /* Set the new CCR1 value */
+                setCx86(CX86_CCR1, Ccr1);
+            }
+
+            /* Set the current features */
+            CpuFeatures = Reg[3];
 
             break;
 
@@ -440,12 +475,38 @@ KiGetFeatureBits(VOID)
         }
     }
 
+#define print_supported(kf_value) ((FeatureBits & kf_value) ? #kf_value : "")
+    DPRINT1("Supported CPU features : %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n",
+    print_supported(KF_V86_VIS),
+    print_supported(KF_RDTSC),
+    print_supported(KF_CR4),
+    print_supported(KF_CMOV),
+    print_supported(KF_GLOBAL_PAGE),
+    print_supported(KF_LARGE_PAGE),
+    print_supported(KF_MTRR),
+    print_supported(KF_CMPXCHG8B),
+    print_supported(KF_MMX),
+    print_supported(KF_WORKING_PTE),
+    print_supported(KF_PAT),
+    print_supported(KF_FXSR),
+    print_supported(KF_FAST_SYSCALL),
+    print_supported(KF_XMMI),
+    print_supported(KF_3DNOW),
+    print_supported(KF_AMDK6MTRR),
+    print_supported(KF_XMMI64),
+    print_supported(KF_DTS),
+    print_supported(KF_NX_BIT),
+    print_supported(KF_NX_DISABLED),
+    print_supported(KF_NX_ENABLED));
+#undef print_supported
+
     /* Return the Feature Bits */
     return FeatureBits;
 }
 
 VOID
 NTAPI
+INIT_FUNCTION
 KiGetCacheInformation(VOID)
 {
     PKIPCR Pcr = (PKIPCR)KeGetPcr();
@@ -677,7 +738,7 @@ KiGetCacheInformation(VOID)
                 /* Check if we support CPUID 0x80000006 */
                 CPUID(0x80000000, &Data[0], &Data[1], &Data[2], &Data[3]);
                 if (Data[0] >= 0x80000006)
-                {   
+                {
                     /* Get 2nd level cache and tlb size */
                     CPUID(0x80000006, &Data[0], &Data[1], &Data[2], &Data[3]);
                     
@@ -748,6 +809,7 @@ KiGetCacheInformation(VOID)
 
 VOID
 NTAPI
+INIT_FUNCTION
 KiSetCR0Bits(VOID)
 {
     ULONG Cr0;
@@ -764,6 +826,7 @@ KiSetCR0Bits(VOID)
 
 VOID
 NTAPI
+INIT_FUNCTION
 KiInitializeTSS2(IN PKTSS Tss,
                  IN PKGDTENTRY TssEntry OPTIONAL)
 {
@@ -817,6 +880,7 @@ KiInitializeTSS(IN PKTSS Tss)
 
 VOID
 FASTCALL
+INIT_FUNCTION
 Ki386InitializeTss(IN PKTSS Tss,
                    IN PKIDTENTRY Idt,
                    IN PKGDTENTRY Gdt)
@@ -976,6 +1040,7 @@ KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)
 
 VOID
 NTAPI
+INIT_FUNCTION
 KiInitializeMachineType(VOID)
 {
     /* Set the Machine Type we got from NTLDR */
@@ -984,6 +1049,7 @@ KiInitializeMachineType(VOID)
 
 ULONG_PTR
 NTAPI
+INIT_FUNCTION
 KiLoadFastSyscallMachineSpecificRegisters(IN ULONG_PTR Context)
 {
     /* Set CS and ESP */
@@ -997,6 +1063,7 @@ KiLoadFastSyscallMachineSpecificRegisters(IN ULONG_PTR Context)
 
 VOID
 NTAPI
+INIT_FUNCTION
 KiRestoreFastSyscallReturnState(VOID)
 {
     /* Check if the CPU Supports fast system call */
@@ -1030,6 +1097,7 @@ KiRestoreFastSyscallReturnState(VOID)
 
 ULONG_PTR
 NTAPI
+INIT_FUNCTION
 Ki386EnableDE(IN ULONG_PTR Context)
 {
     /* Enable DE */
@@ -1039,6 +1107,7 @@ Ki386EnableDE(IN ULONG_PTR Context)
 
 ULONG_PTR
 NTAPI
+INIT_FUNCTION
 Ki386EnableFxsr(IN ULONG_PTR Context)
 {
     /* Enable FXSR */
@@ -1048,6 +1117,7 @@ Ki386EnableFxsr(IN ULONG_PTR Context)
 
 ULONG_PTR
 NTAPI
+INIT_FUNCTION
 Ki386EnableXMMIExceptions(IN ULONG_PTR Context)
 {
     PKIDTENTRY IdtEntry;
@@ -1070,6 +1140,7 @@ Ki386EnableXMMIExceptions(IN ULONG_PTR Context)
 
 VOID
 NTAPI
+INIT_FUNCTION
 KiI386PentiumLockErrataFixup(VOID)
 {
     KDESCRIPTOR IdtDescriptor;
@@ -1161,6 +1232,7 @@ KiSaveProcessorState(IN PKTRAP_FRAME TrapFrame,
 
 BOOLEAN
 NTAPI
+INIT_FUNCTION
 KiIsNpxPresent(VOID)
 {
     ULONG Cr0;
@@ -1173,7 +1245,12 @@ KiIsNpxPresent(VOID)
     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)
@@ -1196,6 +1273,7 @@ KiIsNpxPresent(VOID)
 
 BOOLEAN
 NTAPI
+INIT_FUNCTION
 KiIsNpxErrataPresent(VOID)
 {
     BOOLEAN ErrataPresent;
@@ -1210,7 +1288,7 @@ KiIsNpxErrataPresent(VOID)
     __writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
     
     /* Initialize FPU state */
-    asm volatile ("fninit");
+    Ke386FnInit();
     
     /* Multiply the magic values and divide, we should get the result back */
     Value1 = 4195835.0;
@@ -1227,8 +1305,8 @@ KiIsNpxErrataPresent(VOID)
     return ErrataPresent;
 }
 
-NTAPI
 VOID
+NTAPI
 KiFlushNPXState(IN PFLOATING_SAVE_AREA SaveArea)
 {
     ULONG EFlags, Cr0;
@@ -1273,7 +1351,7 @@ KiFlushNPXState(IN PFLOATING_SAVE_AREA SaveArea)
         
         /* Now load NPX state from the NPX area */
         FxSaveArea = KiGetThreadNpxArea(Thread);
-        Ke386FxStore(FxSaveArea);    
+        Ke386FxStore(FxSaveArea);
     }
     else
     {