1 /** @file 2 UEFI Application to display CPUID leaf information. 3 4 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 **/ 14 15 #include <Uefi.h> 16 #include <Library/BaseLib.h> 17 #include <Library/UefiLib.h> 18 #include <Register/Cpuid.h> 19 20 /// 21 /// Macro used to display the value of a bit field in a register returned by CPUID. 22 /// 23 #define PRINT_BIT_FIELD(Variable, FieldName) \ 24 Print (L"%5a%42a: %x\n", #Variable, #FieldName, Variable.Bits.FieldName); 25 26 /// 27 /// Macro used to display the value of a register returned by CPUID. 28 /// 29 #define PRINT_VALUE(Variable, Description) \ 30 Print (L"%5a%42a: %x\n", #Variable, #Description, Variable); 31 32 /// 33 /// Structure for cache description lookup table 34 /// 35 typedef struct { 36 UINT8 CacheDescriptor; 37 CHAR8 *Type; 38 CHAR8 *Description; 39 } CPUID_CACHE_INFO_DESCRIPTION; 40 41 /// 42 /// Cache description lookup table 43 /// 44 CPUID_CACHE_INFO_DESCRIPTION mCpuidCacheInfoDescription[] = { 45 { 0x00 , "General" , "Null descriptor, this byte contains no information" }, 46 { 0x01 , "TLB" , "Instruction TLB: 4 KByte pages, 4-way set associative, 32 entries" }, 47 { 0x02 , "TLB" , "Instruction TLB: 4 MByte pages, fully associative, 2 entries" }, 48 { 0x03 , "TLB" , "Data TLB: 4 KByte pages, 4-way set associative, 64 entries" }, 49 { 0x04 , "TLB" , "Data TLB: 4 MByte pages, 4-way set associative, 8 entries" }, 50 { 0x05 , "TLB" , "Data TLB1: 4 MByte pages, 4-way set associative, 32 entries" }, 51 { 0x06 , "Cache" , "1st-level instruction cache: 8 KBytes, 4-way set associative, 32 byte line size" }, 52 { 0x08 , "Cache" , "1st-level instruction cache: 16 KBytes, 4-way set associative, 32 byte line size" }, 53 { 0x09 , "Cache" , "1st-level instruction cache: 32KBytes, 4-way set associative, 64 byte line size" }, 54 { 0x0A , "Cache" , "1st-level data cache: 8 KBytes, 2-way set associative, 32 byte line size" }, 55 { 0x0B , "TLB" , "Instruction TLB: 4 MByte pages, 4-way set associative, 4 entries" }, 56 { 0x0C , "Cache" , "1st-level data cache: 16 KBytes, 4-way set associative, 32 byte line size" }, 57 { 0x0D , "Cache" , "1st-level data cache: 16 KBytes, 4-way set associative, 64 byte line size" }, 58 { 0x0E , "Cache" , "1st-level data cache: 24 KBytes, 6-way set associative, 64 byte line size" }, 59 { 0x1D , "Cache" , "2nd-level cache: 128 KBytes, 2-way set associative, 64 byte line size" }, 60 { 0x21 , "Cache" , "2nd-level cache: 256 KBytes, 8-way set associative, 64 byte line size" }, 61 { 0x22 , "Cache" , "3rd-level cache: 512 KBytes, 4-way set associative, 64 byte line size, 2 lines per sector" }, 62 { 0x23 , "Cache" , "3rd-level cache: 1 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector" }, 63 { 0x24 , "Cache" , "2nd-level cache: 1 MBytes, 16-way set associative, 64 byte line size" }, 64 { 0x25 , "Cache" , "3rd-level cache: 2 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector" }, 65 { 0x29 , "Cache" , "3rd-level cache: 4 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector" }, 66 { 0x2C , "Cache" , "1st-level data cache: 32 KBytes, 8-way set associative, 64 byte line size" }, 67 { 0x30 , "Cache" , "1st-level instruction cache: 32 KBytes, 8-way set associative, 64 byte line size" }, 68 { 0x40 , "Cache" , "No 2nd-level cache or, if processor contains a valid 2nd-level cache, no 3rd-level cache" }, 69 { 0x41 , "Cache" , "2nd-level cache: 128 KBytes, 4-way set associative, 32 byte line size" }, 70 { 0x42 , "Cache" , "2nd-level cache: 256 KBytes, 4-way set associative, 32 byte line size" }, 71 { 0x43 , "Cache" , "2nd-level cache: 512 KBytes, 4-way set associative, 32 byte line size" }, 72 { 0x44 , "Cache" , "2nd-level cache: 1 MByte, 4-way set associative, 32 byte line size" }, 73 { 0x45 , "Cache" , "2nd-level cache: 2 MByte, 4-way set associative, 32 byte line size" }, 74 { 0x46 , "Cache" , "3rd-level cache: 4 MByte, 4-way set associative, 64 byte line size" }, 75 { 0x47 , "Cache" , "3rd-level cache: 8 MByte, 8-way set associative, 64 byte line size" }, 76 { 0x48 , "Cache" , "2nd-level cache: 3MByte, 12-way set associative, 64 byte line size" }, 77 { 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" }, 78 { 0x4A , "Cache" , "3rd-level cache: 6MByte, 12-way set associative, 64 byte line size" }, 79 { 0x4B , "Cache" , "3rd-level cache: 8MByte, 16-way set associative, 64 byte line size" }, 80 { 0x4C , "Cache" , "3rd-level cache: 12MByte, 12-way set associative, 64 byte line size" }, 81 { 0x4D , "Cache" , "3rd-level cache: 16MByte, 16-way set associative, 64 byte line size" }, 82 { 0x4E , "Cache" , "2nd-level cache: 6MByte, 24-way set associative, 64 byte line size" }, 83 { 0x4F , "TLB" , "Instruction TLB: 4 KByte pages, 32 entries" }, 84 { 0x50 , "TLB" , "Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 64 entries" }, 85 { 0x51 , "TLB" , "Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 128 entries" }, 86 { 0x52 , "TLB" , "Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 256 entries" }, 87 { 0x55 , "TLB" , "Instruction TLB: 2-MByte or 4-MByte pages, fully associative, 7 entries" }, 88 { 0x56 , "TLB" , "Data TLB0: 4 MByte pages, 4-way set associative, 16 entries" }, 89 { 0x57 , "TLB" , "Data TLB0: 4 KByte pages, 4-way associative, 16 entries" }, 90 { 0x59 , "TLB" , "Data TLB0: 4 KByte pages, fully associative, 16 entries" }, 91 { 0x5A , "TLB" , "Data TLB0: 2 MByte or 4 MByte pages, 4-way set associative, 32 entries" }, 92 { 0x5B , "TLB" , "Data TLB: 4 KByte and 4 MByte pages, 64 entries" }, 93 { 0x5C , "TLB" , "Data TLB: 4 KByte and 4 MByte pages,128 entries" }, 94 { 0x5D , "TLB" , "Data TLB: 4 KByte and 4 MByte pages,256 entries" }, 95 { 0x60 , "Cache" , "1st-level data cache: 16 KByte, 8-way set associative, 64 byte line size" }, 96 { 0x61 , "TLB" , "Instruction TLB: 4 KByte pages, fully associative, 48 entries" }, 97 { 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" }, 98 { 0x64 , "TLB" , "Data TLB: 4 KByte pages, 4-way set associative, 512 entries" }, 99 { 0x66 , "Cache" , "1st-level data cache: 8 KByte, 4-way set associative, 64 byte line size" }, 100 { 0x67 , "Cache" , "1st-level data cache: 16 KByte, 4-way set associative, 64 byte line size" }, 101 { 0x68 , "Cache" , "1st-level data cache: 32 KByte, 4-way set associative, 64 byte line size" }, 102 { 0x6A , "Cache" , "uTLB: 4 KByte pages, 8-way set associative, 64 entries" }, 103 { 0x6B , "Cache" , "DTLB: 4 KByte pages, 8-way set associative, 256 entries" }, 104 { 0x6C , "Cache" , "DTLB: 2M/4M pages, 8-way set associative, 128 entries" }, 105 { 0x6D , "Cache" , "DTLB: 1 GByte pages, fully associative, 16 entries" }, 106 { 0x70 , "Cache" , "Trace cache: 12 K-uop, 8-way set associative" }, 107 { 0x71 , "Cache" , "Trace cache: 16 K-uop, 8-way set associative" }, 108 { 0x72 , "Cache" , "Trace cache: 32 K-uop, 8-way set associative" }, 109 { 0x76 , "TLB" , "Instruction TLB: 2M/4M pages, fully associative, 8 entries" }, 110 { 0x78 , "Cache" , "2nd-level cache: 1 MByte, 4-way set associative, 64byte line size" }, 111 { 0x79 , "Cache" , "2nd-level cache: 128 KByte, 8-way set associative, 64 byte line size, 2 lines per sector" }, 112 { 0x7A , "Cache" , "2nd-level cache: 256 KByte, 8-way set associative, 64 byte line size, 2 lines per sector" }, 113 { 0x7B , "Cache" , "2nd-level cache: 512 KByte, 8-way set associative, 64 byte line size, 2 lines per sector" }, 114 { 0x7C , "Cache" , "2nd-level cache: 1 MByte, 8-way set associative, 64 byte line size, 2 lines per sector" }, 115 { 0x7D , "Cache" , "2nd-level cache: 2 MByte, 8-way set associative, 64byte line size" }, 116 { 0x7F , "Cache" , "2nd-level cache: 512 KByte, 2-way set associative, 64-byte line size" }, 117 { 0x80 , "Cache" , "2nd-level cache: 512 KByte, 8-way set associative, 64-byte line size" }, 118 { 0x82 , "Cache" , "2nd-level cache: 256 KByte, 8-way set associative, 32 byte line size" }, 119 { 0x83 , "Cache" , "2nd-level cache: 512 KByte, 8-way set associative, 32 byte line size" }, 120 { 0x84 , "Cache" , "2nd-level cache: 1 MByte, 8-way set associative, 32 byte line size" }, 121 { 0x85 , "Cache" , "2nd-level cache: 2 MByte, 8-way set associative, 32 byte line size" }, 122 { 0x86 , "Cache" , "2nd-level cache: 512 KByte, 4-way set associative, 64 byte line size" }, 123 { 0x87 , "Cache" , "2nd-level cache: 1 MByte, 8-way set associative, 64 byte line size" }, 124 { 0xA0 , "DTLB" , "DTLB: 4k pages, fully associative, 32 entries" }, 125 { 0xB0 , "TLB" , "Instruction TLB: 4 KByte pages, 4-way set associative, 128 entries" }, 126 { 0xB1 , "TLB" , "Instruction TLB: 2M pages, 4-way, 8 entries or 4M pages, 4-way, 4 entries" }, 127 { 0xB2 , "TLB" , "Instruction TLB: 4KByte pages, 4-way set associative, 64 entries" }, 128 { 0xB3 , "TLB" , "Data TLB: 4 KByte pages, 4-way set associative, 128 entries" }, 129 { 0xB4 , "TLB" , "Data TLB1: 4 KByte pages, 4-way associative, 256 entries" }, 130 { 0xB5 , "TLB" , "Instruction TLB: 4KByte pages, 8-way set associative, 64 entries" }, 131 { 0xB6 , "TLB" , "Instruction TLB: 4KByte pages, 8-way set associative, 128 entries" }, 132 { 0xBA , "TLB" , "Data TLB1: 4 KByte pages, 4-way associative, 64 entries" }, 133 { 0xC0 , "TLB" , "Data TLB: 4 KByte and 4 MByte pages, 4-way associative, 8 entries" }, 134 { 0xC1 , "STLB" , "Shared 2nd-Level TLB: 4 KByte/2MByte pages, 8-way associative, 1024 entries" }, 135 { 0xC2 , "DTLB" , "DTLB: 4 KByte/2 MByte pages, 4-way associative, 16 entries" }, 136 { 0xC3 , "STLB" , "Shared 2nd-Level TLB: 4 KByte /2 MByte pages, 6-way associative, 1536 entries. Also 1GBbyte pages, 4-way, 16 entries." }, 137 { 0xC4 , "DTLB" , "DTLB: 2M/4M Byte pages, 4-way associative, 32 entries" }, 138 { 0xCA , "STLB" , "Shared 2nd-Level TLB: 4 KByte pages, 4-way associative, 512 entries" }, 139 { 0xD0 , "Cache" , "3rd-level cache: 512 KByte, 4-way set associative, 64 byte line size" }, 140 { 0xD1 , "Cache" , "3rd-level cache: 1 MByte, 4-way set associative, 64 byte line size" }, 141 { 0xD2 , "Cache" , "3rd-level cache: 2 MByte, 4-way set associative, 64 byte line size" }, 142 { 0xD6 , "Cache" , "3rd-level cache: 1 MByte, 8-way set associative, 64 byte line size" }, 143 { 0xD7 , "Cache" , "3rd-level cache: 2 MByte, 8-way set associative, 64 byte line size" }, 144 { 0xD8 , "Cache" , "3rd-level cache: 4 MByte, 8-way set associative, 64 byte line size" }, 145 { 0xDC , "Cache" , "3rd-level cache: 1.5 MByte, 12-way set associative, 64 byte line size" }, 146 { 0xDD , "Cache" , "3rd-level cache: 3 MByte, 12-way set associative, 64 byte line size" }, 147 { 0xDE , "Cache" , "3rd-level cache: 6 MByte, 12-way set associative, 64 byte line size" }, 148 { 0xE2 , "Cache" , "3rd-level cache: 2 MByte, 16-way set associative, 64 byte line size" }, 149 { 0xE3 , "Cache" , "3rd-level cache: 4 MByte, 16-way set associative, 64 byte line size" }, 150 { 0xE4 , "Cache" , "3rd-level cache: 8 MByte, 16-way set associative, 64 byte line size" }, 151 { 0xEA , "Cache" , "3rd-level cache: 12MByte, 24-way set associative, 64 byte line size" }, 152 { 0xEB , "Cache" , "3rd-level cache: 18MByte, 24-way set associative, 64 byte line size" }, 153 { 0xEC , "Cache" , "3rd-level cache: 24MByte, 24-way set associative, 64 byte line size" }, 154 { 0xF0 , "Prefetch" , "64-Byte prefetching" }, 155 { 0xF1 , "Prefetch" , "128-Byte prefetching" }, 156 { 0xFF , "General" , "CPUID leaf 2 does not report cache descriptor information, use CPUID leaf 4 to query cache parameters" } 157 }; 158 159 /// 160 /// The maximum supported CPUID leaf index starting from leaf 0x00000000. 161 /// 162 UINT32 gMaximumBasicFunction = CPUID_SIGNATURE; 163 164 /// 165 /// The maximum supported CPUID leaf index starting from leaf 0x80000000. 166 /// 167 UINT32 gMaximumExtendedFunction = CPUID_EXTENDED_FUNCTION; 168 169 /** 170 Display CPUID_SIGNATURE leaf. 171 172 **/ 173 VOID 174 CpuidSignature ( 175 VOID 176 ) 177 { 178 UINT32 Eax; 179 UINT32 Ebx; 180 UINT32 Ecx; 181 UINT32 Edx; 182 CHAR8 Signature[13]; 183 184 AsmCpuid (CPUID_SIGNATURE, &Eax, &Ebx, &Ecx, &Edx); 185 186 Print (L"CPUID_SIGNATURE (Leaf %08x)\n", CPUID_SIGNATURE); 187 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx, Ecx, Edx); 188 PRINT_VALUE (Eax, MaximumLeaf); 189 *(UINT32 *)(Signature + 0) = Ebx; 190 *(UINT32 *)(Signature + 4) = Edx; 191 *(UINT32 *)(Signature + 8) = Ecx; 192 Signature [12] = 0; 193 Print (L" Signature = %a\n", Signature); 194 195 gMaximumBasicFunction = Eax; 196 } 197 198 /** 199 Display CPUID_VERSION_INFO leaf. 200 201 **/ 202 VOID 203 CpuidVersionInfo ( 204 VOID 205 ) 206 { 207 CPUID_VERSION_INFO_EAX Eax; 208 CPUID_VERSION_INFO_EBX Ebx; 209 CPUID_VERSION_INFO_ECX Ecx; 210 CPUID_VERSION_INFO_EDX Edx; 211 UINT32 DisplayFamily; 212 UINT32 DisplayModel; 213 214 if (CPUID_VERSION_INFO > gMaximumBasicFunction) { 215 return; 216 } 217 218 AsmCpuid (CPUID_VERSION_INFO, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); 219 220 Print (L"CPUID_VERSION_INFO (Leaf %08x)\n", CPUID_VERSION_INFO); 221 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); 222 223 DisplayFamily = Eax.Bits.FamilyId; 224 if (Eax.Bits.FamilyId == 0x0F) { 225 DisplayFamily |= (Eax.Bits.ExtendedFamilyId << 4); 226 } 227 228 DisplayModel = Eax.Bits.Model; 229 if (Eax.Bits.FamilyId == 0x06 || Eax.Bits.FamilyId == 0x0f) { 230 DisplayModel |= (Eax.Bits.ExtendedModelId << 4); 231 } 232 233 Print (L" Family = %x Model = %x Stepping = %x\n", DisplayFamily, DisplayModel, Eax.Bits.SteppingId); 234 235 PRINT_BIT_FIELD (Eax, SteppingId); 236 PRINT_BIT_FIELD (Eax, Model); 237 PRINT_BIT_FIELD (Eax, FamilyId); 238 PRINT_BIT_FIELD (Eax, ProcessorType); 239 PRINT_BIT_FIELD (Eax, ExtendedModelId); 240 PRINT_BIT_FIELD (Eax, ExtendedFamilyId); 241 PRINT_BIT_FIELD (Ebx, BrandIndex); 242 PRINT_BIT_FIELD (Ebx, CacheLineSize); 243 PRINT_BIT_FIELD (Ebx, MaximumAddressableIdsForLogicalProcessors); 244 PRINT_BIT_FIELD (Ebx, InitialLocalApicId); 245 PRINT_BIT_FIELD (Ecx, SSE3); 246 PRINT_BIT_FIELD (Ecx, PCLMULQDQ); 247 PRINT_BIT_FIELD (Ecx, DTES64); 248 PRINT_BIT_FIELD (Ecx, MONITOR); 249 PRINT_BIT_FIELD (Ecx, DS_CPL); 250 PRINT_BIT_FIELD (Ecx, VMX); 251 PRINT_BIT_FIELD (Ecx, SMX); 252 PRINT_BIT_FIELD (Ecx, TM2); 253 PRINT_BIT_FIELD (Ecx, SSSE3); 254 PRINT_BIT_FIELD (Ecx, CNXT_ID); 255 PRINT_BIT_FIELD (Ecx, SDBG); 256 PRINT_BIT_FIELD (Ecx, FMA); 257 PRINT_BIT_FIELD (Ecx, CMPXCHG16B); 258 PRINT_BIT_FIELD (Ecx, xTPR_Update_Control); 259 PRINT_BIT_FIELD (Ecx, PDCM); 260 PRINT_BIT_FIELD (Ecx, PCID); 261 PRINT_BIT_FIELD (Ecx, DCA); 262 PRINT_BIT_FIELD (Ecx, SSE4_1); 263 PRINT_BIT_FIELD (Ecx, SSE4_2); 264 PRINT_BIT_FIELD (Ecx, x2APIC); 265 PRINT_BIT_FIELD (Ecx, MOVBE); 266 PRINT_BIT_FIELD (Ecx, POPCNT); 267 PRINT_BIT_FIELD (Ecx, TSC_Deadline); 268 PRINT_BIT_FIELD (Ecx, AESNI); 269 PRINT_BIT_FIELD (Ecx, XSAVE); 270 PRINT_BIT_FIELD (Ecx, OSXSAVE); 271 PRINT_BIT_FIELD (Ecx, AVX); 272 PRINT_BIT_FIELD (Ecx, F16C); 273 PRINT_BIT_FIELD (Ecx, RDRAND); 274 PRINT_BIT_FIELD (Edx, FPU); 275 PRINT_BIT_FIELD (Edx, VME); 276 PRINT_BIT_FIELD (Edx, DE); 277 PRINT_BIT_FIELD (Edx, PSE); 278 PRINT_BIT_FIELD (Edx, TSC); 279 PRINT_BIT_FIELD (Edx, MSR); 280 PRINT_BIT_FIELD (Edx, PAE); 281 PRINT_BIT_FIELD (Edx, MCE); 282 PRINT_BIT_FIELD (Edx, CX8); 283 PRINT_BIT_FIELD (Edx, APIC); 284 PRINT_BIT_FIELD (Edx, SEP); 285 PRINT_BIT_FIELD (Edx, MTRR); 286 PRINT_BIT_FIELD (Edx, PGE); 287 PRINT_BIT_FIELD (Edx, MCA); 288 PRINT_BIT_FIELD (Edx, CMOV); 289 PRINT_BIT_FIELD (Edx, PAT); 290 PRINT_BIT_FIELD (Edx, PSE_36); 291 PRINT_BIT_FIELD (Edx, PSN); 292 PRINT_BIT_FIELD (Edx, CLFSH); 293 PRINT_BIT_FIELD (Edx, DS); 294 PRINT_BIT_FIELD (Edx, ACPI); 295 PRINT_BIT_FIELD (Edx, MMX); 296 PRINT_BIT_FIELD (Edx, FXSR); 297 PRINT_BIT_FIELD (Edx, SSE); 298 PRINT_BIT_FIELD (Edx, SSE2); 299 PRINT_BIT_FIELD (Edx, SS); 300 PRINT_BIT_FIELD (Edx, HTT); 301 PRINT_BIT_FIELD (Edx, TM); 302 PRINT_BIT_FIELD (Edx, PBE); 303 } 304 305 /** 306 Lookup a cache description string from the mCpuidCacheInfoDescription table. 307 308 @param[in] CacheDescriptor Cache descriptor value from CPUID_CACHE_INFO. 309 310 **/ 311 CPUID_CACHE_INFO_DESCRIPTION * 312 LookupCacheDescription ( 313 UINT8 CacheDescriptor 314 ) 315 { 316 UINTN NumDescriptors; 317 UINTN Descriptor; 318 319 if (CacheDescriptor == 0x00) { 320 return NULL; 321 } 322 NumDescriptors = sizeof (mCpuidCacheInfoDescription)/sizeof (mCpuidCacheInfoDescription[0]); 323 for (Descriptor = 0; Descriptor < NumDescriptors; Descriptor++) { 324 if (CacheDescriptor == mCpuidCacheInfoDescription[Descriptor].CacheDescriptor) { 325 return &mCpuidCacheInfoDescription[Descriptor]; 326 } 327 } 328 return NULL; 329 } 330 331 /** 332 Display CPUID_CACHE_INFO leaf for each supported cache descriptor. 333 334 **/ 335 VOID 336 CpuidCacheInfo ( 337 VOID 338 ) 339 { 340 CPUID_CACHE_INFO_CACHE_TLB Eax; 341 CPUID_CACHE_INFO_CACHE_TLB Ebx; 342 CPUID_CACHE_INFO_CACHE_TLB Ecx; 343 CPUID_CACHE_INFO_CACHE_TLB Edx; 344 UINTN Index; 345 CPUID_CACHE_INFO_DESCRIPTION *CacheDescription; 346 347 if (CPUID_CACHE_INFO > gMaximumBasicFunction) { 348 return; 349 } 350 351 AsmCpuid (CPUID_CACHE_INFO, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); 352 353 Print (L"CPUID_CACHE_INFO (Leaf %08x)\n", CPUID_CACHE_INFO); 354 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); 355 if (Eax.Bits.NotValid == 0) { 356 // 357 // Process Eax.CacheDescriptor[1..3]. Ignore Eax.CacheDescriptor[0] 358 // 359 for (Index = 1; Index < 4; Index++) { 360 CacheDescription = LookupCacheDescription (Eax.CacheDescriptor[Index]); 361 if (CacheDescription != NULL) { 362 Print (L" %-8a %a\n", 363 CacheDescription->Type, 364 CacheDescription->Description 365 ); 366 } 367 } 368 } 369 if (Ebx.Bits.NotValid == 0) { 370 // 371 // Process Ebx.CacheDescriptor[0..3] 372 // 373 for (Index = 0; Index < 4; Index++) { 374 CacheDescription = LookupCacheDescription (Ebx.CacheDescriptor[Index]); 375 if (CacheDescription != NULL) { 376 Print (L" %-8a %a\n", 377 CacheDescription->Type, 378 CacheDescription->Description 379 ); 380 } 381 } 382 } 383 if (Ecx.Bits.NotValid == 0) { 384 // 385 // Process Ecx.CacheDescriptor[0..3] 386 // 387 for (Index = 0; Index < 4; Index++) { 388 CacheDescription = LookupCacheDescription (Ecx.CacheDescriptor[Index]); 389 if (CacheDescription != NULL) { 390 Print (L" %-8a %a\n", 391 CacheDescription->Type, 392 CacheDescription->Description 393 ); 394 } 395 } 396 } 397 if (Edx.Bits.NotValid == 0) { 398 // 399 // Process Edx.CacheDescriptor[0..3] 400 // 401 for (Index = 0; Index < 4; Index++) { 402 CacheDescription = LookupCacheDescription (Edx.CacheDescriptor[Index]); 403 if (CacheDescription != NULL) { 404 Print (L" %-8a %a\n", 405 CacheDescription->Type, 406 CacheDescription->Description 407 ); 408 } 409 } 410 } 411 } 412 413 /** 414 Display CPUID_SERIAL_NUMBER leaf if it is supported. 415 416 **/ 417 VOID 418 CpuidSerialNumber ( 419 VOID 420 ) 421 { 422 CPUID_VERSION_INFO_EDX VersionInfoEdx; 423 UINT32 Ecx; 424 UINT32 Edx; 425 426 Print (L"CPUID_SERIAL_NUMBER (Leaf %08x)\n", CPUID_SERIAL_NUMBER); 427 428 if (CPUID_SERIAL_NUMBER > gMaximumBasicFunction) { 429 return; 430 } 431 432 AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32); 433 if (VersionInfoEdx.Bits.PSN == 0) { 434 Print (L" Not Supported\n"); 435 return; 436 } 437 438 AsmCpuid (CPUID_SERIAL_NUMBER, NULL, NULL, &Ecx, &Edx); 439 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, 0, Ecx, Edx); 440 Print (L" Processor Serial Number = %08x%08x%08x\n", 0, Edx, Ecx); 441 } 442 443 /** 444 Display CPUID_CACHE_PARAMS for all supported sub-leafs. 445 446 **/ 447 VOID 448 CpuidCacheParams ( 449 VOID 450 ) 451 { 452 UINT32 CacheLevel; 453 CPUID_CACHE_PARAMS_EAX Eax; 454 CPUID_CACHE_PARAMS_EBX Ebx; 455 UINT32 Ecx; 456 CPUID_CACHE_PARAMS_EDX Edx; 457 458 if (CPUID_CACHE_PARAMS > gMaximumBasicFunction) { 459 return; 460 } 461 462 CacheLevel = 0; 463 do { 464 AsmCpuidEx ( 465 CPUID_CACHE_PARAMS, CacheLevel, 466 &Eax.Uint32, &Ebx.Uint32, &Ecx, &Edx.Uint32 467 ); 468 if (Eax.Bits.CacheType != CPUID_CACHE_PARAMS_CACHE_TYPE_NULL) { 469 Print (L"CPUID_CACHE_PARAMS (Leaf %08x, Sub-Leaf %08x)\n", CPUID_CACHE_PARAMS, CacheLevel); 470 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx, Edx.Uint32); 471 PRINT_BIT_FIELD (Eax, CacheType); 472 PRINT_BIT_FIELD (Eax, CacheLevel); 473 PRINT_BIT_FIELD (Eax, SelfInitializingCache); 474 PRINT_BIT_FIELD (Eax, FullyAssociativeCache); 475 PRINT_BIT_FIELD (Eax, MaximumAddressableIdsForLogicalProcessors); 476 PRINT_BIT_FIELD (Eax, MaximumAddressableIdsForProcessorCores); 477 PRINT_BIT_FIELD (Ebx, LineSize); 478 PRINT_BIT_FIELD (Ebx, LinePartitions); 479 PRINT_BIT_FIELD (Ebx, Ways); 480 PRINT_VALUE (Ecx, NumberOfSets); 481 PRINT_BIT_FIELD (Edx, Invalidate); 482 PRINT_BIT_FIELD (Edx, CacheInclusiveness); 483 PRINT_BIT_FIELD (Edx, ComplexCacheIndexing); 484 } 485 CacheLevel++; 486 } while (Eax.Bits.CacheType != CPUID_CACHE_PARAMS_CACHE_TYPE_NULL); 487 } 488 489 /** 490 Display CPUID_MONITOR_MWAIT leaf. 491 492 **/ 493 VOID 494 CpuidMonitorMwait ( 495 VOID 496 ) 497 { 498 CPUID_MONITOR_MWAIT_EAX Eax; 499 CPUID_MONITOR_MWAIT_EBX Ebx; 500 CPUID_MONITOR_MWAIT_ECX Ecx; 501 CPUID_MONITOR_MWAIT_EDX Edx; 502 503 if (CPUID_MONITOR_MWAIT > gMaximumBasicFunction) { 504 return; 505 } 506 507 AsmCpuid (CPUID_MONITOR_MWAIT, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); 508 509 Print (L"CPUID_MONITOR_MWAIT (Leaf %08x)\n", CPUID_MONITOR_MWAIT); 510 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); 511 512 PRINT_BIT_FIELD (Eax, SmallestMonitorLineSize); 513 PRINT_BIT_FIELD (Ebx, LargestMonitorLineSize); 514 PRINT_BIT_FIELD (Ecx, ExtensionsSupported); 515 PRINT_BIT_FIELD (Ecx, InterruptAsBreak); 516 PRINT_BIT_FIELD (Edx, C0States); 517 PRINT_BIT_FIELD (Edx, C1States); 518 PRINT_BIT_FIELD (Edx, C2States); 519 PRINT_BIT_FIELD (Edx, C3States); 520 PRINT_BIT_FIELD (Edx, C4States); 521 PRINT_BIT_FIELD (Edx, C5States); 522 PRINT_BIT_FIELD (Edx, C6States); 523 PRINT_BIT_FIELD (Edx, C7States); 524 } 525 526 /** 527 Display CPUID_THERMAL_POWER_MANAGEMENT leaf. 528 529 **/ 530 VOID 531 CpuidThermalPowerManagement ( 532 VOID 533 ) 534 { 535 CPUID_THERMAL_POWER_MANAGEMENT_EAX Eax; 536 CPUID_THERMAL_POWER_MANAGEMENT_EBX Ebx; 537 CPUID_THERMAL_POWER_MANAGEMENT_ECX Ecx; 538 539 if (CPUID_THERMAL_POWER_MANAGEMENT > gMaximumBasicFunction) { 540 return; 541 } 542 543 AsmCpuid (CPUID_THERMAL_POWER_MANAGEMENT, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, NULL); 544 545 Print (L"CPUID_THERMAL_POWER_MANAGEMENT (Leaf %08x)\n", CPUID_THERMAL_POWER_MANAGEMENT); 546 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, 0); 547 548 PRINT_BIT_FIELD (Eax, DigitalTemperatureSensor); 549 PRINT_BIT_FIELD (Eax, TurboBoostTechnology); 550 PRINT_BIT_FIELD (Eax, ARAT); 551 PRINT_BIT_FIELD (Eax, PLN); 552 PRINT_BIT_FIELD (Eax, ECMD); 553 PRINT_BIT_FIELD (Eax, PTM); 554 PRINT_BIT_FIELD (Eax, HWP); 555 PRINT_BIT_FIELD (Eax, HWP_Notification); 556 PRINT_BIT_FIELD (Eax, HWP_Activity_Window); 557 PRINT_BIT_FIELD (Eax, HWP_Energy_Performance_Preference); 558 PRINT_BIT_FIELD (Eax, HWP_Package_Level_Request); 559 PRINT_BIT_FIELD (Eax, HDC); 560 PRINT_BIT_FIELD (Ebx, InterruptThresholds); 561 PRINT_BIT_FIELD (Ecx, HardwareCoordinationFeedback); 562 PRINT_BIT_FIELD (Ecx, PerformanceEnergyBias); 563 } 564 565 /** 566 Display CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS for all supported sub-leafs. 567 568 **/ 569 VOID 570 CpuidStructuredExtendedFeatureFlags ( 571 VOID 572 ) 573 { 574 UINT32 Eax; 575 CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_EBX Ebx; 576 CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX Ecx; 577 UINT32 SubLeaf; 578 579 if (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS > gMaximumBasicFunction) { 580 return; 581 } 582 583 AsmCpuidEx ( 584 CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, 585 CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, 586 &Eax, NULL, NULL, NULL 587 ); 588 for (SubLeaf = 0; SubLeaf <= Eax; SubLeaf++) { 589 AsmCpuidEx ( 590 CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, 591 SubLeaf, 592 NULL, &Ebx.Uint32, &Ecx.Uint32, NULL 593 ); 594 if (Ebx.Uint32 != 0 || Ecx.Uint32 != 0) { 595 Print (L"CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS (Leaf %08x, Sub-Leaf %08x)\n", CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, SubLeaf); 596 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx.Uint32, Ecx.Uint32, 0); 597 PRINT_BIT_FIELD (Ebx, FSGSBASE); 598 PRINT_BIT_FIELD (Ebx, IA32_TSC_ADJUST); 599 PRINT_BIT_FIELD (Ebx, SGX); 600 PRINT_BIT_FIELD (Ebx, BMI1); 601 PRINT_BIT_FIELD (Ebx, HLE); 602 PRINT_BIT_FIELD (Ebx, AVX2); 603 PRINT_BIT_FIELD (Ebx, FDP_EXCPTN_ONLY); 604 PRINT_BIT_FIELD (Ebx, SMEP); 605 PRINT_BIT_FIELD (Ebx, BMI2); 606 PRINT_BIT_FIELD (Ebx, EnhancedRepMovsbStosb); 607 PRINT_BIT_FIELD (Ebx, INVPCID); 608 PRINT_BIT_FIELD (Ebx, RTM); 609 PRINT_BIT_FIELD (Ebx, RDT_M); 610 PRINT_BIT_FIELD (Ebx, DeprecateFpuCsDs); 611 PRINT_BIT_FIELD (Ebx, MPX); 612 PRINT_BIT_FIELD (Ebx, RDT_A); 613 PRINT_BIT_FIELD (Ebx, RDSEED); 614 PRINT_BIT_FIELD (Ebx, ADX); 615 PRINT_BIT_FIELD (Ebx, SMAP); 616 PRINT_BIT_FIELD (Ebx, CLFLUSHOPT); 617 PRINT_BIT_FIELD (Ebx, CLWB); 618 PRINT_BIT_FIELD (Ebx, IntelProcessorTrace); 619 PRINT_BIT_FIELD (Ebx, SHA); 620 PRINT_BIT_FIELD (Ecx, PREFETCHWT1); 621 PRINT_BIT_FIELD (Ecx, UMIP); 622 PRINT_BIT_FIELD (Ecx, PKU); 623 PRINT_BIT_FIELD (Ecx, OSPKE); 624 PRINT_BIT_FIELD (Ecx, MAWAU); 625 PRINT_BIT_FIELD (Ecx, RDPID); 626 PRINT_BIT_FIELD (Ecx, SGX_LC); 627 } 628 } 629 } 630 631 /** 632 Display CPUID_DIRECT_CACHE_ACCESS_INFO leaf. 633 634 **/ 635 VOID 636 CpuidDirectCacheAccessInfo ( 637 VOID 638 ) 639 { 640 UINT32 Eax; 641 642 if (CPUID_DIRECT_CACHE_ACCESS_INFO > gMaximumBasicFunction) { 643 return; 644 } 645 646 AsmCpuid (CPUID_DIRECT_CACHE_ACCESS_INFO, &Eax, NULL, NULL, NULL); 647 Print (L"CPUID_DIRECT_CACHE_ACCESS_INFO (Leaf %08x)\n", CPUID_DIRECT_CACHE_ACCESS_INFO); 648 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, 0, 0, 0); 649 } 650 651 /** 652 Display CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING leaf. 653 654 **/ 655 VOID 656 CpuidArchitecturalPerformanceMonitoring ( 657 VOID 658 ) 659 { 660 CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EAX Eax; 661 CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EBX Ebx; 662 CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING_EDX Edx; 663 664 if (CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING > gMaximumBasicFunction) { 665 return; 666 } 667 668 AsmCpuid (CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING, &Eax.Uint32, &Ebx.Uint32, NULL, &Edx.Uint32); 669 Print (L"CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING (Leaf %08x)\n", CPUID_ARCHITECTURAL_PERFORMANCE_MONITORING); 670 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, 0, Edx.Uint32); 671 PRINT_BIT_FIELD (Eax, ArchPerfMonVerID); 672 PRINT_BIT_FIELD (Eax, PerformanceMonitorCounters); 673 PRINT_BIT_FIELD (Eax, PerformanceMonitorCounterWidth); 674 PRINT_BIT_FIELD (Eax, EbxBitVectorLength); 675 PRINT_BIT_FIELD (Ebx, UnhaltedCoreCycles); 676 PRINT_BIT_FIELD (Ebx, InstructionsRetired); 677 PRINT_BIT_FIELD (Ebx, UnhaltedReferenceCycles); 678 PRINT_BIT_FIELD (Ebx, LastLevelCacheReferences); 679 PRINT_BIT_FIELD (Ebx, LastLevelCacheMisses); 680 PRINT_BIT_FIELD (Ebx, BranchInstructionsRetired); 681 PRINT_BIT_FIELD (Ebx, AllBranchMispredictRetired); 682 PRINT_BIT_FIELD (Edx, FixedFunctionPerformanceCounters); 683 PRINT_BIT_FIELD (Edx, FixedFunctionPerformanceCounterWidth); 684 } 685 686 /** 687 Display CPUID_EXTENDED_TOPOLOGY leafs for all supported levels. 688 689 **/ 690 VOID 691 CpuidExtendedTopology ( 692 VOID 693 ) 694 { 695 CPUID_EXTENDED_TOPOLOGY_EAX Eax; 696 CPUID_EXTENDED_TOPOLOGY_EBX Ebx; 697 CPUID_EXTENDED_TOPOLOGY_ECX Ecx; 698 UINT32 Edx; 699 UINT32 LevelNumber; 700 701 if (CPUID_EXTENDED_TOPOLOGY > gMaximumBasicFunction) { 702 return; 703 } 704 705 LevelNumber = 0; 706 do { 707 AsmCpuidEx ( 708 CPUID_EXTENDED_TOPOLOGY, LevelNumber, 709 &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx 710 ); 711 if (Eax.Bits.ApicIdShift != 0) { 712 Print (L"CPUID_EXTENDED_TOPOLOGY (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_TOPOLOGY, LevelNumber); 713 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx); 714 PRINT_BIT_FIELD (Eax, ApicIdShift); 715 PRINT_BIT_FIELD (Ebx, LogicalProcessors); 716 PRINT_BIT_FIELD (Ecx, LevelNumber); 717 PRINT_BIT_FIELD (Ecx, LevelType); 718 PRINT_VALUE (Edx, x2APIC_ID); 719 } 720 LevelNumber++; 721 } while (Eax.Bits.ApicIdShift != 0); 722 } 723 724 /** 725 Display CPUID_EXTENDED_STATE sub-leaf. 726 727 **/ 728 VOID 729 CpuidExtendedStateSubLeaf ( 730 VOID 731 ) 732 { 733 CPUID_EXTENDED_STATE_SUB_LEAF_EAX Eax; 734 UINT32 Ebx; 735 CPUID_EXTENDED_STATE_SUB_LEAF_ECX Ecx; 736 UINT32 Edx; 737 738 AsmCpuidEx ( 739 CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_SUB_LEAF, 740 &Eax.Uint32, &Ebx, &Ecx.Uint32, &Edx 741 ); 742 Print (L"CPUID_EXTENDED_STATE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_SUB_LEAF); 743 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx.Uint32, Edx); 744 PRINT_BIT_FIELD (Eax, XSAVEOPT); 745 PRINT_BIT_FIELD (Eax, XSAVEC); 746 PRINT_BIT_FIELD (Eax, XGETBV); 747 PRINT_BIT_FIELD (Eax, XSAVES); 748 PRINT_VALUE (Ebx, EnabledSaveStateSize_XCR0_IA32_XSS); 749 PRINT_BIT_FIELD (Ecx, XCR0); 750 PRINT_BIT_FIELD (Ecx, PT); 751 PRINT_BIT_FIELD (Ecx, XCR0_1); 752 PRINT_VALUE (Edx, IA32_XSS_Supported_32_63); 753 } 754 755 /** 756 Display CPUID_EXTENDED_STATE size and offset information sub-leaf. 757 758 **/ 759 VOID 760 CpuidExtendedStateSizeOffset ( 761 VOID 762 ) 763 { 764 UINT32 Eax; 765 UINT32 Ebx; 766 CPUID_EXTENDED_STATE_SIZE_OFFSET_ECX Ecx; 767 UINT32 Edx; 768 UINT32 SubLeaf; 769 770 for (SubLeaf = CPUID_EXTENDED_STATE_SIZE_OFFSET; SubLeaf < 32; SubLeaf++) { 771 AsmCpuidEx ( 772 CPUID_EXTENDED_STATE, SubLeaf, 773 &Eax, &Ebx, &Ecx.Uint32, &Edx 774 ); 775 if (Edx != 0) { 776 Print (L"CPUID_EXTENDED_STATE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_STATE, SubLeaf); 777 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx, Ecx.Uint32, Edx); 778 PRINT_VALUE (Eax, FeatureSaveStateSize); 779 PRINT_VALUE (Ebx, FeatureSaveStateOffset); 780 PRINT_BIT_FIELD (Ecx, XSS); 781 PRINT_BIT_FIELD (Ecx, Compacted); 782 } 783 } 784 } 785 786 /** 787 Display CPUID_EXTENDED_STATE main leaf and sub-leafs. 788 789 **/ 790 VOID 791 CpuidExtendedStateMainLeaf ( 792 VOID 793 ) 794 { 795 CPUID_EXTENDED_STATE_MAIN_LEAF_EAX Eax; 796 UINT32 Ebx; 797 UINT32 Ecx; 798 UINT32 Edx; 799 800 if (CPUID_EXTENDED_STATE > gMaximumBasicFunction) { 801 return; 802 } 803 804 AsmCpuidEx ( 805 CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_MAIN_LEAF, 806 &Eax.Uint32, &Ebx, &Ecx, &Edx 807 ); 808 Print (L"CPUID_EXTENDED_STATE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_MAIN_LEAF); 809 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx, Edx); 810 PRINT_BIT_FIELD (Eax, x87); 811 PRINT_BIT_FIELD (Eax, SSE); 812 PRINT_BIT_FIELD (Eax, AVX); 813 PRINT_BIT_FIELD (Eax, MPX); 814 PRINT_BIT_FIELD (Eax, AVX_512); 815 PRINT_BIT_FIELD (Eax, IA32_XSS); 816 PRINT_BIT_FIELD (Eax, PKRU); 817 PRINT_VALUE (Ebx, EnabledSaveStateSize); 818 PRINT_VALUE (Ecx, SupportedSaveStateSize); 819 PRINT_VALUE (Edx, XCR0_Supported_32_63); 820 821 CpuidExtendedStateSubLeaf (); 822 CpuidExtendedStateSizeOffset (); 823 } 824 825 /** 826 Display CPUID_INTEL_RDT_MONITORING enumeration sub-leaf. 827 828 **/ 829 VOID 830 CpuidIntelRdtMonitoringEnumerationSubLeaf ( 831 VOID 832 ) 833 { 834 UINT32 Ebx; 835 CPUID_INTEL_RDT_MONITORING_ENUMERATION_SUB_LEAF_EDX Edx; 836 837 if (CPUID_INTEL_RDT_MONITORING > gMaximumBasicFunction) { 838 return; 839 } 840 841 AsmCpuidEx ( 842 CPUID_INTEL_RDT_MONITORING, CPUID_INTEL_RDT_MONITORING_ENUMERATION_SUB_LEAF, 843 NULL, &Ebx, NULL, &Edx.Uint32 844 ); 845 Print (L"CPUID_INTEL_RDT_MONITORING (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_MONITORING, CPUID_INTEL_RDT_MONITORING_ENUMERATION_SUB_LEAF); 846 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, Ebx, 0, Edx.Uint32); 847 PRINT_VALUE (Ebx, Maximum_RMID_Range); 848 PRINT_BIT_FIELD (Edx, L3CacheRDT_M); 849 } 850 851 /** 852 Display CPUID_INTEL_RDT_MONITORING L3 cache capability sub-leaf. 853 854 **/ 855 VOID 856 CpuidIntelRdtMonitoringL3CacheCapabilitySubLeaf ( 857 VOID 858 ) 859 { 860 UINT32 Ebx; 861 UINT32 Ecx; 862 CPUID_INTEL_RDT_MONITORING_L3_CACHE_SUB_LEAF_EDX Edx; 863 864 if (CPUID_INTEL_RDT_MONITORING > gMaximumBasicFunction) { 865 return; 866 } 867 868 AsmCpuidEx ( 869 CPUID_INTEL_RDT_MONITORING, CPUID_INTEL_RDT_MONITORING_L3_CACHE_SUB_LEAF, 870 NULL, &Ebx, &Ecx, &Edx.Uint32 871 ); 872 Print (L"CPUID_INTEL_RDT_MONITORING (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_MONITORING, CPUID_INTEL_RDT_MONITORING_L3_CACHE_SUB_LEAF); 873 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, Ebx, Ecx, Edx.Uint32); 874 PRINT_VALUE (Ebx, OccupancyConversionFactor); 875 PRINT_VALUE (Ecx, Maximum_RMID_Range); 876 PRINT_BIT_FIELD (Edx, L3CacheOccupancyMonitoring); 877 PRINT_BIT_FIELD (Edx, L3CacheTotalBandwidthMonitoring); 878 PRINT_BIT_FIELD (Edx, L3CacheLocalBandwidthMonitoring); 879 } 880 881 /** 882 Display CPUID_INTEL_RDT_ALLOCATION L3 cache allocation technology enumeration 883 sub-leaf. 884 885 **/ 886 VOID 887 CpuidIntelRdtAllocationL3CacheSubLeaf ( 888 VOID 889 ) 890 { 891 CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_EAX Eax; 892 UINT32 Ebx; 893 CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_ECX Ecx; 894 CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_EDX Edx; 895 896 AsmCpuidEx ( 897 CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF, 898 &Eax.Uint32, &Ebx, &Ecx.Uint32, &Edx.Uint32 899 ); 900 Print (L"CPUID_INTEL_RDT_ALLOCATION (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF); 901 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx.Uint32, Edx.Uint32); 902 PRINT_BIT_FIELD (Eax, CapacityLength); 903 PRINT_VALUE (Ebx, AllocationUnitBitMap); 904 PRINT_BIT_FIELD (Ecx, CosUpdatesInfrequent); 905 PRINT_BIT_FIELD (Ecx, CodeDataPrioritization); 906 PRINT_BIT_FIELD (Edx, HighestCosNumber); 907 } 908 909 /** 910 Display CPUID_INTEL_RDT_ALLOCATION L2 cache allocation technology enumeration 911 sub-leaf. 912 913 **/ 914 VOID 915 CpuidIntelRdtAllocationL2CacheSubLeaf ( 916 VOID 917 ) 918 { 919 CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF_EAX Eax; 920 UINT32 Ebx; 921 CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF_EDX Edx; 922 923 AsmCpuidEx ( 924 CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF, 925 &Eax.Uint32, &Ebx, NULL, &Edx.Uint32 926 ); 927 Print (L"CPUID_INTEL_RDT_ALLOCATION (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF); 928 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, 0, Edx.Uint32); 929 PRINT_BIT_FIELD (Eax, CapacityLength); 930 PRINT_VALUE (Ebx, AllocationUnitBitMap); 931 PRINT_BIT_FIELD (Edx, HighestCosNumber); 932 } 933 934 /** 935 Display CPUID_INTEL_RDT_ALLOCATION main leaf and sub-leaves. 936 937 **/ 938 VOID 939 CpuidIntelRdtAllocationMainLeaf ( 940 VOID 941 ) 942 { 943 CPUID_INTEL_RDT_ALLOCATION_ENUMERATION_SUB_LEAF_EBX Ebx; 944 945 if (CPUID_INTEL_RDT_ALLOCATION > gMaximumBasicFunction) { 946 return; 947 } 948 949 AsmCpuidEx ( 950 CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_ENUMERATION_SUB_LEAF, 951 NULL, &Ebx.Uint32, NULL, NULL 952 ); 953 Print (L"CPUID_INTEL_RDT_ALLOCATION (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_ENUMERATION_SUB_LEAF); 954 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, Ebx.Uint32, 0, 0); 955 PRINT_BIT_FIELD (Ebx, L3CacheAllocation); 956 PRINT_BIT_FIELD (Ebx, L2CacheAllocation); 957 958 CpuidIntelRdtAllocationL3CacheSubLeaf (); 959 CpuidIntelRdtAllocationL2CacheSubLeaf (); 960 } 961 962 /** 963 Display Sub-Leaf 0 Enumeration of Intel SGX Capabilities. 964 965 **/ 966 VOID 967 CpuidEnumerationOfIntelSgxCapabilities0SubLeaf ( 968 VOID 969 ) 970 { 971 CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF_EAX Eax; 972 UINT32 Ebx; 973 CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF_EDX Edx; 974 975 AsmCpuidEx ( 976 CPUID_INTEL_SGX, CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF, 977 &Eax.Uint32, &Ebx, NULL, &Edx.Uint32 978 ); 979 Print (L"CPUID_INTEL_SGX (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_SGX, CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF); 980 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, 0, Edx.Uint32); 981 PRINT_BIT_FIELD (Eax, SGX1); 982 PRINT_BIT_FIELD (Eax, SGX2); 983 PRINT_BIT_FIELD (Edx, MaxEnclaveSize_Not64); 984 PRINT_BIT_FIELD (Edx, MaxEnclaveSize_64); 985 } 986 987 /** 988 Display Sub-Leaf 1 Enumeration of Intel SGX Capabilities. 989 990 **/ 991 VOID 992 CpuidEnumerationOfIntelSgxCapabilities1SubLeaf ( 993 VOID 994 ) 995 { 996 UINT32 Eax; 997 UINT32 Ebx; 998 UINT32 Ecx; 999 UINT32 Edx; 1000 1001 AsmCpuidEx ( 1002 CPUID_INTEL_SGX, CPUID_INTEL_SGX_CAPABILITIES_1_SUB_LEAF, 1003 &Eax, &Ebx, &Ecx, &Edx 1004 ); 1005 Print (L"CPUID_INTEL_SGX (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_SGX, CPUID_INTEL_SGX_CAPABILITIES_1_SUB_LEAF); 1006 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx, Ecx, Edx); 1007 } 1008 1009 /** 1010 Display Sub-Leaf Index 2 or Higher Enumeration of Intel SGX Resources. 1011 1012 **/ 1013 VOID 1014 CpuidEnumerationOfIntelSgxResourcesSubLeaf ( 1015 VOID 1016 ) 1017 { 1018 CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EAX Eax; 1019 CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EBX Ebx; 1020 CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_ECX Ecx; 1021 CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EDX Edx; 1022 UINT32 SubLeaf; 1023 1024 SubLeaf = CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF; 1025 do { 1026 AsmCpuidEx ( 1027 CPUID_INTEL_SGX, SubLeaf, 1028 &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32 1029 ); 1030 if (Eax.Bits.SubLeafType == 0x1) { 1031 Print (L"CPUID_INTEL_SGX (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_SGX, SubLeaf); 1032 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); 1033 PRINT_BIT_FIELD (Eax, SubLeafType); 1034 PRINT_BIT_FIELD (Eax, LowAddressOfEpcSection); 1035 PRINT_BIT_FIELD (Ebx, HighAddressOfEpcSection); 1036 PRINT_BIT_FIELD (Ecx, EpcSection); 1037 PRINT_BIT_FIELD (Ecx, LowSizeOfEpcSection); 1038 PRINT_BIT_FIELD (Edx, HighSizeOfEpcSection); 1039 } 1040 SubLeaf++; 1041 } while (Eax.Bits.SubLeafType == 0x1); 1042 } 1043 1044 /** 1045 Display Intel SGX Resource Enumeration. 1046 1047 **/ 1048 VOID 1049 CpuidEnumerationOfIntelSgx ( 1050 VOID 1051 ) 1052 { 1053 CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_EBX Ebx; 1054 1055 if (CPUID_INTEL_SGX > gMaximumBasicFunction) { 1056 return; 1057 } 1058 1059 AsmCpuidEx ( 1060 CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, 1061 CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, 1062 NULL, &Ebx.Uint32, NULL, NULL 1063 ); 1064 if (Ebx.Bits.SGX != 1) { 1065 // 1066 // Only if CPUID.(EAX=07H, ECX=0H):EBX.SGX = 1, the processor has support 1067 // for Intel SGX. 1068 // 1069 return; 1070 } 1071 1072 CpuidEnumerationOfIntelSgxCapabilities0SubLeaf (); 1073 CpuidEnumerationOfIntelSgxCapabilities1SubLeaf (); 1074 CpuidEnumerationOfIntelSgxResourcesSubLeaf (); 1075 } 1076 1077 /** 1078 Display CPUID_INTEL_PROCESSOR_TRACE sub-leafs. 1079 1080 @param[in] MaximumSubLeaf Maximum sub-leaf index for CPUID_INTEL_PROCESSOR_TRACE. 1081 1082 **/ 1083 VOID 1084 CpuidIntelProcessorTraceSubLeaf ( 1085 UINT32 MaximumSubLeaf 1086 ) 1087 { 1088 UINT32 SubLeaf; 1089 CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF_EAX Eax; 1090 CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF_EBX Ebx; 1091 1092 for (SubLeaf = CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF; SubLeaf <= MaximumSubLeaf; SubLeaf++) { 1093 AsmCpuidEx ( 1094 CPUID_INTEL_PROCESSOR_TRACE, SubLeaf, 1095 &Eax.Uint32, &Ebx.Uint32, NULL, NULL 1096 ); 1097 Print (L"CPUID_INTEL_PROCESSOR_TRACE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_PROCESSOR_TRACE, SubLeaf); 1098 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, 0, 0); 1099 PRINT_BIT_FIELD (Eax, ConfigurableAddressRanges); 1100 PRINT_BIT_FIELD (Eax, MtcPeriodEncodings); 1101 PRINT_BIT_FIELD (Ebx, CycleThresholdEncodings); 1102 PRINT_BIT_FIELD (Ebx, PsbFrequencyEncodings); 1103 } 1104 } 1105 1106 /** 1107 Display CPUID_INTEL_PROCESSOR_TRACE main leaf and sub-leafs. 1108 1109 **/ 1110 VOID 1111 CpuidIntelProcessorTraceMainLeaf ( 1112 VOID 1113 ) 1114 { 1115 UINT32 Eax; 1116 CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_EBX Ebx; 1117 CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_ECX Ecx; 1118 1119 if (CPUID_INTEL_PROCESSOR_TRACE > gMaximumBasicFunction) { 1120 return; 1121 } 1122 1123 AsmCpuidEx ( 1124 CPUID_INTEL_PROCESSOR_TRACE, CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF, 1125 &Eax, &Ebx.Uint32, &Ecx.Uint32, NULL 1126 ); 1127 Print (L"CPUID_INTEL_PROCESSOR_TRACE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_PROCESSOR_TRACE, CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF); 1128 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx.Uint32, Ecx.Uint32, 0); 1129 PRINT_VALUE (Eax, MaximumSubLeaf); 1130 PRINT_BIT_FIELD (Ebx, Cr3Filter); 1131 PRINT_BIT_FIELD (Ebx, ConfigurablePsb); 1132 PRINT_BIT_FIELD (Ebx, IpTraceStopFiltering); 1133 PRINT_BIT_FIELD (Ebx, Mtc); 1134 PRINT_BIT_FIELD (Ebx, PTWrite); 1135 PRINT_BIT_FIELD (Ebx, PowerEventTrace); 1136 PRINT_BIT_FIELD (Ecx, RTIT); 1137 PRINT_BIT_FIELD (Ecx, ToPA); 1138 PRINT_BIT_FIELD (Ecx, SingleRangeOutput); 1139 PRINT_BIT_FIELD (Ecx, TraceTransportSubsystem); 1140 PRINT_BIT_FIELD (Ecx, LIP); 1141 1142 CpuidIntelProcessorTraceSubLeaf (Eax); 1143 } 1144 1145 /** 1146 Display CPUID_TIME_STAMP_COUNTER leaf. 1147 1148 **/ 1149 VOID 1150 CpuidTimeStampCounter ( 1151 VOID 1152 ) 1153 { 1154 UINT32 Eax; 1155 UINT32 Ebx; 1156 UINT32 Ecx; 1157 1158 if (CPUID_TIME_STAMP_COUNTER > gMaximumBasicFunction) { 1159 return; 1160 } 1161 1162 AsmCpuid (CPUID_TIME_STAMP_COUNTER, &Eax, &Ebx, &Ecx, NULL); 1163 Print (L"CPUID_TIME_STAMP_COUNTER (Leaf %08x)\n", CPUID_TIME_STAMP_COUNTER); 1164 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx, Ecx, 0); 1165 } 1166 1167 /** 1168 Display CPUID_PROCESSOR_FREQUENCY leaf. 1169 1170 **/ 1171 VOID 1172 CpuidProcessorFrequency ( 1173 VOID 1174 ) 1175 { 1176 CPUID_PROCESSOR_FREQUENCY_EAX Eax; 1177 CPUID_PROCESSOR_FREQUENCY_EBX Ebx; 1178 CPUID_PROCESSOR_FREQUENCY_ECX Ecx; 1179 1180 if (CPUID_PROCESSOR_FREQUENCY > gMaximumBasicFunction) { 1181 return; 1182 } 1183 1184 AsmCpuid (CPUID_PROCESSOR_FREQUENCY, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, NULL); 1185 Print (L"CPUID_PROCESSOR_FREQUENCY (Leaf %08x)\n", CPUID_PROCESSOR_FREQUENCY); 1186 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, 0); 1187 PRINT_BIT_FIELD (Eax, ProcessorBaseFrequency); 1188 PRINT_BIT_FIELD (Ebx, MaximumFrequency); 1189 PRINT_BIT_FIELD (Ecx, BusFrequency); 1190 } 1191 1192 /** 1193 Display CPUID_SOC_VENDOR sub-leafs that contain the SoC Vendor Brand String. 1194 Also display these sub-leafs as a single SoC Vendor Brand String. 1195 1196 **/ 1197 VOID 1198 CpuidSocVendorBrandString ( 1199 VOID 1200 ) 1201 { 1202 CPUID_SOC_VENDOR_BRAND_STRING_DATA Eax; 1203 CPUID_SOC_VENDOR_BRAND_STRING_DATA Ebx; 1204 CPUID_SOC_VENDOR_BRAND_STRING_DATA Ecx; 1205 CPUID_SOC_VENDOR_BRAND_STRING_DATA Edx; 1206 // 1207 // Array to store brand string from 3 brand string leafs with 1208 // 4 32-bit brand string values per leaf and an extra value to 1209 // null terminate the string. 1210 // 1211 UINT32 BrandString[3 * 4 + 1]; 1212 1213 AsmCpuidEx ( 1214 CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING1, 1215 &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32 1216 ); 1217 Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING1); 1218 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); 1219 BrandString[0] = Eax.Uint32; 1220 BrandString[1] = Ebx.Uint32; 1221 BrandString[2] = Ecx.Uint32; 1222 BrandString[3] = Edx.Uint32; 1223 1224 AsmCpuidEx ( 1225 CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING2, 1226 &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32 1227 ); 1228 Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING2); 1229 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); 1230 BrandString[4] = Eax.Uint32; 1231 BrandString[5] = Ebx.Uint32; 1232 BrandString[6] = Ecx.Uint32; 1233 BrandString[7] = Edx.Uint32; 1234 1235 AsmCpuidEx ( 1236 CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING3, 1237 &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32 1238 ); 1239 Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING3); 1240 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); 1241 BrandString[8] = Eax.Uint32; 1242 BrandString[9] = Ebx.Uint32; 1243 BrandString[10] = Ecx.Uint32; 1244 BrandString[11] = Edx.Uint32; 1245 1246 BrandString[12] = 0; 1247 1248 Print (L"Vendor Brand String = %a\n", (CHAR8 *)BrandString); 1249 } 1250 1251 /** 1252 Display CPUID_SOC_VENDOR main leaf and sub-leafs. 1253 1254 **/ 1255 VOID 1256 CpuidSocVendor ( 1257 VOID 1258 ) 1259 { 1260 UINT32 Eax; 1261 CPUID_SOC_VENDOR_MAIN_LEAF_EBX Ebx; 1262 UINT32 Ecx; 1263 UINT32 Edx; 1264 1265 if (CPUID_SOC_VENDOR > gMaximumBasicFunction) { 1266 return; 1267 } 1268 1269 AsmCpuidEx ( 1270 CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_MAIN_LEAF, 1271 &Eax, &Ebx.Uint32, &Ecx, &Edx 1272 ); 1273 Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_MAIN_LEAF); 1274 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx.Uint32, Ecx, Edx); 1275 if (Eax < 3) { 1276 Print (L" Not Supported\n"); 1277 return; 1278 } 1279 PRINT_VALUE (Eax, MaxSOCID_Index); 1280 PRINT_BIT_FIELD (Ebx, SocVendorId); 1281 PRINT_BIT_FIELD (Ebx, IsVendorScheme); 1282 PRINT_VALUE (Ecx, ProjectID); 1283 PRINT_VALUE (Edx, SteppingID); 1284 CpuidSocVendorBrandString (); 1285 } 1286 1287 /** 1288 Display CPUID_EXTENDED_FUNCTION leaf. 1289 1290 **/ 1291 VOID 1292 CpuidExtendedFunction ( 1293 VOID 1294 ) 1295 { 1296 UINT32 Eax; 1297 1298 AsmCpuid (CPUID_EXTENDED_FUNCTION, &Eax, NULL, NULL, NULL); 1299 Print (L"CPUID_EXTENDED_FUNCTION (Leaf %08x)\n", CPUID_EXTENDED_FUNCTION); 1300 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, 0, 0, 0); 1301 PRINT_VALUE (Eax, MaximumExtendedFunction); 1302 1303 gMaximumExtendedFunction = Eax; 1304 } 1305 1306 /** 1307 Display CPUID_EXTENDED_CPU_SIG leaf. 1308 1309 **/ 1310 VOID 1311 CpuidExtendedCpuSig ( 1312 VOID 1313 ) 1314 { 1315 UINT32 Eax; 1316 CPUID_EXTENDED_CPU_SIG_ECX Ecx; 1317 CPUID_EXTENDED_CPU_SIG_EDX Edx; 1318 1319 if (CPUID_EXTENDED_CPU_SIG > gMaximumExtendedFunction) { 1320 return; 1321 } 1322 1323 AsmCpuid (CPUID_EXTENDED_CPU_SIG, &Eax, NULL, &Ecx.Uint32, &Edx.Uint32); 1324 Print (L"CPUID_EXTENDED_CPU_SIG (Leaf %08x)\n", CPUID_EXTENDED_CPU_SIG); 1325 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, 0, Ecx.Uint32, Edx.Uint32); 1326 PRINT_BIT_FIELD (Ecx, LAHF_SAHF); 1327 PRINT_BIT_FIELD (Ecx, LZCNT); 1328 PRINT_BIT_FIELD (Ecx, PREFETCHW); 1329 PRINT_BIT_FIELD (Edx, SYSCALL_SYSRET); 1330 PRINT_BIT_FIELD (Edx, NX); 1331 PRINT_BIT_FIELD (Edx, Page1GB); 1332 PRINT_BIT_FIELD (Edx, RDTSCP); 1333 PRINT_BIT_FIELD (Edx, LM); 1334 } 1335 1336 /** 1337 Display CPUID_BRAND_STRING1, CPUID_BRAND_STRING2 and CPUID_BRAND_STRING3 1338 leafs. Also display these three leafs as a single brand string. 1339 1340 **/ 1341 VOID 1342 CpuidProcessorBrandString ( 1343 VOID 1344 ) 1345 { 1346 CPUID_BRAND_STRING_DATA Eax; 1347 CPUID_BRAND_STRING_DATA Ebx; 1348 CPUID_BRAND_STRING_DATA Ecx; 1349 CPUID_BRAND_STRING_DATA Edx; 1350 // 1351 // Array to store brand string from 3 brand string leafs with 1352 // 4 32-bit brand string values per leaf and an extra value to 1353 // null terminate the string. 1354 // 1355 UINT32 BrandString[3 * 4 + 1]; 1356 1357 if (CPUID_BRAND_STRING1 <= gMaximumExtendedFunction) { 1358 AsmCpuid (CPUID_BRAND_STRING1, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); 1359 Print (L"CPUID_BRAND_STRING1 (Leaf %08x)\n", CPUID_BRAND_STRING1); 1360 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); 1361 BrandString[0] = Eax.Uint32; 1362 BrandString[1] = Ebx.Uint32; 1363 BrandString[2] = Ecx.Uint32; 1364 BrandString[3] = Edx.Uint32; 1365 } 1366 1367 if (CPUID_BRAND_STRING2 <= gMaximumExtendedFunction) { 1368 AsmCpuid (CPUID_BRAND_STRING2, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); 1369 Print (L"CPUID_BRAND_STRING2 (Leaf %08x)\n", CPUID_BRAND_STRING2); 1370 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); 1371 BrandString[4] = Eax.Uint32; 1372 BrandString[5] = Ebx.Uint32; 1373 BrandString[6] = Ecx.Uint32; 1374 BrandString[7] = Edx.Uint32; 1375 } 1376 1377 if (CPUID_BRAND_STRING3 <= gMaximumExtendedFunction) { 1378 AsmCpuid (CPUID_BRAND_STRING3, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32); 1379 Print (L"CPUID_BRAND_STRING3 (Leaf %08x)\n", CPUID_BRAND_STRING3); 1380 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); 1381 BrandString[8] = Eax.Uint32; 1382 BrandString[9] = Ebx.Uint32; 1383 BrandString[10] = Ecx.Uint32; 1384 BrandString[11] = Edx.Uint32; 1385 } 1386 1387 BrandString[12] = 0; 1388 1389 Print (L"Brand String = %a\n", (CHAR8 *)BrandString); 1390 } 1391 1392 /** 1393 Display CPUID_EXTENDED_CACHE_INFO leaf. 1394 1395 **/ 1396 VOID 1397 CpuidExtendedCacheInfo ( 1398 VOID 1399 ) 1400 { 1401 CPUID_EXTENDED_CACHE_INFO_ECX Ecx; 1402 1403 if (CPUID_EXTENDED_CACHE_INFO > gMaximumExtendedFunction) { 1404 return; 1405 } 1406 1407 AsmCpuid (CPUID_EXTENDED_CACHE_INFO, NULL, NULL, &Ecx.Uint32, NULL); 1408 Print (L"CPUID_EXTENDED_CACHE_INFO (Leaf %08x)\n", CPUID_EXTENDED_CACHE_INFO); 1409 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, 0, Ecx.Uint32, 0); 1410 PRINT_BIT_FIELD (Ecx, CacheLineSize); 1411 PRINT_BIT_FIELD (Ecx, L2Associativity); 1412 PRINT_BIT_FIELD (Ecx, CacheSize); 1413 } 1414 1415 /** 1416 Display CPUID_EXTENDED_TIME_STAMP_COUNTER leaf. 1417 1418 **/ 1419 VOID 1420 CpuidExtendedTimeStampCounter ( 1421 VOID 1422 ) 1423 { 1424 CPUID_EXTENDED_TIME_STAMP_COUNTER_EDX Edx; 1425 1426 if (CPUID_EXTENDED_TIME_STAMP_COUNTER > gMaximumExtendedFunction) { 1427 return; 1428 } 1429 1430 AsmCpuid (CPUID_EXTENDED_TIME_STAMP_COUNTER, NULL, NULL, NULL, &Edx.Uint32); 1431 Print (L"CPUID_EXTENDED_TIME_STAMP_COUNTER (Leaf %08x)\n", CPUID_EXTENDED_TIME_STAMP_COUNTER); 1432 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, 0, 0, Edx.Uint32); 1433 PRINT_BIT_FIELD (Edx, InvariantTsc); 1434 } 1435 1436 /** 1437 Display CPUID_VIR_PHY_ADDRESS_SIZE leaf. 1438 1439 **/ 1440 VOID 1441 CpuidVirPhyAddressSize ( 1442 VOID 1443 ) 1444 { 1445 CPUID_VIR_PHY_ADDRESS_SIZE_EAX Eax; 1446 1447 if (CPUID_VIR_PHY_ADDRESS_SIZE > gMaximumExtendedFunction) { 1448 return; 1449 } 1450 1451 AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &Eax.Uint32, NULL, NULL, NULL); 1452 Print (L"CPUID_VIR_PHY_ADDRESS_SIZE (Leaf %08x)\n", CPUID_VIR_PHY_ADDRESS_SIZE); 1453 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, 0, 0, 0); 1454 PRINT_BIT_FIELD (Eax, PhysicalAddressBits); 1455 PRINT_BIT_FIELD (Eax, LinearAddressBits); 1456 } 1457 1458 /** 1459 The user Entry Point for Application. The user code starts with this function 1460 as the real entry point for the application. 1461 1462 @param[in] ImageHandle The firmware allocated handle for the EFI image. 1463 @param[in] SystemTable A pointer to the EFI System Table. 1464 1465 @retval EFI_SUCCESS The entry point is executed successfully. 1466 @retval other Some error occurs when executing this entry point. 1467 1468 **/ 1469 EFI_STATUS 1470 EFIAPI 1471 UefiMain ( 1472 IN EFI_HANDLE ImageHandle, 1473 IN EFI_SYSTEM_TABLE *SystemTable 1474 ) 1475 { 1476 Print (L"UEFI CPUID Version 0.5\n"); 1477 1478 CpuidSignature (); 1479 CpuidVersionInfo (); 1480 CpuidCacheInfo (); 1481 CpuidSerialNumber (); 1482 CpuidCacheParams(); 1483 CpuidMonitorMwait (); 1484 CpuidThermalPowerManagement (); 1485 CpuidStructuredExtendedFeatureFlags (); 1486 CpuidDirectCacheAccessInfo(); 1487 CpuidArchitecturalPerformanceMonitoring (); 1488 CpuidExtendedTopology (); 1489 CpuidExtendedStateMainLeaf (); 1490 CpuidIntelRdtMonitoringEnumerationSubLeaf (); 1491 CpuidIntelRdtMonitoringL3CacheCapabilitySubLeaf (); 1492 CpuidIntelRdtAllocationMainLeaf (); 1493 CpuidEnumerationOfIntelSgx (); 1494 CpuidIntelProcessorTraceMainLeaf (); 1495 CpuidTimeStampCounter (); 1496 CpuidProcessorFrequency (); 1497 CpuidSocVendor (); 1498 CpuidExtendedFunction (); 1499 CpuidExtendedCpuSig (); 1500 CpuidProcessorBrandString (); 1501 CpuidExtendedCacheInfo (); 1502 CpuidExtendedTimeStampCounter (); 1503 CpuidVirPhyAddressSize (); 1504 1505 return EFI_SUCCESS; 1506 } 1507