[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 #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 // Trap Frame Definition
// //

View file

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

View file

@ -1660,3 +1660,24 @@ KiReleaseNmiListLock(IN KIRQL OldIrql)
{ {
KeReleaseSpinLock(&KiNmiCallbackListLock, 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) OUT PLARGE_INTEGER MsrValue)
{ {
/* Wrap this in SEH in case the MSR doesn't exist */ /* Wrap this in SEH in case the MSR doesn't exist */
//_SEH2_TRY _SEH2_TRY
{ {
/* Read from the MSR */ /* Read from the MSR */
MsrValue->QuadPart = RDMSR(Msr); MsrValue->QuadPart = __readmsr(Msr);
} }
//_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{ {
/* Invalid MSR */ /* Invalid MSR */
//_SEH2_YIELD(return STATUS_NO_SUCH_DEVICE); _SEH2_YIELD(return STATUS_NO_SUCH_DEVICE);
} }
//_SEH2_END; _SEH2_END;
/* Success */ /* Success */
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -117,17 +117,17 @@ KdpSysWriteMsr(IN ULONG Msr,
IN PLARGE_INTEGER MsrValue) IN PLARGE_INTEGER MsrValue)
{ {
/* Wrap this in SEH in case the MSR doesn't exist */ /* Wrap this in SEH in case the MSR doesn't exist */
//_SEH2_TRY _SEH2_TRY
{ {
/* Write to the MSR */ /* Write to the MSR */
WRMSR(Msr, MsrValue->QuadPart); __writemsr(Msr, MsrValue->QuadPart);
} }
//_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{ {
/* Invalid MSR */ /* Invalid MSR */
//_SEH2_YIELD(return STATUS_NO_SUCH_DEVICE); _SEH2_YIELD(return STATUS_NO_SUCH_DEVICE);
} }
//_SEH2_END; _SEH2_END;
/* Success */ /* Success */
return STATUS_SUCCESS; return STATUS_SUCCESS;

View file

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

View file

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

View file

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