diff --git a/sdk/xtdk/amd64/ketypes.h b/sdk/xtdk/amd64/ketypes.h index b2d4a37..e4eb649 100644 --- a/sdk/xtdk/amd64/ketypes.h +++ b/sdk/xtdk/amd64/ketypes.h @@ -69,6 +69,62 @@ #define AMD64_INTERRUPT_GATE 0xE #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 */ #define CONTEXT_ARCHITECTURE 0x00100000 #define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01) diff --git a/sdk/xtdk/i686/ketypes.h b/sdk/xtdk/i686/ketypes.h index 1c5b0b3..5a7fd47 100644 --- a/sdk/xtdk/i686/ketypes.h +++ b/sdk/xtdk/i686/ketypes.h @@ -90,6 +90,62 @@ #define I686_INTERRUPT_GATE 0xE #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 */ #define CONTEXT_ARCHITECTURE 0x00010000 #define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01) diff --git a/xtoskrnl/ar/amd64/procsup.cc b/xtoskrnl/ar/amd64/procsup.cc index cd22542..63ad4f4 100644 --- a/xtoskrnl/ar/amd64/procsup.cc +++ b/xtoskrnl/ar/amd64/procsup.cc @@ -139,10 +139,131 @@ XTAPI VOID AR::ProcSup::IdentifyProcessorFeatures(VOID) { + ULONG MaxExtendedLeaf, MaxStandardLeaf; PKPROCESSOR_CONTROL_BLOCK Prcb; + CPUID_REGISTERS CpuRegisters; /* Get current processor control block */ 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; + } } /** diff --git a/xtoskrnl/ar/i686/procsup.cc b/xtoskrnl/ar/i686/procsup.cc index 2f05926..bf049c0 100644 --- a/xtoskrnl/ar/i686/procsup.cc +++ b/xtoskrnl/ar/i686/procsup.cc @@ -132,10 +132,131 @@ XTAPI VOID AR::ProcSup::IdentifyProcessorFeatures(VOID) { + ULONG MaxExtendedLeaf, MaxStandardLeaf; PKPROCESSOR_CONTROL_BLOCK Prcb; + CPUID_REGISTERS CpuRegisters; /* Get current processor control block */ 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; + } } /**