]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/Application/Cpuid/Cpuid.c
UefiCpuPkg/Cpuid: Dump leaf 1FH information correctly
[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 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 UINT32 LeafFunction
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 (LeafFunction > gMaximumBasicFunction) {
730 return;
731 }
732 if ((LeafFunction != CPUID_EXTENDED_TOPOLOGY) && (LeafFunction != CPUID_V2_EXTENDED_TOPOLOGY)) {
733 return;
734 }
735
736 LevelNumber = 0;
737 for (LevelNumber = 0; ; LevelNumber++) {
738 AsmCpuidEx (
739 LeafFunction, LevelNumber,
740 &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx
741 );
742 if (Ecx.Bits.LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID) {
743 break;
744 }
745 Print (
746 L"%a (Leaf %08x, Sub-Leaf %08x)\n",
747 LeafFunction == CPUID_EXTENDED_TOPOLOGY ? "CPUID_EXTENDED_TOPOLOGY" : "CPUID_V2_EXTENDED_TOPOLOGY",
748 LeafFunction, LevelNumber
749 );
750 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx);
751 PRINT_BIT_FIELD (Eax, ApicIdShift);
752 PRINT_BIT_FIELD (Ebx, LogicalProcessors);
753 PRINT_BIT_FIELD (Ecx, LevelNumber);
754 PRINT_BIT_FIELD (Ecx, LevelType);
755 PRINT_VALUE (Edx, x2APIC_ID);
756 }
757 }
758
759 /**
760 Display CPUID_EXTENDED_STATE sub-leaf.
761
762 **/
763 VOID
764 CpuidExtendedStateSubLeaf (
765 VOID
766 )
767 {
768 CPUID_EXTENDED_STATE_SUB_LEAF_EAX Eax;
769 UINT32 Ebx;
770 CPUID_EXTENDED_STATE_SUB_LEAF_ECX Ecx;
771 UINT32 Edx;
772
773 AsmCpuidEx (
774 CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_SUB_LEAF,
775 &Eax.Uint32, &Ebx, &Ecx.Uint32, &Edx
776 );
777 Print (L"CPUID_EXTENDED_STATE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_SUB_LEAF);
778 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx.Uint32, Edx);
779 PRINT_BIT_FIELD (Eax, XSAVEOPT);
780 PRINT_BIT_FIELD (Eax, XSAVEC);
781 PRINT_BIT_FIELD (Eax, XGETBV);
782 PRINT_BIT_FIELD (Eax, XSAVES);
783 PRINT_VALUE (Ebx, EnabledSaveStateSize_XCR0_IA32_XSS);
784 PRINT_BIT_FIELD (Ecx, XCR0);
785 PRINT_BIT_FIELD (Ecx, HWPState);
786 PRINT_BIT_FIELD (Ecx, PT);
787 PRINT_BIT_FIELD (Ecx, XCR0_1);
788 PRINT_VALUE (Edx, IA32_XSS_Supported_32_63);
789 }
790
791 /**
792 Display CPUID_EXTENDED_STATE size and offset information sub-leaf.
793
794 **/
795 VOID
796 CpuidExtendedStateSizeOffset (
797 VOID
798 )
799 {
800 UINT32 Eax;
801 UINT32 Ebx;
802 CPUID_EXTENDED_STATE_SIZE_OFFSET_ECX Ecx;
803 UINT32 Edx;
804 UINT32 SubLeaf;
805
806 for (SubLeaf = CPUID_EXTENDED_STATE_SIZE_OFFSET; SubLeaf < 32; SubLeaf++) {
807 AsmCpuidEx (
808 CPUID_EXTENDED_STATE, SubLeaf,
809 &Eax, &Ebx, &Ecx.Uint32, &Edx
810 );
811 if (Edx != 0) {
812 Print (L"CPUID_EXTENDED_STATE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_STATE, SubLeaf);
813 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx, Ecx.Uint32, Edx);
814 PRINT_VALUE (Eax, FeatureSaveStateSize);
815 PRINT_VALUE (Ebx, FeatureSaveStateOffset);
816 PRINT_BIT_FIELD (Ecx, XSS);
817 PRINT_BIT_FIELD (Ecx, Compacted);
818 }
819 }
820 }
821
822 /**
823 Display CPUID_EXTENDED_STATE main leaf and sub-leafs.
824
825 **/
826 VOID
827 CpuidExtendedStateMainLeaf (
828 VOID
829 )
830 {
831 CPUID_EXTENDED_STATE_MAIN_LEAF_EAX Eax;
832 UINT32 Ebx;
833 UINT32 Ecx;
834 UINT32 Edx;
835
836 if (CPUID_EXTENDED_STATE > gMaximumBasicFunction) {
837 return;
838 }
839
840 AsmCpuidEx (
841 CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_MAIN_LEAF,
842 &Eax.Uint32, &Ebx, &Ecx, &Edx
843 );
844 Print (L"CPUID_EXTENDED_STATE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_MAIN_LEAF);
845 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx, Edx);
846 PRINT_BIT_FIELD (Eax, x87);
847 PRINT_BIT_FIELD (Eax, SSE);
848 PRINT_BIT_FIELD (Eax, AVX);
849 PRINT_BIT_FIELD (Eax, MPX);
850 PRINT_BIT_FIELD (Eax, AVX_512);
851 PRINT_BIT_FIELD (Eax, IA32_XSS);
852 PRINT_BIT_FIELD (Eax, PKRU);
853 PRINT_BIT_FIELD (Eax, IA32_XSS_2);
854 PRINT_VALUE (Ebx, EnabledSaveStateSize);
855 PRINT_VALUE (Ecx, SupportedSaveStateSize);
856 PRINT_VALUE (Edx, XCR0_Supported_32_63);
857
858 CpuidExtendedStateSubLeaf ();
859 CpuidExtendedStateSizeOffset ();
860 }
861
862 /**
863 Display CPUID_INTEL_RDT_MONITORING enumeration sub-leaf.
864
865 **/
866 VOID
867 CpuidIntelRdtMonitoringEnumerationSubLeaf (
868 VOID
869 )
870 {
871 UINT32 Ebx;
872 CPUID_INTEL_RDT_MONITORING_ENUMERATION_SUB_LEAF_EDX Edx;
873
874 if (CPUID_INTEL_RDT_MONITORING > gMaximumBasicFunction) {
875 return;
876 }
877
878 AsmCpuidEx (
879 CPUID_INTEL_RDT_MONITORING, CPUID_INTEL_RDT_MONITORING_ENUMERATION_SUB_LEAF,
880 NULL, &Ebx, NULL, &Edx.Uint32
881 );
882 Print (L"CPUID_INTEL_RDT_MONITORING (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_MONITORING, CPUID_INTEL_RDT_MONITORING_ENUMERATION_SUB_LEAF);
883 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, Ebx, 0, Edx.Uint32);
884 PRINT_VALUE (Ebx, Maximum_RMID_Range);
885 PRINT_BIT_FIELD (Edx, L3CacheRDT_M);
886 }
887
888 /**
889 Display CPUID_INTEL_RDT_MONITORING L3 cache capability sub-leaf.
890
891 **/
892 VOID
893 CpuidIntelRdtMonitoringL3CacheCapabilitySubLeaf (
894 VOID
895 )
896 {
897 UINT32 Ebx;
898 UINT32 Ecx;
899 CPUID_INTEL_RDT_MONITORING_L3_CACHE_SUB_LEAF_EDX Edx;
900
901 if (CPUID_INTEL_RDT_MONITORING > gMaximumBasicFunction) {
902 return;
903 }
904
905 AsmCpuidEx (
906 CPUID_INTEL_RDT_MONITORING, CPUID_INTEL_RDT_MONITORING_L3_CACHE_SUB_LEAF,
907 NULL, &Ebx, &Ecx, &Edx.Uint32
908 );
909 Print (L"CPUID_INTEL_RDT_MONITORING (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_MONITORING, CPUID_INTEL_RDT_MONITORING_L3_CACHE_SUB_LEAF);
910 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, Ebx, Ecx, Edx.Uint32);
911 PRINT_VALUE (Ebx, OccupancyConversionFactor);
912 PRINT_VALUE (Ecx, Maximum_RMID_Range);
913 PRINT_BIT_FIELD (Edx, L3CacheOccupancyMonitoring);
914 PRINT_BIT_FIELD (Edx, L3CacheTotalBandwidthMonitoring);
915 PRINT_BIT_FIELD (Edx, L3CacheLocalBandwidthMonitoring);
916 }
917
918 /**
919 Display CPUID_INTEL_RDT_ALLOCATION memory bandwidth allocation technology enumeration
920 sub-leaf.
921
922 **/
923 VOID
924 CpuidIntelRdtAllocationMemoryBandwidthSubLeaf (
925 VOID
926 )
927 {
928 CPUID_INTEL_RDT_ALLOCATION_MEMORY_BANDWIDTH_SUB_LEAF_EAX Eax;
929 UINT32 Ebx;
930 CPUID_INTEL_RDT_ALLOCATION_MEMORY_BANDWIDTH_SUB_LEAF_ECX Ecx;
931 CPUID_INTEL_RDT_ALLOCATION_MEMORY_BANDWIDTH_SUB_LEAF_EDX Edx;
932
933 AsmCpuidEx (
934 CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_MEMORY_BANDWIDTH_SUB_LEAF,
935 &Eax.Uint32, &Ebx, &Ecx.Uint32, &Edx.Uint32
936 );
937 Print (L"CPUID_INTEL_RDT_ALLOCATION (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_MEMORY_BANDWIDTH_SUB_LEAF);
938 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx.Uint32, Edx.Uint32);
939 PRINT_BIT_FIELD (Eax, MaximumMBAThrottling);
940 PRINT_VALUE (Ebx, AllocationUnitBitMap);
941 PRINT_BIT_FIELD (Ecx, Liner);
942 PRINT_BIT_FIELD (Edx, HighestCosNumber);
943 }
944
945 /**
946 Display CPUID_INTEL_RDT_ALLOCATION L3 cache allocation technology enumeration
947 sub-leaf.
948
949 **/
950 VOID
951 CpuidIntelRdtAllocationL3CacheSubLeaf (
952 VOID
953 )
954 {
955 CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_EAX Eax;
956 UINT32 Ebx;
957 CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_ECX Ecx;
958 CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF_EDX Edx;
959
960 AsmCpuidEx (
961 CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF,
962 &Eax.Uint32, &Ebx, &Ecx.Uint32, &Edx.Uint32
963 );
964 Print (L"CPUID_INTEL_RDT_ALLOCATION (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_L3_CACHE_SUB_LEAF);
965 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx.Uint32, Edx.Uint32);
966 PRINT_BIT_FIELD (Eax, CapacityLength);
967 PRINT_VALUE (Ebx, AllocationUnitBitMap);
968 PRINT_BIT_FIELD (Ecx, CodeDataPrioritization);
969 PRINT_BIT_FIELD (Edx, HighestCosNumber);
970 }
971
972 /**
973 Display CPUID_INTEL_RDT_ALLOCATION L2 cache allocation technology enumeration
974 sub-leaf.
975
976 **/
977 VOID
978 CpuidIntelRdtAllocationL2CacheSubLeaf (
979 VOID
980 )
981 {
982 CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF_EAX Eax;
983 UINT32 Ebx;
984 CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF_EDX Edx;
985
986 AsmCpuidEx (
987 CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF,
988 &Eax.Uint32, &Ebx, NULL, &Edx.Uint32
989 );
990 Print (L"CPUID_INTEL_RDT_ALLOCATION (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_L2_CACHE_SUB_LEAF);
991 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, 0, Edx.Uint32);
992 PRINT_BIT_FIELD (Eax, CapacityLength);
993 PRINT_VALUE (Ebx, AllocationUnitBitMap);
994 PRINT_BIT_FIELD (Edx, HighestCosNumber);
995 }
996
997 /**
998 Display CPUID_INTEL_RDT_ALLOCATION main leaf and sub-leaves.
999
1000 **/
1001 VOID
1002 CpuidIntelRdtAllocationMainLeaf (
1003 VOID
1004 )
1005 {
1006 CPUID_INTEL_RDT_ALLOCATION_ENUMERATION_SUB_LEAF_EBX Ebx;
1007
1008 if (CPUID_INTEL_RDT_ALLOCATION > gMaximumBasicFunction) {
1009 return;
1010 }
1011
1012 AsmCpuidEx (
1013 CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_ENUMERATION_SUB_LEAF,
1014 NULL, &Ebx.Uint32, NULL, NULL
1015 );
1016 Print (L"CPUID_INTEL_RDT_ALLOCATION (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_RDT_ALLOCATION, CPUID_INTEL_RDT_ALLOCATION_ENUMERATION_SUB_LEAF);
1017 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, Ebx.Uint32, 0, 0);
1018 PRINT_BIT_FIELD (Ebx, L3CacheAllocation);
1019 PRINT_BIT_FIELD (Ebx, L2CacheAllocation);
1020 PRINT_BIT_FIELD (Ebx, MemoryBandwidth);
1021 CpuidIntelRdtAllocationMemoryBandwidthSubLeaf ();
1022 CpuidIntelRdtAllocationL3CacheSubLeaf ();
1023 CpuidIntelRdtAllocationL2CacheSubLeaf ();
1024 }
1025
1026 /**
1027 Display Sub-Leaf 0 Enumeration of Intel SGX Capabilities.
1028
1029 **/
1030 VOID
1031 CpuidEnumerationOfIntelSgxCapabilities0SubLeaf (
1032 VOID
1033 )
1034 {
1035 CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF_EAX Eax;
1036 UINT32 Ebx;
1037 CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF_EDX Edx;
1038
1039 AsmCpuidEx (
1040 CPUID_INTEL_SGX, CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF,
1041 &Eax.Uint32, &Ebx, NULL, &Edx.Uint32
1042 );
1043 Print (L"CPUID_INTEL_SGX (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_SGX, CPUID_INTEL_SGX_CAPABILITIES_0_SUB_LEAF);
1044 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, 0, Edx.Uint32);
1045 PRINT_BIT_FIELD (Eax, SGX1);
1046 PRINT_BIT_FIELD (Eax, SGX2);
1047 PRINT_BIT_FIELD (Eax, ENCLV);
1048 PRINT_BIT_FIELD (Eax, ENCLS);
1049 PRINT_BIT_FIELD (Edx, MaxEnclaveSize_Not64);
1050 PRINT_BIT_FIELD (Edx, MaxEnclaveSize_64);
1051 }
1052
1053 /**
1054 Display Sub-Leaf 1 Enumeration of Intel SGX Capabilities.
1055
1056 **/
1057 VOID
1058 CpuidEnumerationOfIntelSgxCapabilities1SubLeaf (
1059 VOID
1060 )
1061 {
1062 UINT32 Eax;
1063 UINT32 Ebx;
1064 UINT32 Ecx;
1065 UINT32 Edx;
1066
1067 AsmCpuidEx (
1068 CPUID_INTEL_SGX, CPUID_INTEL_SGX_CAPABILITIES_1_SUB_LEAF,
1069 &Eax, &Ebx, &Ecx, &Edx
1070 );
1071 Print (L"CPUID_INTEL_SGX (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_SGX, CPUID_INTEL_SGX_CAPABILITIES_1_SUB_LEAF);
1072 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx, Ecx, Edx);
1073 }
1074
1075 /**
1076 Display Sub-Leaf Index 2 or Higher Enumeration of Intel SGX Resources.
1077
1078 **/
1079 VOID
1080 CpuidEnumerationOfIntelSgxResourcesSubLeaf (
1081 VOID
1082 )
1083 {
1084 CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EAX Eax;
1085 CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EBX Ebx;
1086 CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_ECX Ecx;
1087 CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF_EDX Edx;
1088 UINT32 SubLeaf;
1089
1090 SubLeaf = CPUID_INTEL_SGX_CAPABILITIES_RESOURCES_SUB_LEAF;
1091 do {
1092 AsmCpuidEx (
1093 CPUID_INTEL_SGX, SubLeaf,
1094 &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32
1095 );
1096 if (Eax.Bits.SubLeafType == 0x1) {
1097 Print (L"CPUID_INTEL_SGX (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_SGX, SubLeaf);
1098 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32);
1099 PRINT_BIT_FIELD (Eax, SubLeafType);
1100 PRINT_BIT_FIELD (Eax, LowAddressOfEpcSection);
1101 PRINT_BIT_FIELD (Ebx, HighAddressOfEpcSection);
1102 PRINT_BIT_FIELD (Ecx, EpcSection);
1103 PRINT_BIT_FIELD (Ecx, LowSizeOfEpcSection);
1104 PRINT_BIT_FIELD (Edx, HighSizeOfEpcSection);
1105 }
1106 SubLeaf++;
1107 } while (Eax.Bits.SubLeafType == 0x1);
1108 }
1109
1110 /**
1111 Display Intel SGX Resource Enumeration.
1112
1113 **/
1114 VOID
1115 CpuidEnumerationOfIntelSgx (
1116 VOID
1117 )
1118 {
1119 CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_EBX Ebx;
1120
1121 if (CPUID_INTEL_SGX > gMaximumBasicFunction) {
1122 return;
1123 }
1124
1125 AsmCpuidEx (
1126 CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS,
1127 CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO,
1128 NULL, &Ebx.Uint32, NULL, NULL
1129 );
1130 if (Ebx.Bits.SGX != 1) {
1131 //
1132 // Only if CPUID.(EAX=07H, ECX=0H):EBX.SGX = 1, the processor has support
1133 // for Intel SGX.
1134 //
1135 return;
1136 }
1137
1138 CpuidEnumerationOfIntelSgxCapabilities0SubLeaf ();
1139 CpuidEnumerationOfIntelSgxCapabilities1SubLeaf ();
1140 CpuidEnumerationOfIntelSgxResourcesSubLeaf ();
1141 }
1142
1143 /**
1144 Display CPUID_INTEL_PROCESSOR_TRACE sub-leafs.
1145
1146 @param[in] MaximumSubLeaf Maximum sub-leaf index for CPUID_INTEL_PROCESSOR_TRACE.
1147
1148 **/
1149 VOID
1150 CpuidIntelProcessorTraceSubLeaf (
1151 UINT32 MaximumSubLeaf
1152 )
1153 {
1154 UINT32 SubLeaf;
1155 CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF_EAX Eax;
1156 CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF_EBX Ebx;
1157
1158 for (SubLeaf = CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF; SubLeaf <= MaximumSubLeaf; SubLeaf++) {
1159 AsmCpuidEx (
1160 CPUID_INTEL_PROCESSOR_TRACE, SubLeaf,
1161 &Eax.Uint32, &Ebx.Uint32, NULL, NULL
1162 );
1163 Print (L"CPUID_INTEL_PROCESSOR_TRACE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_PROCESSOR_TRACE, SubLeaf);
1164 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, 0, 0);
1165 PRINT_BIT_FIELD (Eax, ConfigurableAddressRanges);
1166 PRINT_BIT_FIELD (Eax, MtcPeriodEncodings);
1167 PRINT_BIT_FIELD (Ebx, CycleThresholdEncodings);
1168 PRINT_BIT_FIELD (Ebx, PsbFrequencyEncodings);
1169 }
1170 }
1171
1172 /**
1173 Display CPUID_INTEL_PROCESSOR_TRACE main leaf and sub-leafs.
1174
1175 **/
1176 VOID
1177 CpuidIntelProcessorTraceMainLeaf (
1178 VOID
1179 )
1180 {
1181 UINT32 Eax;
1182 CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_EBX Ebx;
1183 CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_ECX Ecx;
1184
1185 if (CPUID_INTEL_PROCESSOR_TRACE > gMaximumBasicFunction) {
1186 return;
1187 }
1188
1189 AsmCpuidEx (
1190 CPUID_INTEL_PROCESSOR_TRACE, CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF,
1191 &Eax, &Ebx.Uint32, &Ecx.Uint32, NULL
1192 );
1193 Print (L"CPUID_INTEL_PROCESSOR_TRACE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_PROCESSOR_TRACE, CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF);
1194 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx.Uint32, Ecx.Uint32, 0);
1195 PRINT_VALUE (Eax, MaximumSubLeaf);
1196 PRINT_BIT_FIELD (Ebx, Cr3Filter);
1197 PRINT_BIT_FIELD (Ebx, ConfigurablePsb);
1198 PRINT_BIT_FIELD (Ebx, IpTraceStopFiltering);
1199 PRINT_BIT_FIELD (Ebx, Mtc);
1200 PRINT_BIT_FIELD (Ebx, PTWrite);
1201 PRINT_BIT_FIELD (Ebx, PowerEventTrace);
1202 PRINT_BIT_FIELD (Ecx, RTIT);
1203 PRINT_BIT_FIELD (Ecx, ToPA);
1204 PRINT_BIT_FIELD (Ecx, SingleRangeOutput);
1205 PRINT_BIT_FIELD (Ecx, TraceTransportSubsystem);
1206 PRINT_BIT_FIELD (Ecx, LIP);
1207
1208 CpuidIntelProcessorTraceSubLeaf (Eax);
1209 }
1210
1211 /**
1212 Display CPUID_TIME_STAMP_COUNTER leaf.
1213
1214 **/
1215 VOID
1216 CpuidTimeStampCounter (
1217 VOID
1218 )
1219 {
1220 UINT32 Eax;
1221 UINT32 Ebx;
1222 UINT32 Ecx;
1223
1224 if (CPUID_TIME_STAMP_COUNTER > gMaximumBasicFunction) {
1225 return;
1226 }
1227
1228 AsmCpuid (CPUID_TIME_STAMP_COUNTER, &Eax, &Ebx, &Ecx, NULL);
1229 Print (L"CPUID_TIME_STAMP_COUNTER (Leaf %08x)\n", CPUID_TIME_STAMP_COUNTER);
1230 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx, Ecx, 0);
1231 }
1232
1233 /**
1234 Display CPUID_PROCESSOR_FREQUENCY leaf.
1235
1236 **/
1237 VOID
1238 CpuidProcessorFrequency (
1239 VOID
1240 )
1241 {
1242 CPUID_PROCESSOR_FREQUENCY_EAX Eax;
1243 CPUID_PROCESSOR_FREQUENCY_EBX Ebx;
1244 CPUID_PROCESSOR_FREQUENCY_ECX Ecx;
1245
1246 if (CPUID_PROCESSOR_FREQUENCY > gMaximumBasicFunction) {
1247 return;
1248 }
1249
1250 AsmCpuid (CPUID_PROCESSOR_FREQUENCY, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, NULL);
1251 Print (L"CPUID_PROCESSOR_FREQUENCY (Leaf %08x)\n", CPUID_PROCESSOR_FREQUENCY);
1252 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, 0);
1253 PRINT_BIT_FIELD (Eax, ProcessorBaseFrequency);
1254 PRINT_BIT_FIELD (Ebx, MaximumFrequency);
1255 PRINT_BIT_FIELD (Ecx, BusFrequency);
1256 }
1257
1258 /**
1259 Display CPUID_SOC_VENDOR sub-leafs that contain the SoC Vendor Brand String.
1260 Also display these sub-leafs as a single SoC Vendor Brand String.
1261
1262 **/
1263 VOID
1264 CpuidSocVendorBrandString (
1265 VOID
1266 )
1267 {
1268 CPUID_SOC_VENDOR_BRAND_STRING_DATA Eax;
1269 CPUID_SOC_VENDOR_BRAND_STRING_DATA Ebx;
1270 CPUID_SOC_VENDOR_BRAND_STRING_DATA Ecx;
1271 CPUID_SOC_VENDOR_BRAND_STRING_DATA Edx;
1272 //
1273 // Array to store brand string from 3 brand string leafs with
1274 // 4 32-bit brand string values per leaf and an extra value to
1275 // null terminate the string.
1276 //
1277 UINT32 BrandString[3 * 4 + 1];
1278
1279 AsmCpuidEx (
1280 CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING1,
1281 &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32
1282 );
1283 Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING1);
1284 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32);
1285 BrandString[0] = Eax.Uint32;
1286 BrandString[1] = Ebx.Uint32;
1287 BrandString[2] = Ecx.Uint32;
1288 BrandString[3] = Edx.Uint32;
1289
1290 AsmCpuidEx (
1291 CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING2,
1292 &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32
1293 );
1294 Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING2);
1295 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32);
1296 BrandString[4] = Eax.Uint32;
1297 BrandString[5] = Ebx.Uint32;
1298 BrandString[6] = Ecx.Uint32;
1299 BrandString[7] = Edx.Uint32;
1300
1301 AsmCpuidEx (
1302 CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING3,
1303 &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32
1304 );
1305 Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING3);
1306 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32);
1307 BrandString[8] = Eax.Uint32;
1308 BrandString[9] = Ebx.Uint32;
1309 BrandString[10] = Ecx.Uint32;
1310 BrandString[11] = Edx.Uint32;
1311
1312 BrandString[12] = 0;
1313
1314 Print (L"Vendor Brand String = %a\n", (CHAR8 *)BrandString);
1315 }
1316
1317 /**
1318 Display CPUID_SOC_VENDOR main leaf and sub-leafs.
1319
1320 **/
1321 VOID
1322 CpuidSocVendor (
1323 VOID
1324 )
1325 {
1326 UINT32 Eax;
1327 CPUID_SOC_VENDOR_MAIN_LEAF_EBX Ebx;
1328 UINT32 Ecx;
1329 UINT32 Edx;
1330
1331 if (CPUID_SOC_VENDOR > gMaximumBasicFunction) {
1332 return;
1333 }
1334
1335 AsmCpuidEx (
1336 CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_MAIN_LEAF,
1337 &Eax, &Ebx.Uint32, &Ecx, &Edx
1338 );
1339 Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_MAIN_LEAF);
1340 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx.Uint32, Ecx, Edx);
1341 if (Eax < 3) {
1342 Print (L" Not Supported\n");
1343 return;
1344 }
1345 PRINT_VALUE (Eax, MaxSOCID_Index);
1346 PRINT_BIT_FIELD (Ebx, SocVendorId);
1347 PRINT_BIT_FIELD (Ebx, IsVendorScheme);
1348 PRINT_VALUE (Ecx, ProjectID);
1349 PRINT_VALUE (Edx, SteppingID);
1350 CpuidSocVendorBrandString ();
1351 }
1352
1353 /**
1354 Display CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS main leaf and sub-leafs.
1355
1356 **/
1357 VOID
1358 CpuidDeterministicAddressTranslationParameters (
1359 VOID
1360 )
1361 {
1362 UINT32 Eax;
1363 CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS_EBX Ebx;
1364 UINT32 Ecx;
1365 CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS_EDX Edx;
1366
1367 if (CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS > gMaximumBasicFunction) {
1368 return;
1369 }
1370
1371 AsmCpuidEx (
1372 CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS,
1373 CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS_MAIN_LEAF,
1374 &Eax, &Ebx.Uint32, &Ecx, &Edx.Uint32
1375 );
1376 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);
1377 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx.Uint32, Ecx, Edx.Uint32);
1378
1379 PRINT_VALUE (Eax, MaxID_Index);
1380 PRINT_BIT_FIELD (Ebx, Page4K);
1381 PRINT_BIT_FIELD (Ebx, Page2M);
1382 PRINT_BIT_FIELD (Ebx, Page4M);
1383 PRINT_BIT_FIELD (Ebx, Page1G);
1384 PRINT_BIT_FIELD (Ebx, Partitioning);
1385 PRINT_BIT_FIELD (Ebx, Way);
1386
1387 PRINT_VALUE (Ecx, NumberOfSets);
1388
1389 PRINT_BIT_FIELD (Edx, TranslationCacheType);
1390 PRINT_BIT_FIELD (Edx, TranslationCacheLevel);
1391 PRINT_BIT_FIELD (Edx, FullyAssociative);
1392 PRINT_BIT_FIELD (Edx, MaximumNum);
1393 }
1394
1395 /**
1396 Display CPUID_EXTENDED_FUNCTION leaf.
1397
1398 **/
1399 VOID
1400 CpuidExtendedFunction (
1401 VOID
1402 )
1403 {
1404 UINT32 Eax;
1405
1406 AsmCpuid (CPUID_EXTENDED_FUNCTION, &Eax, NULL, NULL, NULL);
1407 Print (L"CPUID_EXTENDED_FUNCTION (Leaf %08x)\n", CPUID_EXTENDED_FUNCTION);
1408 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, 0, 0, 0);
1409 PRINT_VALUE (Eax, MaximumExtendedFunction);
1410
1411 gMaximumExtendedFunction = Eax;
1412 }
1413
1414 /**
1415 Display CPUID_EXTENDED_CPU_SIG leaf.
1416
1417 **/
1418 VOID
1419 CpuidExtendedCpuSig (
1420 VOID
1421 )
1422 {
1423 UINT32 Eax;
1424 CPUID_EXTENDED_CPU_SIG_ECX Ecx;
1425 CPUID_EXTENDED_CPU_SIG_EDX Edx;
1426
1427 if (CPUID_EXTENDED_CPU_SIG > gMaximumExtendedFunction) {
1428 return;
1429 }
1430
1431 AsmCpuid (CPUID_EXTENDED_CPU_SIG, &Eax, NULL, &Ecx.Uint32, &Edx.Uint32);
1432 Print (L"CPUID_EXTENDED_CPU_SIG (Leaf %08x)\n", CPUID_EXTENDED_CPU_SIG);
1433 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, 0, Ecx.Uint32, Edx.Uint32);
1434 PRINT_BIT_FIELD (Ecx, LAHF_SAHF);
1435 PRINT_BIT_FIELD (Ecx, LZCNT);
1436 PRINT_BIT_FIELD (Ecx, PREFETCHW);
1437 PRINT_BIT_FIELD (Edx, SYSCALL_SYSRET);
1438 PRINT_BIT_FIELD (Edx, NX);
1439 PRINT_BIT_FIELD (Edx, Page1GB);
1440 PRINT_BIT_FIELD (Edx, RDTSCP);
1441 PRINT_BIT_FIELD (Edx, LM);
1442 }
1443
1444 /**
1445 Display CPUID_BRAND_STRING1, CPUID_BRAND_STRING2 and CPUID_BRAND_STRING3
1446 leafs. Also display these three leafs as a single brand string.
1447
1448 **/
1449 VOID
1450 CpuidProcessorBrandString (
1451 VOID
1452 )
1453 {
1454 CPUID_BRAND_STRING_DATA Eax;
1455 CPUID_BRAND_STRING_DATA Ebx;
1456 CPUID_BRAND_STRING_DATA Ecx;
1457 CPUID_BRAND_STRING_DATA Edx;
1458 //
1459 // Array to store brand string from 3 brand string leafs with
1460 // 4 32-bit brand string values per leaf and an extra value to
1461 // null terminate the string.
1462 //
1463 UINT32 BrandString[3 * 4 + 1];
1464
1465 if (CPUID_BRAND_STRING1 <= gMaximumExtendedFunction) {
1466 AsmCpuid (CPUID_BRAND_STRING1, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32);
1467 Print (L"CPUID_BRAND_STRING1 (Leaf %08x)\n", CPUID_BRAND_STRING1);
1468 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32);
1469 BrandString[0] = Eax.Uint32;
1470 BrandString[1] = Ebx.Uint32;
1471 BrandString[2] = Ecx.Uint32;
1472 BrandString[3] = Edx.Uint32;
1473 }
1474
1475 if (CPUID_BRAND_STRING2 <= gMaximumExtendedFunction) {
1476 AsmCpuid (CPUID_BRAND_STRING2, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32);
1477 Print (L"CPUID_BRAND_STRING2 (Leaf %08x)\n", CPUID_BRAND_STRING2);
1478 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32);
1479 BrandString[4] = Eax.Uint32;
1480 BrandString[5] = Ebx.Uint32;
1481 BrandString[6] = Ecx.Uint32;
1482 BrandString[7] = Edx.Uint32;
1483 }
1484
1485 if (CPUID_BRAND_STRING3 <= gMaximumExtendedFunction) {
1486 AsmCpuid (CPUID_BRAND_STRING3, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32);
1487 Print (L"CPUID_BRAND_STRING3 (Leaf %08x)\n", CPUID_BRAND_STRING3);
1488 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32);
1489 BrandString[8] = Eax.Uint32;
1490 BrandString[9] = Ebx.Uint32;
1491 BrandString[10] = Ecx.Uint32;
1492 BrandString[11] = Edx.Uint32;
1493 }
1494
1495 BrandString[12] = 0;
1496
1497 Print (L"Brand String = %a\n", (CHAR8 *)BrandString);
1498 }
1499
1500 /**
1501 Display CPUID_EXTENDED_CACHE_INFO leaf.
1502
1503 **/
1504 VOID
1505 CpuidExtendedCacheInfo (
1506 VOID
1507 )
1508 {
1509 CPUID_EXTENDED_CACHE_INFO_ECX Ecx;
1510
1511 if (CPUID_EXTENDED_CACHE_INFO > gMaximumExtendedFunction) {
1512 return;
1513 }
1514
1515 AsmCpuid (CPUID_EXTENDED_CACHE_INFO, NULL, NULL, &Ecx.Uint32, NULL);
1516 Print (L"CPUID_EXTENDED_CACHE_INFO (Leaf %08x)\n", CPUID_EXTENDED_CACHE_INFO);
1517 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, 0, Ecx.Uint32, 0);
1518 PRINT_BIT_FIELD (Ecx, CacheLineSize);
1519 PRINT_BIT_FIELD (Ecx, L2Associativity);
1520 PRINT_BIT_FIELD (Ecx, CacheSize);
1521 }
1522
1523 /**
1524 Display CPUID_EXTENDED_TIME_STAMP_COUNTER leaf.
1525
1526 **/
1527 VOID
1528 CpuidExtendedTimeStampCounter (
1529 VOID
1530 )
1531 {
1532 CPUID_EXTENDED_TIME_STAMP_COUNTER_EDX Edx;
1533
1534 if (CPUID_EXTENDED_TIME_STAMP_COUNTER > gMaximumExtendedFunction) {
1535 return;
1536 }
1537
1538 AsmCpuid (CPUID_EXTENDED_TIME_STAMP_COUNTER, NULL, NULL, NULL, &Edx.Uint32);
1539 Print (L"CPUID_EXTENDED_TIME_STAMP_COUNTER (Leaf %08x)\n", CPUID_EXTENDED_TIME_STAMP_COUNTER);
1540 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, 0, 0, Edx.Uint32);
1541 PRINT_BIT_FIELD (Edx, InvariantTsc);
1542 }
1543
1544 /**
1545 Display CPUID_VIR_PHY_ADDRESS_SIZE leaf.
1546
1547 **/
1548 VOID
1549 CpuidVirPhyAddressSize (
1550 VOID
1551 )
1552 {
1553 CPUID_VIR_PHY_ADDRESS_SIZE_EAX Eax;
1554
1555 if (CPUID_VIR_PHY_ADDRESS_SIZE > gMaximumExtendedFunction) {
1556 return;
1557 }
1558
1559 AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &Eax.Uint32, NULL, NULL, NULL);
1560 Print (L"CPUID_VIR_PHY_ADDRESS_SIZE (Leaf %08x)\n", CPUID_VIR_PHY_ADDRESS_SIZE);
1561 Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, 0, 0, 0);
1562 PRINT_BIT_FIELD (Eax, PhysicalAddressBits);
1563 PRINT_BIT_FIELD (Eax, LinearAddressBits);
1564 }
1565
1566 /**
1567 The user Entry Point for Application. The user code starts with this function
1568 as the real entry point for the application.
1569
1570 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1571 @param[in] SystemTable A pointer to the EFI System Table.
1572
1573 @retval EFI_SUCCESS The entry point is executed successfully.
1574 @retval other Some error occurs when executing this entry point.
1575
1576 **/
1577 EFI_STATUS
1578 EFIAPI
1579 UefiMain (
1580 IN EFI_HANDLE ImageHandle,
1581 IN EFI_SYSTEM_TABLE *SystemTable
1582 )
1583 {
1584 Print (L"UEFI CPUID Version 0.5\n");
1585
1586 CpuidSignature ();
1587 CpuidVersionInfo ();
1588 CpuidCacheInfo ();
1589 CpuidSerialNumber ();
1590 CpuidCacheParams();
1591 CpuidMonitorMwait ();
1592 CpuidThermalPowerManagement ();
1593 CpuidStructuredExtendedFeatureFlags ();
1594 CpuidDirectCacheAccessInfo();
1595 CpuidArchitecturalPerformanceMonitoring ();
1596 CpuidExtendedTopology (CPUID_EXTENDED_TOPOLOGY);
1597 CpuidExtendedStateMainLeaf ();
1598 CpuidIntelRdtMonitoringEnumerationSubLeaf ();
1599 CpuidIntelRdtMonitoringL3CacheCapabilitySubLeaf ();
1600 CpuidIntelRdtAllocationMainLeaf ();
1601 CpuidEnumerationOfIntelSgx ();
1602 CpuidIntelProcessorTraceMainLeaf ();
1603 CpuidTimeStampCounter ();
1604 CpuidProcessorFrequency ();
1605 CpuidSocVendor ();
1606 CpuidDeterministicAddressTranslationParameters ();
1607 CpuidExtendedTopology (CPUID_V2_EXTENDED_TOPOLOGY);
1608 CpuidExtendedFunction ();
1609 CpuidExtendedCpuSig ();
1610 CpuidProcessorBrandString ();
1611 CpuidExtendedCacheInfo ();
1612 CpuidExtendedTimeStampCounter ();
1613 CpuidVirPhyAddressSize ();
1614
1615 return EFI_SUCCESS;
1616 }