以下代码由Cpuid.c改写得到
c
/** @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>
#include <Library/UefiBootServicesTableLib.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
ReadCpuidAppEntryPoint(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable)
{
EFI_STATUS Status;
EFI_INPUT_KEY Key;
CHAR16 NumberString[3] = {0};
UINTN NSindex = 0;
UINTN Choice = 0;
Print(L"UEFI CPUID Version 0.5\n");
Start:
Print(L"Select the function:\n");
Print(L" 0: Esc\n");
Print(L" 1: Display CPUID_SIGNATURE leaf\n");
Print(L" 2: Display CPUID_VERSION_INFO leaf\n");
Print(L" 3: Display CPUID_CACHE_INFO leaf for each supported cache descriptor\n");
Print(L" 4: Display CPUID_SERIAL_NUMBER leaf if it is supported\n");
Print(L" 5: Display CPUID_CACHE_PARAMS for all supported sub-leafs\n");
Print(L" 6: Display CPUID_MONITOR_MWAIT leaf\n");
Print(L" 7: Display CPUID_THERMAL_POWER_MANAGEMENT leaf\n");
Print(L" 8: Display CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS for all supported sub-leafs\n");
Print(L" 9: Display CPUID_DIRECT_CACHE_ACCESS_INFO leaf\n");
Print(L" 10: Display CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING leaf\n");
Print(L" 11: Display CPUID_EXTENDED_TOPOLOGY leafs for all supported levels\n");
Print(L" 12: Display CPUID_EXTENDED_STATE main leaf and sub-leafs\n");
Print(L" 13: Display CPUID_INTEL_RDT_MONITORING enumeration sub-leaf\n");
Print(L" 14: Display CPUID_INTEL_RDT_MONITORING L3 cache capability sub-leaf\n");
Print(L" 15: Display CPUID_INTEL_RDT_ALLOCATION main leaf and sub-leaves\n");
Print(L" 16: Display Intel SGX Resource Enumeration\n");
Print(L" 17: Display CPUID_INTEL_PROCESSOR_TRACE main leaf and sub-leafs\n");
Print(L" 18: Display CPUID_TIME_STAMP_COUNTER leaf\n");
Print(L" 19: Display CPUID_PROCESSOR_FREQUENCY leaf\n");
Print(L" 20: Display CPUID_SOC_VENDOR main leaf and sub-leafs\n");
Print(L" 21: Display CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS main leaf and sub-leafs\n");
Print(L" 22: Display CPUID_EXTENDED_TOPOLOGY leafs for all supported levels\n");
Print(L" 23: Display CPUID_EXTENDED_FUNCTION leaf\n");
Print(L" 24: Display CPUID_EXTENDED_CPU_SIG leaf\n");
Print(L" 25: Display CPUID_BRAND_STRING1, CPUID_BRAND_STRING2 and CPUID_BRAND_STRING3leafs\n");
Print(L" Also display these three leafs as a single brand string\n");
Print(L" 26: Display CPUID_EXTENDED_CACHE_INFO leaf\n");
Print(L" 27: Display CPUID_EXTENDED_TIME_STAMP_COUNTER leaf\n");
Print(L" 28: Display CPUID_VIR_PHY_ADDRESS_SIZE leaf\n");
Print(L"Please press a key:");
while (gST->ConIn->ReadKeyStroke(gST->ConIn, &Key) == EFI_SUCCESS)
;
while (TRUE)
{
Status = gST->ConIn->ReadKeyStroke(gST->ConIn, &Key);
if (EFI_ERROR(Status))
{
continue;
}
if (Key.UnicodeChar >= L'0' && Key.UnicodeChar <= L'9')
{
NumberString[NSindex] = Key.UnicodeChar;
Print(L"%c", NumberString[NSindex]);
NSindex++;
}
if (Key.UnicodeChar == L'\r')
{
NumberString[NSindex] = L'\0';
Print(L"\n");
break;
}
}
Choice = StrDecimalToUintn(NumberString);
for (UINT8 i = 0; i < 3; i++)
{
NumberString[i] = 0;
}
NSindex = 0;
if (Choice == 1)
{
CpuidSignature();
}
else if (Choice == 2)
{
CpuidVersionInfo();
}
else if (Choice == 3)
{
CpuidCacheInfo();
}
else if (Choice == 4)
{
CpuidSerialNumber();
}
else if (Choice == 5)
{
CpuidCacheParams();
}
else if (Choice == 6)
{
CpuidMonitorMwait();
}
else if (Choice == 7)
{
CpuidThermalPowerManagement();
}
else if (Choice == 8)
{
CpuidStructuredExtendedFeatureFlags();
}
else if (Choice == 9)
{
CpuidDirectCacheAccessInfo();
}
else if (Choice == 10)
{
CpuidArchitecturalPerformanceMonitoring();
}
else if (Choice == 11)
{
CpuidExtendedTopology(CPUID_EXTENDED_TOPOLOGY);
}
else if (Choice == 12)
{
CpuidExtendedStateMainLeaf();
}
else if (Choice == 13)
{
CpuidIntelRdtMonitoringEnumerationSubLeaf();
}
else if (Choice == 14)
{
CpuidIntelRdtMonitoringL3CacheCapabilitySubLeaf();
}
else if (Choice == 15)
{
CpuidIntelRdtAllocationMainLeaf();
}
else if (Choice == 16)
{
CpuidEnumerationOfIntelSgx();
}
else if (Choice == 17)
{
CpuidIntelProcessorTraceMainLeaf();
}
else if (Choice == 18)
{
CpuidTimeStampCounter();
}
else if (Choice == 19)
{
CpuidProcessorFrequency();
}
else if (Choice == 20)
{
CpuidSocVendor();
}
else if (Choice == 21)
{
CpuidDeterministicAddressTranslationParameters();
}
else if (Choice == 22)
{
CpuidExtendedTopology(CPUID_V2_EXTENDED_TOPOLOGY);
}
else if (Choice == 23)
{
CpuidExtendedFunction();
}
else if (Choice == 24)
{
CpuidExtendedCpuSig();
}
else if (Choice == 25)
{
CpuidProcessorBrandString();
}
else if (Choice == 26)
{
CpuidExtendedCacheInfo();
}
else if (Choice == 27)
{
CpuidExtendedTimeStampCounter();
}
else if (Choice == 28)
{
CpuidVirPhyAddressSize();
}
else if (Choice == 0)
{
goto Done;
}
else
{
Print(L"No No matches\n");
}
Print(L"Press 'Enter' to continue...");
while (TRUE)
{
Status = gST->ConIn->ReadKeyStroke(gST->ConIn, &Key);
if (EFI_ERROR(Status))
{
continue;
}
if (Key.UnicodeChar == L'\r')
{
Print(L"\n");
break;
}
}
goto Start;
Done:
return EFI_SUCCESS;
}
输出结果:


