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