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