Author: cfinck
Date: Thu Oct 2 16:57:36 2008
New Revision: 36630
URL:
http://svn.reactos.org/svn/reactos?rev=36630&view=rev
Log:
- Add the other CPU_* codes (got them from a PDB)
- Restructure the CPU vendor check in KiGetFeatureBits with a switch statement
- Enable experimental support for Cyrix, Transmeta, Centaur and Rise CPUs (experimental =
mostly untested)
- Just add CMPXCHG8B support to the feature bits for Centaur CPUs like it's already
done for Rise CPUs without touching any MSRs.
The instruction already works properly by default according to two official Centaur
datasheets. Also Geoz on IRC already reported that his C3 Nehemiah works with ReactOS
after this patch.
- Enable the 3DNow detection code through extended CPUID also for Centaur CPUs (all CPUs
from IDT WinChip C6 to VIA C3 Ezra-T supported it)
- Report the presence of AMD K6 MTRRs also for mobile AMD K6-2+/K6-III+ CPUs (model D)
Modified:
trunk/reactos/include/ndk/asm.h
trunk/reactos/ntoskrnl/ke/i386/cpu.c
Modified: trunk/reactos/include/ndk/asm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/asm.h?rev=3663…
==============================================================================
--- trunk/reactos/include/ndk/asm.h [iso-8859-1] (original)
+++ trunk/reactos/include/ndk/asm.h [iso-8859-1] Thu Oct 2 16:57:36 2008
@@ -40,8 +40,14 @@
//
// CPU Types
//
+#define CPU_NONE 0x0
#define CPU_INTEL 0x1
#define CPU_AMD 0x2
+#define CPU_CYRIX 0x3
+#define CPU_TRANSMETA 0x4
+#define CPU_CENTAUR 0x5
+#define CPU_RISE 0x6
+#define CPU_UNKNOWN 0x7
//
// Selector Names
Modified: trunk/reactos/ntoskrnl/ke/i386/cpu.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/cpu.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/cpu.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/cpu.c [iso-8859-1] Thu Oct 2 16:57:36 2008
@@ -216,23 +216,23 @@
}
else if (!strcmp(Prcb->VendorString, CmpCyrixID))
{
- DPRINT1("Cyrix CPUs not fully supported\n");
- return 0;
+ DPRINT1("Cyrix CPU support not fully tested!\n");
+ return CPU_CYRIX;
}
else if (!strcmp(Prcb->VendorString, CmpTransmetaID))
{
- DPRINT1("Transmeta CPUs not fully supported\n");
- return 0;
+ DPRINT1("Transmeta CPU support not fully tested!\n");
+ return CPU_TRANSMETA;
}
else if (!strcmp(Prcb->VendorString, CmpCentaurID))
{
- DPRINT1("VIA CPUs not fully supported\n");
- return 0;
+ DPRINT1("Centaur CPU support not fully tested!\n");
+ return CPU_CENTAUR;
}
else if (!strcmp(Prcb->VendorString, CmpRiseID))
{
- DPRINT1("Rise CPUs not fully supported\n");
- return 0;
+ DPRINT1("Rise CPU support not fully tested!\n");
+ return CPU_RISE;
}
/* Invalid CPU */
@@ -262,136 +262,121 @@
/* Set the initial APIC ID */
Prcb->InitialApicId = (UCHAR)(Reg[1] >> 24);
- /* Check for AMD CPU */
- if (Vendor == CPU_AMD)
- {
- /* Check if this is a K5 or higher. */
- if ((Reg[0] & 0x0F00) >= 0x0500)
- {
- /* Check if this is a K5 specifically. */
+ switch (Vendor)
+ {
+ /* Intel CPUs */
+ case CPU_INTEL:
+ /* Check if it's a P6 */
+ if (Prcb->CpuType == 6)
+ {
+ /* Perform the special sequence to get the MicroCode Signature */
+ WRMSR(0x8B, 0);
+ CPUID(Reg, 1);
+ Prcb->UpdateSignature.QuadPart = RDMSR(0x8B);
+ }
+ else if (Prcb->CpuType == 5)
+ {
+ /* On P5, enable workaround for the LOCK errata. */
+ KiI386PentiumLockErrataPresent = TRUE;
+ }
+
+ /* Check for broken P6 with bad SMP PTE implementation */
+ if (((Reg[0] & 0x0FF0) == 0x0610 && (Reg[0] & 0x000F) <=
0x9) ||
+ ((Reg[0] & 0x0FF0) == 0x0630 && (Reg[0] & 0x000F) <=
0x4))
+ {
+ /* Remove support for correct PTE support. */
+ FeatureBits &= ~KF_WORKING_PTE;
+ }
+
+ /* Check if the CPU is too old to support SYSENTER */
+ if ((Prcb->CpuType < 6) ||
+ ((Prcb->CpuType == 6) && (Prcb->CpuStep < 0x0303)))
+ {
+ /* Disable it */
+ Reg[3] &= ~0x800;
+ }
+
+ /* Set the current features */
+ CpuFeatures = Reg[3];
+
+ break;
+
+ /* AMD CPUs */
+ case CPU_AMD:
+
+ /* Check if this is a K5 or K6. (family 5) */
if ((Reg[0] & 0x0F00) == 0x0500)
{
/* Get the Model Number */
switch (Reg[0] & 0x00F0)
{
- /* Check if this is the Model 1 */
+ /* Model 1: K5 - 5k86 (initial models) */
case 0x0010:
/* Check if this is Step 0 or 1. They don't support PGE */
if ((Reg[0] & 0x000F) > 0x03) break;
+ /* Model 0: K5 - SSA5 */
case 0x0000:
/* Model 0 doesn't support PGE at all. */
Reg[3] &= ~0x2000;
break;
+ /* Model 8: K6-2 */
case 0x0080:
/* K6-2, Step 8 and over have support for MTRR. */
if ((Reg[0] & 0x000F) >= 0x8) FeatureBits |=
KF_AMDK6MTRR;
break;
+ /* Model 9: K6-III
+ Model D: K6-2+, K6-III+ */
case 0x0090:
-
- /* As does the K6-3 */
+ case 0x00D0:
+
FeatureBits |= KF_AMDK6MTRR;
- break;
-
- default:
break;
}
}
- }
- else
- {
- /* Families below 5 don't support PGE, PSE or CMOV at all */
- Reg[3] &= ~(0x08 | 0x2000 | 0x8000);
-
- /* They also don't support advanced CPUID functions. */
- ExtendedCPUID = FALSE;
- }
-
- /* Set the current features */
- CpuFeatures = Reg[3];
- }
-
- /* Now check if this is Intel */
- if (Vendor == CPU_INTEL)
- {
- /* Check if it's a P6 */
- if (Prcb->CpuType == 6)
- {
- /* Perform the special sequence to get the MicroCode Signature */
- WRMSR(0x8B, 0);
- CPUID(Reg, 1);
- Prcb->UpdateSignature.QuadPart = RDMSR(0x8B);
- }
- else if (Prcb->CpuType == 5)
- {
- /* On P5, enable workaround for the LOCK errata. */
- KiI386PentiumLockErrataPresent = TRUE;
- }
-
- /* Check for broken P6 with bad SMP PTE implementation */
- if (((Reg[0] & 0x0FF0) == 0x0610 && (Reg[0] & 0x000F) <= 0x9)
||
- ((Reg[0] & 0x0FF0) == 0x0630 && (Reg[0] & 0x000F) <=
0x4))
- {
- /* Remove support for correct PTE support. */
- FeatureBits &= ~KF_WORKING_PTE;
- }
-
- /* Check if the CPU is too old to support SYSENTER */
- if ((Prcb->CpuType < 6) ||
- ((Prcb->CpuType == 6) && (Prcb->CpuStep < 0x0303)))
- {
- /* Disable it */
- Reg[3] &= ~0x800;
- }
-
- /* Set the current features */
- CpuFeatures = Reg[3];
- }
-
-#ifdef CPU_TRANSMETA
- if (Vendor == CPU_TRANSMETA)
- {
- /* Enable CMPXCHG8B if the family (>= 5), model and stepping (>= 4.2)
support it */
- if ((Reg[0] & 0x0F00) >= 0x0500 && (Reg[0] & 0x00FF) >=
0x0042)
- {
- WRMSR(0x80860004, RDMSR(0x80860004) | 0x0100);
- FeatureBits |= KF_CMPXCHG8B;
- }
- }
-#endif
-
-#ifdef CPU_CENTAUR
- if (Vendor == CPU_CENTAUR)
- {
- /* If CMPXCHG8B is not detected, try to enable it */
- if (!(CpuFeatures & 0x00000100))
- {
- if ((Reg[0] & 0x0F00) == 0x0500)
+ else if((Reg[0] & 0x0F00) < 0x0500)
{
- WRMSR(0x0107, RDMSR(0x0107) | 0x02);
+ /* Families below 5 don't support PGE, PSE or CMOV at all */
+ Reg[3] &= ~(0x08 | 0x2000 | 0x8000);
+
+ /* They also don't support advanced CPUID functions. */
+ ExtendedCPUID = FALSE;
+ }
+
+ /* Set the current features */
+ CpuFeatures = Reg[3];
+
+ break;
+
+ /* Cyrix CPUs */
+ case CPU_CYRIX:
+ break;
+
+ /* Transmeta CPUs */
+ case CPU_TRANSMETA:
+ /* Enable CMPXCHG8B if the family (>= 5), model and stepping (>= 4.2)
support it */
+ if ((Reg[0] & 0x0FFF) >= 0x0542)
+ {
+ WRMSR(0x80860004, RDMSR(0x80860004) | 0x0100);
FeatureBits |= KF_CMPXCHG8B;
}
- else if ((Reg[0] & 0x0F00) >= 0x0600)
- {
- WRMSR(0x1107, (RDMSR(0x1107) | 0x02) & ~((LONGLONG)0x01));
- FeatureBits |= KF_CMPXCHG8B;
- }
- }
- }
-#endif
-
-#ifdef CPU_RISE
- if (Vendor == CPU_RISE)
- {
- /* Windows Vista assumes CMPXCHG8B is always supported on Rise */
- FeatureBits |= KF_CMPXCHG8B;
- }
-#endif
+
+ break;
+
+ /* Centaur, IDT, Rise and VIA CPUs */
+ case CPU_CENTAUR:
+ case CPU_RISE:
+ /* These CPUs don't report the presence of CMPXCHG8B through CPUID.
+ However, this feature exists and operates properly without any additional
steps. */
+ FeatureBits |= KF_CMPXCHG8B;
+
+ break;
+ }
/* Convert all CPUID Feature bits into our format */
if (CpuFeatures & 0x00000002) FeatureBits |= KF_V86_VIS | KF_CR4;
@@ -446,6 +431,7 @@
switch (Vendor)
{
case CPU_AMD:
+ case CPU_CENTAUR:
if (Reg[3] & 0x80000000) FeatureBits |= KF_3DNOW;
break;
}