2 * (C) 2001-2010 Dave Jones.
4 * Licensed under the terms of the GNU GPL License version 2.
6 * Feature flag decoding.
14 static void flag_decode(unsigned long reg, const char * reg_desc, const char *flags[], const char *flags_desc[])
18 for (i = 0; i < 32; i++) {
22 printf(" %s", flags[i]);
24 printf(" [%s:%u]", reg_desc, i);
27 printf(" %-8s", flags[i]);
29 printf(" [%s:%u] ", reg_desc, i);
31 printf("\t%s\n", flags_desc[i]);
40 void get_feature_flags(struct cpudata *cpu)
42 unsigned int eax, ebx, ecx, edx;
44 cpuid(cpu->number, 0x00000001, &eax, &ebx, &ecx, &edx);
47 if (cpu->maxei >= 0x80000001) {
48 cpuid(cpu->number, 0x80000001, &eax, &ebx, &ecx, &edx);
49 cpu->eflags_ecx = ecx;
50 cpu->eflags_edx = edx;
54 void show_extra_intel_flags(struct cpudata *cpu)
56 unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
57 /* CPUID 0x00000006 EAX flags */
58 const char *intel_cpuid_06_eax_flags[] = {
59 "dts", "ida", "arat", NULL, "pln", "ecmd", "ptm", NULL,
60 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
61 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
62 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
64 const char *intel_cpuid_06_eax_flags_desc[] = {
65 "Digital temperature sensor supported", // 0
66 "Intel Dynamic Acceleration Technology (Turbo Boost)", // 1
67 "Always Running APIC Timer", // 2
69 "Power limit notification controls", // 4
70 "Clock modulation duty cycle extension", // 5
71 "Package thermal management", // 6
99 /* CPUID 0x80000007 EDX flags */
100 const char *intel_cpuid_80000007_edx_flags[] = {
101 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
102 "nonstop_tsc", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
103 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
104 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
106 const char *intel_cpuid_80000007_edx_flags_desc[] = {
115 "Invariant/nonstop/constant TSC", // 8
142 if (cpu->cpuid_level >= 0x06) {
143 cpuid(cpu->number, 0x06, &eax, &ebx, &ecx, &edx);
144 flag_decode(eax, "6:eax", intel_cpuid_06_eax_flags, intel_cpuid_06_eax_flags_desc);
146 // Intel CPUID 0x80000007
147 if (cpu->maxei >= 0x80000007) {
148 cpuid(cpu->number, 0x80000007, &eax, &ebx, &ecx, &edx);
149 flag_decode(edx, "80000007:edx", intel_cpuid_80000007_edx_flags, intel_cpuid_80000007_edx_flags_desc);
153 static void decode_feature_flags(struct cpudata *cpu)
155 unsigned int eax, ebx, ecx, edx;
157 /* CPUID 0x00000001 EDX flags */
158 const char *generic_cap_flags[] = {
159 "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
160 "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
161 "pat", "pse36", "psn", "clflsh", NULL, "ds", "acpi", "mmx",
162 "fxsr", "sse", "sse2", "ss", "ht", "tm", NULL, "pbe"
164 const char *generic_cap_flags_desc[] = {
166 "Virtual Mode Extensions", // 1
167 "Debugging Extensions", // 2
168 "Page Size Extensions", // 3
169 "Time Stamp Counter", // 4
170 "Model-Specific Registers", // 5
171 "Physical Address Extensions", // 6
172 "Machine Check Exception", // 7
173 "CMPXCHG8 instruction", // 8
176 "SYSENTER/SYSEXIT instructions", // 11
177 "Memory Type Range Registers", // 12
178 "Page Global Enable", // 13
179 "Machine Check Architecture", // 14
180 "CMOV instruction", // 15
181 "Page Attribute Table", // 16
183 "Processor serial number", /* reserved on AMD */ // 18
184 "CLFLUSH instruction", // 19
186 "Debug Trace Store", /* reserved on AMD */ // 21
187 "ACPI via MSR", /* reserved on AMD */ // 22
189 "FXSAVE and FXRSTOR instructions", // 24
191 "SSE2 support", // 26
192 "CPU self snoop", /* reserved on AMD */ // 27
193 "Hyper-Threading", // 28
194 "Thermal Monitor", /* reserved on AMD */ // 29
196 "Pending Break Enable" /* reserved on AMD */ // 31
198 /* CPUID 0x00000001 ECX flags */
199 const char *intel_cap_generic_ecx_flags[] = {
200 "sse3", "pclmuldq", "dtes64", "monitor", "ds-cpl", "vmx", "smx", "est",
201 "tm2", "ssse3", "cid", NULL, "fma", "cx16", "xTPR", "pdcm",
202 NULL, "pcid", "dca", "sse4_1", "sse4_2", "x2apic", "movbe", "popcnt",
203 "tsc-deadline", "aes", "xsave", "osxsave", "avx", NULL, NULL, NULL
205 const char *intel_cap_generic_ecx_flags_desc[] = {
206 "Streaming SIMD Extensions 3", // 0
207 "PCLMULDQ Instruction", // 1
208 "64-Bit Debug Store", // 2
209 "MONITOR/MWAIT", // 3
210 "CPL Qualified Debug Store", // 4
211 "Virtual Machine Extensions", // 5
212 "Safer Mode Extensions", // 6
213 "Enhanced Intel SpeedStep Technology", // 7
214 "Thermal Monitor 2", // 8
215 "Supplemental Streaming SIMD Extensions 3", // 9
216 "L1 Context ID", // 10
218 "Fused Multiply Add", // 12
220 "xTPR Update Control", // 14
221 "Perfmon and Debug Capability", // 15
223 "Process-context identifiers", // 17
224 "Direct Cache Access", // 18
225 "Streaming SIMD Extensions 4.1", // 19
226 "Streaming SIMD Extensions 4.2", // 20
227 "Extended xAPIC Support", // 21
228 "MOVBE Instruction", // 22
229 "POPCNT Instruction", // 23
230 "TSC Deadline support", // 24
231 "AES Instruction", // 25
232 "XSAVE/XSTOR States", // 26
233 "OS-Enabled Extended State Management", // 27
234 "AVX instruction extensions", // 28
239 /* CPUID 0x80000001 EDX flags */
240 const char *intel_cap_extended_edx_flags[] = {
241 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
242 NULL, NULL, NULL, "SYSCALL", NULL, NULL, NULL, NULL,
243 NULL, NULL, NULL, NULL, "xd", NULL, NULL, NULL,
244 NULL, NULL, "pdpe1gb", "rdtscp", NULL, "em64t", NULL, NULL,
246 const char *intel_cap_extended_edx_flags_desc[] = {
258 "SYSCALL/SYSRET instructions", // 11
267 "Execution Disable Bit", // 20
273 "1-GByte pages", // 26
274 "RDTSCP and IA32_TSC_AUX", // 27
276 "Intel 64 Instruction Set Architecture", // 29
280 /* CPUID 0x80000001 ECX flags */
281 const char *intel_cap_extended_ecx_flags[] = {
282 "lahf_lm", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
283 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
284 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
285 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
287 const char *intel_cap_extended_ecx_flags_desc[] = {
288 "LAHF/SAHF available in 64-bit mode", // 0
322 const char *amd_cap_generic_ecx_flags[] = {
323 "sse3", "pclmulqdq", NULL, "mwait", NULL, NULL, NULL, NULL,
324 NULL, "ssse3", NULL, NULL, "fma", "cmpxchg16b", NULL, NULL,
325 NULL, NULL, NULL, "sse4_1", "sse4_2", NULL, NULL, "popcnt",
326 NULL, "aes", "xsave", "osxsave", "avx", "f16c", NULL, NULL
328 const char *amd_cap_generic_ecx_flags_desc[] = {
329 "Streaming SIMD Extensions 3", // 0
332 "MONITOR/MWAIT instructions", // 3
338 "Supplemental Streaming SIMD Extensions 3", // 9
342 "CMPXCHG16B instruction", // 13
348 "Streaming SIMD Extensions 4.1", // 19
351 "POPCNT instruction", // 23
361 const char *amd_cap_extended_edx_flags[] = {
362 "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
363 "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
364 "pat", "pse36", NULL, "mp", "nx", NULL, "mmxext", "mmx",
365 "fxsr", "ffxsr", "page1gb", "rdtscp",
366 NULL, "lm", "3dnowext", "3dnow"
367 }; /* "mp" defined for CPUs prior to AMD family 0xf */
369 const char *amd_cap_extended_ecx_flags[] = {
370 "lahf/sahf", "CmpLegacy", "svm", "ExtApicSpace",
371 "LockMovCr0", "abm", "sse4a", "misalignsse",
372 "3dnowPref", "osvw", "ibs", "xop",
373 "skinit", "wdt", NULL, "lwp",
374 "fma4", NULL, NULL, "NodeId",
375 NULL, "tbm", "TopoExt", "PerfCtrExtCore",
376 "PerfCtrExtNB", NULL, NULL, NULL, NULL, NULL, NULL, NULL
379 const char *centaur_cap_extended_ecx_flags[] = {
380 "sse3", NULL, NULL, NULL, NULL, NULL, NULL, "EPS",
381 "tm2", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
382 NULL, NULL, NULL, NULL, NULL, NULL, "mmxext", NULL,
383 NULL, NULL, NULL, NULL, NULL, NULL, "3dnowext", "3dnow"
385 const char *centaur_cap_extended_edx_flags[] = {
386 NULL, NULL, "RNGp", "RNGe", NULL, NULL, "ACEp", "ACEe",
387 "ACE2p", "ACE2e", "PHEp", "PHEe", "PMMp", "PMMe", NULL, NULL,
388 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
389 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
392 const char *transmeta_cap_flags[] = {
393 "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
394 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
395 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
396 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
399 printf("Feature flags:\n");
400 flag_decode(cpu->flags_edx, "1:edx", generic_cap_flags, generic_cap_flags_desc);
402 /* Vendor specific extensions. */
403 switch (cpu->vendor) {
405 flag_decode(cpu->flags_ecx, "1:ecx", amd_cap_generic_ecx_flags, amd_cap_generic_ecx_flags_desc);
407 if (cpu->maxei < 0x80000001)
409 printf("Extended feature flags:\n");
410 flag_decode(cpu->eflags_edx, "80000001:edx", amd_cap_extended_edx_flags, NULL);
411 flag_decode(cpu->eflags_ecx, "80000001:ecx", amd_cap_extended_ecx_flags, NULL);
417 printf("Extended feature flags:\n");
418 flag_decode(cpu->flags_ecx, "1:ecx", centaur_cap_extended_ecx_flags, NULL);
419 cpuid(cpu->number, 0xc0000000, &eax, &ebx, &ecx, &edx);
420 if (eax >=0xc0000001) {
421 cpuid(cpu->number, 0xc0000001, &eax, &ebx, &ecx, &edx);
422 cpu->flags_edx = edx;
423 flag_decode(cpu->flags_edx, "1:edx", centaur_cap_extended_edx_flags, NULL);
427 case VENDOR_TRANSMETA:
429 printf("Extended feature flags:\n");
430 flag_decode(cpu->flags_ecx, "1:ecx", transmeta_cap_flags, NULL);
438 flag_decode(cpu->flags_ecx, "1:ecx", intel_cap_generic_ecx_flags, intel_cap_generic_ecx_flags_desc);
440 if (cpu->maxei < 0x80000001)
442 printf("Extended feature flags:\n");
443 flag_decode(cpu->eflags_edx, "80000001:edx", intel_cap_extended_edx_flags, intel_cap_extended_edx_flags_desc);
444 flag_decode(cpu->eflags_ecx, "80000001:ecx", intel_cap_extended_ecx_flags, intel_cap_extended_ecx_flags_desc);
445 show_extra_intel_flags(cpu);
449 /* Unknown CPU manufacturer or no special handling needed */
456 static sigjmp_buf out;
458 static void sigill(__attribute__((__unused__))int sig)
463 static void test_longnop(void)
467 signal(SIGILL, sigill);
469 died = sigsetjmp(out, 1);
472 asm volatile(".byte 0x0f,0x1f,0x00 /* nopl 0(%eax) */");
474 printf("Long NOPs supported: %s\n", died ? "no" : "yes");
477 void display_feature_flags(struct cpudata *cpu)
479 decode_feature_flags(cpu);