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