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