mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 06:53:37 +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
|
#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
|
||||||
//
|
//
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue