/** @file | |
UEFI Application to display CPUID leaf information. | |
Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include <Uefi.h> | |
#include <Library/BaseLib.h> | |
#include <Library/UefiLib.h> | |
#include <Register/Intel/Cpuid.h> | |
/// | |
/// Macro used to display the value of a bit field in a register returned by CPUID. | |
/// | |
#define PRINT_BIT_FIELD(Variable, FieldName) \ | |
Print (L"%5a%42a: %x\n", #Variable, #FieldName, Variable.Bits.FieldName); | |
/// | |
/// Macro used to display the value of a register returned by CPUID. | |
/// | |
#define PRINT_VALUE(Variable, Description) \ | |
Print (L"%5a%42a: %x\n", #Variable, #Description, Variable); | |
/// | |
/// Structure for cache description lookup table | |
/// | |
typedef struct { | |
UINT8 CacheDescriptor; | |
CHAR8 *Type; | |
CHAR8 *Description; | |
} CPUID_CACHE_INFO_DESCRIPTION; | |
/// | |
/// Cache description lookup table | |
/// | |
CPUID_CACHE_INFO_DESCRIPTION mCpuidCacheInfoDescription[] = { | |
{ 0x00, "General", "Null descriptor, this byte contains no information" }, | |
{ 0x01, "TLB", "Instruction TLB: 4 KByte pages, 4-way set associative, 32 entries" }, | |
{ 0x02, "TLB", "Instruction TLB: 4 MByte pages, fully associative, 2 entries" }, | |
{ 0x03, "TLB", "Data TLB: 4 KByte pages, 4-way set associative, 64 entries" }, | |
{ 0x04, "TLB", "Data TLB: 4 MByte pages, 4-way set associative, 8 entries" }, | |
{ 0x05, "TLB", "Data TLB1: 4 MByte pages, 4-way set associative, 32 entries" }, | |
{ 0x06, "Cache", "1st-level instruction cache: 8 KBytes, 4-way set associative, 32 byte line size" }, | |
{ 0x08, "Cache", "1st-level instruction cache: 16 KBytes, 4-way set associative, 32 byte line size" }, | |
{ 0x09, "Cache", "1st-level instruction cache: 32KBytes, 4-way set associative, 64 byte line size" }, | |
{ 0x0A, "Cache", "1st-level data cache: 8 KBytes, 2-way set associative, 32 byte line size" }, | |
{ 0x0B, "TLB", "Instruction TLB: 4 MByte pages, 4-way set associative, 4 entries" }, | |
{ 0x0C, "Cache", "1st-level data cache: 16 KBytes, 4-way set associative, 32 byte line size" }, | |
{ 0x0D, "Cache", "1st-level data cache: 16 KBytes, 4-way set associative, 64 byte line size" }, | |
{ 0x0E, "Cache", "1st-level data cache: 24 KBytes, 6-way set associative, 64 byte line size" }, | |
{ 0x1D, "Cache", "2nd-level cache: 128 KBytes, 2-way set associative, 64 byte line size" }, | |
{ 0x21, "Cache", "2nd-level cache: 256 KBytes, 8-way set associative, 64 byte line size" }, | |
{ 0x22, "Cache", "3rd-level cache: 512 KBytes, 4-way set associative, 64 byte line size, 2 lines per sector" }, | |
{ 0x23, "Cache", "3rd-level cache: 1 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector" }, | |
{ 0x24, "Cache", "2nd-level cache: 1 MBytes, 16-way set associative, 64 byte line size" }, | |
{ 0x25, "Cache", "3rd-level cache: 2 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector" }, | |
{ 0x29, "Cache", "3rd-level cache: 4 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector" }, | |
{ 0x2C, "Cache", "1st-level data cache: 32 KBytes, 8-way set associative, 64 byte line size" }, | |
{ 0x30, "Cache", "1st-level instruction cache: 32 KBytes, 8-way set associative, 64 byte line size" }, | |
{ 0x40, "Cache", "No 2nd-level cache or, if processor contains a valid 2nd-level cache, no 3rd-level cache" }, | |
{ 0x41, "Cache", "2nd-level cache: 128 KBytes, 4-way set associative, 32 byte line size" }, | |
{ 0x42, "Cache", "2nd-level cache: 256 KBytes, 4-way set associative, 32 byte line size" }, | |
{ 0x43, "Cache", "2nd-level cache: 512 KBytes, 4-way set associative, 32 byte line size" }, | |
{ 0x44, "Cache", "2nd-level cache: 1 MByte, 4-way set associative, 32 byte line size" }, | |
{ 0x45, "Cache", "2nd-level cache: 2 MByte, 4-way set associative, 32 byte line size" }, | |
{ 0x46, "Cache", "3rd-level cache: 4 MByte, 4-way set associative, 64 byte line size" }, | |
{ 0x47, "Cache", "3rd-level cache: 8 MByte, 8-way set associative, 64 byte line size" }, | |
{ 0x48, "Cache", "2nd-level cache: 3MByte, 12-way set associative, 64 byte line size" }, | |
{ 0x49, "Cache", "3rd-level cache: 4MB, 16-way set associative, 64-byte line size (Intel Xeon processor MP, Family 0FH, Model 06H). 2nd-level cache: 4 MByte, 16-way set associative, 64 byte line size" }, | |
{ 0x4A, "Cache", "3rd-level cache: 6MByte, 12-way set associative, 64 byte line size" }, | |
{ 0x4B, "Cache", "3rd-level cache: 8MByte, 16-way set associative, 64 byte line size" }, | |
{ 0x4C, "Cache", "3rd-level cache: 12MByte, 12-way set associative, 64 byte line size" }, | |
{ 0x4D, "Cache", "3rd-level cache: 16MByte, 16-way set associative, 64 byte line size" }, | |
{ 0x4E, "Cache", "2nd-level cache: 6MByte, 24-way set associative, 64 byte line size" }, | |
{ 0x4F, "TLB", "Instruction TLB: 4 KByte pages, 32 entries" }, | |
{ 0x50, "TLB", "Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 64 entries" }, | |
{ 0x51, "TLB", "Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 128 entries" }, | |
{ 0x52, "TLB", "Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 256 entries" }, | |
{ 0x55, "TLB", "Instruction TLB: 2-MByte or 4-MByte pages, fully associative, 7 entries" }, | |
{ 0x56, "TLB", "Data TLB0: 4 MByte pages, 4-way set associative, 16 entries" }, | |
{ 0x57, "TLB", "Data TLB0: 4 KByte pages, 4-way associative, 16 entries" }, | |
{ 0x59, "TLB", "Data TLB0: 4 KByte pages, fully associative, 16 entries" }, | |
{ 0x5A, "TLB", "Data TLB0: 2 MByte or 4 MByte pages, 4-way set associative, 32 entries" }, | |
{ 0x5B, "TLB", "Data TLB: 4 KByte and 4 MByte pages, 64 entries" }, | |
{ 0x5C, "TLB", "Data TLB: 4 KByte and 4 MByte pages,128 entries" }, | |
{ 0x5D, "TLB", "Data TLB: 4 KByte and 4 MByte pages,256 entries" }, | |
{ 0x60, "Cache", "1st-level data cache: 16 KByte, 8-way set associative, 64 byte line size" }, | |
{ 0x61, "TLB", "Instruction TLB: 4 KByte pages, fully associative, 48 entries" }, | |
{ 0x63, "TLB", "Data TLB: 2 MByte or 4 MByte pages, 4-way set associative, 32 entries and a separate array with 1 GByte pages, 4-way set associative, 4 entries" }, | |
{ 0x64, "TLB", "Data TLB: 4 KByte pages, 4-way set associative, 512 entries" }, | |
{ 0x66, "Cache", "1st-level data cache: 8 KByte, 4-way set associative, 64 byte line size" }, | |
{ 0x67, "Cache", "1st-level data cache: 16 KByte, 4-way set associative, 64 byte line size" }, | |
{ 0x68, "Cache", "1st-level data cache: 32 KByte, 4-way set associative, 64 byte line size" }, | |
{ 0x6A, "Cache", "uTLB: 4 KByte pages, 8-way set associative, 64 entries" }, | |
{ 0x6B, "Cache", "DTLB: 4 KByte pages, 8-way set associative, 256 entries" }, | |
{ 0x6C, "Cache", "DTLB: 2M/4M pages, 8-way set associative, 128 entries" }, | |
{ 0x6D, "Cache", "DTLB: 1 GByte pages, fully associative, 16 entries" }, | |
{ 0x70, "Cache", "Trace cache: 12 K-uop, 8-way set associative" }, | |
{ 0x71, "Cache", "Trace cache: 16 K-uop, 8-way set associative" }, | |
{ 0x72, "Cache", "Trace cache: 32 K-uop, 8-way set associative" }, | |
{ 0x76, "TLB", "Instruction TLB: 2M/4M pages, fully associative, 8 entries" }, | |
{ 0x78, "Cache", "2nd-level cache: 1 MByte, 4-way set associative, 64byte line size" }, | |
{ 0x79, "Cache", "2nd-level cache: 128 KByte, 8-way set associative, 64 byte line size, 2 lines per sector" }, | |
{ 0x7A, "Cache", "2nd-level cache: 256 KByte, 8-way set associative, 64 byte line size, 2 lines per sector" }, | |
{ 0x7B, "Cache", "2nd-level cache: 512 KByte, 8-way set associative, 64 byte line size, 2 lines per sector" }, | |
{ 0x7C, "Cache", "2nd-level cache: 1 MByte, 8-way set associative, 64 byte line size, 2 lines per sector" }, | |
{ 0x7D, "Cache", "2nd-level cache: 2 MByte, 8-way set associative, 64byte line size" }, | |
{ 0x7F, "Cache", "2nd-level cache: 512 KByte, 2-way set associative, 64-byte line size" }, | |
{ 0x80, "Cache", "2nd-level cache: 512 KByte, 8-way set associative, 64-byte line size" }, | |
{ 0x82, "Cache", "2nd-level cache: 256 KByte, 8-way set associative, 32 byte line size" }, | |
{ 0x83, "Cache", "2nd-level cache: 512 KByte, 8-way set associative, 32 byte line size" }, | |
{ 0x84, "Cache", "2nd-level cache: 1 MByte, 8-way set associative, 32 byte line size" }, | |
{ 0x85, "Cache", "2nd-level cache: 2 MByte, 8-way set associative, 32 byte line size" }, | |
{ 0x86, "Cache", "2nd-level cache: 512 KByte, 4-way set associative, 64 byte line size" }, | |
{ 0x87, "Cache", "2nd-level cache: 1 MByte, 8-way set associative, 64 byte line size" }, | |
{ 0xA0, "DTLB", "DTLB: 4k pages, fully associative, 32 entries" }, | |
{ 0xB0, "TLB", "Instruction TLB: 4 KByte pages, 4-way set associative, 128 entries" }, | |
{ 0xB1, "TLB", "Instruction TLB: 2M pages, 4-way, 8 entries or 4M pages, 4-way, 4 entries" }, | |
{ 0xB2, "TLB", "Instruction TLB: 4KByte pages, 4-way set associative, 64 entries" }, | |
{ 0xB3, "TLB", "Data TLB: 4 KByte pages, 4-way set associative, 128 entries" }, | |
{ 0xB4, "TLB", "Data TLB1: 4 KByte pages, 4-way associative, 256 entries" }, | |
{ 0xB5, "TLB", "Instruction TLB: 4KByte pages, 8-way set associative, 64 entries" }, | |
{ 0xB6, "TLB", "Instruction TLB: 4KByte pages, 8-way set associative, 128 entries" }, | |
{ 0xBA, "TLB", "Data TLB1: 4 KByte pages, 4-way associative, 64 entries" }, | |
{ 0xC0, "TLB", "Data TLB: 4 KByte and 4 MByte pages, 4-way associative, 8 entries" }, | |
{ 0xC1, "STLB", "Shared 2nd-Level TLB: 4 KByte/2MByte pages, 8-way associative, 1024 entries" }, | |
{ 0xC2, "DTLB", "DTLB: 4 KByte/2 MByte pages, 4-way associative, 16 entries" }, | |
{ 0xC3, "STLB", "Shared 2nd-Level TLB: 4 KByte /2 MByte pages, 6-way associative, 1536 entries. Also 1GBbyte pages, 4-way, 16 entries." }, | |
{ 0xC4, "DTLB", "DTLB: 2M/4M Byte pages, 4-way associative, 32 entries" }, | |
{ 0xCA, "STLB", "Shared 2nd-Level TLB: 4 KByte pages, 4-way associative, 512 entries" }, | |
{ 0xD0, "Cache", "3rd-level cache: 512 KByte, 4-way set associative, 64 byte line size" }, | |
{ 0xD1, "Cache", "3rd-level cache: 1 MByte, 4-way set associative, 64 byte line size" }, | |
{ 0xD2, "Cache", "3rd-level cache: 2 MByte, 4-way set associative, 64 byte line size" }, | |
{ 0xD6, "Cache", "3rd-level cache: 1 MByte, 8-way set associative, 64 byte line size" }, | |
{ 0xD7, "Cache", "3rd-level cache: 2 MByte, 8-way set associative, 64 byte line size" }, | |
{ 0xD8, "Cache", "3rd-level cache: 4 MByte, 8-way set associative, 64 byte line size" }, | |
{ 0xDC, "Cache", "3rd-level cache: 1.5 MByte, 12-way set associative, 64 byte line size" }, | |
{ 0xDD, "Cache", "3rd-level cache: 3 MByte, 12-way set associative, 64 byte line size" }, | |
{ 0xDE, "Cache", "3rd-level cache: 6 MByte, 12-way set associative, 64 byte line size" }, | |
{ 0xE2, "Cache", "3rd-level cache: 2 MByte, 16-way set associative, 64 byte line size" }, | |
{ 0xE3, "Cache", "3rd-level cache: 4 MByte, 16-way set associative, 64 byte line size" }, | |
{ 0xE4, "Cache", "3rd-level cache: 8 MByte, 16-way set associative, 64 byte line size" }, | |
{ 0xEA, "Cache", "3rd-level cache: 12MByte, 24-way set associative, 64 byte line size" }, | |
{ 0xEB, "Cache", "3rd-level cache: 18MByte, 24-way set associative, 64 byte line size" }, | |
{ 0xEC, "Cache", "3rd-level cache: 24MByte, 24-way set associative, 64 byte line size" }, | |
{ 0xF0, "Prefetch", "64-Byte prefetching" }, | |
{ 0xF1, "Prefetch", "128-Byte prefetching" }, | |
{ 0xFE, "General", "CPUID leaf 2 does not report TLB descriptor information; use CPUID leaf 18H to query TLB and other address translation parameters." }, | |
{ 0xFF, "General", "CPUID leaf 2 does not report cache descriptor information, use CPUID leaf 4 to query cache parameters" } | |
}; | |
/// | |
/// The maximum supported CPUID leaf index starting from leaf 0x00000000. | |
/// | |
UINT32 gMaximumBasicFunction = CPUID_SIGNATURE; | |
/// | |
/// The maximum supported CPUID leaf index starting from leaf 0x80000000. | |
/// | |
UINT32 gMaximumExtendedFunction = CPUID_EXTENDED_FUNCTION; | |
/** | |
Display CPUID_SIGNATURE leaf. | |
**/ | |
VOID | |
CpuidSignature ( | |
VOID | |
) | |
{ | |
UINT32 Eax; | |
UINT32 Ebx; | |
UINT32 Ecx; | |
UINT32 Edx; | |
CHAR8 Signature[13]; | |
AsmCpuid (CPUID_SIGNATURE, &Eax, &Ebx, &Ecx, &Edx); | |
Print (L"CPUID_SIGNATURE (Leaf %08x)\n", CPUID_SIGNATURE); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx, Ecx, Edx); | |
PRINT_VALUE (Eax, MaximumLeaf); | |
*(UINT32 *)(Signature + 0) = Ebx; | |
*(UINT32 *)(Signature + 4) = Edx; | |
*(UINT32 *)(Signature + 8) = Ecx; | |
Signature[12] = 0; | |
Print (L" Signature = %a\n", Signature); | |
gMaximumBasicFunction = Eax; | |
} | |
/** | |
Display CPUID_VERSION_INFO leaf. | |
**/ | |
VOID | |
CpuidVersionInfo ( | |
VOID | |
) | |
{ | |
CPUID_VERSION_INFO_EAX Eax; | |
CPUID_VERSION_INFO_EBX Ebx; | |
CPUID_VERSION_INFO_ECX Ecx; | |
CPUID_VERSION_INFO_EDX Edx; | |
UINT32 DisplayFamily; | |
UINT32 DisplayModel; | |
if (CPUID_VERSION_INFO > gMaximumBasicFunction) { | |
return; | |
} | |
AsmCpuid (CPUID_VERSION_INFO, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); | |
Print (L"CPUID_VERSION_INFO (Leaf %08x)\n", CPUID_VERSION_INFO); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); | |
DisplayFamily = Eax.Bits.FamilyId; | |
if (Eax.Bits.FamilyId == 0x0F) { | |
DisplayFamily += Eax.Bits.ExtendedFamilyId; | |
} | |
DisplayModel = Eax.Bits.Model; | |
if ((Eax.Bits.FamilyId == 0x06) || (Eax.Bits.FamilyId == 0x0f)) { | |
DisplayModel += (Eax.Bits.ExtendedModelId << 4); | |
} | |
Print (L" Family = %x Model = %x Stepping = %x\n", DisplayFamily, DisplayModel, Eax.Bits.SteppingId); | |
PRINT_BIT_FIELD (Eax, SteppingId); | |
PRINT_BIT_FIELD (Eax, Model); | |
PRINT_BIT_FIELD (Eax, FamilyId); | |
PRINT_BIT_FIELD (Eax, ProcessorType); | |
PRINT_BIT_FIELD (Eax, ExtendedModelId); | |
PRINT_BIT_FIELD (Eax, ExtendedFamilyId); | |
PRINT_BIT_FIELD (Ebx, BrandIndex); | |
PRINT_BIT_FIELD (Ebx, CacheLineSize); | |
PRINT_BIT_FIELD (Ebx, MaximumAddressableIdsForLogicalProcessors); | |
PRINT_BIT_FIELD (Ebx, InitialLocalApicId); | |
PRINT_BIT_FIELD (Ecx, SSE3); | |
PRINT_BIT_FIELD (Ecx, PCLMULQDQ); | |
PRINT_BIT_FIELD (Ecx, DTES64); | |
PRINT_BIT_FIELD (Ecx, MONITOR); | |
PRINT_BIT_FIELD (Ecx, DS_CPL); | |
PRINT_BIT_FIELD (Ecx, VMX); | |
PRINT_BIT_FIELD (Ecx, SMX); | |
PRINT_BIT_FIELD (Ecx, TM2); | |
PRINT_BIT_FIELD (Ecx, SSSE3); | |
PRINT_BIT_FIELD (Ecx, CNXT_ID); | |
PRINT_BIT_FIELD (Ecx, SDBG); | |
PRINT_BIT_FIELD (Ecx, FMA); | |
PRINT_BIT_FIELD (Ecx, CMPXCHG16B); | |
PRINT_BIT_FIELD (Ecx, xTPR_Update_Control); | |
PRINT_BIT_FIELD (Ecx, PDCM); | |
PRINT_BIT_FIELD (Ecx, PCID); | |
PRINT_BIT_FIELD (Ecx, DCA); | |
PRINT_BIT_FIELD (Ecx, SSE4_1); | |
PRINT_BIT_FIELD (Ecx, SSE4_2); | |
PRINT_BIT_FIELD (Ecx, x2APIC); | |
PRINT_BIT_FIELD (Ecx, MOVBE); | |
PRINT_BIT_FIELD (Ecx, POPCNT); | |
PRINT_BIT_FIELD (Ecx, TSC_Deadline); | |
PRINT_BIT_FIELD (Ecx, AESNI); | |
PRINT_BIT_FIELD (Ecx, XSAVE); | |
PRINT_BIT_FIELD (Ecx, OSXSAVE); | |
PRINT_BIT_FIELD (Ecx, AVX); | |
PRINT_BIT_FIELD (Ecx, F16C); | |
PRINT_BIT_FIELD (Ecx, RDRAND); | |
PRINT_BIT_FIELD (Edx, FPU); | |
PRINT_BIT_FIELD (Edx, VME); | |
PRINT_BIT_FIELD (Edx, DE); | |
PRINT_BIT_FIELD (Edx, PSE); | |
PRINT_BIT_FIELD (Edx, TSC); | |
PRINT_BIT_FIELD (Edx, MSR); | |
PRINT_BIT_FIELD (Edx, PAE); | |
PRINT_BIT_FIELD (Edx, MCE); | |
PRINT_BIT_FIELD (Edx, CX8); | |
PRINT_BIT_FIELD (Edx, APIC); | |
PRINT_BIT_FIELD (Edx, SEP); | |
PRINT_BIT_FIELD (Edx, MTRR); | |
PRINT_BIT_FIELD (Edx, PGE); | |
PRINT_BIT_FIELD (Edx, MCA); | |
PRINT_BIT_FIELD (Edx, CMOV); | |
PRINT_BIT_FIELD (Edx, PAT); | |
PRINT_BIT_FIELD (Edx, PSE_36); | |
PRINT_BIT_FIELD (Edx, PSN); | |
PRINT_BIT_FIELD (Edx, CLFSH); | |
PRINT_BIT_FIELD (Edx, DS); | |
PRINT_BIT_FIELD (Edx, ACPI); | |
PRINT_BIT_FIELD (Edx, MMX); | |
PRINT_BIT_FIELD (Edx, FXSR); | |
PRINT_BIT_FIELD (Edx, SSE); | |
PRINT_BIT_FIELD (Edx, SSE2); | |
PRINT_BIT_FIELD (Edx, SS); | |
PRINT_BIT_FIELD (Edx, HTT); | |
PRINT_BIT_FIELD (Edx, TM); | |
PRINT_BIT_FIELD (Edx, PBE); | |
} | |
/** | |
Lookup a cache description string from the mCpuidCacheInfoDescription table. | |
@param[in] CacheDescriptor Cache descriptor value from CPUID_CACHE_INFO. | |
**/ | |
CPUID_CACHE_INFO_DESCRIPTION * | |
LookupCacheDescription ( | |
UINT8 CacheDescriptor | |
) | |
{ | |
UINTN NumDescriptors; | |
UINTN Descriptor; | |
if (CacheDescriptor == 0x00) { | |
return NULL; | |
} | |
NumDescriptors = sizeof (mCpuidCacheInfoDescription)/sizeof (mCpuidCacheInfoDescription[0]); | |
for (Descriptor = 0; Descriptor < NumDescriptors; Descriptor++) { | |
if (CacheDescriptor == mCpuidCacheInfoDescription[Descriptor].CacheDescriptor) { | |
return &mCpuidCacheInfoDescription[Descriptor]; | |
} | |
} | |
return NULL; | |
} | |
/** | |
Display CPUID_CACHE_INFO leaf for each supported cache descriptor. | |
**/ | |
VOID | |
CpuidCacheInfo ( | |
VOID | |
) | |
{ | |
CPUID_CACHE_INFO_CACHE_TLB Eax; | |
CPUID_CACHE_INFO_CACHE_TLB Ebx; | |
CPUID_CACHE_INFO_CACHE_TLB Ecx; | |
CPUID_CACHE_INFO_CACHE_TLB Edx; | |
UINTN Index; | |
CPUID_CACHE_INFO_DESCRIPTION *CacheDescription; | |
if (CPUID_CACHE_INFO > gMaximumBasicFunction) { | |
return; | |
} | |
AsmCpuid (CPUID_CACHE_INFO, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); | |
Print (L"CPUID_CACHE_INFO (Leaf %08x)\n", CPUID_CACHE_INFO); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); | |
if (Eax.Bits.NotValid == 0) { | |
// | |
// Process Eax.CacheDescriptor[1..3]. Ignore Eax.CacheDescriptor[0] | |
// | |
for (Index = 1; Index < 4; Index++) { | |
CacheDescription = LookupCacheDescription (Eax.CacheDescriptor[Index]); | |
if (CacheDescription != NULL) { | |
Print ( | |
L" %-8a %a\n", | |
CacheDescription->Type, | |
CacheDescription->Description | |
); | |
} | |
} | |
} | |
if (Ebx.Bits.NotValid == 0) { | |
// | |
// Process Ebx.CacheDescriptor[0..3] | |
// | |
for (Index = 0; Index < 4; Index++) { | |
CacheDescription = LookupCacheDescription (Ebx.CacheDescriptor[Index]); | |
if (CacheDescription != NULL) { | |
Print ( | |
L" %-8a %a\n", | |
CacheDescription->Type, | |
CacheDescription->Description | |
); | |
} | |
} | |
} | |
if (Ecx.Bits.NotValid == 0) { | |
// | |
// Process Ecx.CacheDescriptor[0..3] | |
// | |
for (Index = 0; Index < 4; Index++) { | |
CacheDescription = LookupCacheDescription (Ecx.CacheDescriptor[Index]); | |
if (CacheDescription != NULL) { | |
Print ( | |
L" %-8a %a\n", | |
CacheDescription->Type, | |
CacheDescription->Description | |
); | |
} | |
} | |
} | |
if (Edx.Bits.NotValid == 0) { | |
// | |
// Process Edx.CacheDescriptor[0..3] | |
// | |
for (Index = 0; Index < 4; Index++) { | |
CacheDescription = LookupCacheDescription (Edx.CacheDescriptor[Index]); | |
if (CacheDescription != NULL) { | |
Print ( | |
L" %-8a %a\n", | |
CacheDescription->Type, | |
CacheDescription->Description | |
); | |
} | |
} | |
} | |
} | |
/** | |
Display CPUID_SERIAL_NUMBER leaf if it is supported. | |
**/ | |
VOID | |
CpuidSerialNumber ( | |
VOID | |
) | |
{ | |
CPUID_VERSION_INFO_EDX VersionInfoEdx; | |
UINT32 Ecx; | |
UINT32 Edx; | |
Print (L"CPUID_SERIAL_NUMBER (Leaf %08x)\n", CPUID_SERIAL_NUMBER); | |
if (CPUID_SERIAL_NUMBER > gMaximumBasicFunction) { | |
return; | |
} | |
AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32); | |
if (VersionInfoEdx.Bits.PSN == 0) { | |
Print (L" Not Supported\n"); | |
return; | |
} | |
AsmCpuid (CPUID_SERIAL_NUMBER, NULL, NULL, &Ecx, &Edx); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, 0, Ecx, Edx); | |
Print (L" Processor Serial Number = %08x%08x%08x\n", 0, Edx, Ecx); | |
} | |
/** | |
Display CPUID_CACHE_PARAMS for all supported sub-leafs. | |
**/ | |
VOID | |
CpuidCacheParams ( | |
VOID | |
) | |
{ | |
UINT32 CacheLevel; | |
CPUID_CACHE_PARAMS_EAX Eax; | |
CPUID_CACHE_PARAMS_EBX Ebx; | |
UINT32 Ecx; | |
CPUID_CACHE_PARAMS_EDX Edx; | |
if (CPUID_CACHE_PARAMS > gMaximumBasicFunction) { | |
return; | |
} | |
CacheLevel = 0; | |
do { | |
AsmCpuidEx ( | |
CPUID_CACHE_PARAMS, | |
CacheLevel, | |
&Eax.Uint32, | |
&Ebx.Uint32, | |
&Ecx, | |
&Edx.Uint32 | |
); | |
if (Eax.Bits.CacheType != CPUID_CACHE_PARAMS_CACHE_TYPE_NULL) { | |
Print (L"CPUID_CACHE_PARAMS (Leaf %08x, Sub-Leaf %08x)\n", CPUID_CACHE_PARAMS, CacheLevel); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx, Edx.Uint32); | |
PRINT_BIT_FIELD (Eax, CacheType); | |
PRINT_BIT_FIELD (Eax, CacheLevel); | |
PRINT_BIT_FIELD (Eax, SelfInitializingCache); | |
PRINT_BIT_FIELD (Eax, FullyAssociativeCache); | |
PRINT_BIT_FIELD (Eax, MaximumAddressableIdsForLogicalProcessors); | |
PRINT_BIT_FIELD (Eax, MaximumAddressableIdsForProcessorCores); | |
PRINT_BIT_FIELD (Ebx, LineSize); | |
PRINT_BIT_FIELD (Ebx, LinePartitions); | |
PRINT_BIT_FIELD (Ebx, Ways); | |
PRINT_VALUE (Ecx, NumberOfSets); | |
PRINT_BIT_FIELD (Edx, Invalidate); | |
PRINT_BIT_FIELD (Edx, CacheInclusiveness); | |
PRINT_BIT_FIELD (Edx, ComplexCacheIndexing); | |
} | |
CacheLevel++; | |
} while (Eax.Bits.CacheType != CPUID_CACHE_PARAMS_CACHE_TYPE_NULL); | |
} | |
/** | |
Display CPUID_MONITOR_MWAIT leaf. | |
**/ | |
VOID | |
CpuidMonitorMwait ( | |
VOID | |
) | |
{ | |
CPUID_MONITOR_MWAIT_EAX Eax; | |
CPUID_MONITOR_MWAIT_EBX Ebx; | |
CPUID_MONITOR_MWAIT_ECX Ecx; | |
CPUID_MONITOR_MWAIT_EDX Edx; | |
if (CPUID_MONITOR_MWAIT > gMaximumBasicFunction) { | |
return; | |
} | |
AsmCpuid (CPUID_MONITOR_MWAIT, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); | |
Print (L"CPUID_MONITOR_MWAIT (Leaf %08x)\n", CPUID_MONITOR_MWAIT); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); | |
PRINT_BIT_FIELD (Eax, SmallestMonitorLineSize); | |
PRINT_BIT_FIELD (Ebx, LargestMonitorLineSize); | |
PRINT_BIT_FIELD (Ecx, ExtensionsSupported); | |
PRINT_BIT_FIELD (Ecx, InterruptAsBreak); | |
PRINT_BIT_FIELD (Edx, C0States); | |
PRINT_BIT_FIELD (Edx, C1States); | |
PRINT_BIT_FIELD (Edx, C2States); | |
PRINT_BIT_FIELD (Edx, C3States); | |
PRINT_BIT_FIELD (Edx, C4States); | |
PRINT_BIT_FIELD (Edx, C5States); | |
PRINT_BIT_FIELD (Edx, C6States); | |
PRINT_BIT_FIELD (Edx, C7States); | |
} | |
/** | |
Display CPUID_THERMAL_POWER_MANAGEMENT leaf. | |
**/ | |
VOID | |
CpuidThermalPowerManagement ( | |
VOID | |
) | |
{ | |
CPUID_THERMAL_POWER_MANAGEMENT_EAX Eax; | |
CPUID_THERMAL_POWER_MANAGEMENT_EBX Ebx; | |
CPUID_THERMAL_POWER_MANAGEMENT_ECX Ecx; | |
if (CPUID_THERMAL_POWER_MANAGEMENT > gMaximumBasicFunction) { | |
return; | |
} | |
AsmCpuid (CPUID_THERMAL_POWER_MANAGEMENT, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, NULL); | |
Print (L"CPUID_THERMAL_POWER_MANAGEMENT (Leaf %08x)\n", CPUID_THERMAL_POWER_MANAGEMENT); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, 0); | |
PRINT_BIT_FIELD (Eax, DigitalTemperatureSensor); | |
PRINT_BIT_FIELD (Eax, TurboBoostTechnology); | |
PRINT_BIT_FIELD (Eax, ARAT); | |
PRINT_BIT_FIELD (Eax, PLN); | |
PRINT_BIT_FIELD (Eax, ECMD); | |
PRINT_BIT_FIELD (Eax, PTM); | |
PRINT_BIT_FIELD (Eax, HWP); | |
PRINT_BIT_FIELD (Eax, HWP_Notification); | |
PRINT_BIT_FIELD (Eax, HWP_Activity_Window); | |
PRINT_BIT_FIELD (Eax, HWP_Energy_Performance_Preference); | |
PRINT_BIT_FIELD (Eax, HWP_Package_Level_Request); | |
PRINT_BIT_FIELD (Eax, HDC); | |
PRINT_BIT_FIELD (Eax, TurboBoostMaxTechnology30); | |
PRINT_BIT_FIELD (Eax, HWPCapabilities); | |
PRINT_BIT_FIELD (Eax, HWPPECIOverride); | |
PRINT_BIT_FIELD (Eax, FlexibleHWP); | |
PRINT_BIT_FIELD (Eax, FastAccessMode); | |
PRINT_BIT_FIELD (Eax, IgnoringIdleLogicalProcessorHWPRequest); | |
PRINT_BIT_FIELD (Ebx, InterruptThresholds); | |
PRINT_BIT_FIELD (Ecx, HardwareCoordinationFeedback); | |
PRINT_BIT_FIELD (Ecx, PerformanceEnergyBias); | |
} | |
/** | |
Display CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS for all supported sub-leafs. | |
**/ | |
VOID | |
CpuidStructuredExtendedFeatureFlags ( | |
VOID | |
) | |
{ | |
UINT32 Eax; | |
CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_EBX Ebx; | |
CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX Ecx; | |
CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_EDX Edx; | |
UINT32 SubLeaf; | |
if (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS > gMaximumBasicFunction) { | |
return; | |
} | |
AsmCpuidEx ( | |
CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, | |
CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, | |
&Eax, | |
NULL, | |
NULL, | |
NULL | |
); | |
for (SubLeaf = 0; SubLeaf <= Eax; SubLeaf++) { | |
AsmCpuidEx ( | |
CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, | |
SubLeaf, | |
NULL, | |
&Ebx.Uint32, | |
&Ecx.Uint32, | |
&Edx.Uint32 | |
); | |
if ((Ebx.Uint32 != 0) || (Ecx.Uint32 != 0) || (Edx.Uint32 != 0)) { | |
Print (L"CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS (Leaf %08x, Sub-Leaf %08x)\n", CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, SubLeaf); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); | |
PRINT_BIT_FIELD (Ebx, FSGSBASE); | |
PRINT_BIT_FIELD (Ebx, IA32_TSC_ADJUST); | |
PRINT_BIT_FIELD (Ebx, SGX); | |
PRINT_BIT_FIELD (Ebx, BMI1); | |
PRINT_BIT_FIELD (Ebx, HLE); | |
PRINT_BIT_FIELD (Ebx, AVX2); | |
PRINT_BIT_FIELD (Ebx, FDP_EXCPTN_ONLY); | |
PRINT_BIT_FIELD (Ebx, SMEP); | |
PRINT_BIT_FIELD (Ebx, BMI2); | |
PRINT_BIT_FIELD (Ebx, EnhancedRepMovsbStosb); | |
PRINT_BIT_FIELD (Ebx, INVPCID); | |
PRINT_BIT_FIELD (Ebx, RTM); | |
PRINT_BIT_FIELD (Ebx, RDT_M); | |
PRINT_BIT_FIELD (Ebx, DeprecateFpuCsDs); | |
PRINT_BIT_FIELD (Ebx, MPX); | |
PRINT_BIT_FIELD (Ebx, RDT_A); | |
PRINT_BIT_FIELD (Ebx, AVX512F); | |
PRINT_BIT_FIELD (Ebx, AVX512DQ); | |
PRINT_BIT_FIELD (Ebx, RDSEED); | |
PRINT_BIT_FIELD (Ebx, ADX); | |
PRINT_BIT_FIELD (Ebx, SMAP); | |
PRINT_BIT_FIELD (Ebx, AVX512_IFMA); | |
PRINT_BIT_FIELD (Ebx, CLFLUSHOPT); | |
PRINT_BIT_FIELD (Ebx, CLWB); | |
PRINT_BIT_FIELD (Ebx, IntelProcessorTrace); | |
PRINT_BIT_FIELD (Ebx, AVX512PF); | |
PRINT_BIT_FIELD (Ebx, AVX512ER); | |
PRINT_BIT_FIELD (Ebx, AVX512CD); | |
PRINT_BIT_FIELD (Ebx, SHA); | |
PRINT_BIT_FIELD (Ebx, AVX512BW); | |
PRINT_BIT_FIELD (Ebx, AVX512VL); | |
PRINT_BIT_FIELD (Ecx, PREFETCHWT1); | |
PRINT_BIT_FIELD (Ecx, AVX512_VBMI); | |
PRINT_BIT_FIELD (Ecx, UMIP); | |
PRINT_BIT_FIELD (Ecx, PKU); | |
PRINT_BIT_FIELD (Ecx, OSPKE); | |
PRINT_BIT_FIELD (Ecx, AVX512_VPOPCNTDQ); | |
PRINT_BIT_FIELD (Ecx, MAWAU); | |
PRINT_BIT_FIELD (Ecx, RDPID); | |
PRINT_BIT_FIELD (Ecx, SGX_LC); | |
PRINT_BIT_FIELD (Edx, AVX512_4VNNIW); | |
PRINT_BIT_FIELD (Edx, AVX512_4FMAPS); | |
PRINT_BIT_FIELD (Edx, EnumeratesSupportForIBRSAndIBPB); | |
PRINT_BIT_FIELD (Edx, EnumeratesSupportForSTIBP); | |
PRINT_BIT_FIELD (Edx, EnumeratesSupportForL1D_FLUSH); | |
PRINT_BIT_FIELD (Edx, EnumeratesSupportForCapability); | |
PRINT_BIT_FIELD (Edx, EnumeratesSupportForSSBD); | |
} | |
} | |
} | |
/** | |
Display CPUID_DIRECT_CACHE_ACCESS_INFO leaf. | |
**/ | |
VOID | |
CpuidDirectCacheAccessInfo ( | |
VOID | |
) | |
{ | |
UINT32 Eax; | |
if (CPUID_DIRECT_CACHE_ACCESS_INFO > gMaximumBasicFunction) { | |
return; | |
} | |
AsmCpuid (CPUID_DIRECT_CACHE_ACCESS_INFO, &Eax, NULL, NULL, NULL); | |
Print (L"CPUID_DIRECT_CACHE_ACCESS_INFO (Leaf %08x)\n", CPUID_DIRECT_CACHE_ACCESS_INFO); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, 0, 0, 0); | |
} | |
/** | |
Display CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING leaf. | |
**/ | |
VOID | |
CpuidArchitecturalPerformanceMonitoring ( | |
VOID | |
) | |
{ | |
CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EAX Eax; | |
CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EBX Ebx; | |
CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EDX Edx; | |
if (CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING > gMaximumBasicFunction) { | |
return; | |
} | |
AsmCpuid (CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING, &Eax.Uint32, &Ebx.Uint32, NULL, &Edx.Uint32); | |
Print (L"CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING (Leaf %08x)\n", CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, 0, Edx.Uint32); | |
PRINT_BIT_FIELD (Eax, ArchPerfMonVerID); | |
PRINT_BIT_FIELD (Eax, PerformanceMonitorCounters); | |
PRINT_BIT_FIELD (Eax, PerformanceMonitorCounterWidth); | |
PRINT_BIT_FIELD (Eax, EbxBitVectorLength); | |
PRINT_BIT_FIELD (Ebx, UnhaltedCoreCycles); | |
PRINT_BIT_FIELD (Ebx, InstructionsRetired); | |
PRINT_BIT_FIELD (Ebx, UnhaltedReferenceCycles); | |
PRINT_BIT_FIELD (Ebx, LastLevelCacheReferences); | |
PRINT_BIT_FIELD (Ebx, LastLevelCacheMisses); | |
PRINT_BIT_FIELD (Ebx, BranchInstructionsRetired); | |
PRINT_BIT_FIELD (Ebx, AllBranchMispredictRetired); | |
PRINT_BIT_FIELD (Edx, FixedFunctionPerformanceCounters); | |
PRINT_BIT_FIELD (Edx, FixedFunctionPerformanceCounterWidth); | |
PRINT_BIT_FIELD (Edx, AnyThreadDeprecation); | |
} | |
/** | |
Display CPUID_EXTENDED_TOPOLOGY leafs for all supported levels. | |
@param[in] LeafFunction Leaf function index for CPUID_EXTENDED_TOPOLOGY. | |
**/ | |
VOID | |
CpuidExtendedTopology ( | |
UINT32 LeafFunction | |
) | |
{ | |
CPUID_EXTENDED_TOPOLOGY_EAX Eax; | |
CPUID_EXTENDED_TOPOLOGY_EBX Ebx; | |
CPUID_EXTENDED_TOPOLOGY_ECX Ecx; | |
UINT32 Edx; | |
UINT32 LevelNumber; | |
if (LeafFunction > gMaximumBasicFunction) { | |
return; | |
} | |
if ((LeafFunction != CPUID_EXTENDED_TOPOLOGY) && (LeafFunction != CPUID_V2_EXTENDED_TOPOLOGY)) { | |
return; | |
} | |
LevelNumber = 0; | |
for (LevelNumber = 0; ; LevelNumber++) { | |
AsmCpuidEx ( | |
LeafFunction, | |
LevelNumber, | |
&Eax.Uint32, | |
&Ebx.Uint32, | |
&Ecx.Uint32, | |
&Edx | |
); | |
if (Ecx.Bits.LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID) { | |
break; | |
} | |
Print ( | |
L"%a (Leaf %08x, Sub-Leaf %08x)\n", | |
LeafFunction == CPUID_EXTENDED_TOPOLOGY ? "CPUID_EXTENDED_TOPOLOGY" : "CPUID_V2_EXTENDED_TOPOLOGY", | |
LeafFunction, | |
LevelNumber | |
); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx); | |
PRINT_BIT_FIELD (Eax, ApicIdShift); | |
PRINT_BIT_FIELD (Ebx, LogicalProcessors); | |
PRINT_BIT_FIELD (Ecx, LevelNumber); | |
PRINT_BIT_FIELD (Ecx, LevelType); | |
PRINT_VALUE (Edx, x2APIC_ID); | |
} | |
} | |
/** | |
Display CPUID_EXTENDED_STATE sub-leaf. | |
**/ | |
VOID | |
CpuidExtendedStateSubLeaf ( | |
VOID | |
) | |
{ | |
CPUID_EXTENDED_STATE_SUB_LEAF_EAX Eax; | |
UINT32 Ebx; | |
CPUID_EXTENDED_STATE_SUB_LEAF_ECX Ecx; | |
UINT32 Edx; | |
AsmCpuidEx ( | |
CPUID_EXTENDED_STATE, | |
CPUID_EXTENDED_STATE_SUB_LEAF, | |
&Eax.Uint32, | |
&Ebx, | |
&Ecx.Uint32, | |
&Edx | |
); | |
Print (L"CPUID_EXTENDED_STATE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_SUB_LEAF); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx.Uint32, Edx); | |
PRINT_BIT_FIELD (Eax, XSAVEOPT); | |
PRINT_BIT_FIELD (Eax, XSAVEC); | |
PRINT_BIT_FIELD (Eax, XGETBV); | |
PRINT_BIT_FIELD (Eax, XSAVES); | |
PRINT_VALUE (Ebx, EnabledSaveStateSize_XCR0_IA32_XSS); | |
PRINT_BIT_FIELD (Ecx, XCR0); | |
PRINT_BIT_FIELD (Ecx, HWPState); | |
PRINT_BIT_FIELD (Ecx, PT); | |
PRINT_BIT_FIELD (Ecx, XCR0_1); | |
PRINT_VALUE (Edx, IA32_XSS_Supported_32_63); | |
} | |
/** | |
Display CPUID_EXTENDED_STATE size and offset information sub-leaf. | |
**/ | |
VOID | |
CpuidExtendedStateSizeOffset ( | |
VOID | |
) | |
{ | |
UINT32 Eax; | |
UINT32 Ebx; | |
CPUID_EXTENDED_STATE_SIZE_OFFSET_ECX Ecx; | |
UINT32 Edx; | |
UINT32 SubLeaf; | |
for (SubLeaf = CPUID_EXTENDED_STATE_SIZE_OFFSET; SubLeaf < 32; SubLeaf++) { | |
AsmCpuidEx ( | |
CPUID_EXTENDED_STATE, | |
SubLeaf, | |
&Eax, | |
&Ebx, | |
&Ecx.Uint32, | |
&Edx | |
); | |
if (Edx != 0) { | |
Print (L"CPUID_EXTENDED_STATE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_STATE, SubLeaf); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx, Ecx.Uint32, Edx); | |
PRINT_VALUE (Eax, FeatureSaveStateSize); | |
PRINT_VALUE (Ebx, FeatureSaveStateOffset); | |
PRINT_BIT_FIELD (Ecx, XSS); | |
PRINT_BIT_FIELD (Ecx, Compacted); | |
} | |
} | |
} | |
/** | |
Display CPUID_EXTENDED_STATE main leaf and sub-leafs. | |
**/ | |
VOID | |
CpuidExtendedStateMainLeaf ( | |
VOID | |
) | |
{ | |
CPUID_EXTENDED_STATE_MAIN_LEAF_EAX Eax; | |
UINT32 Ebx; | |
UINT32 Ecx; | |
UINT32 Edx; | |
if (CPUID_EXTENDED_STATE > gMaximumBasicFunction) { | |
return; | |
} | |
AsmCpuidEx ( | |
CPUID_EXTENDED_STATE, | |
CPUID_EXTENDED_STATE_MAIN_LEAF, | |
&Eax.Uint32, | |
&Ebx, | |
&Ecx, | |
&Edx | |
); | |
Print (L"CPUID_EXTENDED_STATE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_MAIN_LEAF); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx, Edx); | |
PRINT_BIT_FIELD (Eax, x87); | |
PRINT_BIT_FIELD (Eax, SSE); | |
PRINT_BIT_FIELD (Eax, AVX); | |
PRINT_BIT_FIELD (Eax, MPX); | |
PRINT_BIT_FIELD (Eax, AVX_512); | |
PRINT_BIT_FIELD (Eax, IA32_XSS); | |
PRINT_BIT_FIELD (Eax, PKRU); | |
PRINT_BIT_FIELD (Eax, IA32_XSS_2); | |
PRINT_VALUE (Ebx, EnabledSaveStateSize); | |
PRINT_VALUE (Ecx, SupportedSaveStateSize); | |
PRINT_VALUE (Edx, XCR0_Supported_32_63); | |
CpuidExtendedStateSubLeaf (); | |
CpuidExtendedStateSizeOffset (); | |
} | |
/** | |
Display CPUID_INTEL_RDT_MONITORING enumeration sub-leaf. | |
**/ | |
VOID | |
CpuidIntelRdtMonitoringEnumerationSubLeaf ( | |
VOID | |
) | |
{ | |
UINT32 Ebx; | |
CPUID_INTEL_RDT_MONITORING_ENUMERATION_SUB_LEAF_EDX Edx; | |
if (CPUID_INTEL_RDT_MONITORING > gMaximumBasicFunction) { | |
return; | |
} | |
AsmCpuidEx ( | |
CPUID_INTEL_RDT_MONITORING, | |
CPUID_INTEL_RDT_MONITORING_ENUMERATION_SUB_LEAF, | |
NULL, | |
&Ebx, | |
NULL, | |
&Edx.Uint32 | |
); | |
Print (L"CPUID_INTEL_RDT_MONITORING (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_MONITORING, CPUID_INTEL_RDT_MONITORING_ENUMERATION_SUB_LEAF); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, Ebx, 0, Edx.Uint32); | |
PRINT_VALUE (Ebx, Maximum_RMID_Range); | |
PRINT_BIT_FIELD (Edx, L3CacheRDT_M); | |
} | |
/** | |
Display CPUID_INTEL_RDT_MONITORING L3 cache capability sub-leaf. | |
**/ | |
VOID | |
CpuidIntelRdtMonitoringL3CacheCapabilitySubLeaf ( | |
VOID | |
) | |
{ | |
UINT32 Ebx; | |
UINT32 Ecx; | |
CPUID_INTEL_RDT_MONITORING_L3_CACHE_SUB_LEAF_EDX Edx; | |
if (CPUID_INTEL_RDT_MONITORING > gMaximumBasicFunction) { | |
return; | |
} | |
AsmCpuidEx ( | |
CPUID_INTEL_RDT_MONITORING, | |
CPUID_INTEL_RDT_MONITORING_L3_CACHE_SUB_LEAF, | |
NULL, | |
&Ebx, | |
&Ecx, | |
&Edx.Uint32 | |
); | |
Print (L"CPUID_INTEL_RDT_MONITORING (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_MONITORING, CPUID_INTEL_RDT_MONITORING_L3_CACHE_SUB_LEAF); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, Ebx, Ecx, Edx.Uint32); | |
PRINT_VALUE (Ebx, OccupancyConversionFactor); | |
PRINT_VALUE (Ecx, Maximum_RMID_Range); | |
PRINT_BIT_FIELD (Edx, L3CacheOccupancyMonitoring); | |
PRINT_BIT_FIELD (Edx, L3CacheTotalBandwidthMonitoring); | |
PRINT_BIT_FIELD (Edx, L3CacheLocalBandwidthMonitoring); | |
} | |
/** | |
Display CPUID_INTEL_RDT_ALLOCATION memory bandwidth allocation technology enumeration | |
sub-leaf. | |
**/ | |
VOID | |
CpuidIntelRdtAllocationMemoryBandwidthSubLeaf ( | |
VOID | |
) | |
{ | |
CPUID_INTEL_RDT_ALLOCATION_MEMORY_BANDWIDTH_SUB_LEAF_EAX Eax; | |
UINT32 Ebx; | |
CPUID_INTEL_RDT_ALLOCATION_MEMORY_BANDWIDTH_SUB_LEAF_ECX Ecx; | |
CPUID_INTEL_RDT_ALLOCATION_MEMORY_BANDWIDTH_SUB_LEAF_EDX Edx; | |
AsmCpuidEx ( | |
CPUID_INTEL_RDT_ALLOCATION, | |
CPUID_INTEL_RDT_ALLOCATION_MEMORY_BANDWIDTH_SUB_LEAF, | |
&Eax.Uint32, | |
&Ebx, | |
&Ecx.Uint32, | |
&Edx.Uint32 | |
); | |
Print (L"CPUID_INTEL_RDT_ALLOCATION (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_MEMORY_BANDWIDTH_SUB_LEAF); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx.Uint32, Edx.Uint32); | |
PRINT_BIT_FIELD (Eax, MaximumMBAThrottling); | |
PRINT_VALUE (Ebx, AllocationUnitBitMap); | |
PRINT_BIT_FIELD (Ecx, Liner); | |
PRINT_BIT_FIELD (Edx, HighestCosNumber); | |
} | |
/** | |
Display CPUID_INTEL_RDT_ALLOCATION L3 cache allocation technology enumeration | |
sub-leaf. | |
**/ | |
VOID | |
CpuidIntelRdtAllocationL3CacheSubLeaf ( | |
VOID | |
) | |
{ | |
CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_EAX Eax; | |
UINT32 Ebx; | |
CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_ECX Ecx; | |
CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_EDX Edx; | |
AsmCpuidEx ( | |
CPUID_INTEL_RDT_ALLOCATION, | |
CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF, | |
&Eax.Uint32, | |
&Ebx, | |
&Ecx.Uint32, | |
&Edx.Uint32 | |
); | |
Print (L"CPUID_INTEL_RDT_ALLOCATION (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx.Uint32, Edx.Uint32); | |
PRINT_BIT_FIELD (Eax, CapacityLength); | |
PRINT_VALUE (Ebx, AllocationUnitBitMap); | |
PRINT_BIT_FIELD (Ecx, CodeDataPrioritization); | |
PRINT_BIT_FIELD (Edx, HighestCosNumber); | |
} | |
/** | |
Display CPUID_INTEL_RDT_ALLOCATION L2 cache allocation technology enumeration | |
sub-leaf. | |
**/ | |
VOID | |
CpuidIntelRdtAllocationL2CacheSubLeaf ( | |
VOID | |
) | |
{ | |
CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF_EAX Eax; | |
UINT32 Ebx; | |
CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF_EDX Edx; | |
AsmCpuidEx ( | |
CPUID_INTEL_RDT_ALLOCATION, | |
CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF, | |
&Eax.Uint32, | |
&Ebx, | |
NULL, | |
&Edx.Uint32 | |
); | |
Print (L"CPUID_INTEL_RDT_ALLOCATION (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, 0, Edx.Uint32); | |
PRINT_BIT_FIELD (Eax, CapacityLength); | |
PRINT_VALUE (Ebx, AllocationUnitBitMap); | |
PRINT_BIT_FIELD (Edx, HighestCosNumber); | |
} | |
/** | |
Display CPUID_INTEL_RDT_ALLOCATION main leaf and sub-leaves. | |
**/ | |
VOID | |
CpuidIntelRdtAllocationMainLeaf ( | |
VOID | |
) | |
{ | |
CPUID_INTEL_RDT_ALLOCATION_ENUMERATION_SUB_LEAF_EBX Ebx; | |
if (CPUID_INTEL_RDT_ALLOCATION > gMaximumBasicFunction) { | |
return; | |
} | |
AsmCpuidEx ( | |
CPUID_INTEL_RDT_ALLOCATION, | |
CPUID_INTEL_RDT_ALLOCATION_ENUMERATION_SUB_LEAF, | |
NULL, | |
&Ebx.Uint32, | |
NULL, | |
NULL | |
); | |
Print (L"CPUID_INTEL_RDT_ALLOCATION (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_ENUMERATION_SUB_LEAF); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, Ebx.Uint32, 0, 0); | |
PRINT_BIT_FIELD (Ebx, L3CacheAllocation); | |
PRINT_BIT_FIELD (Ebx, L2CacheAllocation); | |
PRINT_BIT_FIELD (Ebx, MemoryBandwidth); | |
CpuidIntelRdtAllocationMemoryBandwidthSubLeaf (); | |
CpuidIntelRdtAllocationL3CacheSubLeaf (); | |
CpuidIntelRdtAllocationL2CacheSubLeaf (); | |
} | |
/** | |
Display Sub-Leaf 0 Enumeration of Intel SGX Capabilities. | |
**/ | |
VOID | |
CpuidEnumerationOfIntelSgxCapabilities0SubLeaf ( | |
VOID | |
) | |
{ | |
CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF_EAX Eax; | |
UINT32 Ebx; | |
CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF_EDX Edx; | |
AsmCpuidEx ( | |
CPUID_INTEL_SGX, | |
CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF, | |
&Eax.Uint32, | |
&Ebx, | |
NULL, | |
&Edx.Uint32 | |
); | |
Print (L"CPUID_INTEL_SGX (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_SGX, CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, 0, Edx.Uint32); | |
PRINT_BIT_FIELD (Eax, SGX1); | |
PRINT_BIT_FIELD (Eax, SGX2); | |
PRINT_BIT_FIELD (Eax, ENCLV); | |
PRINT_BIT_FIELD (Eax, ENCLS); | |
PRINT_BIT_FIELD (Edx, MaxEnclaveSize_Not64); | |
PRINT_BIT_FIELD (Edx, MaxEnclaveSize_64); | |
} | |
/** | |
Display Sub-Leaf 1 Enumeration of Intel SGX Capabilities. | |
**/ | |
VOID | |
CpuidEnumerationOfIntelSgxCapabilities1SubLeaf ( | |
VOID | |
) | |
{ | |
UINT32 Eax; | |
UINT32 Ebx; | |
UINT32 Ecx; | |
UINT32 Edx; | |
AsmCpuidEx ( | |
CPUID_INTEL_SGX, | |
CPUID_INTEL_SGX_CAPABILITIES_1_SUB_LEAF, | |
&Eax, | |
&Ebx, | |
&Ecx, | |
&Edx | |
); | |
Print (L"CPUID_INTEL_SGX (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_SGX, CPUID_INTEL_SGX_CAPABILITIES_1_SUB_LEAF); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx, Ecx, Edx); | |
} | |
/** | |
Display Sub-Leaf Index 2 or Higher Enumeration of Intel SGX Resources. | |
**/ | |
VOID | |
CpuidEnumerationOfIntelSgxResourcesSubLeaf ( | |
VOID | |
) | |
{ | |
CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EAX Eax; | |
CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EBX Ebx; | |
CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_ECX Ecx; | |
CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EDX Edx; | |
UINT32 SubLeaf; | |
SubLeaf = CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF; | |
do { | |
AsmCpuidEx ( | |
CPUID_INTEL_SGX, | |
SubLeaf, | |
&Eax.Uint32, | |
&Ebx.Uint32, | |
&Ecx.Uint32, | |
&Edx.Uint32 | |
); | |
if (Eax.Bits.SubLeafType == 0x1) { | |
Print (L"CPUID_INTEL_SGX (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_SGX, SubLeaf); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); | |
PRINT_BIT_FIELD (Eax, SubLeafType); | |
PRINT_BIT_FIELD (Eax, LowAddressOfEpcSection); | |
PRINT_BIT_FIELD (Ebx, HighAddressOfEpcSection); | |
PRINT_BIT_FIELD (Ecx, EpcSection); | |
PRINT_BIT_FIELD (Ecx, LowSizeOfEpcSection); | |
PRINT_BIT_FIELD (Edx, HighSizeOfEpcSection); | |
} | |
SubLeaf++; | |
} while (Eax.Bits.SubLeafType == 0x1); | |
} | |
/** | |
Display Intel SGX Resource Enumeration. | |
**/ | |
VOID | |
CpuidEnumerationOfIntelSgx ( | |
VOID | |
) | |
{ | |
CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_EBX Ebx; | |
if (CPUID_INTEL_SGX > gMaximumBasicFunction) { | |
return; | |
} | |
AsmCpuidEx ( | |
CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, | |
CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, | |
NULL, | |
&Ebx.Uint32, | |
NULL, | |
NULL | |
); | |
if (Ebx.Bits.SGX != 1) { | |
// | |
// Only if CPUID.(EAX=07H, ECX=0H):EBX.SGX = 1, the processor has support | |
// for Intel SGX. | |
// | |
return; | |
} | |
CpuidEnumerationOfIntelSgxCapabilities0SubLeaf (); | |
CpuidEnumerationOfIntelSgxCapabilities1SubLeaf (); | |
CpuidEnumerationOfIntelSgxResourcesSubLeaf (); | |
} | |
/** | |
Display CPUID_INTEL_PROCESSOR_TRACE sub-leafs. | |
@param[in] MaximumSubLeaf Maximum sub-leaf index for CPUID_INTEL_PROCESSOR_TRACE. | |
**/ | |
VOID | |
CpuidIntelProcessorTraceSubLeaf ( | |
UINT32 MaximumSubLeaf | |
) | |
{ | |
UINT32 SubLeaf; | |
CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF_EAX Eax; | |
CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF_EBX Ebx; | |
for (SubLeaf = CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF; SubLeaf <= MaximumSubLeaf; SubLeaf++) { | |
AsmCpuidEx ( | |
CPUID_INTEL_PROCESSOR_TRACE, | |
SubLeaf, | |
&Eax.Uint32, | |
&Ebx.Uint32, | |
NULL, | |
NULL | |
); | |
Print (L"CPUID_INTEL_PROCESSOR_TRACE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_PROCESSOR_TRACE, SubLeaf); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, 0, 0); | |
PRINT_BIT_FIELD (Eax, ConfigurableAddressRanges); | |
PRINT_BIT_FIELD (Eax, MtcPeriodEncodings); | |
PRINT_BIT_FIELD (Ebx, CycleThresholdEncodings); | |
PRINT_BIT_FIELD (Ebx, PsbFrequencyEncodings); | |
} | |
} | |
/** | |
Display CPUID_INTEL_PROCESSOR_TRACE main leaf and sub-leafs. | |
**/ | |
VOID | |
CpuidIntelProcessorTraceMainLeaf ( | |
VOID | |
) | |
{ | |
UINT32 Eax; | |
CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_EBX Ebx; | |
CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_ECX Ecx; | |
if (CPUID_INTEL_PROCESSOR_TRACE > gMaximumBasicFunction) { | |
return; | |
} | |
AsmCpuidEx ( | |
CPUID_INTEL_PROCESSOR_TRACE, | |
CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF, | |
&Eax, | |
&Ebx.Uint32, | |
&Ecx.Uint32, | |
NULL | |
); | |
Print (L"CPUID_INTEL_PROCESSOR_TRACE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_PROCESSOR_TRACE, CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx.Uint32, Ecx.Uint32, 0); | |
PRINT_VALUE (Eax, MaximumSubLeaf); | |
PRINT_BIT_FIELD (Ebx, Cr3Filter); | |
PRINT_BIT_FIELD (Ebx, ConfigurablePsb); | |
PRINT_BIT_FIELD (Ebx, IpTraceStopFiltering); | |
PRINT_BIT_FIELD (Ebx, Mtc); | |
PRINT_BIT_FIELD (Ebx, PTWrite); | |
PRINT_BIT_FIELD (Ebx, PowerEventTrace); | |
PRINT_BIT_FIELD (Ecx, RTIT); | |
PRINT_BIT_FIELD (Ecx, ToPA); | |
PRINT_BIT_FIELD (Ecx, SingleRangeOutput); | |
PRINT_BIT_FIELD (Ecx, TraceTransportSubsystem); | |
PRINT_BIT_FIELD (Ecx, LIP); | |
CpuidIntelProcessorTraceSubLeaf (Eax); | |
} | |
/** | |
Display CPUID_TIME_STAMP_COUNTER leaf. | |
**/ | |
VOID | |
CpuidTimeStampCounter ( | |
VOID | |
) | |
{ | |
UINT32 Eax; | |
UINT32 Ebx; | |
UINT32 Ecx; | |
if (CPUID_TIME_STAMP_COUNTER > gMaximumBasicFunction) { | |
return; | |
} | |
AsmCpuid (CPUID_TIME_STAMP_COUNTER, &Eax, &Ebx, &Ecx, NULL); | |
Print (L"CPUID_TIME_STAMP_COUNTER (Leaf %08x)\n", CPUID_TIME_STAMP_COUNTER); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx, Ecx, 0); | |
} | |
/** | |
Display CPUID_PROCESSOR_FREQUENCY leaf. | |
**/ | |
VOID | |
CpuidProcessorFrequency ( | |
VOID | |
) | |
{ | |
CPUID_PROCESSOR_FREQUENCY_EAX Eax; | |
CPUID_PROCESSOR_FREQUENCY_EBX Ebx; | |
CPUID_PROCESSOR_FREQUENCY_ECX Ecx; | |
if (CPUID_PROCESSOR_FREQUENCY > gMaximumBasicFunction) { | |
return; | |
} | |
AsmCpuid (CPUID_PROCESSOR_FREQUENCY, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, NULL); | |
Print (L"CPUID_PROCESSOR_FREQUENCY (Leaf %08x)\n", CPUID_PROCESSOR_FREQUENCY); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, 0); | |
PRINT_BIT_FIELD (Eax, ProcessorBaseFrequency); | |
PRINT_BIT_FIELD (Ebx, MaximumFrequency); | |
PRINT_BIT_FIELD (Ecx, BusFrequency); | |
} | |
/** | |
Display CPUID_SOC_VENDOR sub-leafs that contain the SoC Vendor Brand String. | |
Also display these sub-leafs as a single SoC Vendor Brand String. | |
**/ | |
VOID | |
CpuidSocVendorBrandString ( | |
VOID | |
) | |
{ | |
CPUID_SOC_VENDOR_BRAND_STRING_DATA Eax; | |
CPUID_SOC_VENDOR_BRAND_STRING_DATA Ebx; | |
CPUID_SOC_VENDOR_BRAND_STRING_DATA Ecx; | |
CPUID_SOC_VENDOR_BRAND_STRING_DATA Edx; | |
// | |
// Array to store brand string from 3 brand string leafs with | |
// 4 32-bit brand string values per leaf and an extra value to | |
// null terminate the string. | |
// | |
UINT32 BrandString[3 * 4 + 1]; | |
AsmCpuidEx ( | |
CPUID_SOC_VENDOR, | |
CPUID_SOC_VENDOR_BRAND_STRING1, | |
&Eax.Uint32, | |
&Ebx.Uint32, | |
&Ecx.Uint32, | |
&Edx.Uint32 | |
); | |
Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING1); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); | |
BrandString[0] = Eax.Uint32; | |
BrandString[1] = Ebx.Uint32; | |
BrandString[2] = Ecx.Uint32; | |
BrandString[3] = Edx.Uint32; | |
AsmCpuidEx ( | |
CPUID_SOC_VENDOR, | |
CPUID_SOC_VENDOR_BRAND_STRING2, | |
&Eax.Uint32, | |
&Ebx.Uint32, | |
&Ecx.Uint32, | |
&Edx.Uint32 | |
); | |
Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING2); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); | |
BrandString[4] = Eax.Uint32; | |
BrandString[5] = Ebx.Uint32; | |
BrandString[6] = Ecx.Uint32; | |
BrandString[7] = Edx.Uint32; | |
AsmCpuidEx ( | |
CPUID_SOC_VENDOR, | |
CPUID_SOC_VENDOR_BRAND_STRING3, | |
&Eax.Uint32, | |
&Ebx.Uint32, | |
&Ecx.Uint32, | |
&Edx.Uint32 | |
); | |
Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING3); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); | |
BrandString[8] = Eax.Uint32; | |
BrandString[9] = Ebx.Uint32; | |
BrandString[10] = Ecx.Uint32; | |
BrandString[11] = Edx.Uint32; | |
BrandString[12] = 0; | |
Print (L"Vendor Brand String = %a\n", (CHAR8 *)BrandString); | |
} | |
/** | |
Display CPUID_SOC_VENDOR main leaf and sub-leafs. | |
**/ | |
VOID | |
CpuidSocVendor ( | |
VOID | |
) | |
{ | |
UINT32 Eax; | |
CPUID_SOC_VENDOR_MAIN_LEAF_EBX Ebx; | |
UINT32 Ecx; | |
UINT32 Edx; | |
if (CPUID_SOC_VENDOR > gMaximumBasicFunction) { | |
return; | |
} | |
AsmCpuidEx ( | |
CPUID_SOC_VENDOR, | |
CPUID_SOC_VENDOR_MAIN_LEAF, | |
&Eax, | |
&Ebx.Uint32, | |
&Ecx, | |
&Edx | |
); | |
Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_MAIN_LEAF); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx.Uint32, Ecx, Edx); | |
if (Eax < 3) { | |
Print (L" Not Supported\n"); | |
return; | |
} | |
PRINT_VALUE (Eax, MaxSOCID_Index); | |
PRINT_BIT_FIELD (Ebx, SocVendorId); | |
PRINT_BIT_FIELD (Ebx, IsVendorScheme); | |
PRINT_VALUE (Ecx, ProjectID); | |
PRINT_VALUE (Edx, SteppingID); | |
CpuidSocVendorBrandString (); | |
} | |
/** | |
Display CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS main leaf and sub-leafs. | |
**/ | |
VOID | |
CpuidDeterministicAddressTranslationParameters ( | |
VOID | |
) | |
{ | |
UINT32 Eax; | |
CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS_EBX Ebx; | |
UINT32 Ecx; | |
CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS_EDX Edx; | |
if (CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS > gMaximumBasicFunction) { | |
return; | |
} | |
AsmCpuidEx ( | |
CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS, | |
CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS_MAIN_LEAF, | |
&Eax, | |
&Ebx.Uint32, | |
&Ecx, | |
&Edx.Uint32 | |
); | |
Print (L"CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS (Leaf %08x, Sub-Leaf %08x)\n", CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS, CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS_MAIN_LEAF); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx.Uint32, Ecx, Edx.Uint32); | |
PRINT_VALUE (Eax, MaxID_Index); | |
PRINT_BIT_FIELD (Ebx, Page4K); | |
PRINT_BIT_FIELD (Ebx, Page2M); | |
PRINT_BIT_FIELD (Ebx, Page4M); | |
PRINT_BIT_FIELD (Ebx, Page1G); | |
PRINT_BIT_FIELD (Ebx, Partitioning); | |
PRINT_BIT_FIELD (Ebx, Way); | |
PRINT_VALUE (Ecx, NumberOfSets); | |
PRINT_BIT_FIELD (Edx, TranslationCacheType); | |
PRINT_BIT_FIELD (Edx, TranslationCacheLevel); | |
PRINT_BIT_FIELD (Edx, FullyAssociative); | |
PRINT_BIT_FIELD (Edx, MaximumNum); | |
} | |
/** | |
Display CPUID_EXTENDED_FUNCTION leaf. | |
**/ | |
VOID | |
CpuidExtendedFunction ( | |
VOID | |
) | |
{ | |
UINT32 Eax; | |
AsmCpuid (CPUID_EXTENDED_FUNCTION, &Eax, NULL, NULL, NULL); | |
Print (L"CPUID_EXTENDED_FUNCTION (Leaf %08x)\n", CPUID_EXTENDED_FUNCTION); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, 0, 0, 0); | |
PRINT_VALUE (Eax, MaximumExtendedFunction); | |
gMaximumExtendedFunction = Eax; | |
} | |
/** | |
Display CPUID_EXTENDED_CPU_SIG leaf. | |
**/ | |
VOID | |
CpuidExtendedCpuSig ( | |
VOID | |
) | |
{ | |
UINT32 Eax; | |
CPUID_EXTENDED_CPU_SIG_ECX Ecx; | |
CPUID_EXTENDED_CPU_SIG_EDX Edx; | |
if (CPUID_EXTENDED_CPU_SIG > gMaximumExtendedFunction) { | |
return; | |
} | |
AsmCpuid (CPUID_EXTENDED_CPU_SIG, &Eax, NULL, &Ecx.Uint32, &Edx.Uint32); | |
Print (L"CPUID_EXTENDED_CPU_SIG (Leaf %08x)\n", CPUID_EXTENDED_CPU_SIG); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, 0, Ecx.Uint32, Edx.Uint32); | |
PRINT_BIT_FIELD (Ecx, LAHF_SAHF); | |
PRINT_BIT_FIELD (Ecx, LZCNT); | |
PRINT_BIT_FIELD (Ecx, PREFETCHW); | |
PRINT_BIT_FIELD (Edx, SYSCALL_SYSRET); | |
PRINT_BIT_FIELD (Edx, NX); | |
PRINT_BIT_FIELD (Edx, Page1GB); | |
PRINT_BIT_FIELD (Edx, RDTSCP); | |
PRINT_BIT_FIELD (Edx, LM); | |
} | |
/** | |
Display CPUID_BRAND_STRING1, CPUID_BRAND_STRING2 and CPUID_BRAND_STRING3 | |
leafs. Also display these three leafs as a single brand string. | |
**/ | |
VOID | |
CpuidProcessorBrandString ( | |
VOID | |
) | |
{ | |
CPUID_BRAND_STRING_DATA Eax; | |
CPUID_BRAND_STRING_DATA Ebx; | |
CPUID_BRAND_STRING_DATA Ecx; | |
CPUID_BRAND_STRING_DATA Edx; | |
// | |
// Array to store brand string from 3 brand string leafs with | |
// 4 32-bit brand string values per leaf and an extra value to | |
// null terminate the string. | |
// | |
UINT32 BrandString[3 * 4 + 1]; | |
if (CPUID_BRAND_STRING1 <= gMaximumExtendedFunction) { | |
AsmCpuid (CPUID_BRAND_STRING1, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); | |
Print (L"CPUID_BRAND_STRING1 (Leaf %08x)\n", CPUID_BRAND_STRING1); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); | |
BrandString[0] = Eax.Uint32; | |
BrandString[1] = Ebx.Uint32; | |
BrandString[2] = Ecx.Uint32; | |
BrandString[3] = Edx.Uint32; | |
} | |
if (CPUID_BRAND_STRING2 <= gMaximumExtendedFunction) { | |
AsmCpuid (CPUID_BRAND_STRING2, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); | |
Print (L"CPUID_BRAND_STRING2 (Leaf %08x)\n", CPUID_BRAND_STRING2); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); | |
BrandString[4] = Eax.Uint32; | |
BrandString[5] = Ebx.Uint32; | |
BrandString[6] = Ecx.Uint32; | |
BrandString[7] = Edx.Uint32; | |
} | |
if (CPUID_BRAND_STRING3 <= gMaximumExtendedFunction) { | |
AsmCpuid (CPUID_BRAND_STRING3, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); | |
Print (L"CPUID_BRAND_STRING3 (Leaf %08x)\n", CPUID_BRAND_STRING3); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); | |
BrandString[8] = Eax.Uint32; | |
BrandString[9] = Ebx.Uint32; | |
BrandString[10] = Ecx.Uint32; | |
BrandString[11] = Edx.Uint32; | |
} | |
BrandString[12] = 0; | |
Print (L"Brand String = %a\n", (CHAR8 *)BrandString); | |
} | |
/** | |
Display CPUID_EXTENDED_CACHE_INFO leaf. | |
**/ | |
VOID | |
CpuidExtendedCacheInfo ( | |
VOID | |
) | |
{ | |
CPUID_EXTENDED_CACHE_INFO_ECX Ecx; | |
if (CPUID_EXTENDED_CACHE_INFO > gMaximumExtendedFunction) { | |
return; | |
} | |
AsmCpuid (CPUID_EXTENDED_CACHE_INFO, NULL, NULL, &Ecx.Uint32, NULL); | |
Print (L"CPUID_EXTENDED_CACHE_INFO (Leaf %08x)\n", CPUID_EXTENDED_CACHE_INFO); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, 0, Ecx.Uint32, 0); | |
PRINT_BIT_FIELD (Ecx, CacheLineSize); | |
PRINT_BIT_FIELD (Ecx, L2Associativity); | |
PRINT_BIT_FIELD (Ecx, CacheSize); | |
} | |
/** | |
Display CPUID_EXTENDED_TIME_STAMP_COUNTER leaf. | |
**/ | |
VOID | |
CpuidExtendedTimeStampCounter ( | |
VOID | |
) | |
{ | |
CPUID_EXTENDED_TIME_STAMP_COUNTER_EDX Edx; | |
if (CPUID_EXTENDED_TIME_STAMP_COUNTER > gMaximumExtendedFunction) { | |
return; | |
} | |
AsmCpuid (CPUID_EXTENDED_TIME_STAMP_COUNTER, NULL, NULL, NULL, &Edx.Uint32); | |
Print (L"CPUID_EXTENDED_TIME_STAMP_COUNTER (Leaf %08x)\n", CPUID_EXTENDED_TIME_STAMP_COUNTER); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, 0, 0, Edx.Uint32); | |
PRINT_BIT_FIELD (Edx, InvariantTsc); | |
} | |
/** | |
Display CPUID_VIR_PHY_ADDRESS_SIZE leaf. | |
**/ | |
VOID | |
CpuidVirPhyAddressSize ( | |
VOID | |
) | |
{ | |
CPUID_VIR_PHY_ADDRESS_SIZE_EAX Eax; | |
if (CPUID_VIR_PHY_ADDRESS_SIZE > gMaximumExtendedFunction) { | |
return; | |
} | |
AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &Eax.Uint32, NULL, NULL, NULL); | |
Print (L"CPUID_VIR_PHY_ADDRESS_SIZE (Leaf %08x)\n", CPUID_VIR_PHY_ADDRESS_SIZE); | |
Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, 0, 0, 0); | |
PRINT_BIT_FIELD (Eax, PhysicalAddressBits); | |
PRINT_BIT_FIELD (Eax, LinearAddressBits); | |
} | |
/** | |
The user Entry Point for Application. The user code starts with this function | |
as the real entry point for the application. | |
@param[in] ImageHandle The firmware allocated handle for the EFI image. | |
@param[in] SystemTable A pointer to the EFI System Table. | |
@retval EFI_SUCCESS The entry point is executed successfully. | |
@retval other Some error occurs when executing this entry point. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
UefiMain ( | |
IN EFI_HANDLE ImageHandle, | |
IN EFI_SYSTEM_TABLE *SystemTable | |
) | |
{ | |
Print (L"UEFI CPUID Version 0.5\n"); | |
CpuidSignature (); | |
CpuidVersionInfo (); | |
CpuidCacheInfo (); | |
CpuidSerialNumber (); | |
CpuidCacheParams (); | |
CpuidMonitorMwait (); | |
CpuidThermalPowerManagement (); | |
CpuidStructuredExtendedFeatureFlags (); | |
CpuidDirectCacheAccessInfo (); | |
CpuidArchitecturalPerformanceMonitoring (); | |
CpuidExtendedTopology (CPUID_EXTENDED_TOPOLOGY); | |
CpuidExtendedStateMainLeaf (); | |
CpuidIntelRdtMonitoringEnumerationSubLeaf (); | |
CpuidIntelRdtMonitoringL3CacheCapabilitySubLeaf (); | |
CpuidIntelRdtAllocationMainLeaf (); | |
CpuidEnumerationOfIntelSgx (); | |
CpuidIntelProcessorTraceMainLeaf (); | |
CpuidTimeStampCounter (); | |
CpuidProcessorFrequency (); | |
CpuidSocVendor (); | |
CpuidDeterministicAddressTranslationParameters (); | |
CpuidExtendedTopology (CPUID_V2_EXTENDED_TOPOLOGY); | |
CpuidExtendedFunction (); | |
CpuidExtendedCpuSig (); | |
CpuidProcessorBrandString (); | |
CpuidExtendedCacheInfo (); | |
CpuidExtendedTimeStampCounter (); | |
CpuidVirPhyAddressSize (); | |
return EFI_SUCCESS; | |
} |