--- /dev/null
+/** @file\r
+ UEFI Application to display CPUID leaf information.\r
+\r
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Register/Cpuid.h>\r
+\r
+///\r
+/// Macro used to display the value of a bit field in a register returned by CPUID.\r
+///\r
+#define PRINT_BIT_FIELD(Variable, FieldName) \\r
+ Print (L"%5a%42a: %x\n", #Variable, #FieldName, ##Variable.Bits.##FieldName);\r
+\r
+///\r
+/// Macro used to display the value of a register returned by CPUID.\r
+///\r
+#define PRINT_VALUE(Variable, Description) \\r
+ Print (L"%5a%42a: %x\n", #Variable, #Description, Variable);\r
+\r
+///\r
+/// Structure for cache description lookup table\r
+///\r
+typedef struct {\r
+ UINT8 CacheDescriptor;\r
+ CHAR8 *Type;\r
+ CHAR8 *Description;\r
+} CPUID_CACHE_INFO_DESCRIPTION;\r
+\r
+///\r
+/// Cache description lookup table\r
+///\r
+CPUID_CACHE_INFO_DESCRIPTION mCpuidCacheInfoDescription[] = {\r
+ { 0x00 , "General" , "Null descriptor, this byte contains no information" },\r
+ { 0x01 , "TLB" , "Instruction TLB: 4 KByte pages, 4-way set associative, 32 entries" },\r
+ { 0x02 , "TLB" , "Instruction TLB: 4 MByte pages, fully associative, 2 entries" },\r
+ { 0x03 , "TLB" , "Data TLB: 4 KByte pages, 4-way set associative, 64 entries" },\r
+ { 0x04 , "TLB" , "Data TLB: 4 MByte pages, 4-way set associative, 8 entries" },\r
+ { 0x05 , "TLB" , "Data TLB1: 4 MByte pages, 4-way set associative, 32 entries" },\r
+ { 0x06 , "Cache" , "1st-level instruction cache: 8 KBytes, 4-way set associative, 32 byte line size" },\r
+ { 0x08 , "Cache" , "1st-level instruction cache: 16 KBytes, 4-way set associative, 32 byte line size" },\r
+ { 0x09 , "Cache" , "1st-level instruction cache: 32KBytes, 4-way set associative, 64 byte line size" },\r
+ { 0x0A , "Cache" , "1st-level data cache: 8 KBytes, 2-way set associative, 32 byte line size" },\r
+ { 0x0B , "TLB" , "Instruction TLB: 4 MByte pages, 4-way set associative, 4 entries" },\r
+ { 0x0C , "Cache" , "1st-level data cache: 16 KBytes, 4-way set associative, 32 byte line size" },\r
+ { 0x0D , "Cache" , "1st-level data cache: 16 KBytes, 4-way set associative, 64 byte line size" },\r
+ { 0x0E , "Cache" , "1st-level data cache: 24 KBytes, 6-way set associative, 64 byte line size" },\r
+ { 0x1D , "Cache" , "2nd-level cache: 128 KBytes, 2-way set associative, 64 byte line size" },\r
+ { 0x21 , "Cache" , "2nd-level cache: 256 KBytes, 8-way set associative, 64 byte line size" },\r
+ { 0x22 , "Cache" , "3rd-level cache: 512 KBytes, 4-way set associative, 64 byte line size, 2 lines per sector" },\r
+ { 0x23 , "Cache" , "3rd-level cache: 1 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector" },\r
+ { 0x24 , "Cache" , "2nd-level cache: 1 MBytes, 16-way set associative, 64 byte line size" },\r
+ { 0x25 , "Cache" , "3rd-level cache: 2 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector" },\r
+ { 0x29 , "Cache" , "3rd-level cache: 4 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector" },\r
+ { 0x2C , "Cache" , "1st-level data cache: 32 KBytes, 8-way set associative, 64 byte line size" },\r
+ { 0x30 , "Cache" , "1st-level instruction cache: 32 KBytes, 8-way set associative, 64 byte line size" },\r
+ { 0x40 , "Cache" , "No 2nd-level cache or, if processor contains a valid 2nd-level cache, no 3rd-level cache" },\r
+ { 0x41 , "Cache" , "2nd-level cache: 128 KBytes, 4-way set associative, 32 byte line size" },\r
+ { 0x42 , "Cache" , "2nd-level cache: 256 KBytes, 4-way set associative, 32 byte line size" },\r
+ { 0x43 , "Cache" , "2nd-level cache: 512 KBytes, 4-way set associative, 32 byte line size" },\r
+ { 0x44 , "Cache" , "2nd-level cache: 1 MByte, 4-way set associative, 32 byte line size" },\r
+ { 0x45 , "Cache" , "2nd-level cache: 2 MByte, 4-way set associative, 32 byte line size" },\r
+ { 0x46 , "Cache" , "3rd-level cache: 4 MByte, 4-way set associative, 64 byte line size" },\r
+ { 0x47 , "Cache" , "3rd-level cache: 8 MByte, 8-way set associative, 64 byte line size" },\r
+ { 0x48 , "Cache" , "2nd-level cache: 3MByte, 12-way set associative, 64 byte line size" },\r
+ { 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" },\r
+ { 0x4A , "Cache" , "3rd-level cache: 6MByte, 12-way set associative, 64 byte line size" },\r
+ { 0x4B , "Cache" , "3rd-level cache: 8MByte, 16-way set associative, 64 byte line size" },\r
+ { 0x4C , "Cache" , "3rd-level cache: 12MByte, 12-way set associative, 64 byte line size" },\r
+ { 0x4D , "Cache" , "3rd-level cache: 16MByte, 16-way set associative, 64 byte line size" },\r
+ { 0x4E , "Cache" , "2nd-level cache: 6MByte, 24-way set associative, 64 byte line size" },\r
+ { 0x4F , "TLB" , "Instruction TLB: 4 KByte pages, 32 entries" },\r
+ { 0x50 , "TLB" , "Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 64 entries" },\r
+ { 0x51 , "TLB" , "Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 128 entries" },\r
+ { 0x52 , "TLB" , "Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 256 entries" },\r
+ { 0x55 , "TLB" , "Instruction TLB: 2-MByte or 4-MByte pages, fully associative, 7 entries" },\r
+ { 0x56 , "TLB" , "Data TLB0: 4 MByte pages, 4-way set associative, 16 entries" },\r
+ { 0x57 , "TLB" , "Data TLB0: 4 KByte pages, 4-way associative, 16 entries" },\r
+ { 0x59 , "TLB" , "Data TLB0: 4 KByte pages, fully associative, 16 entries" },\r
+ { 0x5A , "TLB" , "Data TLB0: 2-MByte or 4 MByte pages, 4-way set associative, 32 entries" },\r
+ { 0x5B , "TLB" , "Data TLB: 4 KByte and 4 MByte pages, 64 entries" },\r
+ { 0x5C , "TLB" , "Data TLB: 4 KByte and 4 MByte pages,128 entries" },\r
+ { 0x5D , "TLB" , "Data TLB: 4 KByte and 4 MByte pages,256 entries" },\r
+ { 0x60 , "Cache" , "1st-level data cache: 16 KByte, 8-way set associative, 64 byte line size" },\r
+ { 0x61 , "TLB" , "Instruction TLB: 4 KByte pages, fully associative, 48 entries" },\r
+ { 0x63 , "TLB" , "Data TLB: 1 GByte pages, 4-way set associative, 4 entries" },\r
+ { 0x66 , "Cache" , "1st-level data cache: 8 KByte, 4-way set associative, 64 byte line size" },\r
+ { 0x67 , "Cache" , "1st-level data cache: 16 KByte, 4-way set associative, 64 byte line size" },\r
+ { 0x68 , "Cache" , "1st-level data cache: 32 KByte, 4-way set associative, 64 byte line size" },\r
+ { 0x6A , "Cache" , "uTLB: 4 KByte pages, 8-way set associative, 64 entries" },\r
+ { 0x6B , "Cache" , "DTLB: 4 KByte pages, 8-way set associative, 256 entries" },\r
+ { 0x6C , "Cache" , "DTLB: 2M/4M pages, 8-way set associative, 128 entries" },\r
+ { 0x6D , "Cache" , "DTLB: 1 GByte pages, fully associative, 16 entries" },\r
+ { 0x70 , "Cache" , "Trace cache: 12 K-uop, 8-way set associative" },\r
+ { 0x71 , "Cache" , "Trace cache: 16 K-uop, 8-way set associative" },\r
+ { 0x72 , "Cache" , "Trace cache: 32 K-uop, 8-way set associative" },\r
+ { 0x76 , "TLB" , "Instruction TLB: 2M/4M pages, fully associative, 8 entries" },\r
+ { 0x78 , "Cache" , "2nd-level cache: 1 MByte, 4-way set associative, 64byte line size" },\r
+ { 0x79 , "Cache" , "2nd-level cache: 128 KByte, 8-way set associative, 64 byte line size, 2 lines per sector" },\r
+ { 0x7A , "Cache" , "2nd-level cache: 256 KByte, 8-way set associative, 64 byte line size, 2 lines per sector" },\r
+ { 0x7B , "Cache" , "2nd-level cache: 512 KByte, 8-way set associative, 64 byte line size, 2 lines per sector" },\r
+ { 0x7C , "Cache" , "2nd-level cache: 1 MByte, 8-way set associative, 64 byte line size, 2 lines per sector" },\r
+ { 0x7D , "Cache" , "2nd-level cache: 2 MByte, 8-way set associative, 64byte line size" },\r
+ { 0x7F , "Cache" , "2nd-level cache: 512 KByte, 2-way set associative, 64-byte line size" },\r
+ { 0x80 , "Cache" , "2nd-level cache: 512 KByte, 8-way set associative, 64-byte line size" },\r
+ { 0x82 , "Cache" , "2nd-level cache: 256 KByte, 8-way set associative, 32 byte line size" },\r
+ { 0x83 , "Cache" , "2nd-level cache: 512 KByte, 8-way set associative, 32 byte line size" },\r
+ { 0x84 , "Cache" , "2nd-level cache: 1 MByte, 8-way set associative, 32 byte line size" },\r
+ { 0x85 , "Cache" , "2nd-level cache: 2 MByte, 8-way set associative, 32 byte line size" },\r
+ { 0x86 , "Cache" , "2nd-level cache: 512 KByte, 4-way set associative, 64 byte line size" },\r
+ { 0x87 , "Cache" , "2nd-level cache: 1 MByte, 8-way set associative, 64 byte line size" },\r
+ { 0xA0 , "DTLB" , "DTLB: 4k pages, fully associative, 32 entries" },\r
+ { 0xB0 , "TLB" , "Instruction TLB: 4 KByte pages, 4-way set associative, 128 entries" },\r
+ { 0xB1 , "TLB" , "Instruction TLB: 2M pages, 4-way, 8 entries or 4M pages, 4-way, 4 entries" },\r
+ { 0xB2 , "TLB" , "Instruction TLB: 4KByte pages, 4-way set associative, 64 entries" },\r
+ { 0xB3 , "TLB" , "Data TLB: 4 KByte pages, 4-way set associative, 128 entries" },\r
+ { 0xB4 , "TLB" , "Data TLB1: 4 KByte pages, 4-way associative, 256 entries" },\r
+ { 0xB5 , "TLB" , "Instruction TLB: 4KByte pages, 8-way set associative, 64 entries" },\r
+ { 0xB6 , "TLB" , "Instruction TLB: 4KByte pages, 8-way set associative, 128 entries" },\r
+ { 0xBA , "TLB" , "Data TLB1: 4 KByte pages, 4-way associative, 64 entries" },\r
+ { 0xC0 , "TLB" , "Data TLB: 4 KByte and 4 MByte pages, 4-way associative, 8 entries" },\r
+ { 0xC1 , "STLB" , "Shared 2nd-Level TLB: 4 KByte/2MByte pages, 8-way associative, 1024 entries" },\r
+ { 0xC2 , "DTLB" , "DTLB: 4 KByte/2 MByte pages, 4-way associative, 16 entries" },\r
+ { 0xC3 , "STLB" , "Shared 2nd-Level TLB: 4 KByte /2 MByte pages, 6-way associative, 1536 entries. Also 1GBbyte pages, 4-way, 16 entries." },\r
+ { 0xCA , "STLB" , "Shared 2nd-Level TLB: 4 KByte pages, 4-way associative, 512 entries" },\r
+ { 0xD0 , "Cache" , "3rd-level cache: 512 KByte, 4-way set associative, 64 byte line size" },\r
+ { 0xD1 , "Cache" , "3rd-level cache: 1 MByte, 4-way set associative, 64 byte line size" },\r
+ { 0xD2 , "Cache" , "3rd-level cache: 2 MByte, 4-way set associative, 64 byte line size" },\r
+ { 0xD6 , "Cache" , "3rd-level cache: 1 MByte, 8-way set associative, 64 byte line size" },\r
+ { 0xD7 , "Cache" , "3rd-level cache: 2 MByte, 8-way set associative, 64 byte line size" },\r
+ { 0xD8 , "Cache" , "3rd-level cache: 4 MByte, 8-way set associative, 64 byte line size" },\r
+ { 0xDC , "Cache" , "3rd-level cache: 1.5 MByte, 12-way set associative, 64 byte line size" },\r
+ { 0xDD , "Cache" , "3rd-level cache: 3 MByte, 12-way set associative, 64 byte line size" },\r
+ { 0xDE , "Cache" , "3rd-level cache: 6 MByte, 12-way set associative, 64 byte line size" },\r
+ { 0xE2 , "Cache" , "3rd-level cache: 2 MByte, 16-way set associative, 64 byte line size" },\r
+ { 0xE3 , "Cache" , "3rd-level cache: 4 MByte, 16-way set associative, 64 byte line size" },\r
+ { 0xE4 , "Cache" , "3rd-level cache: 8 MByte, 16-way set associative, 64 byte line size" },\r
+ { 0xEA , "Cache" , "3rd-level cache: 12MByte, 24-way set associative, 64 byte line size" },\r
+ { 0xEB , "Cache" , "3rd-level cache: 18MByte, 24-way set associative, 64 byte line size" },\r
+ { 0xEC , "Cache" , "3rd-level cache: 24MByte, 24-way set associative, 64 byte line size" },\r
+ { 0xF0 , "Prefetch" , "64-Byte prefetching" },\r
+ { 0xF1 , "Prefetch" , "128-Byte prefetching" },\r
+ { 0xFF , "General" , "CPUID leaf 2 does not report cache descriptor information, use CPUID leaf 4 to query cache parameters" }\r
+};\r
+\r
+///\r
+/// The maximum supported CPUID leaf index starting from leaf 0x00000000.\r
+///\r
+UINT32 gMaximumBasicFunction = CPUID_SIGNATURE;\r
+\r
+///\r
+/// The maximum supported CPUID leaf index starting from leaf 0x80000000.\r
+///\r
+UINT32 gMaximumExtendedFunction = CPUID_EXTENDED_FUNCTION;\r
+\r
+/**\r
+ Display CPUID_SIGNATURE leaf.\r
+\r
+**/\r
+VOID\r
+CpuidSignature (\r
+ VOID\r
+ )\r
+{\r
+ UINT32 Eax;\r
+ UINT32 Ebx;\r
+ UINT32 Ecx;\r
+ UINT32 Edx;\r
+ CHAR8 Signature[13];\r
+\r
+ if (CPUID_SIGNATURE > gMaximumBasicFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuid (CPUID_SIGNATURE, &Eax, &Ebx, &Ecx, &Edx);\r
+\r
+ Print (L"CPUID_SIGNATURE (Leaf %08x)\n", CPUID_SIGNATURE);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx, Ecx, Edx);\r
+ PRINT_VALUE (Eax, MaximumLeaf);\r
+ *(UINT32 *)(Signature + 0) = Ebx;\r
+ *(UINT32 *)(Signature + 4) = Edx;\r
+ *(UINT32 *)(Signature + 8) = Ecx;\r
+ Signature [12] = 0;\r
+ Print (L" Signature = %a\n", Signature);\r
+\r
+ gMaximumBasicFunction = Eax;\r
+}\r
+\r
+/**\r
+ Display CPUID_VERSION_INFO leaf.\r
+\r
+**/\r
+VOID\r
+CpuidVersionInfo (\r
+ VOID\r
+ )\r
+{\r
+ CPUID_VERSION_INFO_EAX Eax;\r
+ CPUID_VERSION_INFO_EBX Ebx;\r
+ CPUID_VERSION_INFO_ECX Ecx;\r
+ CPUID_VERSION_INFO_EDX Edx;\r
+ UINTN DisplayFamily;\r
+ UINTN DisplayModel;\r
+\r
+ if (CPUID_VERSION_INFO > gMaximumBasicFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuid (CPUID_VERSION_INFO, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32);\r
+\r
+ Print (L"CPUID_VERSION_INFO (Leaf %08x)\n", CPUID_VERSION_INFO);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32);\r
+\r
+ DisplayFamily = Eax.Bits.FamilyId;\r
+ if (Eax.Bits.FamilyId == 0x0F) {\r
+ DisplayFamily |= (Eax.Bits.ExtendedFamilyId << 4);\r
+ }\r
+\r
+ DisplayModel = Eax.Bits.Model;\r
+ if (Eax.Bits.FamilyId == 0x06 || Eax.Bits.FamilyId == 0x0f) {\r
+ DisplayModel |= (Eax.Bits.ExtendedModelId << 4);\r
+ }\r
+\r
+ Print (L" Family = %x Model = %x Stepping = %x\n", DisplayFamily, DisplayModel, Eax.Bits.SteppingId);\r
+\r
+ PRINT_BIT_FIELD (Eax, SteppingId);\r
+ PRINT_BIT_FIELD (Eax, Model);\r
+ PRINT_BIT_FIELD (Eax, FamilyId);\r
+ PRINT_BIT_FIELD (Eax, ProcessorType);\r
+ PRINT_BIT_FIELD (Eax, ExtendedModelId);\r
+ PRINT_BIT_FIELD (Eax, ExtendedFamilyId);\r
+ PRINT_BIT_FIELD (Ebx, BrandIndex);\r
+ PRINT_BIT_FIELD (Ebx, CacheLineSize);\r
+ PRINT_BIT_FIELD (Ebx, MaximumAddressableIdsForLogicalProcessors);\r
+ PRINT_BIT_FIELD (Ebx, InitialLocalApicId);\r
+ PRINT_BIT_FIELD (Ecx, SSE3);\r
+ PRINT_BIT_FIELD (Ecx, PCLMULQDQ);\r
+ PRINT_BIT_FIELD (Ecx, DTES64);\r
+ PRINT_BIT_FIELD (Ecx, MONITOR);\r
+ PRINT_BIT_FIELD (Ecx, DS_CPL);\r
+ PRINT_BIT_FIELD (Ecx, VMX);\r
+ PRINT_BIT_FIELD (Ecx, SMX);\r
+ PRINT_BIT_FIELD (Ecx, TM2);\r
+ PRINT_BIT_FIELD (Ecx, SSSE3);\r
+ PRINT_BIT_FIELD (Ecx, CNXT_ID);\r
+ PRINT_BIT_FIELD (Ecx, SDBG);\r
+ PRINT_BIT_FIELD (Ecx, FMA);\r
+ PRINT_BIT_FIELD (Ecx, CMPXCHG16B);\r
+ PRINT_BIT_FIELD (Ecx, xTPR_Update_Control);\r
+ PRINT_BIT_FIELD (Ecx, PDCM);\r
+ PRINT_BIT_FIELD (Ecx, PCID);\r
+ PRINT_BIT_FIELD (Ecx, DCA);\r
+ PRINT_BIT_FIELD (Ecx, SSE4_1);\r
+ PRINT_BIT_FIELD (Ecx, SSE4_2);\r
+ PRINT_BIT_FIELD (Ecx, x2APIC);\r
+ PRINT_BIT_FIELD (Ecx, MOVBE);\r
+ PRINT_BIT_FIELD (Ecx, POPCNT);\r
+ PRINT_BIT_FIELD (Ecx, TSC_Deadline);\r
+ PRINT_BIT_FIELD (Ecx, AESNI);\r
+ PRINT_BIT_FIELD (Ecx, XSAVE);\r
+ PRINT_BIT_FIELD (Ecx, OSXSAVE);\r
+ PRINT_BIT_FIELD (Ecx, AVX);\r
+ PRINT_BIT_FIELD (Ecx, F16C);\r
+ PRINT_BIT_FIELD (Ecx, RDRAND);\r
+ PRINT_BIT_FIELD (Edx, FPU);\r
+ PRINT_BIT_FIELD (Edx, VME);\r
+ PRINT_BIT_FIELD (Edx, DE);\r
+ PRINT_BIT_FIELD (Edx, PSE);\r
+ PRINT_BIT_FIELD (Edx, TSC);\r
+ PRINT_BIT_FIELD (Edx, MSR);\r
+ PRINT_BIT_FIELD (Edx, PAE);\r
+ PRINT_BIT_FIELD (Edx, MCE);\r
+ PRINT_BIT_FIELD (Edx, CX8);\r
+ PRINT_BIT_FIELD (Edx, APIC);\r
+ PRINT_BIT_FIELD (Edx, SEP);\r
+ PRINT_BIT_FIELD (Edx, MTRR);\r
+ PRINT_BIT_FIELD (Edx, PGE);\r
+ PRINT_BIT_FIELD (Edx, MCA);\r
+ PRINT_BIT_FIELD (Edx, CMOV);\r
+ PRINT_BIT_FIELD (Edx, PAT);\r
+ PRINT_BIT_FIELD (Edx, PSE_36);\r
+ PRINT_BIT_FIELD (Edx, PSN);\r
+ PRINT_BIT_FIELD (Edx, CLFSH);\r
+ PRINT_BIT_FIELD (Edx, DS);\r
+ PRINT_BIT_FIELD (Edx, ACPI);\r
+ PRINT_BIT_FIELD (Edx, MMX);\r
+ PRINT_BIT_FIELD (Edx, FXSR);\r
+ PRINT_BIT_FIELD (Edx, SSE);\r
+ PRINT_BIT_FIELD (Edx, SSE2);\r
+ PRINT_BIT_FIELD (Edx, SS);\r
+ PRINT_BIT_FIELD (Edx, HTT);\r
+ PRINT_BIT_FIELD (Edx, TM);\r
+ PRINT_BIT_FIELD (Edx, PBE);\r
+}\r
+\r
+/**\r
+ Lookup a cache description string from the mCpuidCacheInfoDescription table.\r
+\r
+ @param[in] CacheDescriptor Cache descriptor value from CPUID_CACHE_INFO.\r
+\r
+**/\r
+CPUID_CACHE_INFO_DESCRIPTION *\r
+LookupCacheDescription (\r
+ UINT8 CacheDescriptor\r
+ )\r
+{\r
+ UINTN NumDescriptors;\r
+ UINTN Descriptor;\r
+\r
+ if (CacheDescriptor == 0x00) {\r
+ return NULL;\r
+ }\r
+ NumDescriptors = sizeof (mCpuidCacheInfoDescription)/sizeof (mCpuidCacheInfoDescription[0]);\r
+ for (Descriptor = 0; Descriptor < NumDescriptors; Descriptor++) {\r
+ if (CacheDescriptor == mCpuidCacheInfoDescription[Descriptor].CacheDescriptor) {\r
+ return &mCpuidCacheInfoDescription[Descriptor];\r
+ }\r
+ }\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Display CPUID_CACHE_INFO leaf for each supported cache descriptor.\r
+\r
+**/\r
+VOID\r
+CpuidCacheInfo (\r
+ VOID\r
+ )\r
+{\r
+ CPUID_CACHE_INFO_CACHE_TLB Eax;\r
+ CPUID_CACHE_INFO_CACHE_TLB Ebx;\r
+ CPUID_CACHE_INFO_CACHE_TLB Ecx;\r
+ CPUID_CACHE_INFO_CACHE_TLB Edx;\r
+ UINTN Index;\r
+ CPUID_CACHE_INFO_DESCRIPTION *CacheDescription;\r
+\r
+ if (CPUID_CACHE_INFO > gMaximumBasicFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuid (CPUID_CACHE_INFO, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32);\r
+\r
+ Print (L"CPUID_CACHE_INFO (Leaf %08x)\n", CPUID_CACHE_INFO);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32);\r
+ if (Eax.Bits.NotValid == 0) {\r
+ //\r
+ // Process Eax.CacheDescriptor[1..3]. Ignore Eax.CacheDescriptor[0]\r
+ //\r
+ for (Index = 1; Index < 4; Index++) {\r
+ CacheDescription = LookupCacheDescription (Eax.CacheDescriptor[Index]);\r
+ if (CacheDescription != NULL) {\r
+ Print (L" %-8a %a\n",\r
+ CacheDescription->Type,\r
+ CacheDescription->Description\r
+ );\r
+ }\r
+ }\r
+ }\r
+ if (Ebx.Bits.NotValid == 0) {\r
+ //\r
+ // Process Ebx.CacheDescriptor[0..3]\r
+ //\r
+ for (Index = 0; Index < 4; Index++) {\r
+ CacheDescription = LookupCacheDescription (Ebx.CacheDescriptor[Index]);\r
+ if (CacheDescription != NULL) {\r
+ Print (L" %-8a %a\n",\r
+ CacheDescription->Type,\r
+ CacheDescription->Description\r
+ );\r
+ }\r
+ }\r
+ }\r
+ if (Ecx.Bits.NotValid == 0) {\r
+ //\r
+ // Process Ecx.CacheDescriptor[0..3]\r
+ //\r
+ for (Index = 0; Index < 4; Index++) {\r
+ CacheDescription = LookupCacheDescription (Ecx.CacheDescriptor[Index]);\r
+ if (CacheDescription != NULL) {\r
+ Print (L" %-8a %a\n",\r
+ CacheDescription->Type,\r
+ CacheDescription->Description\r
+ );\r
+ }\r
+ }\r
+ }\r
+ if (Edx.Bits.NotValid == 0) {\r
+ //\r
+ // Process Edx.CacheDescriptor[0..3]\r
+ //\r
+ for (Index = 0; Index < 4; Index++) {\r
+ CacheDescription = LookupCacheDescription (Edx.CacheDescriptor[Index]);\r
+ if (CacheDescription != NULL) {\r
+ Print (L" %-8a %a\n",\r
+ CacheDescription->Type,\r
+ CacheDescription->Description\r
+ );\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Display CPUID_SERIAL_NUMBER leaf if it is supported.\r
+\r
+**/\r
+VOID\r
+CpuidSerialNumber (\r
+ VOID\r
+ )\r
+{\r
+ CPUID_VERSION_INFO_EDX VersionInfoEdx;\r
+ UINT32 Ecx;\r
+ UINT32 Edx;\r
+\r
+ Print (L"CPUID_SERIAL_NUMBER (Leaf %08x)\n", CPUID_SERIAL_NUMBER);\r
+\r
+ if (CPUID_SERIAL_NUMBER > gMaximumBasicFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32);\r
+ if (VersionInfoEdx.Bits.PSN == 0) {\r
+ Print (L" Not Supported\n");\r
+ return;\r
+ }\r
+\r
+ AsmCpuid (CPUID_SERIAL_NUMBER, NULL, NULL, &Ecx, &Edx);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, 0, Ecx, Edx);\r
+ Print (L" Processor Serial Number = %08x%08x%08x\n", 0, Edx, Ecx);\r
+}\r
+\r
+/**\r
+ Display CPUID_CACHE_PARAMS for all supported sub-leafs.\r
+\r
+**/\r
+VOID\r
+CpuidCacheParams (\r
+ VOID\r
+ )\r
+{\r
+ UINT32 CacheLevel;\r
+ CPUID_CACHE_PARAMS_EAX Eax;\r
+ CPUID_CACHE_PARAMS_EBX Ebx;\r
+ UINT32 Ecx;\r
+ CPUID_CACHE_PARAMS_EDX Edx;\r
+\r
+ if (CPUID_CACHE_PARAMS > gMaximumBasicFunction) {\r
+ return;\r
+ }\r
+\r
+ CacheLevel = 0;\r
+ do {\r
+ AsmCpuidEx (\r
+ CPUID_CACHE_PARAMS, CacheLevel,\r
+ &Eax.Uint32, &Ebx.Uint32, &Ecx, &Edx.Uint32\r
+ );\r
+ if (Eax.Bits.CacheType != CPUID_CACHE_PARAMS_CACHE_TYPE_NULL) {\r
+ Print (L"CPUID_CACHE_PARAMS (Leaf %08x, Sub-Leaf %08x)\n", CPUID_CACHE_PARAMS, CacheLevel);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx, Edx.Uint32);\r
+ PRINT_BIT_FIELD (Eax, CacheType);\r
+ PRINT_BIT_FIELD (Eax, CacheLevel);\r
+ PRINT_BIT_FIELD (Eax, SelfInitializingCache);\r
+ PRINT_BIT_FIELD (Eax, FullyAssociativeCache);\r
+ PRINT_BIT_FIELD (Eax, MaximumAddressableIdsForLogicalProcessors);\r
+ PRINT_BIT_FIELD (Eax, MaximumAddressableIdsForProcessorCores);\r
+ PRINT_BIT_FIELD (Ebx, LineSize);\r
+ PRINT_BIT_FIELD (Ebx, LinePartitions);\r
+ PRINT_BIT_FIELD (Ebx, Ways);\r
+ PRINT_VALUE (Ecx, NumberOfSets);\r
+ PRINT_BIT_FIELD (Edx, Invalidate);\r
+ PRINT_BIT_FIELD (Edx, CacheInclusiveness);\r
+ PRINT_BIT_FIELD (Edx, ComplexCacheIndexing);\r
+ }\r
+ CacheLevel++;\r
+ } while (Eax.Bits.CacheType != CPUID_CACHE_PARAMS_CACHE_TYPE_NULL);\r
+}\r
+\r
+/**\r
+ Display CPUID_MONITOR_MWAIT leaf.\r
+\r
+**/\r
+VOID\r
+CpuidMonitorMwait (\r
+ VOID\r
+ )\r
+{\r
+ CPUID_MONITOR_MWAIT_EAX Eax;\r
+ CPUID_MONITOR_MWAIT_EBX Ebx;\r
+ CPUID_MONITOR_MWAIT_ECX Ecx;\r
+ CPUID_MONITOR_MWAIT_EDX Edx;\r
+\r
+ if (CPUID_MONITOR_MWAIT > gMaximumBasicFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuid (CPUID_MONITOR_MWAIT, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32);\r
+\r
+ Print (L"CPUID_MONITOR_MWAIT (Leaf %08x)\n", CPUID_MONITOR_MWAIT);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32);\r
+\r
+ PRINT_BIT_FIELD (Eax, SmallestMonitorLineSize);\r
+ PRINT_BIT_FIELD (Ebx, LargestMonitorLineSize);\r
+ PRINT_BIT_FIELD (Ecx, ExtensionsSupported);\r
+ PRINT_BIT_FIELD (Ecx, InterruptAsBreak);\r
+ PRINT_BIT_FIELD (Edx, C0States);\r
+ PRINT_BIT_FIELD (Edx, C1States);\r
+ PRINT_BIT_FIELD (Edx, C2States);\r
+ PRINT_BIT_FIELD (Edx, C3States);\r
+ PRINT_BIT_FIELD (Edx, C4States);\r
+ PRINT_BIT_FIELD (Edx, C5States);\r
+ PRINT_BIT_FIELD (Edx, C6States);\r
+ PRINT_BIT_FIELD (Edx, C7States);\r
+}\r
+\r
+/**\r
+ Display CPUID_THERMAL_POWER_MANAGEMENT leaf.\r
+\r
+**/\r
+VOID\r
+CpuidThermalPowerManagement (\r
+ VOID\r
+ )\r
+{\r
+ CPUID_THERMAL_POWER_MANAGEMENT_EAX Eax;\r
+ CPUID_THERMAL_POWER_MANAGEMENT_EBX Ebx;\r
+ CPUID_THERMAL_POWER_MANAGEMENT_ECX Ecx;\r
+\r
+ if (CPUID_THERMAL_POWER_MANAGEMENT > gMaximumBasicFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuid (CPUID_THERMAL_POWER_MANAGEMENT, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, NULL);\r
+\r
+ Print (L"CPUID_THERMAL_POWER_MANAGEMENT (Leaf %08x)\n", CPUID_THERMAL_POWER_MANAGEMENT);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, 0);\r
+\r
+ PRINT_BIT_FIELD (Eax, DigitalTemperatureSensor);\r
+ PRINT_BIT_FIELD (Eax, TurboBoostTechnology);\r
+ PRINT_BIT_FIELD (Eax, ARAT);\r
+ PRINT_BIT_FIELD (Eax, PLN);\r
+ PRINT_BIT_FIELD (Eax, ECMD);\r
+ PRINT_BIT_FIELD (Eax, PTM);\r
+ PRINT_BIT_FIELD (Eax, HWP);\r
+ PRINT_BIT_FIELD (Eax, HWP_Notification);\r
+ PRINT_BIT_FIELD (Eax, HWP_Activity_Window);\r
+ PRINT_BIT_FIELD (Eax, HWP_Energy_Performance_Preference);\r
+ PRINT_BIT_FIELD (Eax, HWP_Package_Level_Request);\r
+ PRINT_BIT_FIELD (Eax, HDC);\r
+ PRINT_BIT_FIELD (Ebx, InterruptThresholds);\r
+ PRINT_BIT_FIELD (Ecx, HardwareCoordinationFeedback);\r
+ PRINT_BIT_FIELD (Ecx, PerformanceEnergyBias);\r
+}\r
+\r
+/**\r
+ Display CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS for all supported sub-leafs.\r
+\r
+**/\r
+VOID\r
+CpuidStructuredExtendedFeatureFlags (\r
+ VOID\r
+ )\r
+{\r
+ UINT32 Eax;\r
+ CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_EBX Ebx;\r
+ CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX Ecx;\r
+ UINT32 SubLeaf;\r
+\r
+ if (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS > gMaximumBasicFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuidEx (\r
+ CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS,\r
+ CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO,\r
+ &Eax, NULL, NULL, NULL\r
+ );\r
+ for (SubLeaf = 0; SubLeaf <= Eax; SubLeaf++) {\r
+ AsmCpuidEx (\r
+ CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS,\r
+ SubLeaf,\r
+ NULL, &Ebx.Uint32, &Ecx.Uint32, NULL\r
+ );\r
+ if (Ebx.Uint32 != 0 || Ecx.Uint32 != 0) {\r
+ Print (L"CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS (Leaf %08x, Sub-Leaf %08x)\n", CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, SubLeaf);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx.Uint32, Ecx.Uint32, 0);\r
+ PRINT_BIT_FIELD (Ebx, FSGSBASE);\r
+ PRINT_BIT_FIELD (Ebx, IA32_TSC_ADJUST);\r
+ PRINT_BIT_FIELD (Ebx, BMI1);\r
+ PRINT_BIT_FIELD (Ebx, HLE);\r
+ PRINT_BIT_FIELD (Ebx, AVX2);\r
+ PRINT_BIT_FIELD (Ebx, FDP_EXCPTN_ONLY);\r
+ PRINT_BIT_FIELD (Ebx, SMEP);\r
+ PRINT_BIT_FIELD (Ebx, BMI2);\r
+ PRINT_BIT_FIELD (Ebx, EnhancedRepMovsbStosb);\r
+ PRINT_BIT_FIELD (Ebx, INVPCID);\r
+ PRINT_BIT_FIELD (Ebx, RTM);\r
+ PRINT_BIT_FIELD (Ebx, PQM);\r
+ PRINT_BIT_FIELD (Ebx, DeprecateFpuCsDs);\r
+ PRINT_BIT_FIELD (Ebx, MPX);\r
+ PRINT_BIT_FIELD (Ebx, PQE);\r
+ PRINT_BIT_FIELD (Ebx, RDSEED);\r
+ PRINT_BIT_FIELD (Ebx, ADX);\r
+ PRINT_BIT_FIELD (Ebx, SMAP);\r
+ PRINT_BIT_FIELD (Ebx, CLFLUSHOPT);\r
+ PRINT_BIT_FIELD (Ebx, IntelProcessorTrace);\r
+ PRINT_BIT_FIELD (Ecx, PREFETCHWT1);\r
+ PRINT_BIT_FIELD (Ecx, PKU);\r
+ PRINT_BIT_FIELD (Ecx, OSPKE);\r
+ }\r
+ SubLeaf++;\r
+ } while (SubLeaf <= Eax);\r
+}\r
+\r
+/**\r
+ Display CPUID_DIRECT_CACHE_ACCESS_INFO leaf.\r
+\r
+**/\r
+VOID\r
+CpuidDirectCacheAccessInfo (\r
+ VOID\r
+ )\r
+{\r
+ UINT32 Eax;\r
+\r
+ if (CPUID_DIRECT_CACHE_ACCESS_INFO > gMaximumBasicFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuid (CPUID_DIRECT_CACHE_ACCESS_INFO, &Eax, NULL, NULL, NULL);\r
+ Print (L"CPUID_DIRECT_CACHE_ACCESS_INFO (Leaf %08x)\n", CPUID_DIRECT_CACHE_ACCESS_INFO);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, 0, 0, 0);\r
+}\r
+\r
+/**\r
+ Display CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING leaf.\r
+\r
+**/\r
+VOID\r
+CpuidArchitecturalPerformanceMonitoring (\r
+ VOID\r
+ )\r
+{\r
+ CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EAX Eax;\r
+ CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EBX Ebx;\r
+ CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EDX Edx;\r
+\r
+ if (CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING > gMaximumBasicFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuid (CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING, &Eax.Uint32, &Ebx.Uint32, NULL, &Edx.Uint32);\r
+ Print (L"CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING (Leaf %08x)\n", CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, 0, Edx.Uint32);\r
+ PRINT_BIT_FIELD (Eax, ArchPerfMonVerID);\r
+ PRINT_BIT_FIELD (Eax, PerformanceMonitorCounters);\r
+ PRINT_BIT_FIELD (Eax, PerformanceMonitorCounterWidth);\r
+ PRINT_BIT_FIELD (Eax, EbxBitVectorLength);\r
+ PRINT_BIT_FIELD (Ebx, UnhaltedCoreCycles);\r
+ PRINT_BIT_FIELD (Ebx, InstructionsRetired);\r
+ PRINT_BIT_FIELD (Ebx, UnhaltedReferenceCycles);\r
+ PRINT_BIT_FIELD (Ebx, LastLevelCacheReferences);\r
+ PRINT_BIT_FIELD (Ebx, LastLevelCacheMisses);\r
+ PRINT_BIT_FIELD (Ebx, BranchInstructionsRetired);\r
+ PRINT_BIT_FIELD (Ebx, AllBranchMispredictRetired);\r
+ PRINT_BIT_FIELD (Edx, FixedFunctionPerformanceCounters);\r
+ PRINT_BIT_FIELD (Edx, FixedFunctionPerformanceCounterWidth);\r
+}\r
+\r
+/**\r
+ Display CPUID_EXTENDED_TOPOLOGY leafs for all supported levels.\r
+\r
+**/\r
+VOID\r
+CpuidExtendedTopology (\r
+ VOID\r
+ )\r
+{\r
+ CPUID_EXTENDED_TOPOLOGY_EAX Eax;\r
+ CPUID_EXTENDED_TOPOLOGY_EBX Ebx;\r
+ CPUID_EXTENDED_TOPOLOGY_ECX Ecx;\r
+ UINT32 Edx;\r
+ UINT32 LevelNumber;\r
+\r
+ if (CPUID_EXTENDED_TOPOLOGY > gMaximumBasicFunction) {\r
+ return;\r
+ }\r
+\r
+ LevelNumber = 0;\r
+ do {\r
+ AsmCpuidEx (\r
+ CPUID_EXTENDED_TOPOLOGY, LevelNumber,\r
+ &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx\r
+ );\r
+ if (Eax.Bits.ApicIdShift != 0) {\r
+ Print (L"CPUID_EXTENDED_TOPOLOGY (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_TOPOLOGY, LevelNumber);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx);\r
+ PRINT_BIT_FIELD (Eax, ApicIdShift);\r
+ PRINT_BIT_FIELD (Ebx, LogicalProcessors);\r
+ PRINT_BIT_FIELD (Ecx, LevelNumber);\r
+ PRINT_BIT_FIELD (Ecx, LevelType);\r
+ PRINT_VALUE (Edx, x2APIC_ID);\r
+ }\r
+ LevelNumber++;\r
+ } while (Eax.Bits.ApicIdShift != 0);\r
+}\r
+\r
+/**\r
+ Display CPUID_EXTENDED_STATE sub-leaf.\r
+\r
+**/\r
+VOID\r
+CpuidExtendedStateSubLeaf (\r
+ VOID\r
+ )\r
+{\r
+ CPUID_EXTENDED_STATE_SUB_LEAF_EAX Eax;\r
+ UINT32 Ebx;\r
+ CPUID_EXTENDED_STATE_SUB_LEAF_ECX Ecx;\r
+ UINT32 Edx;\r
+\r
+ AsmCpuidEx (\r
+ CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_SUB_LEAF,\r
+ &Eax.Uint32, &Ebx, &Ecx.Uint32, &Edx\r
+ );\r
+ Print (L"CPUID_EXTENDED_STATE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_SUB_LEAF);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx.Uint32, Edx);\r
+ PRINT_BIT_FIELD (Eax, XSAVEOPT);\r
+ PRINT_BIT_FIELD (Eax, XSAVEC);\r
+ PRINT_BIT_FIELD (Eax, XGETBV);\r
+ PRINT_BIT_FIELD (Eax, XSAVES);\r
+ PRINT_VALUE (Ebx, EnabledSaveStateSize_XCR0_IA32_XSS);\r
+ PRINT_BIT_FIELD (Ecx, XCR0);\r
+ PRINT_BIT_FIELD (Ecx, PT);\r
+ PRINT_BIT_FIELD (Ecx, XCR0_1);\r
+ PRINT_VALUE (Edx, IA32_XSS_Supported_32_63);\r
+}\r
+\r
+/**\r
+ Display CPUID_EXTENDED_STATE size and offset information sub-leaf.\r
+\r
+**/\r
+VOID\r
+CpuidExtendedStateSizeOffset (\r
+ VOID\r
+ )\r
+{\r
+ UINT32 Eax;\r
+ UINT32 Ebx;\r
+ CPUID_EXTENDED_STATE_SIZE_OFFSET_ECX Ecx;\r
+ UINT32 Edx;\r
+ UINT32 SubLeaf;\r
+\r
+ for (SubLeaf = CPUID_EXTENDED_STATE_SIZE_OFFSET; SubLeaf < 32; SubLeaf++) {\r
+ AsmCpuidEx (\r
+ CPUID_EXTENDED_STATE, SubLeaf,\r
+ &Eax, &Ebx, &Ecx.Uint32, &Edx\r
+ );\r
+ if (Edx != 0) {\r
+ Print (L"CPUID_EXTENDED_STATE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_STATE, SubLeaf);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx, Ecx.Uint32, Edx);\r
+ PRINT_VALUE (Eax, FeatureSaveStateSize);\r
+ PRINT_VALUE (Ebx, FeatureSaveStateOffset);\r
+ PRINT_BIT_FIELD (Ecx, XSS);\r
+ PRINT_BIT_FIELD (Ecx, Compacted);\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Display CPUID_EXTENDED_STATE main leaf and sub-leafs.\r
+\r
+**/\r
+VOID\r
+CpuidExtendedStateMainLeaf (\r
+ VOID\r
+ )\r
+{\r
+ CPUID_EXTENDED_STATE_MAIN_LEAF_EAX Eax;\r
+ UINT32 Ebx;\r
+ UINT32 Ecx;\r
+ UINT32 Edx;\r
+\r
+ if (CPUID_EXTENDED_STATE > gMaximumBasicFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuidEx (\r
+ CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_MAIN_LEAF,\r
+ &Eax.Uint32, &Ebx, &Ecx, &Edx\r
+ );\r
+ Print (L"CPUID_EXTENDED_STATE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_MAIN_LEAF);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx, Edx);\r
+ PRINT_BIT_FIELD (Eax, x87);\r
+ PRINT_BIT_FIELD (Eax, SSE);\r
+ PRINT_BIT_FIELD (Eax, AVX);\r
+ PRINT_BIT_FIELD (Eax, MPX);\r
+ PRINT_BIT_FIELD (Eax, AVX_512);\r
+ PRINT_BIT_FIELD (Eax, IA32_XSS);\r
+ PRINT_BIT_FIELD (Eax, PKRU);\r
+ PRINT_VALUE (Ebx, EnabledSaveStateSize);\r
+ PRINT_VALUE (Ecx, SupportedSaveStateSize);\r
+ PRINT_VALUE (Edx, XCR0_Supported_32_63);\r
+\r
+ CpuidExtendedStateSubLeaf ();\r
+ CpuidExtendedStateSizeOffset ();\r
+}\r
+\r
+/**\r
+ Display CPUID_PLATFORM_QOS_MONITORING enumeration sub-leaf.\r
+\r
+**/\r
+VOID\r
+CpuidPlatformQosMonitoringEnumerationSubLeaf (\r
+ VOID\r
+ )\r
+{\r
+ UINT32 Ebx;\r
+ CPUID_PLATFORM_QOS_MONITORING_ENUMERATION_SUB_LEAF_EDX Edx;\r
+\r
+ if (CPUID_PLATFORM_QOS_MONITORING > gMaximumBasicFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuidEx (\r
+ CPUID_PLATFORM_QOS_MONITORING, CPUID_PLATFORM_QOS_MONITORING_ENUMERATION_SUB_LEAF,\r
+ NULL, &Ebx, NULL, &Edx.Uint32\r
+ );\r
+ Print (L"CPUID_PLATFORM_QOS_MONITORING (Leaf %08x, Sub-Leaf %08x)\n", CPUID_PLATFORM_QOS_MONITORING, CPUID_PLATFORM_QOS_MONITORING_ENUMERATION_SUB_LEAF);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, Ebx, 0, Edx.Uint32);\r
+ PRINT_VALUE (Ebx, Maximum_RMID_Range);\r
+ PRINT_BIT_FIELD (Edx, L3CacheQosEnforcement);\r
+}\r
+\r
+/**\r
+ Display CPUID_PLATFORM_QOS_MONITORING capability sub-leaf.\r
+\r
+**/\r
+VOID\r
+CpuidPlatformQosMonitoringCapabilitySubLeaf (\r
+ VOID\r
+ )\r
+{\r
+ UINT32 Ebx;\r
+ UINT32 Ecx;\r
+ CPUID_PLATFORM_QOS_MONITORING_CAPABILITY_SUB_LEAF_EDX Edx;\r
+\r
+ if (CPUID_PLATFORM_QOS_MONITORING > gMaximumBasicFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuidEx (\r
+ CPUID_PLATFORM_QOS_MONITORING, CPUID_PLATFORM_QOS_MONITORING_CAPABILITY_SUB_LEAF,\r
+ NULL, &Ebx, &Ecx, &Edx.Uint32\r
+ );\r
+ Print (L"CPUID_PLATFORM_QOS_MONITORING (Leaf %08x, Sub-Leaf %08x)\n", CPUID_PLATFORM_QOS_MONITORING, CPUID_PLATFORM_QOS_MONITORING_CAPABILITY_SUB_LEAF);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, Ebx, Ecx, Edx.Uint32);\r
+ PRINT_VALUE (Ebx, OccupancyConversionFactor);\r
+ PRINT_VALUE (Ecx, Maximum_RMID_Range);\r
+ PRINT_BIT_FIELD (Edx, L3CacheOccupancyMonitoring);\r
+}\r
+\r
+/**\r
+ Display CPUID_PLATFORM_QOS_ENFORCEMENT sub-leaf.\r
+\r
+**/\r
+VOID\r
+CpuidPlatformQosEnforcementResidSubLeaf (\r
+ VOID\r
+ )\r
+{\r
+ CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF_EAX Eax;\r
+ UINT32 Ebx;\r
+ CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF_ECX Ecx;\r
+ CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF_EDX Edx;\r
+\r
+ AsmCpuidEx (\r
+ CPUID_PLATFORM_QOS_ENFORCEMENT, CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF,\r
+ &Eax.Uint32, &Ebx, &Ecx.Uint32, &Edx.Uint32\r
+ );\r
+ Print (L"CPUID_PLATFORM_QOS_ENFORCEMENT (Leaf %08x, Sub-Leaf %08x)\n", CPUID_PLATFORM_QOS_ENFORCEMENT, CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx.Uint32, Edx.Uint32);\r
+ PRINT_BIT_FIELD (Eax, CapacityLength);\r
+ PRINT_VALUE (Ebx, AllocationUnitBitMap);\r
+ PRINT_BIT_FIELD (Ecx, CosUpdatesInfrequent);\r
+ PRINT_BIT_FIELD (Ecx, CodeDataPrioritization);\r
+ PRINT_BIT_FIELD (Edx, HighestCosNumber);\r
+}\r
+\r
+/**\r
+ Display CPUID_PLATFORM_QOS_ENFORCEMENT main leaf and sub-leaf.\r
+\r
+**/\r
+VOID\r
+CpuidPlatformQosEnforcementMainLeaf (\r
+ VOID\r
+ )\r
+{\r
+ CPUID_PLATFORM_QOS_ENFORCEMENT_MAIN_LEAF_EBX Ebx;\r
+\r
+ if (CPUID_PLATFORM_QOS_ENFORCEMENT > gMaximumBasicFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuidEx (\r
+ CPUID_PLATFORM_QOS_ENFORCEMENT, CPUID_PLATFORM_QOS_ENFORCEMENT_MAIN_LEAF,\r
+ NULL, &Ebx.Uint32, NULL, NULL\r
+ );\r
+ Print (L"CPUID_PLATFORM_QOS_ENFORCEMENT (Leaf %08x, Sub-Leaf %08x)\n", CPUID_PLATFORM_QOS_ENFORCEMENT, CPUID_PLATFORM_QOS_ENFORCEMENT_MAIN_LEAF);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, Ebx.Uint32, 0, 0);\r
+ PRINT_BIT_FIELD (Ebx, L3CacheQosEnforcement);\r
+\r
+ CpuidPlatformQosEnforcementResidSubLeaf ();\r
+}\r
+\r
+/**\r
+ Display CPUID_INTEL_PROCESSOR_TRACE sub-leafs.\r
+\r
+ @param[in] MaximumSubLeaf Maximum sub-leaf index for CPUID_INTEL_PROCESSOR_TRACE.\r
+\r
+**/\r
+VOID\r
+CpuidIntelProcessorTraceSubLeaf (\r
+ UINT32 MaximumSubLeaf\r
+ )\r
+{\r
+ UINT32 SubLeaf;\r
+ CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF_EAX Eax;\r
+ CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF_EBX Ebx;\r
+\r
+ for (SubLeaf = CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF; SubLeaf <= MaximumSubLeaf; SubLeaf++) {\r
+ AsmCpuidEx (\r
+ CPUID_INTEL_PROCESSOR_TRACE, SubLeaf,\r
+ &Eax.Uint32, &Ebx.Uint32, NULL, NULL\r
+ );\r
+ Print (L"CPUID_INTEL_PROCESSOR_TRACE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_PROCESSOR_TRACE, SubLeaf);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, 0, 0);\r
+ PRINT_BIT_FIELD (Eax, ConfigurableAddressRanges);\r
+ PRINT_BIT_FIELD (Eax, MtcPeriodEncodings);\r
+ PRINT_BIT_FIELD (Ebx, CycleThresholdEncodings);\r
+ PRINT_BIT_FIELD (Ebx, PsbFrequencyEncodings);\r
+ }\r
+}\r
+\r
+/**\r
+ Display CPUID_INTEL_PROCESSOR_TRACE main leaf and sub-leafs.\r
+\r
+**/\r
+VOID\r
+CpuidIntelProcessorTraceMainLeaf (\r
+ VOID\r
+ )\r
+{\r
+ UINT32 Eax;\r
+ CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_EBX Ebx;\r
+ CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_ECX Ecx;\r
+\r
+ if (CPUID_INTEL_PROCESSOR_TRACE > gMaximumBasicFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuidEx (\r
+ CPUID_INTEL_PROCESSOR_TRACE, CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF,\r
+ &Eax, &Ebx.Uint32, &Ecx.Uint32, NULL\r
+ );\r
+ Print (L"CPUID_INTEL_PROCESSOR_TRACE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_PROCESSOR_TRACE, CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx.Uint32, Ecx.Uint32, 0);\r
+ PRINT_VALUE (Eax, MaximumSubLeaf);\r
+ PRINT_BIT_FIELD (Ebx, Cr3Filter);\r
+ PRINT_BIT_FIELD (Ebx, ConfigurablePsb);\r
+ PRINT_BIT_FIELD (Ebx, IpTraceStopFiltering);\r
+ PRINT_BIT_FIELD (Ebx, Mtc);\r
+ PRINT_BIT_FIELD (Ecx, RTIT);\r
+ PRINT_BIT_FIELD (Ecx, ToPA);\r
+ PRINT_BIT_FIELD (Ecx, SingleRangeOutput);\r
+ PRINT_BIT_FIELD (Ecx, TraceTransportSubsystem);\r
+ PRINT_BIT_FIELD (Ecx, LIP);\r
+\r
+ CpuidIntelProcessorTraceSubLeaf (Eax);\r
+}\r
+\r
+/**\r
+ Display CPUID_TIME_STAMP_COUNTER leaf.\r
+\r
+**/\r
+VOID\r
+CpuidTimeStampCounter (\r
+ VOID\r
+ )\r
+{\r
+ UINT32 Eax;\r
+ UINT32 Ebx;\r
+\r
+ if (CPUID_TIME_STAMP_COUNTER > gMaximumBasicFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuid (CPUID_TIME_STAMP_COUNTER, &Eax, &Ebx, NULL, NULL);\r
+ Print (L"CPUID_TIME_STAMP_COUNTER (Leaf %08x)\n", CPUID_TIME_STAMP_COUNTER);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx, 0, 0);\r
+}\r
+\r
+/**\r
+ Display CPUID_PROCESSOR_FREQUENCY leaf.\r
+\r
+**/\r
+VOID\r
+CpuidProcessorFrequency (\r
+ VOID\r
+ )\r
+{\r
+ CPUID_PROCESSOR_FREQUENCY_EAX Eax;\r
+ CPUID_PROCESSOR_FREQUENCY_EBX Ebx;\r
+ CPUID_PROCESSOR_FREQUENCY_ECX Ecx;\r
+\r
+ if (CPUID_PROCESSOR_FREQUENCY > gMaximumBasicFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuid (CPUID_PROCESSOR_FREQUENCY, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, NULL);\r
+ Print (L"CPUID_PROCESSOR_FREQUENCY (Leaf %08x)\n", CPUID_PROCESSOR_FREQUENCY);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, 0);\r
+ PRINT_BIT_FIELD (Eax, ProcessorBaseFrequency);\r
+ PRINT_BIT_FIELD (Ebx, MaximumFrequency);\r
+ PRINT_BIT_FIELD (Ecx, BusFrequency);\r
+}\r
+\r
+/**\r
+ Display CPUID_SOC_VENDOR sub-leafs that contain the SoC Vendor Brand String.\r
+ Also display these sub-leafs as a single SoC Vendor Brand String.\r
+\r
+**/\r
+VOID\r
+CpuidSocVendorBrandString (\r
+ VOID\r
+ )\r
+{\r
+ CPUID_SOC_VENDOR_BRAND_STRING_DATA Eax;\r
+ CPUID_SOC_VENDOR_BRAND_STRING_DATA Ebx;\r
+ CPUID_SOC_VENDOR_BRAND_STRING_DATA Ecx;\r
+ CPUID_SOC_VENDOR_BRAND_STRING_DATA Edx;\r
+ //\r
+ // Array to store brand string from 3 brand string leafs with\r
+ // 4 32-bit brand string values per leaf and an extra value to\r
+ // null terminate the string.\r
+ //\r
+ UINT32 BrandString[3 * 4 + 1];\r
+\r
+ AsmCpuidEx (\r
+ CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING1,\r
+ &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32\r
+ );\r
+ Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING1);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32);\r
+ BrandString[0] = Eax.Uint32;\r
+ BrandString[1] = Ebx.Uint32;\r
+ BrandString[2] = Ecx.Uint32;\r
+ BrandString[3] = Edx.Uint32;\r
+\r
+ AsmCpuidEx (\r
+ CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING2,\r
+ &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32\r
+ );\r
+ Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING2);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32);\r
+ BrandString[4] = Eax.Uint32;\r
+ BrandString[5] = Ebx.Uint32;\r
+ BrandString[6] = Ecx.Uint32;\r
+ BrandString[7] = Edx.Uint32;\r
+\r
+ AsmCpuidEx (\r
+ CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING3,\r
+ &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32\r
+ );\r
+ Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING3);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32);\r
+ BrandString[8] = Eax.Uint32;\r
+ BrandString[9] = Ebx.Uint32;\r
+ BrandString[10] = Ecx.Uint32;\r
+ BrandString[11] = Edx.Uint32;\r
+\r
+ BrandString[12] = 0;\r
+\r
+ Print (L"Vendor Brand String = %a\n", (CHAR8 *)BrandString);\r
+}\r
+\r
+/**\r
+ Display CPUID_SOC_VENDOR main leaf and sub-leafs.\r
+\r
+**/\r
+VOID\r
+CpuidSocVendor (\r
+ VOID\r
+ )\r
+{\r
+ UINT32 Eax;\r
+ CPUID_SOC_VENDOR_MAIN_LEAF_EBX Ebx;\r
+ UINT32 Ecx;\r
+ UINT32 Edx;\r
+\r
+ if (CPUID_SOC_VENDOR > gMaximumBasicFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuidEx (\r
+ CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_MAIN_LEAF,\r
+ &Eax, &Ebx.Uint32, &Ecx, &Edx\r
+ );\r
+ Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_MAIN_LEAF);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx.Uint32, Ecx, Edx);\r
+ if (Eax < 3) {\r
+ Print (L" Not Supported\n");\r
+ return;\r
+ }\r
+ PRINT_VALUE (Eax, MaxSOCID_Index);\r
+ PRINT_BIT_FIELD (Ebx, SocVendorId);\r
+ PRINT_BIT_FIELD (Ebx, IsVendorScheme);\r
+ PRINT_VALUE (Ecx, ProjectID);\r
+ PRINT_VALUE (Edx, SteppingID);\r
+ CpuidSocVendorBrandString ();\r
+}\r
+\r
+/**\r
+ Display CPUID_EXTENDED_FUNCTION leaf.\r
+\r
+**/\r
+VOID\r
+CpuidExtendedFunction (\r
+ VOID\r
+ )\r
+{\r
+ UINT32 Eax;\r
+\r
+ AsmCpuid (CPUID_EXTENDED_FUNCTION, &Eax, NULL, NULL, NULL);\r
+ Print (L"CPUID_EXTENDED_FUNCTION (Leaf %08x)\n", CPUID_EXTENDED_FUNCTION);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, 0, 0, 0);\r
+ PRINT_VALUE (Eax, MaximumExtendedFunction);\r
+\r
+ gMaximumExtendedFunction = Eax;\r
+}\r
+\r
+/**\r
+ Display CPUID_EXTENDED_CPU_SIG leaf.\r
+\r
+**/\r
+VOID\r
+CpuidExtendedCpuSig (\r
+ VOID\r
+ )\r
+{\r
+ UINT32 Eax;\r
+ CPUID_EXTENDED_CPU_SIG_ECX Ecx;\r
+ CPUID_EXTENDED_CPU_SIG_EDX Edx;\r
+\r
+ if (CPUID_EXTENDED_CPU_SIG > gMaximumExtendedFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuid (CPUID_EXTENDED_CPU_SIG, &Eax, NULL, &Ecx.Uint32, &Edx.Uint32);\r
+ Print (L"CPUID_EXTENDED_CPU_SIG (Leaf %08x)\n", CPUID_EXTENDED_CPU_SIG);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, 0, Ecx.Uint32, Edx.Uint32);\r
+ PRINT_BIT_FIELD (Ecx, LAHF_SAHF);\r
+ PRINT_BIT_FIELD (Ecx, LZCNT);\r
+ PRINT_BIT_FIELD (Ecx, PREFETCHW);\r
+ PRINT_BIT_FIELD (Edx, SYSCALL_SYSRET);\r
+ PRINT_BIT_FIELD (Edx, NX);\r
+ PRINT_BIT_FIELD (Edx, Page1GB);\r
+ PRINT_BIT_FIELD (Edx, RDTSCP);\r
+ PRINT_BIT_FIELD (Edx, LM);\r
+}\r
+\r
+/**\r
+ Display CPUID_BRAND_STRING1, CPUID_BRAND_STRING2 and CPUID_BRAND_STRING3\r
+ leafs. Also display these three leafs as a single brand string.\r
+\r
+**/\r
+VOID\r
+CpuidProcessorBrandString (\r
+ VOID\r
+ )\r
+{\r
+ CPUID_BRAND_STRING_DATA Eax;\r
+ CPUID_BRAND_STRING_DATA Ebx;\r
+ CPUID_BRAND_STRING_DATA Ecx;\r
+ CPUID_BRAND_STRING_DATA Edx;\r
+ //\r
+ // Array to store brand string from 3 brand string leafs with\r
+ // 4 32-bit brand string values per leaf and an extra value to\r
+ // null terminate the string.\r
+ //\r
+ UINT32 BrandString[3 * 4 + 1];\r
+\r
+ if (CPUID_BRAND_STRING1 <= gMaximumExtendedFunction) {\r
+ AsmCpuid (CPUID_BRAND_STRING1, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32);\r
+ Print (L"CPUID_BRAND_STRING1 (Leaf %08x)\n", CPUID_BRAND_STRING1);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32);\r
+ BrandString[0] = Eax.Uint32;\r
+ BrandString[1] = Ebx.Uint32;\r
+ BrandString[2] = Ecx.Uint32;\r
+ BrandString[3] = Edx.Uint32;\r
+ }\r
+\r
+ if (CPUID_BRAND_STRING2 <= gMaximumExtendedFunction) {\r
+ AsmCpuid (CPUID_BRAND_STRING2, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32);\r
+ Print (L"CPUID_BRAND_STRING2 (Leaf %08x)\n", CPUID_BRAND_STRING2);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32);\r
+ BrandString[4] = Eax.Uint32;\r
+ BrandString[5] = Ebx.Uint32;\r
+ BrandString[6] = Ecx.Uint32;\r
+ BrandString[7] = Edx.Uint32;\r
+ }\r
+\r
+ if (CPUID_BRAND_STRING3 <= gMaximumExtendedFunction) {\r
+ AsmCpuid (CPUID_BRAND_STRING3, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32);\r
+ Print (L"CPUID_BRAND_STRING3 (Leaf %08x)\n", CPUID_BRAND_STRING3);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32);\r
+ BrandString[8] = Eax.Uint32;\r
+ BrandString[9] = Ebx.Uint32;\r
+ BrandString[10] = Ecx.Uint32;\r
+ BrandString[11] = Edx.Uint32;\r
+ }\r
+\r
+ BrandString[12] = 0;\r
+\r
+ Print (L"Brand String = %a\n", (CHAR8 *)BrandString);\r
+}\r
+\r
+/**\r
+ Display CPUID_EXTENDED_CACHE_INFO leaf.\r
+\r
+**/\r
+VOID\r
+CpuidExtendedCacheInfo (\r
+ VOID\r
+ )\r
+{\r
+ CPUID_EXTENDED_CACHE_INFO_ECX Ecx;\r
+\r
+ if (CPUID_EXTENDED_CACHE_INFO > gMaximumExtendedFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuid (CPUID_EXTENDED_CACHE_INFO, NULL, NULL, &Ecx.Uint32, NULL);\r
+ Print (L"CPUID_EXTENDED_CACHE_INFO (Leaf %08x)\n", CPUID_EXTENDED_CACHE_INFO);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, 0, Ecx.Uint32, 0);\r
+ PRINT_BIT_FIELD (Ecx, CacheLineSize);\r
+ PRINT_BIT_FIELD (Ecx, L2Associativity);\r
+ PRINT_BIT_FIELD (Ecx, CacheSize);\r
+}\r
+\r
+/**\r
+ Display CPUID_EXTENDED_TIME_STAMP_COUNTER leaf.\r
+\r
+**/\r
+VOID\r
+CpuidExtendedTimeStampCounter (\r
+ VOID\r
+ )\r
+{\r
+ CPUID_EXTENDED_TIME_STAMP_COUNTER_EDX Edx;\r
+\r
+ if (CPUID_EXTENDED_TIME_STAMP_COUNTER > gMaximumExtendedFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuid (CPUID_EXTENDED_TIME_STAMP_COUNTER, NULL, NULL, NULL, &Edx.Uint32);\r
+ Print (L"CPUID_EXTENDED_TIME_STAMP_COUNTER (Leaf %08x)\n", CPUID_EXTENDED_TIME_STAMP_COUNTER);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, 0, 0, Edx.Uint32);\r
+ PRINT_BIT_FIELD (Edx, InvariantTsc);\r
+}\r
+\r
+/**\r
+ Display CPUID_VIR_PHY_ADDRESS_SIZE leaf.\r
+\r
+**/\r
+VOID\r
+CpuidVirPhyAddressSize (\r
+ VOID\r
+ )\r
+{\r
+ CPUID_VIR_PHY_ADDRESS_SIZE_EAX Eax;\r
+\r
+ if (CPUID_VIR_PHY_ADDRESS_SIZE > gMaximumExtendedFunction) {\r
+ return;\r
+ }\r
+\r
+ AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &Eax.Uint32, NULL, NULL, NULL);\r
+ Print (L"CPUID_VIR_PHY_ADDRESS_SIZE (Leaf %08x)\n", CPUID_VIR_PHY_ADDRESS_SIZE);\r
+ Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, 0, 0, 0);\r
+ PRINT_BIT_FIELD (Eax, PhysicalAddressBits);\r
+ PRINT_BIT_FIELD (Eax, LinearAddressBits);\r
+}\r
+\r
+/**\r
+ The user Entry Point for Application. The user code starts with this function\r
+ as the real entry point for the application.\r
+\r
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
+ @param[in] SystemTable A pointer to the EFI System Table.\r
+\r
+ @retval EFI_SUCCESS The entry point is executed successfully.\r
+ @retval other Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UefiMain (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ Print (L"UEFI CPUID Version 0.5\n");\r
+\r
+ CpuidSignature ();\r
+ CpuidVersionInfo ();\r
+ CpuidCacheInfo ();\r
+ CpuidSerialNumber ();\r
+ CpuidCacheParams();\r
+ CpuidMonitorMwait ();\r
+ CpuidThermalPowerManagement ();\r
+ CpuidStructuredExtendedFeatureFlags ();\r
+ CpuidDirectCacheAccessInfo();\r
+ CpuidArchitecturalPerformanceMonitoring ();\r
+ CpuidExtendedTopology ();\r
+ CpuidExtendedStateMainLeaf ();\r
+ CpuidPlatformQosMonitoringEnumerationSubLeaf ();\r
+ CpuidPlatformQosMonitoringCapabilitySubLeaf ();\r
+ CpuidPlatformQosEnforcementMainLeaf ();\r
+ CpuidIntelProcessorTraceMainLeaf ();\r
+ CpuidTimeStampCounter ();\r
+ CpuidProcessorFrequency ();\r
+ CpuidSocVendor ();\r
+ CpuidExtendedFunction ();\r
+ CpuidExtendedCpuSig ();\r
+ CpuidProcessorBrandString ();\r
+ CpuidExtendedCacheInfo ();\r
+ CpuidExtendedTimeStampCounter ();\r
+ CpuidVirPhyAddressSize ();\r
+\r
+ return EFI_SUCCESS;\r
+}\r