- 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)

svn path=/trunk/; revision=36630
This commit is contained in:
Colin Finck 2008-10-02 21:57:36 +00:00
parent 44d59eb606
commit bfbc5ffd7d
2 changed files with 91 additions and 99 deletions

View file

@ -40,8 +40,14 @@ Author:
//
// 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

View file

@ -216,23 +216,23 @@ KiGetCpuVendor(VOID)
}
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 @@ KiGetFeatureBits(VOID)
/* Set the initial APIC ID */
Prcb->InitialApicId = (UCHAR)(Reg[1] >> 24);
/* Check for AMD CPU */
if (Vendor == CPU_AMD)
switch (Vendor)
{
/* Check if this is a K5 or higher. */
if ((Reg[0] & 0x0F00) >= 0x0500)
{
/* Check if this is a K5 specifically. */
/* 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:
case 0x00D0:
/* As does the K6-3 */
FeatureBits |= KF_AMDK6MTRR;
break;
default:
break;
}
}
}
else
{
/* Families below 5 don't support PGE, PSE or CMOV at all */
Reg[3] &= ~(0x08 | 0x2000 | 0x8000);
else if((Reg[0] & 0x0F00) < 0x0500)
{
/* 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;
}
/* They also don't support advanced CPUID functions. */
ExtendedCPUID = FALSE;
}
/* Set the current features */
CpuFeatures = Reg[3];
}
/* 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;
}
break;
/* 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;
}
/* Cyrix CPUs */
case CPU_CYRIX:
break;
/* 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;
}
/* 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;
}
/* Set the current features */
CpuFeatures = Reg[3];
}
break;
#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);
/* 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;
}
}
#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)
{
WRMSR(0x0107, RDMSR(0x0107) | 0x02);
FeatureBits |= KF_CMPXCHG8B;
}
else if ((Reg[0] & 0x0F00) >= 0x0600)
{
WRMSR(0x1107, (RDMSR(0x1107) | 0x02) & ~((LONGLONG)0x01));
FeatureBits |= KF_CMPXCHG8B;
}
}
break;
}
#endif
#ifdef CPU_RISE
if (Vendor == CPU_RISE)
{
/* Windows Vista assumes CMPXCHG8B is always supported on Rise */
FeatureBits |= KF_CMPXCHG8B;
}
#endif
/* Convert all CPUID Feature bits into our format */
if (CpuFeatures & 0x00000002) FeatureBits |= KF_V86_VIS | KF_CR4;
@ -446,6 +431,7 @@ KiGetFeatureBits(VOID)
switch (Vendor)
{
case CPU_AMD:
case CPU_CENTAUR:
if (Reg[3] & 0x80000000) FeatureBits |= KF_3DNOW;
break;
}