Implement processor feature enumeration mapping
This commit is contained in:
@@ -69,6 +69,62 @@
|
|||||||
#define AMD64_INTERRUPT_GATE 0xE
|
#define AMD64_INTERRUPT_GATE 0xE
|
||||||
#define AMD64_TRAP_GATE 0xF
|
#define AMD64_TRAP_GATE 0xF
|
||||||
|
|
||||||
|
/* Kernel CPU Standard Features */
|
||||||
|
#define KCF_VME (1ULL << 0) /* Virtual 8086 Mode Enhancements */
|
||||||
|
#define KCF_LARGE_PAGE (1ULL << 1) /* Page Size Extensions */
|
||||||
|
#define KCF_RDTSC (1ULL << 2) /* Time Stamp Counter */
|
||||||
|
#define KCF_PAE (1ULL << 3) /* Physical Address Extension */
|
||||||
|
#define KCF_MCE (1ULL << 4) /* Machine Check Exception */
|
||||||
|
#define KCF_CMPXCHG8B (1ULL << 5) /* CMPXCHG8B Instruction */
|
||||||
|
#define KCF_APIC (1ULL << 6) /* APIC On-Chip */
|
||||||
|
#define KCF_FAST_SYSCALL (1ULL << 7) /* SYSENTER/SYSEXIT Instructions */
|
||||||
|
#define KCF_MTRR (1ULL << 8) /* Memory Type Range Registers */
|
||||||
|
#define KCF_GLOBAL_PAGE (1ULL << 9) /* Page Global Enable */
|
||||||
|
#define KCF_MCA (1ULL << 10) /* Machine Check Architecture */
|
||||||
|
#define KCF_CMOV (1ULL << 11) /* Conditional Move Instructions */
|
||||||
|
#define KCF_PAT (1ULL << 12) /* Page Attribute Table */
|
||||||
|
#define KCF_PSE36 (1ULL << 13) /* 36-bit Page Size Extension */
|
||||||
|
#define KCF_CLFLUSH (1ULL << 14) /* CLFLUSH Instruction */
|
||||||
|
#define KCF_FXSR (1ULL << 15) /* FXSAVE/FXRSTOR Instructions */
|
||||||
|
#define KCF_ACPI (1ULL << 16) /* Thermal Monitor and Software Controlled Clock */
|
||||||
|
#define KCF_MMX (1ULL << 17) /* MMX Technology */
|
||||||
|
#define KCF_SSE (1ULL << 18) /* Streaming SIMD Extensions */
|
||||||
|
#define KCF_SSE2 (1ULL << 19) /* Streaming SIMD Extensions 2 */
|
||||||
|
#define KCF_SMT (1ULL << 20) /* Hyper-Threading Technology */
|
||||||
|
#define KCF_SSE3 (1ULL << 21) /* Streaming SIMD Extensions 3 */
|
||||||
|
#define KCF_VMX (1ULL << 22) /* Intel Virtual Machine Extensions */
|
||||||
|
#define KCF_SSSE3 (1ULL << 23) /* Supplemental SSE3 Instructions */
|
||||||
|
#define KCF_SSE41 (1ULL << 24) /* SSE4.1 Instructions */
|
||||||
|
#define KCF_SSE42 (1ULL << 25) /* SSE4.2 Instructions */
|
||||||
|
#define KCF_X2APIC (1ULL << 26) /* x2APIC Support */
|
||||||
|
#define KCF_POPCNT (1ULL << 27) /* POPCNT Instruction */
|
||||||
|
#define KCF_TSC_DEADLINE (1ULL << 28) /* TSC Deadline Timer */
|
||||||
|
#define KCF_AES (1ULL << 29) /* AES-NI Instruction Set */
|
||||||
|
#define KCF_XSAVE (1ULL << 30) /* XSAVE/XRSTOR Instructions */
|
||||||
|
#define KCF_AVX (1ULL << 31) /* Advanced Vector Extensions */
|
||||||
|
#define KCF_RDRAND (1ULL << 32) /* RDRAND Instruction */
|
||||||
|
#define KCF_FSGSBASE (1ULL << 33) /* RDFSBASE/WRFSBASE Instructions */
|
||||||
|
#define KCF_AVX2 (1ULL << 34) /* AVX2 Instructions */
|
||||||
|
#define KCF_SMEP (1ULL << 35) /* Supervisor Mode Execution Prevention */
|
||||||
|
#define KCF_RDSEED (1ULL << 36) /* RDSEED Instruction */
|
||||||
|
#define KCF_SMAP (1ULL << 37) /* Supervisor Mode Access Prevention */
|
||||||
|
#define KCF_SHA (1ULL << 38) /* SHA Extensions */
|
||||||
|
#define KCF_LA57 (1ULL << 39) /* 57-bit Linear Addresses */
|
||||||
|
#define KCF_ARAT (1ULL << 40) /* Always Running APIC Timer */
|
||||||
|
|
||||||
|
/* Kernel CPU Extended Features */
|
||||||
|
#define KCF_SVM (1ULL << 0) /* AMD Secure Virtual Machine */
|
||||||
|
#define KCF_SSE4A (1ULL << 1) /* SSE4A Instructions */
|
||||||
|
#define KCF_FMA4 (1ULL << 2) /* FMA4 Instructions */
|
||||||
|
#define KCF_TOPOEXT (1ULL << 3) /* AMD Topology Extensions */
|
||||||
|
#define KCF_SYSCALL (1ULL << 4) /* SYSCALL/SYSRET Instructions */
|
||||||
|
#define KCF_NX_BIT (1ULL << 5) /* No-Execute Page Protection */
|
||||||
|
#define KCF_RDTSCP (1ULL << 6) /* RDTSCP Instruction */
|
||||||
|
#define KCF_64BIT (1ULL << 7) /* Long Mode Support */
|
||||||
|
#define KCF_3DNOW_EXT (1ULL << 8) /* 3DNow! Extensions */
|
||||||
|
#define KCF_3DNOW (1ULL << 9) /* 3DNow! Instructions */
|
||||||
|
#define KCF_INVARIANT_TSC (1ULL << 10) /* Invariant Time Stamp Counter */
|
||||||
|
|
||||||
/* Context control flags */
|
/* Context control flags */
|
||||||
#define CONTEXT_ARCHITECTURE 0x00100000
|
#define CONTEXT_ARCHITECTURE 0x00100000
|
||||||
#define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01)
|
#define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01)
|
||||||
|
|||||||
@@ -90,6 +90,62 @@
|
|||||||
#define I686_INTERRUPT_GATE 0xE
|
#define I686_INTERRUPT_GATE 0xE
|
||||||
#define I686_TRAP_GATE 0xF
|
#define I686_TRAP_GATE 0xF
|
||||||
|
|
||||||
|
/* Kernel CPU Standard Features */
|
||||||
|
#define KCF_VME (1ULL << 0) /* Virtual 8086 Mode Enhancements */
|
||||||
|
#define KCF_LARGE_PAGE (1ULL << 1) /* Page Size Extensions */
|
||||||
|
#define KCF_RDTSC (1ULL << 2) /* Time Stamp Counter */
|
||||||
|
#define KCF_PAE (1ULL << 3) /* Physical Address Extension */
|
||||||
|
#define KCF_MCE (1ULL << 4) /* Machine Check Exception */
|
||||||
|
#define KCF_CMPXCHG8B (1ULL << 5) /* CMPXCHG8B Instruction */
|
||||||
|
#define KCF_APIC (1ULL << 6) /* APIC On-Chip */
|
||||||
|
#define KCF_FAST_SYSCALL (1ULL << 7) /* SYSENTER/SYSEXIT Instructions */
|
||||||
|
#define KCF_MTRR (1ULL << 8) /* Memory Type Range Registers */
|
||||||
|
#define KCF_GLOBAL_PAGE (1ULL << 9) /* Page Global Enable */
|
||||||
|
#define KCF_MCA (1ULL << 10) /* Machine Check Architecture */
|
||||||
|
#define KCF_CMOV (1ULL << 11) /* Conditional Move Instructions */
|
||||||
|
#define KCF_PAT (1ULL << 12) /* Page Attribute Table */
|
||||||
|
#define KCF_PSE36 (1ULL << 13) /* 36-bit Page Size Extension */
|
||||||
|
#define KCF_CLFLUSH (1ULL << 14) /* CLFLUSH Instruction */
|
||||||
|
#define KCF_FXSR (1ULL << 15) /* FXSAVE/FXRSTOR Instructions */
|
||||||
|
#define KCF_ACPI (1ULL << 16) /* Thermal Monitor and Software Controlled Clock */
|
||||||
|
#define KCF_MMX (1ULL << 17) /* MMX Technology */
|
||||||
|
#define KCF_SSE (1ULL << 18) /* Streaming SIMD Extensions */
|
||||||
|
#define KCF_SSE2 (1ULL << 19) /* Streaming SIMD Extensions 2 */
|
||||||
|
#define KCF_SMT (1ULL << 20) /* Hyper-Threading Technology */
|
||||||
|
#define KCF_SSE3 (1ULL << 21) /* Streaming SIMD Extensions 3 */
|
||||||
|
#define KCF_VMX (1ULL << 22) /* Intel Virtual Machine Extensions */
|
||||||
|
#define KCF_SSSE3 (1ULL << 23) /* Supplemental SSE3 Instructions */
|
||||||
|
#define KCF_SSE41 (1ULL << 24) /* SSE4.1 Instructions */
|
||||||
|
#define KCF_SSE42 (1ULL << 25) /* SSE4.2 Instructions */
|
||||||
|
#define KCF_X2APIC (1ULL << 26) /* x2APIC Support */
|
||||||
|
#define KCF_POPCNT (1ULL << 27) /* POPCNT Instruction */
|
||||||
|
#define KCF_TSC_DEADLINE (1ULL << 28) /* TSC Deadline Timer */
|
||||||
|
#define KCF_AES (1ULL << 29) /* AES-NI Instruction Set */
|
||||||
|
#define KCF_XSAVE (1ULL << 30) /* XSAVE/XRSTOR Instructions */
|
||||||
|
#define KCF_AVX (1ULL << 31) /* Advanced Vector Extensions */
|
||||||
|
#define KCF_RDRAND (1ULL << 32) /* RDRAND Instruction */
|
||||||
|
#define KCF_FSGSBASE (1ULL << 33) /* RDFSBASE/WRFSBASE Instructions */
|
||||||
|
#define KCF_AVX2 (1ULL << 34) /* AVX2 Instructions */
|
||||||
|
#define KCF_SMEP (1ULL << 35) /* Supervisor Mode Execution Prevention */
|
||||||
|
#define KCF_RDSEED (1ULL << 36) /* RDSEED Instruction */
|
||||||
|
#define KCF_SMAP (1ULL << 37) /* Supervisor Mode Access Prevention */
|
||||||
|
#define KCF_SHA (1ULL << 38) /* SHA Extensions */
|
||||||
|
#define KCF_LA57 (1ULL << 39) /* 57-bit Linear Addresses */
|
||||||
|
#define KCF_ARAT (1ULL << 40) /* Always Running APIC Timer */
|
||||||
|
|
||||||
|
/* Kernel CPU Extended Features */
|
||||||
|
#define KCF_SVM (1ULL << 0) /* AMD Secure Virtual Machine */
|
||||||
|
#define KCF_SSE4A (1ULL << 1) /* SSE4A Instructions */
|
||||||
|
#define KCF_FMA4 (1ULL << 2) /* FMA4 Instructions */
|
||||||
|
#define KCF_TOPOEXT (1ULL << 3) /* AMD Topology Extensions */
|
||||||
|
#define KCF_SYSCALL (1ULL << 4) /* SYSCALL/SYSRET Instructions */
|
||||||
|
#define KCF_NX_BIT (1ULL << 5) /* No-Execute Page Protection */
|
||||||
|
#define KCF_RDTSCP (1ULL << 6) /* RDTSCP Instruction */
|
||||||
|
#define KCF_64BIT (1ULL << 7) /* Long Mode Support */
|
||||||
|
#define KCF_3DNOW_EXT (1ULL << 8) /* 3DNow! Extensions */
|
||||||
|
#define KCF_3DNOW (1ULL << 9) /* 3DNow! Instructions */
|
||||||
|
#define KCF_INVARIANT_TSC (1ULL << 10) /* Invariant Time Stamp Counter */
|
||||||
|
|
||||||
/* Context control flags */
|
/* Context control flags */
|
||||||
#define CONTEXT_ARCHITECTURE 0x00010000
|
#define CONTEXT_ARCHITECTURE 0x00010000
|
||||||
#define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01)
|
#define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01)
|
||||||
|
|||||||
@@ -139,10 +139,131 @@ XTAPI
|
|||||||
VOID
|
VOID
|
||||||
AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
||||||
{
|
{
|
||||||
|
ULONG MaxExtendedLeaf, MaxStandardLeaf;
|
||||||
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
||||||
|
CPUID_REGISTERS CpuRegisters;
|
||||||
|
|
||||||
/* Get current processor control block */
|
/* Get current processor control block */
|
||||||
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
||||||
|
|
||||||
|
/* Get maximum CPUID standard leaf */
|
||||||
|
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||||
|
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
||||||
|
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||||
|
MaxStandardLeaf = CpuRegisters.Eax;
|
||||||
|
|
||||||
|
/* Get maximum CPUID extended leaf */
|
||||||
|
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||||
|
CpuRegisters.Leaf = CPUID_GET_EXTENDED_MAX;
|
||||||
|
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||||
|
MaxExtendedLeaf = CpuRegisters.Eax;
|
||||||
|
|
||||||
|
/* Check if CPU supports standard features leaf */
|
||||||
|
if(MaxStandardLeaf >= CPUID_GET_STANDARD1_FEATURES)
|
||||||
|
{
|
||||||
|
/* Get CPU standard features */
|
||||||
|
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||||
|
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||||
|
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||||
|
|
||||||
|
/* Store CPU standard features in processor control block */
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE3) Prcb->CpuId.FeatureBits |= KCF_SSE3;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_VMX) Prcb->CpuId.FeatureBits |= KCF_VMX;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSSE3) Prcb->CpuId.FeatureBits |= KCF_SSSE3;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4_1) Prcb->CpuId.FeatureBits |= KCF_SSE41;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4_2) Prcb->CpuId.FeatureBits |= KCF_SSE42;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_X2APIC) Prcb->CpuId.FeatureBits |= KCF_X2APIC;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_POPCNT) Prcb->CpuId.FeatureBits |= KCF_POPCNT;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TSC_DEADLINE) Prcb->CpuId.FeatureBits |= KCF_TSC_DEADLINE;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_AES) Prcb->CpuId.FeatureBits |= KCF_AES;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_XSAVE) Prcb->CpuId.FeatureBits |= KCF_XSAVE;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_AVX) Prcb->CpuId.FeatureBits |= KCF_AVX;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_RDRAND) Prcb->CpuId.FeatureBits |= KCF_RDRAND;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_VME) Prcb->CpuId.FeatureBits |= KCF_VME;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PSE) Prcb->CpuId.FeatureBits |= KCF_LARGE_PAGE;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSC) Prcb->CpuId.FeatureBits |= KCF_RDTSC;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PAE) Prcb->CpuId.FeatureBits |= KCF_PAE;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MCE) Prcb->CpuId.FeatureBits |= KCF_MCE;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CX8) Prcb->CpuId.FeatureBits |= KCF_CMPXCHG8B;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC) Prcb->CpuId.FeatureBits |= KCF_APIC;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SEP) Prcb->CpuId.FeatureBits |= KCF_FAST_SYSCALL;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MTRR) Prcb->CpuId.FeatureBits |= KCF_MTRR;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE) Prcb->CpuId.FeatureBits |= KCF_GLOBAL_PAGE;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MCA) Prcb->CpuId.FeatureBits |= KCF_MCA;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CMOV) Prcb->CpuId.FeatureBits |= KCF_CMOV;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PAT) Prcb->CpuId.FeatureBits |= KCF_PAT;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PSE36) Prcb->CpuId.FeatureBits |= KCF_PSE36;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CLFLUSH) Prcb->CpuId.FeatureBits |= KCF_CLFLUSH;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_FXSR) Prcb->CpuId.FeatureBits |= KCF_FXSR;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_ACPI) Prcb->CpuId.FeatureBits |= KCF_ACPI;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MMX) Prcb->CpuId.FeatureBits |= KCF_MMX;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SSE) Prcb->CpuId.FeatureBits |= KCF_SSE;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SSE2) Prcb->CpuId.FeatureBits |= KCF_SSE2;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_HTT) Prcb->CpuId.FeatureBits |= KCF_SMT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if CPU supports standard7 features leaf */
|
||||||
|
if(MaxStandardLeaf >= CPUID_GET_STANDARD7_FEATURES)
|
||||||
|
{
|
||||||
|
/* Get CPU standard features */
|
||||||
|
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||||
|
CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES;
|
||||||
|
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||||
|
|
||||||
|
/* Store CPU standard7 features in processor control block */
|
||||||
|
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_FSGSBASE) Prcb->CpuId.FeatureBits |= KCF_FSGSBASE;
|
||||||
|
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_AVX2) Prcb->CpuId.FeatureBits |= KCF_AVX2;
|
||||||
|
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SMEP) Prcb->CpuId.FeatureBits |= KCF_SMEP;
|
||||||
|
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_RDSEED) Prcb->CpuId.FeatureBits |= KCF_RDSEED;
|
||||||
|
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SMAP) Prcb->CpuId.FeatureBits |= KCF_SMAP;
|
||||||
|
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SHA) Prcb->CpuId.FeatureBits |= KCF_SHA;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) Prcb->CpuId.FeatureBits |= KCF_LA57;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if CPU supports power management leaf */
|
||||||
|
if(MaxStandardLeaf >= CPUID_GET_POWER_MANAGEMENT)
|
||||||
|
{
|
||||||
|
/* Get CPU power management features */
|
||||||
|
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||||
|
CpuRegisters.Leaf = CPUID_GET_POWER_MANAGEMENT;
|
||||||
|
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||||
|
|
||||||
|
/* Store CPU power management features in processor control block */
|
||||||
|
if(CpuRegisters.Eax & CPUID_FEATURES_EAX_ARAT) Prcb->CpuId.FeatureBits |= KCF_ARAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if CPU supports extended features leaf */
|
||||||
|
if(MaxExtendedLeaf >= CPUID_GET_EXTENDED_FEATURES)
|
||||||
|
{
|
||||||
|
/* Get CPU extended features */
|
||||||
|
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||||
|
CpuRegisters.Leaf = CPUID_GET_EXTENDED_FEATURES;
|
||||||
|
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||||
|
|
||||||
|
/* Store CPU extended features in processor control block */
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SVM) Prcb->CpuId.ExtendedFeatureBits |= KCF_SVM;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4A) Prcb->CpuId.ExtendedFeatureBits |= KCF_SSE4A;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_FMA4) Prcb->CpuId.ExtendedFeatureBits |= KCF_FMA4;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TOPOLOGY_EXTENSIONS) Prcb->CpuId.ExtendedFeatureBits |= KCF_TOPOEXT;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SYSCALL_SYSRET) Prcb->CpuId.ExtendedFeatureBits |= KCF_SYSCALL;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_NX) Prcb->CpuId.ExtendedFeatureBits |= KCF_NX_BIT;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_RDTSCP) Prcb->CpuId.ExtendedFeatureBits |= KCF_RDTSCP;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_LONG_MODE) Prcb->CpuId.ExtendedFeatureBits |= KCF_64BIT;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_3DNOW_EXT) Prcb->CpuId.ExtendedFeatureBits |= KCF_3DNOW_EXT;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_3DNOW) Prcb->CpuId.ExtendedFeatureBits |= KCF_3DNOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if CPU supports advanced power management leaf */
|
||||||
|
if(MaxExtendedLeaf >= CPUID_GET_ADVANCED_POWER_MANAGEMENT)
|
||||||
|
{
|
||||||
|
/* Get CPU advanced power management features */
|
||||||
|
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||||
|
CpuRegisters.Leaf = CPUID_GET_ADVANCED_POWER_MANAGEMENT;
|
||||||
|
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||||
|
|
||||||
|
/* Store CPU advanced power management features in processor control block */
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSCI) Prcb->CpuId.ExtendedFeatureBits |= KCF_INVARIANT_TSC;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -132,10 +132,131 @@ XTAPI
|
|||||||
VOID
|
VOID
|
||||||
AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
||||||
{
|
{
|
||||||
|
ULONG MaxExtendedLeaf, MaxStandardLeaf;
|
||||||
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
||||||
|
CPUID_REGISTERS CpuRegisters;
|
||||||
|
|
||||||
/* Get current processor control block */
|
/* Get current processor control block */
|
||||||
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
||||||
|
|
||||||
|
/* Get maximum CPUID standard leaf */
|
||||||
|
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||||
|
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
||||||
|
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||||
|
MaxStandardLeaf = CpuRegisters.Eax;
|
||||||
|
|
||||||
|
/* Get maximum CPUID extended leaf */
|
||||||
|
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||||
|
CpuRegisters.Leaf = CPUID_GET_EXTENDED_MAX;
|
||||||
|
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||||
|
MaxExtendedLeaf = CpuRegisters.Eax;
|
||||||
|
|
||||||
|
/* Check if CPU supports standard features leaf */
|
||||||
|
if(MaxStandardLeaf >= CPUID_GET_STANDARD1_FEATURES)
|
||||||
|
{
|
||||||
|
/* Get CPU standard features */
|
||||||
|
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||||
|
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||||
|
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||||
|
|
||||||
|
/* Store CPU standard features in processor control block */
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE3) Prcb->CpuId.FeatureBits |= KCF_SSE3;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_VMX) Prcb->CpuId.FeatureBits |= KCF_VMX;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSSE3) Prcb->CpuId.FeatureBits |= KCF_SSSE3;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4_1) Prcb->CpuId.FeatureBits |= KCF_SSE41;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4_2) Prcb->CpuId.FeatureBits |= KCF_SSE42;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_X2APIC) Prcb->CpuId.FeatureBits |= KCF_X2APIC;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_POPCNT) Prcb->CpuId.FeatureBits |= KCF_POPCNT;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TSC_DEADLINE) Prcb->CpuId.FeatureBits |= KCF_TSC_DEADLINE;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_AES) Prcb->CpuId.FeatureBits |= KCF_AES;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_XSAVE) Prcb->CpuId.FeatureBits |= KCF_XSAVE;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_AVX) Prcb->CpuId.FeatureBits |= KCF_AVX;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_RDRAND) Prcb->CpuId.FeatureBits |= KCF_RDRAND;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_VME) Prcb->CpuId.FeatureBits |= KCF_VME;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PSE) Prcb->CpuId.FeatureBits |= KCF_LARGE_PAGE;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSC) Prcb->CpuId.FeatureBits |= KCF_RDTSC;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PAE) Prcb->CpuId.FeatureBits |= KCF_PAE;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MCE) Prcb->CpuId.FeatureBits |= KCF_MCE;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CX8) Prcb->CpuId.FeatureBits |= KCF_CMPXCHG8B;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC) Prcb->CpuId.FeatureBits |= KCF_APIC;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SEP) Prcb->CpuId.FeatureBits |= KCF_FAST_SYSCALL;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MTRR) Prcb->CpuId.FeatureBits |= KCF_MTRR;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE) Prcb->CpuId.FeatureBits |= KCF_GLOBAL_PAGE;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MCA) Prcb->CpuId.FeatureBits |= KCF_MCA;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CMOV) Prcb->CpuId.FeatureBits |= KCF_CMOV;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PAT) Prcb->CpuId.FeatureBits |= KCF_PAT;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PSE36) Prcb->CpuId.FeatureBits |= KCF_PSE36;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CLFLUSH) Prcb->CpuId.FeatureBits |= KCF_CLFLUSH;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_FXSR) Prcb->CpuId.FeatureBits |= KCF_FXSR;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_ACPI) Prcb->CpuId.FeatureBits |= KCF_ACPI;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MMX) Prcb->CpuId.FeatureBits |= KCF_MMX;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SSE) Prcb->CpuId.FeatureBits |= KCF_SSE;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SSE2) Prcb->CpuId.FeatureBits |= KCF_SSE2;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_HTT) Prcb->CpuId.FeatureBits |= KCF_SMT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if CPU supports standard7 features leaf */
|
||||||
|
if(MaxStandardLeaf >= CPUID_GET_STANDARD7_FEATURES)
|
||||||
|
{
|
||||||
|
/* Get CPU standard features */
|
||||||
|
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||||
|
CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES;
|
||||||
|
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||||
|
|
||||||
|
/* Store CPU standard7 features in processor control block */
|
||||||
|
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_FSGSBASE) Prcb->CpuId.FeatureBits |= KCF_FSGSBASE;
|
||||||
|
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_AVX2) Prcb->CpuId.FeatureBits |= KCF_AVX2;
|
||||||
|
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SMEP) Prcb->CpuId.FeatureBits |= KCF_SMEP;
|
||||||
|
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_RDSEED) Prcb->CpuId.FeatureBits |= KCF_RDSEED;
|
||||||
|
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SMAP) Prcb->CpuId.FeatureBits |= KCF_SMAP;
|
||||||
|
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SHA) Prcb->CpuId.FeatureBits |= KCF_SHA;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) Prcb->CpuId.FeatureBits |= KCF_LA57;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if CPU supports power management leaf */
|
||||||
|
if(MaxStandardLeaf >= CPUID_GET_POWER_MANAGEMENT)
|
||||||
|
{
|
||||||
|
/* Get CPU power management features */
|
||||||
|
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||||
|
CpuRegisters.Leaf = CPUID_GET_POWER_MANAGEMENT;
|
||||||
|
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||||
|
|
||||||
|
/* Store CPU power management features in processor control block */
|
||||||
|
if(CpuRegisters.Eax & CPUID_FEATURES_EAX_ARAT) Prcb->CpuId.FeatureBits |= KCF_ARAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if CPU supports extended features leaf */
|
||||||
|
if(MaxExtendedLeaf >= CPUID_GET_EXTENDED_FEATURES)
|
||||||
|
{
|
||||||
|
/* Get CPU extended features */
|
||||||
|
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||||
|
CpuRegisters.Leaf = CPUID_GET_EXTENDED_FEATURES;
|
||||||
|
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||||
|
|
||||||
|
/* Store CPU extended features in processor control block */
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SVM) Prcb->CpuId.ExtendedFeatureBits |= KCF_SVM;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4A) Prcb->CpuId.ExtendedFeatureBits |= KCF_SSE4A;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_FMA4) Prcb->CpuId.ExtendedFeatureBits |= KCF_FMA4;
|
||||||
|
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TOPOLOGY_EXTENSIONS) Prcb->CpuId.ExtendedFeatureBits |= KCF_TOPOEXT;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SYSCALL_SYSRET) Prcb->CpuId.ExtendedFeatureBits |= KCF_SYSCALL;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_NX) Prcb->CpuId.ExtendedFeatureBits |= KCF_NX_BIT;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_RDTSCP) Prcb->CpuId.ExtendedFeatureBits |= KCF_RDTSCP;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_LONG_MODE) Prcb->CpuId.ExtendedFeatureBits |= KCF_64BIT;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_3DNOW_EXT) Prcb->CpuId.ExtendedFeatureBits |= KCF_3DNOW_EXT;
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_3DNOW) Prcb->CpuId.ExtendedFeatureBits |= KCF_3DNOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if CPU supports advanced power management leaf */
|
||||||
|
if(MaxExtendedLeaf >= CPUID_GET_ADVANCED_POWER_MANAGEMENT)
|
||||||
|
{
|
||||||
|
/* Get CPU advanced power management features */
|
||||||
|
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||||
|
CpuRegisters.Leaf = CPUID_GET_ADVANCED_POWER_MANAGEMENT;
|
||||||
|
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||||
|
|
||||||
|
/* Store CPU advanced power management features in processor control block */
|
||||||
|
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSCI) Prcb->CpuId.ExtendedFeatureBits |= KCF_INVARIANT_TSC;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user