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