mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 08:55:19 +00:00
[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:
parent
0100d8de0c
commit
5b7d2dec59
8 changed files with 185 additions and 253 deletions
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 =
|
||||
|
|
Loading…
Reference in a new issue