[NTOSKRNL]

- Implement KiCpuId and make use of it
- Get rid of ugly CPUID, RDMSR and WRMSR functions
- remove unused KTS_ constants

svn path=/trunk/; revision=67524
This commit is contained in:
Timo Kreuzer 2015-05-02 23:11:50 +00:00
parent 0100d8de0c
commit 5b7d2dec59
8 changed files with 185 additions and 253 deletions

View file

@ -191,6 +191,21 @@ typedef KIO_ACCESS_MAP *PKIO_ACCESS_MAP;
//
#define NUMBER_POOL_LOOKASIDE_LISTS 32
//
// Structure for CPUID
//
typedef union _CPU_INFO
{
UINT32 AsUINT32[4];
struct
{
ULONG Eax;
ULONG Ebx;
ULONG Ecx;
ULONG Edx;
};
} CPU_INFO, *PCPU_INFO;
//
// Trap Frame Definition
//

View file

@ -230,11 +230,13 @@ VOID
NTAPI
CmpGetIntelBrandString(OUT PCHAR CpuString)
{
ULONG BrandId, Ebx, Signature, Dummy;
CPU_INFO CpuInfo;
ULONG BrandId, Signature;
/* Get the Brand Id */
CPUID(0x00000001, &Signature, &Ebx, &Dummy, &Dummy);
BrandId = Ebx & 0xFF;
KiCpuId(&CpuInfo, 0x00000001);
Signature = CpuInfo.Eax;
BrandId = CpuInfo.Ebx & 0xFF;
switch (BrandId)
{
@ -329,7 +331,8 @@ CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBloc
HANDLE KeyHandle, BiosHandle, SystemHandle, FpuHandle, SectionHandle;
CONFIGURATION_COMPONENT_DATA ConfigData;
CHAR Buffer[128];
ULONG VendorId, ExtendedId, Dummy;
CPU_INFO CpuInfo;
ULONG VendorId, ExtendedId;
PKPRCB Prcb;
USHORT IndexTable[MaximumType + 1] = {0};
ANSI_STRING TempString;
@ -521,7 +524,8 @@ CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBloc
else
{
/* Check if we have extended CPUID that supports name ID */
CPUID(0x80000000, &ExtendedId, &Dummy, &Dummy, &Dummy);
KiCpuId(&CpuInfo, 0x80000000);
ExtendedId = CpuInfo.Eax;
if (ExtendedId >= 0x80000004)
{
/* Do all the CPUIDs required to get the full name */
@ -529,11 +533,11 @@ CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBloc
for (ExtendedId = 2; ExtendedId <= 4; ExtendedId++)
{
/* Do the CPUID and save the name string */
CPUID(0x80000000 | ExtendedId,
(PULONG)PartialString,
(PULONG)PartialString + 1,
(PULONG)PartialString + 2,
(PULONG)PartialString + 3);
KiCpuId(&CpuInfo, 0x80000000 | ExtendedId);
((PULONG)PartialString)[0] = CpuInfo.Eax;
((PULONG)PartialString)[1] = CpuInfo.Ebx;
((PULONG)PartialString)[2] = CpuInfo.Ecx;
((PULONG)PartialString)[3] = CpuInfo.Edx;
/* Go to the next name string */
PartialString += 16;
@ -544,7 +548,8 @@ CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBloc
}
else
{
CPUID(0x00000000, &Dummy, &VendorId, &Dummy, &Dummy);
KiCpuId(&CpuInfo, 0x00000000);
VendorId = CpuInfo.Ebx;
PartialString = CpuString;
switch (VendorId)
{

View file

@ -153,37 +153,8 @@ extern VOID __cdecl KiInterruptTemplate(VOID);
/* One of the Reserved Wait Blocks, this one is for the Thread's Timer */
#define TIMER_WAIT_BLOCK 0x3L
#define KTS_SYSCALL_BIT (((KTRAP_STATE_BITS) { { .SystemCall = TRUE } }).Bits)
#define KTS_PM_BIT (((KTRAP_STATE_BITS) { { .PreviousMode = TRUE } }).Bits)
#define KTS_SEG_BIT (((KTRAP_STATE_BITS) { { .Segments = TRUE } }).Bits)
#define KTS_VOL_BIT (((KTRAP_STATE_BITS) { { .Volatiles = TRUE } }).Bits)
#define KTS_FULL_BIT (((KTRAP_STATE_BITS) { { .Full = TRUE } }).Bits)
/* INTERNAL KERNEL FUNCTIONS ************************************************/
VOID
NTAPI
CPUID(
IN ULONG InfoType,
OUT PULONG CpuInfoEax,
OUT PULONG CpuInfoEbx,
OUT PULONG CpuInfoEcx,
OUT PULONG CpuInfoEdx
);
LONGLONG
FASTCALL
RDMSR(
IN ULONG Register
);
VOID
NTAPI
WRMSR(
IN ULONG Register,
IN LONGLONG Value
);
/* Finds a new thread to run */
LONG_PTR
FASTCALL

View file

@ -1660,3 +1660,24 @@ KiReleaseNmiListLock(IN KIRQL OldIrql)
{
KeReleaseSpinLock(&KiNmiCallbackListLock, OldIrql);
}
#if defined(_M_IX86) || defined(_M_AMD64)
FORCEINLINE
VOID
KiCpuId(
PCPU_INFO CpuInfo,
ULONG Function)
{
__cpuid((INT*)CpuInfo->AsUINT32, Function);
}
FORCEINLINE
VOID
KiCpuIdEx(
PCPU_INFO CpuInfo,
ULONG Function,
ULONG SubFunction)
{
__cpuidex((INT*)CpuInfo->AsUINT32, Function, SubFunction);
}
#endif /* _M_IX86 || _M_AMD64 */

View file

@ -95,17 +95,17 @@ KdpSysReadMsr(IN ULONG Msr,
OUT PLARGE_INTEGER MsrValue)
{
/* Wrap this in SEH in case the MSR doesn't exist */
//_SEH2_TRY
_SEH2_TRY
{
/* Read from the MSR */
MsrValue->QuadPart = RDMSR(Msr);
MsrValue->QuadPart = __readmsr(Msr);
}
//_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Invalid MSR */
//_SEH2_YIELD(return STATUS_NO_SUCH_DEVICE);
_SEH2_YIELD(return STATUS_NO_SUCH_DEVICE);
}
//_SEH2_END;
_SEH2_END;
/* Success */
return STATUS_SUCCESS;
@ -117,17 +117,17 @@ KdpSysWriteMsr(IN ULONG Msr,
IN PLARGE_INTEGER MsrValue)
{
/* Wrap this in SEH in case the MSR doesn't exist */
//_SEH2_TRY
_SEH2_TRY
{
/* Write to the MSR */
WRMSR(Msr, MsrValue->QuadPart);
__writemsr(Msr, MsrValue->QuadPart);
}
//_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Invalid MSR */
//_SEH2_YIELD(return STATUS_NO_SUCH_DEVICE);
_SEH2_YIELD(return STATUS_NO_SUCH_DEVICE);
}
//_SEH2_END;
_SEH2_END;
/* Success */
return STATUS_SUCCESS;

View file

@ -48,28 +48,6 @@ static const CHAR CmpTransmetaID[] = "GenuineTMx86";
static const CHAR CmpCentaurID[] = "CentaurHauls";
static const CHAR CmpRiseID[] = "RiseRiseRise";
/* SUPPORT ROUTINES FOR MSVC COMPATIBILITY ***********************************/
VOID
NTAPI
CPUID(IN ULONG InfoType,
OUT PULONG CpuInfoEax,
OUT PULONG CpuInfoEbx,
OUT PULONG CpuInfoEcx,
OUT PULONG CpuInfoEdx)
{
ULONG CpuInfo[4];
/* Perform the CPUID Operation */
__cpuid((int*)CpuInfo, InfoType);
/* Return the results */
*CpuInfoEax = CpuInfo[0];
*CpuInfoEbx = CpuInfo[1];
*CpuInfoEcx = CpuInfo[2];
*CpuInfoEdx = CpuInfo[3];
}
/* FUNCTIONS *****************************************************************/
VOID
@ -77,7 +55,7 @@ NTAPI
KiSetProcessorType(VOID)
{
ULONG64 EFlags;
INT Reg[4];
CPU_INFO CpuInfo;
ULONG Stepping, Type;
/* Start by assuming no CPUID data */
@ -87,7 +65,7 @@ KiSetProcessorType(VOID)
EFlags = __readeflags();
/* Do CPUID 1 now */
__cpuid(Reg, 1);
KiCpuId(&CpuInfo, 1);
/*
* Get the Stepping and Type. The stepping contains both the
@ -96,11 +74,11 @@ KiSetProcessorType(VOID)
*
* For the stepping, we convert this: zzzzzzxy into this: x0y
*/
Stepping = Reg[0] & 0xF0;
Stepping = CpuInfo.Eax & 0xF0;
Stepping <<= 4;
Stepping += (Reg[0] & 0xFF);
Stepping += (CpuInfo.Eax & 0xFF);
Stepping &= 0xF0F;
Type = Reg[0] & 0xF00;
Type = CpuInfo.Eax & 0xF00;
Type >>= 8;
/* Save them in the PRCB */
@ -117,16 +95,16 @@ NTAPI
KiGetCpuVendor(VOID)
{
PKPRCB Prcb = KeGetCurrentPrcb();
INT Vendor[5];
CPU_INFO CpuInfo;
/* Get the Vendor ID and null-terminate it */
__cpuid(Vendor, 0);
KiCpuId(&CpuInfo, 0);
/* Copy it to the PRCB and null-terminate it */
*(ULONG*)&Prcb->VendorString[0] = Vendor[1]; // ebx
*(ULONG*)&Prcb->VendorString[4] = Vendor[3]; // edx
*(ULONG*)&Prcb->VendorString[8] = Vendor[2]; // ecx
*(ULONG*)&Prcb->VendorString[12] = 0;
*(ULONG*)&Prcb->VendorString[0] = CpuInfo.Ebx;
*(ULONG*)&Prcb->VendorString[4] = CpuInfo.Edx;
*(ULONG*)&Prcb->VendorString[8] = CpuInfo.Ecx;
Prcb->VendorString[12] = 0;
/* Now check the CPU Type */
if (!strcmp((PCHAR)Prcb->VendorString, CmpIntelID))
@ -137,20 +115,10 @@ KiGetCpuVendor(VOID)
{
return CPU_AMD;
}
else if (!strcmp((PCHAR)Prcb->VendorString, CmpCyrixID))
{
DPRINT1("Cyrix CPUs not fully supported\n");
return 0;
}
else if (!strcmp((PCHAR)Prcb->VendorString, CmpTransmetaID))
{
DPRINT1("Transmeta CPUs not fully supported\n");
return 0;
}
else if (!strcmp((PCHAR)Prcb->VendorString, CmpCentaurID))
{
DPRINT1("VIA CPUs not fully supported\n");
return 0;
return CPU_VIA;
}
else if (!strcmp((PCHAR)Prcb->VendorString, CmpRiseID))
{
@ -159,7 +127,7 @@ KiGetCpuVendor(VOID)
}
/* Invalid CPU */
return 0;
return CPU_UNKNOWN;
}
ULONG
@ -168,9 +136,8 @@ KiGetFeatureBits(VOID)
{
PKPRCB Prcb = KeGetCurrentPrcb();
ULONG Vendor;
ULONG FeatureBits = KF_WORKING_PTE;
INT Reg[4];
ULONG CpuFeatures = 0;
ULONG FeatureBits = KF_WORKING_PTE;;
CPU_INFO CpuInfo;
/* Get the Vendor ID */
Vendor = KiGetCpuVendor();
@ -178,44 +145,41 @@ KiGetFeatureBits(VOID)
/* Make sure we got a valid vendor ID at least. */
if (!Vendor) return FeatureBits;
/* Get the CPUID Info. Features are in Reg[3]. */
__cpuid(Reg, 1);
/* Get the CPUID Info. */
KiCpuId(&CpuInfo, 1);
/* Set the initial APIC ID */
Prcb->InitialApicId = (UCHAR)(Reg[1] >> 24);
/* Set the current features */
CpuFeatures = Reg[3];
Prcb->InitialApicId = (UCHAR)(CpuInfo.Ebx >> 24);
/* Convert all CPUID Feature bits into our format */
if (CpuFeatures & 0x00000002) FeatureBits |= KF_V86_VIS | KF_CR4;
if (CpuFeatures & 0x00000008) FeatureBits |= KF_LARGE_PAGE | KF_CR4;
if (CpuFeatures & 0x00000010) FeatureBits |= KF_RDTSC;
if (CpuFeatures & 0x00000100) FeatureBits |= KF_CMPXCHG8B;
if (CpuFeatures & 0x00000800) FeatureBits |= KF_FAST_SYSCALL;
if (CpuFeatures & 0x00001000) FeatureBits |= KF_MTRR;
if (CpuFeatures & 0x00002000) FeatureBits |= KF_GLOBAL_PAGE | KF_CR4;
if (CpuFeatures & 0x00008000) FeatureBits |= KF_CMOV;
if (CpuFeatures & 0x00010000) FeatureBits |= KF_PAT;
if (CpuFeatures & 0x00200000) FeatureBits |= KF_DTS;
if (CpuFeatures & 0x00800000) FeatureBits |= KF_MMX;
if (CpuFeatures & 0x01000000) FeatureBits |= KF_FXSR;
if (CpuFeatures & 0x02000000) FeatureBits |= KF_XMMI;
if (CpuFeatures & 0x04000000) FeatureBits |= KF_XMMI64;
if (CpuInfo.Edx & 0x00000002) FeatureBits |= KF_V86_VIS | KF_CR4;
if (CpuInfo.Edx & 0x00000008) FeatureBits |= KF_LARGE_PAGE | KF_CR4;
if (CpuInfo.Edx & 0x00000010) FeatureBits |= KF_RDTSC;
if (CpuInfo.Edx & 0x00000100) FeatureBits |= KF_CMPXCHG8B;
if (CpuInfo.Edx & 0x00000800) FeatureBits |= KF_FAST_SYSCALL;
if (CpuInfo.Edx & 0x00001000) FeatureBits |= KF_MTRR;
if (CpuInfo.Edx & 0x00002000) FeatureBits |= KF_GLOBAL_PAGE | KF_CR4;
if (CpuInfo.Edx & 0x00008000) FeatureBits |= KF_CMOV;
if (CpuInfo.Edx & 0x00010000) FeatureBits |= KF_PAT;
if (CpuInfo.Edx & 0x00200000) FeatureBits |= KF_DTS;
if (CpuInfo.Edx & 0x00800000) FeatureBits |= KF_MMX;
if (CpuInfo.Edx & 0x01000000) FeatureBits |= KF_FXSR;
if (CpuInfo.Edx & 0x02000000) FeatureBits |= KF_XMMI;
if (CpuInfo.Edx & 0x04000000) FeatureBits |= KF_XMMI64;
if (Reg[2] & 0x00000001) FeatureBits |= KF_SSE3;
//if (Reg[2] & 0x00000008) FeatureBits |= KF_MONITOR;
//if (Reg[2] & 0x00000200) FeatureBits |= KF_SSE3SUP;
if (Reg[2] & 0x00002000) FeatureBits |= KF_CMPXCHG16B;
//if (Reg[2] & 0x00080000) FeatureBits |= KF_SSE41;
//if (Reg[2] & 0x00800000) FeatureBits |= KF_POPCNT;
if (Reg[2] & 0x04000000) FeatureBits |= KF_XSTATE;
if (CpuInfo.Ecx & 0x00000001) FeatureBits |= KF_SSE3;
//if (CpuInfo.Ecx & 0x00000008) FeatureBits |= KF_MONITOR;
//if (CpuInfo.Ecx & 0x00000200) FeatureBits |= KF_SSE3SUP;
if (CpuInfo.Ecx & 0x00002000) FeatureBits |= KF_CMPXCHG16B;
//if (CpuInfo.Ecx & 0x00080000) FeatureBits |= KF_SSE41;
//if (CpuInfo.Ecx & 0x00800000) FeatureBits |= KF_POPCNT;
if (CpuInfo.Ecx & 0x04000000) FeatureBits |= KF_XSTATE;
/* Check if the CPU has hyper-threading */
if (CpuFeatures & 0x10000000)
if (CpuInfo.Ecx & 0x10000000)
{
/* Set the number of logical CPUs */
Prcb->LogicalProcessorsPerPhysicalProcessor = (UCHAR)(Reg[1] >> 16);
Prcb->LogicalProcessorsPerPhysicalProcessor = (UCHAR)(CpuInfo.Ebx >> 16);
if (Prcb->LogicalProcessorsPerPhysicalProcessor > 1)
{
/* We're on dual-core */
@ -229,23 +193,23 @@ KiGetFeatureBits(VOID)
}
/* Check extended cpuid features */
__cpuid(Reg, 0x80000000);
if ((Reg[0] & 0xffffff00) == 0x80000000)
KiCpuId(&CpuInfo, 0x80000000);
if ((CpuInfo.Eax & 0xffffff00) == 0x80000000)
{
/* Check if CPUID 0x80000001 is supported */
if (Reg[0] >= 0x80000001)
if (CpuInfo.Eax >= 0x80000001)
{
/* Check which extended features are available. */
__cpuid(Reg, 0x80000001);
KiCpuId(&CpuInfo, 0x80000001);
/* Check if NX-bit is supported */
if (Reg[3] & 0x00100000) FeatureBits |= KF_NX_BIT;
if (CpuInfo.Edx & 0x00100000) FeatureBits |= KF_NX_BIT;
/* Now handle each features for each CPU Vendor */
switch (Vendor)
{
case CPU_AMD:
if (Reg[3] & 0x80000000) FeatureBits |= KF_3DNOW;
if (CpuInfo.Edx & 0x80000000) FeatureBits |= KF_3DNOW;
break;
}
}
@ -261,11 +225,11 @@ KiGetCacheInformation(VOID)
{
PKIPCR Pcr = (PKIPCR)KeGetPcr();
ULONG Vendor;
INT Data[4];
ULONG CacheRequests = 0, i;
ULONG CurrentRegister;
UCHAR RegisterByte;
BOOLEAN FirstPass = TRUE;
CPU_INFO CpuInfo;
/* Set default L2 size */
Pcr->SecondLevelCacheSize = 0;
@ -281,14 +245,14 @@ KiGetCacheInformation(VOID)
case CPU_INTEL:
/*Check if we support CPUID 2 */
__cpuid(Data, 0);
if (Data[0] >= 2)
KiCpuId(&CpuInfo, 0);
if (CpuInfo.Eax >= 2)
{
/* We need to loop for the number of times CPUID will tell us to */
do
{
/* Do the CPUID call */
__cpuid(Data, 2);
KiCpuId(&CpuInfo, 2);
/* Check if it was the first call */
if (FirstPass)
@ -297,8 +261,8 @@ KiGetCacheInformation(VOID)
* The number of times to loop is the first byte. Read
* it and then destroy it so we don't get confused.
*/
CacheRequests = Data[0] & 0xFF;
Data[0] &= 0xFFFFFF00;
CacheRequests = CpuInfo.Eax & 0xFF;
CpuInfo.Eax &= 0xFFFFFF00;
/* Don't go over this again */
FirstPass = FALSE;
@ -308,7 +272,7 @@ KiGetCacheInformation(VOID)
for (i = 0; i < 4; i++)
{
/* Get the current register */
CurrentRegister = Data[i];
CurrentRegister = CpuInfo.AsUINT32[i];
/*
* If the upper bit is set, then this register should
@ -350,14 +314,14 @@ KiGetCacheInformation(VOID)
case CPU_AMD:
/* Check if we support CPUID 0x80000006 */
__cpuid(Data, 0x80000000);
if (Data[0] >= 6)
KiCpuId(&CpuInfo, 0x80000000);
if (CpuInfo.Eax >= 6)
{
/* Get 2nd level cache and tlb size */
__cpuid(Data, 0x80000006);
KiCpuId(&CpuInfo, 0x80000006);
/* Set the L2 Cache Size */
Pcr->SecondLevelCacheSize = (Data[2] & 0xFFFF0000) >> 6;
Pcr->SecondLevelCacheSize = (CpuInfo.Ecx & 0xFFFF0000) >> 6;
}
break;
}

View file

@ -62,43 +62,6 @@ static const CHAR CmpRiseID[] = "RiseRiseRise";
/* SUPPORT ROUTINES FOR MSVC COMPATIBILITY ***********************************/
VOID
NTAPI
CPUID(IN ULONG InfoType,
OUT PULONG CpuInfoEax,
OUT PULONG CpuInfoEbx,
OUT PULONG CpuInfoEcx,
OUT PULONG CpuInfoEdx)
{
ULONG CpuInfo[4];
/* Perform the CPUID Operation */
__cpuid((int*)CpuInfo, InfoType);
/* Return the results */
*CpuInfoEax = CpuInfo[0];
*CpuInfoEbx = CpuInfo[1];
*CpuInfoEcx = CpuInfo[2];
*CpuInfoEdx = CpuInfo[3];
}
VOID
NTAPI
WRMSR(IN ULONG Register,
IN LONGLONG Value)
{
/* Write to the MSR */
__writemsr(Register, Value);
}
LONGLONG
FASTCALL
RDMSR(IN ULONG Register)
{
/* Read from the MSR */
return __readmsr(Register);
}
/* NSC/Cyrix CPU configuration register index */
#define CX86_CCR1 0xc1
@ -128,7 +91,7 @@ INIT_FUNCTION
KiSetProcessorType(VOID)
{
ULONG EFlags, NewEFlags;
ULONG Reg, Dummy;
CPU_INFO CpuInfo;
ULONG Stepping, Type;
/* Start by assuming no CPUID data */
@ -150,11 +113,11 @@ KiSetProcessorType(VOID)
__writeeflags(EFlags);
/* Peform CPUID 0 to see if CPUID 1 is supported */
CPUID(0, &Reg, &Dummy, &Dummy, &Dummy);
if (Reg > 0)
KiCpuId(&CpuInfo, 0);
if (CpuInfo.Eax > 0)
{
/* Do CPUID 1 now */
CPUID(1, &Reg, &Dummy, &Dummy, &Dummy);
KiCpuId(&CpuInfo, 1);
/*
* Get the Stepping and Type. The stepping contains both the
@ -163,11 +126,11 @@ KiSetProcessorType(VOID)
*
* For the stepping, we convert this: zzzzzzxy into this: x0y
*/
Stepping = Reg & 0xF0;
Stepping = CpuInfo.Eax & 0xF0;
Stepping <<= 4;
Stepping += (Reg & 0xFF);
Stepping += (CpuInfo.Eax & 0xFF);
Stepping &= 0xF0F;
Type = Reg & 0xF00;
Type = CpuInfo.Eax & 0xF00;
Type >>= 8;
/* Save them in the PRCB */
@ -195,27 +158,20 @@ INIT_FUNCTION
KiGetCpuVendor(VOID)
{
PKPRCB Prcb = KeGetCurrentPrcb();
ULONG Vendor[5];
ULONG Temp;
CPU_INFO CpuInfo;
/* Assume no Vendor ID and fail if no CPUID Support. */
Prcb->VendorString[0] = 0;
if (!Prcb->CpuID) return 0;
/* Get the Vendor ID and null-terminate it */
CPUID(0, &Vendor[0], &Vendor[1], &Vendor[2], &Vendor[3]);
Vendor[4] = 0;
/* Get the Vendor ID */
KiCpuId(&CpuInfo, 0);
/* Re-arrange vendor string */
Temp = Vendor[2];
Vendor[2] = Vendor[3];
Vendor[3] = Temp;
/* Copy it to the PRCB and null-terminate it again */
RtlCopyMemory(Prcb->VendorString,
&Vendor[1],
sizeof(Prcb->VendorString) - sizeof(CHAR));
Prcb->VendorString[sizeof(Prcb->VendorString) - sizeof(CHAR)] = ANSI_NULL;
/* Copy it to the PRCB and null-terminate it */
*(ULONG*)&Prcb->VendorString[0] = CpuInfo.Ebx;
*(ULONG*)&Prcb->VendorString[4] = CpuInfo.Edx;
*(ULONG*)&Prcb->VendorString[8] = CpuInfo.Ecx;
Prcb->VendorString[12] = 0;
/* Now check the CPU Type */
if (!strcmp(Prcb->VendorString, CmpIntelID))
@ -260,7 +216,7 @@ KiGetFeatureBits(VOID)
PKPRCB Prcb = KeGetCurrentPrcb();
ULONG Vendor;
ULONG FeatureBits = KF_WORKING_PTE;
ULONG Reg[4], Dummy;
CPU_INFO CpuInfo, DummyCpuInfo;
UCHAR Ccr1;
BOOLEAN ExtendedCPUID = TRUE;
ULONG CpuFeatures = 0;
@ -272,10 +228,10 @@ KiGetFeatureBits(VOID)
if (!Vendor) return FeatureBits;
/* Get the CPUID Info. Features are in Reg[3]. */
CPUID(1, &Reg[0], &Reg[1], &Dummy, &Reg[3]);
KiCpuId(&CpuInfo, 1);
/* Set the initial APIC ID */
Prcb->InitialApicId = (UCHAR)(Reg[1] >> 24);
Prcb->InitialApicId = (UCHAR)(CpuInfo.Ebx >> 24);
switch (Vendor)
{
@ -286,9 +242,9 @@ KiGetFeatureBits(VOID)
if (Prcb->CpuType == 6)
{
/* Perform the special sequence to get the MicroCode Signature */
WRMSR(0x8B, 0);
CPUID(1, &Dummy, &Dummy, &Dummy, &Dummy);
Prcb->UpdateSignature.QuadPart = RDMSR(0x8B);
__writemsr(0x8B, 0);
KiCpuId(&DummyCpuInfo, 1);
Prcb->UpdateSignature.QuadPart = __readmsr(0x8B);
}
else if (Prcb->CpuType == 5)
{
@ -297,8 +253,8 @@ KiGetFeatureBits(VOID)
}
/* 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))
if (((CpuInfo.Eax & 0x0FF0) == 0x0610 && (CpuInfo.Eax & 0x000F) <= 0x9) ||
((CpuInfo.Eax & 0x0FF0) == 0x0630 && (CpuInfo.Eax & 0x000F) <= 0x4))
{
/* Remove support for correct PTE support. */
FeatureBits &= ~KF_WORKING_PTE;
@ -309,7 +265,7 @@ KiGetFeatureBits(VOID)
((Prcb->CpuType == 6) && (Prcb->CpuStep < 0x0303)))
{
/* Disable it */
Reg[3] &= ~0x800;
CpuInfo.Edx &= ~0x800;
}
break;
@ -318,29 +274,29 @@ KiGetFeatureBits(VOID)
case CPU_AMD:
/* Check if this is a K5 or K6. (family 5) */
if ((Reg[0] & 0x0F00) == 0x0500)
if ((CpuInfo.Eax & 0x0F00) == 0x0500)
{
/* Get the Model Number */
switch (Reg[0] & 0x00F0)
switch (CpuInfo.Eax & 0x00F0)
{
/* 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;
if ((CpuInfo.Eax & 0x000F) > 0x03) break;
/* Model 0: K5 - SSA5 */
case 0x0000:
/* Model 0 doesn't support PGE at all. */
Reg[3] &= ~0x2000;
CpuInfo.Edx &= ~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;
if ((CpuInfo.Eax & 0x000F) >= 0x8) FeatureBits |= KF_AMDK6MTRR;
break;
/* Model 9: K6-III
@ -352,10 +308,10 @@ KiGetFeatureBits(VOID)
break;
}
}
else if((Reg[0] & 0x0F00) < 0x0500)
else if((CpuInfo.Eax & 0x0F00) < 0x0500)
{
/* Families below 5 don't support PGE, PSE or CMOV at all */
Reg[3] &= ~(0x08 | 0x2000 | 0x8000);
CpuInfo.Edx &= ~(0x08 | 0x2000 | 0x8000);
/* They also don't support advanced CPUID functions. */
ExtendedCPUID = FALSE;
@ -386,9 +342,9 @@ KiGetFeatureBits(VOID)
case CPU_TRANSMETA:
/* Enable CMPXCHG8B if the family (>= 5), model and stepping (>= 4.2) support it */
if ((Reg[0] & 0x0FFF) >= 0x0542)
if ((CpuInfo.Eax & 0x0FFF) >= 0x0542)
{
WRMSR(0x80860004, RDMSR(0x80860004) | 0x0100);
__writemsr(0x80860004, __readmsr(0x80860004) | 0x0100);
FeatureBits |= KF_CMPXCHG8B;
}
@ -406,7 +362,7 @@ KiGetFeatureBits(VOID)
}
/* Set the current features */
CpuFeatures = Reg[3];
CpuFeatures = CpuInfo.Edx;
/* Convert all CPUID Feature bits into our format */
if (CpuFeatures & 0x00000002) FeatureBits |= KF_V86_VIS | KF_CR4;
@ -428,7 +384,7 @@ KiGetFeatureBits(VOID)
if (CpuFeatures & 0x10000000)
{
/* Set the number of logical CPUs */
Prcb->LogicalProcessorsPerPhysicalProcessor = (UCHAR)(Reg[1] >> 16);
Prcb->LogicalProcessorsPerPhysicalProcessor = (UCHAR)(CpuInfo.Ebx >> 16);
if (Prcb->LogicalProcessorsPerPhysicalProcessor > 1)
{
/* We're on dual-core */
@ -445,24 +401,24 @@ KiGetFeatureBits(VOID)
if (ExtendedCPUID)
{
/* Do the call */
CPUID(0x80000000, &Reg[0], &Dummy, &Dummy, &Dummy);
if ((Reg[0] & 0xffffff00) == 0x80000000)
KiCpuId(&CpuInfo, 0x80000000);
if ((CpuInfo.Eax & 0xffffff00) == 0x80000000)
{
/* Check if CPUID 0x80000001 is supported */
if (Reg[0] >= 0x80000001)
if (CpuInfo.Eax >= 0x80000001)
{
/* Check which extended features are available. */
CPUID(0x80000001, &Dummy, &Dummy, &Dummy, &Reg[3]);
KiCpuId(&CpuInfo, 0x80000001);
/* Check if NX-bit is supported */
if (Reg[3] & 0x00100000) FeatureBits |= KF_NX_BIT;
if (CpuInfo.Edx & 0x00100000) FeatureBits |= KF_NX_BIT;
/* Now handle each features for each CPU Vendor */
switch (Vendor)
{
case CPU_AMD:
case CPU_CENTAUR:
if (Reg[3] & 0x80000000) FeatureBits |= KF_3DNOW;
if (CpuInfo.Edx & 0x80000000) FeatureBits |= KF_3DNOW;
break;
}
}
@ -505,7 +461,7 @@ KiGetCacheInformation(VOID)
{
PKIPCR Pcr = (PKIPCR)KeGetPcr();
ULONG Vendor;
ULONG Data[4], Dummy;
CPU_INFO CpuInfo;
ULONG CacheRequests = 0, i;
ULONG CurrentRegister;
UCHAR RegisterByte, Associativity = 0;
@ -526,14 +482,14 @@ KiGetCacheInformation(VOID)
case CPU_INTEL:
/*Check if we support CPUID 2 */
CPUID(0, &Data[0], &Dummy, &Dummy, &Dummy);
if (Data[0] >= 2)
KiCpuId(&CpuInfo, 0);
if (CpuInfo.Eax >= 2)
{
/* We need to loop for the number of times CPUID will tell us to */
do
{
/* Do the CPUID call */
CPUID(2, &Data[0], &Data[1], &Data[2], &Data[3]);
KiCpuId(&CpuInfo, 2);
/* Check if it was the first call */
if (FirstPass)
@ -542,8 +498,8 @@ KiGetCacheInformation(VOID)
* The number of times to loop is the first byte. Read
* it and then destroy it so we don't get confused.
*/
CacheRequests = Data[0] & 0xFF;
Data[0] &= 0xFFFFFF00;
CacheRequests = CpuInfo.Eax & 0xFF;
CpuInfo.Eax &= 0xFFFFFF00;
/* Don't go over this again */
FirstPass = FALSE;
@ -553,7 +509,7 @@ KiGetCacheInformation(VOID)
for (i = 0; i < 4; i++)
{
/* Get the current register */
CurrentRegister = Data[i];
CurrentRegister = CpuInfo.AsUINT32[i];
/*
* If the upper bit is set, then this register should
@ -722,25 +678,25 @@ KiGetCacheInformation(VOID)
case CPU_AMD:
/* Check if we support CPUID 0x80000005 */
CPUID(0x80000000, &Data[0], &Data[1], &Data[2], &Data[3]);
if (Data[0] >= 0x80000006)
KiCpuId(&CpuInfo, 0x80000000);
if (CpuInfo.Eax >= 0x80000006)
{
/* Get L1 size first */
CPUID(0x80000005, &Data[0], &Data[1], &Data[2], &Data[3]);
KePrefetchNTAGranularity = Data[2] & 0xFF;
KiCpuId(&CpuInfo, 0x80000005);
KePrefetchNTAGranularity = CpuInfo.Ecx & 0xFF;
/* Check if we support CPUID 0x80000006 */
CPUID(0x80000000, &Data[0], &Data[1], &Data[2], &Data[3]);
if (Data[0] >= 0x80000006)
KiCpuId(&CpuInfo, 0x80000000);
if (CpuInfo.Eax >= 0x80000006)
{
/* Get 2nd level cache and tlb size */
CPUID(0x80000006, &Data[0], &Data[1], &Data[2], &Data[3]);
KiCpuId(&CpuInfo, 0x80000006);
/* Cache line size */
CacheLine = Data[2] & 0xFF;
CacheLine = CpuInfo.Ecx & 0xFF;
/* Hardcode associativity */
RegisterByte = (Data[2] >> 12) & 0xFF;
RegisterByte = (CpuInfo.Ecx >> 12) & 0xFF;
switch (RegisterByte)
{
case 2:
@ -766,7 +722,7 @@ KiGetCacheInformation(VOID)
}
/* Compute size */
Size = (Data[2] >> 16) << 10;
Size = (CpuInfo.Ecx >> 16) << 10;
/* Hack for Model 6, Steping 300 */
if ((KeGetCurrentPrcb()->CpuType == 6) &&
@ -1047,11 +1003,11 @@ INIT_FUNCTION
KiLoadFastSyscallMachineSpecificRegisters(IN ULONG_PTR Context)
{
/* Set CS and ESP */
WRMSR(0x174, KGDT_R0_CODE);
WRMSR(0x175, (ULONG_PTR)KeGetCurrentPrcb()->DpcStack);
__writemsr(0x174, KGDT_R0_CODE);
__writemsr(0x175, (ULONG_PTR)KeGetCurrentPrcb()->DpcStack);
/* Set LSTAR */
WRMSR(0x176, (ULONG_PTR)KiFastCallEntry);
__writemsr(0x176, (ULONG_PTR)KiFastCallEntry);
return 0;
}

View file

@ -43,7 +43,7 @@ KiInitMachineDependent(VOID)
ULONG i, Affinity, Sample = 0;
PFX_SAVE_AREA FxSaveArea;
ULONG MXCsrMask = 0xFFBF;
ULONG Dummy;
CPU_INFO CpuInfo;
KI_SAMPLE_MAP Samples[4];
PKI_SAMPLE_MAP CurrentSample = Samples;
LARGE_IDENTITY_MAP IdentityMap;
@ -190,7 +190,7 @@ KiInitMachineDependent(VOID)
for (;;)
{
/* Do a dummy CPUID to start the sample */
CPUID(0, &Dummy, &Dummy, &Dummy, &Dummy);
KiCpuId(&CpuInfo, 0);
/* Fill out the starting data */
CurrentSample->PerfStart = KeQueryPerformanceCounter(NULL);
@ -203,7 +203,7 @@ KiInitMachineDependent(VOID)
&CurrentSample->PerfFreq);
/* Do another dummy CPUID */
CPUID(0, &Dummy, &Dummy, &Dummy, &Dummy);
KiCpuId(&CpuInfo, 0);
/* Fill out the ending data */
CurrentSample->PerfEnd =