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