1
/* Intel and AMD x86 CPUID display program v 3.3 (1 Jan 2002)
2
* Copyright 2002 Phil Karn, KA9Q
3
* Updated 24 Apr 2001 to latest Intel CPUID spec
4
* Updated 22 Dec 2001 to decode Intel flag 28, hyper threading
5
* Updated 1 Jan 2002 to cover AMD Duron, Athlon
6
* May be used under the terms of the GNU Public License (GPL)
9
* ftp://download.intel.com/design/pro/applnots/24161809.pdf (AP-485)
10
* http://developer.intel.com/design/Pentium4/manuals/24547103.pdf
11
* http://developer.intel.com/design/pentiumiii/applnots/24512501.pdf (AP-909)
12
* http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/20734.pdf
18
void decode_intel_tlb(int);
19
void decode_cyrix_tlb(int);
20
void dointel(int),doamd(int),docyrix(int);
21
void printregs(int eax,int ebx,int ecx,int edx);
24
char *Brands[MAXBRANDS] = {
27
"Pentium III processor",
28
"Intel Pentium III Xeon processor",
33
"Intel Pentium 4 processor",
36
#define cpuid(in,a,b,c,d)\
37
asm("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in));
41
unsigned long li,maxi,maxei,ebx,ecx,edx,unused;
43
/* Insert code here to test if CPUID instruction is available */
45
/* Dump all the CPUID results in raw hex */
46
cpuid(0,maxi,unused,unused,unused);
47
maxi &= 0xffff; /* The high-order word is non-zero on some Cyrix CPUs */
48
printf(" eax in eax ebx ecx edx\n");
50
unsigned long eax,ebx,ecx,edx;
52
cpuid(i,eax,ebx,ecx,edx);
53
printf("%08x %08lx %08lx %08lx %08lx\n",i,eax,ebx,ecx,edx);
55
cpuid(0x80000000,maxei,unused,unused,unused);
56
for(li=0x80000000;li<=maxei;li++){
57
unsigned long eax,ebx,ecx,edx;
59
cpuid(li,eax,ebx,ecx,edx);
60
printf("%08lx %08lx %08lx %08lx %08lx\n",li,eax,ebx,ecx,edx);
64
/* Vendor ID and max CPUID level supported */
65
cpuid(0,unused,ebx,ecx,edx);
66
printf("Vendor ID: \"");
68
putchar(ebx >> (8*i));
70
putchar(edx >> (8*i));
72
putchar(ecx >> (8*i));
73
printf("\"; CPUID level %ld\n\n",maxi);
76
case 0x756e6547: /* Intel */
79
case 0x68747541: /* AMD */
82
case 0x69727943: /* Cyrix */
86
printf("Unknown vendor\n");
92
char *Intel_feature_flags[] = {
93
"FPU Floating Point Unit",
94
"VME Virtual 8086 Mode Enhancements",
95
"DE Debugging Extensions",
96
"PSE Page Size Extensions",
97
"TSC Time Stamp Counter",
98
"MSR Model Specific Registers",
99
"PAE Physical Address Extension",
100
"MCE Machine Check Exception",
101
"CX8 COMPXCHG8B Instruction",
102
"APIC On-chip Advanced Programmable Interrupt Controller present and enabled",
104
"SEP Fast System Call",
105
"MTRR Memory Type Range Registers",
106
"PGE PTE Global Flag",
107
"MCA Machine Check Architecture",
108
"CMOV Conditional Move and Compare Instructions",
109
"FGPAT Page Attribute Table",
110
"PSE-36 36-bit Page Size Extension",
111
"PN Processor Serial Number present and enabled",
112
"CLFSH CFLUSH instruction",
115
"ACPI Thermal Monitor and Clock Ctrl",
116
"MMX MMX instruction set",
117
"FXSR Fast FP/MMX Streaming SIMD Extensions save/restore",
118
"SSE Streaming SIMD Extensions instruction set",
119
"SSE2 SSE2 extensions",
121
"HT Hyper Threading",
122
"TM Thermal monitor",
127
/* Intel-specific information */
128
void dointel(int maxi){
129
printf("Intel-specific functions:\n");
132
/* Family/model/type etc */
133
int clf,apic_id,feature_flags;
134
int extended_model = -1,extended_family = -1;
135
unsigned long eax,ebx,edx,unused;
136
int stepping,model,family,type,reserved,brand,siblings;
139
cpuid(1,eax,ebx,unused,edx);
140
printf("Version %08lx:\n",eax);
141
stepping = eax & 0xf;
142
model = (eax >> 4) & 0xf;
143
family = (eax >> 8) & 0xf;
144
type = (eax >> 12) & 0x3;
145
reserved = eax >> 14;
146
clf = (ebx >> 8) & 0xff;
147
apic_id = (ebx >> 24) & 0xff;
148
siblings = (ebx >> 16) & 0xff;
151
printf("Type %d - ",type);
154
printf("Original OEM");
160
printf("Dual-capable");
168
printf("Family %d - ",family);
180
printf("Pentium Pro");
187
extended_family = (eax >> 20) & 0xff;
188
printf("Extended family %d\n",extended_family);
190
printf("Model %d - ",model);
213
printf("write-back enhanced DX2");
229
printf("for 486 system");
239
printf("Pentium Pro");
242
printf("Pentium II Model 3");
245
printf("Pentium II Model 5/Xeon/Celeron");
251
printf("Pentium III/Pentium III Xeon - external L2 cache");
254
printf("Pentium III/Pentium III Xeon - internal L2 cache");
263
extended_model = (eax >> 16) & 0xf;
264
printf("Extended model %d\n",extended_model);
266
printf("Stepping %d\n",stepping);
268
printf("Reserved %d\n\n",reserved);
272
printf("Brand index: %d [",brand);
273
if(brand < MAXBRANDS){
274
printf("%s]\n",Brands[brand]);
276
printf("not in table]\n");
279
cpuid(0x80000000,eax,ebx,unused,edx);
280
if(eax & 0x80000000){
281
/* Extended feature/signature bits supported */
283
if(maxe >= 0x80000004){
286
printf("Extended brand string: \"");
287
for(i=0x80000002;i<=0x80000004;i++){
288
unsigned long eax,ebx,ecx,edx;
290
cpuid(i,eax,ebx,ecx,edx);
291
printregs(eax,ebx,ecx,edx);
297
printf("CLFLUSH instruction cache line size: %d\n",clf);
300
printf("Initial APIC ID: %d\n",apic_id);
302
if(feature_flags & (1<<28)){
303
printf("Hyper threading siblings: %d\n",siblings);
306
printf("\nFeature flags %08x:\n",feature_flags);
308
if(feature_flags & (1<<i)){
309
printf("%s\n",Intel_feature_flags[i]);
315
/* Decode TLB and cache info */
319
printf("TLB and cache info:\n");
321
unsigned long eax,ebx,ecx,edx;
323
cpuid(2,eax,ebx,ecx,edx);
325
decode_intel_tlb(eax >> 8);
326
decode_intel_tlb(eax >> 16);
327
decode_intel_tlb(eax >> 24);
329
if((ebx & 0x80000000) == 0){
330
decode_intel_tlb(ebx);
331
decode_intel_tlb(ebx >> 8);
332
decode_intel_tlb(ebx >> 16);
333
decode_intel_tlb(ebx >> 24);
335
if((ecx & 0x80000000) == 0){
336
decode_intel_tlb(ecx);
337
decode_intel_tlb(ecx >> 8);
338
decode_intel_tlb(ecx >> 16);
339
decode_intel_tlb(ecx >> 24);
341
if((edx & 0x80000000) == 0){
342
decode_intel_tlb(edx);
343
decode_intel_tlb(edx >> 8);
344
decode_intel_tlb(edx >> 16);
345
decode_intel_tlb(edx >> 24);
350
/* Pentium III CPU serial number */
351
unsigned long signature,unused,ecx,edx;
353
cpuid(1,signature,unused,unused,unused);
354
cpuid(3,unused,unused,ecx,edx);
355
printf("Processor serial: ");
356
printf("%04lX",signature >> 16);
357
printf("-%04lX",signature & 0xffff);
358
printf("-%04lX",edx >> 16);
359
printf("-%04lX",edx & 0xffff);
360
printf("-%04lX",ecx >> 16);
361
printf("-%04lX\n",ecx & 0xffff);
364
void printregs(int eax,int ebx,int ecx,int edx){
370
string[j] = eax >> (8*j);
371
string[j+4] = ebx >> (8*j);
372
string[j+8] = ecx >> (8*j);
373
string[j+12] = edx >> (8*j);
379
/* Decode Intel TLB and cache info descriptors */
380
void decode_intel_tlb(int x){
388
printf("Instruction TLB: 4KB pages, 4-way set assoc, 32 entries\n");
391
printf("Instruction TLB: 4MB pages, 4-way set assoc, 2 entries\n");
394
printf("Data TLB: 4KB pages, 4-way set assoc, 64 entries\n");
397
printf("Data TLB: 4MB pages, 4-way set assoc, 8 entries\n");
400
printf("1st-level instruction cache: 8KB, 4-way set assoc, 32 byte line size\n");
403
printf("1st-level instruction cache: 16KB, 4-way set assoc, 32 byte line size\n");
406
printf("1st-level data cache: 8KB, 2-way set assoc, 32 byte line size\n");
409
printf("1st-level data cache: 16KB, 4-way set assoc, 32 byte line size\n");
412
printf("No 2nd-level cache, or if 2nd-level cache exists, no 3rd-level cache\n");
415
printf("2nd-level cache: 128KB, 4-way set assoc, 32 byte line size\n");
418
printf("2nd-level cache: 256KB, 4-way set assoc, 32 byte line size\n");
421
printf("2nd-level cache: 512KB, 4-way set assoc, 32 byte line size\n");
424
printf("2nd-level cache: 1MB, 4-way set assoc, 32 byte line size\n");
427
printf("2nd-level cache: 2MB, 4-way set assoc, 32 byte line size\n");
430
printf("Instruction TLB: 4KB and 2MB or 4MB pages, 64 entries\n");
433
printf("Instruction TLB: 4KB and 2MB or 4MB pages, 128 entries\n");
436
printf("Instruction TLB: 4KB and 2MB or 4MB pages, 256 entries\n");
439
printf("Data TLB: 4KB and 4MB pages, 64 entries\n");
442
printf("Data TLB: 4KB and 4MB pages, 128 entries\n");
445
printf("Data TLB: 4KB and 4MB pages, 256 entries\n");
448
printf("1st-level data cache: 8KB, 4-way set assoc, 64 byte line size\n");
451
printf("1st-level data cache: 16KB, 4-way set assoc, 64 byte line size\n");
454
printf("1st-level data cache: 32KB, 4-way set assoc, 64 byte line size\n");
457
printf("Trace cache: 12K-micro-op, 4-way set assoc\n");
460
printf("Trace cache: 16K-micro-op, 4-way set assoc\n");
463
printf("Trace cache: 32K-micro-op, 4-way set assoc\n");
466
printf("2nd-level cache: 128KB, 8-way set assoc, sectored, 64 byte line size\n");
469
printf("2nd-level cache: 256KB, 8-way set assoc, sectored, 64 byte line size\n");
472
printf("2nd-level cache: 512KB, 8-way set assoc, sectored, 64 byte line size\n");
475
printf("2nd-level cache: 1MB, 8-way set assoc, sectored, 64 byte line size\n");
478
printf("2nd-level cache: 256KB, 8-way set assoc, 32 byte line size\n");
481
printf("2nd-level cache: 512KB, 8-way set assoc 32 byte line size\n");
484
printf("2nd-level cache: 1MB, 8-way set assoc, 32 byte line size\n");
487
printf("2nd-level cache: 2MB, 8-way set assoc, 32 byte line size\n");
490
printf("unknown TLB/cache descriptor\n");
494
char *AMD_feature_flags[] = {
495
"Floating Point Unit",
496
"Virtual Mode Extensions",
497
"Debugging Extensions",
498
"Page Size Extensions",
499
"Time Stamp Counter (with RDTSC and CR4 disable bit)",
500
"Model Specific Registers with RDMSR & WRMSR",
501
"PAE - Page Address Extensions",
502
"Machine Check Exception",
503
"COMPXCHG8B Instruction",
506
"SYSCALL/SYSRET or SYSENTER/SYSEXIT instructions",
507
"MTRR - Memory Type Range Registers",
508
"Global paging extension",
509
"Machine Check Architecture",
510
"Conditional Move Instruction",
511
"PAT - Page Attribute Table",
512
"PSE-36 - Page Size Extensions",
517
"AMD MMX Instruction Extensions",
525
"3DNow! Instruction Extensions",
526
"3DNow instructions",
550
/* AMD-specific information */
551
void doamd(int maxi){
552
unsigned long maxei,unused;
555
printf("AMD-specific functions\n");
557
/* Do standard stuff */
559
unsigned long eax,ebx,edx,unused;
560
int stepping,model,reserved;
562
cpuid(1,eax,ebx,unused,edx);
563
stepping = eax & 0xf;
564
model = (eax >> 4) & 0xf;
565
family = (eax >> 8) & 0xf;
566
reserved = eax >> 12;
568
printf("Version %08lx:\n",eax);
569
printf("Family: %d Model: %d [",family,model);
572
printf("486 model %d",model);
582
printf("K6 Model %d",model);
585
printf("K6-2 Model 8");
588
printf("K6-III Model 9");
591
printf("K5/K6 model %d",model);
600
printf("Athlon model %d",model);
603
printf("Duron model 3");
606
printf("Athlon MP/Mobile Athlon model 6");
609
printf("Mobile Duron Model 7");
612
printf("Duron/Athlon model %d",model);
622
printf("Standard feature flags %08lx:\n",edx);
624
if(family == 5 && model == 0){
626
printf("Global Paging Extensions\n");
628
printf("13 - reserved\n");
631
printf("%s\n",AMD_feature_flags[i]);
637
/* Check for presence of extended info */
638
cpuid(0x80000000,maxei,unused,unused,unused);
642
if(maxei >= 0x80000001){
643
unsigned long eax,ebx,ecx,edx;
644
int stepping,model,generation,reserved;
647
cpuid(0x80000001,eax,ebx,ecx,edx);
648
stepping = eax & 0xf;
649
model = (eax >> 4) & 0xf;
650
generation = (eax >> 8) & 0xf;
651
reserved = eax >> 12;
653
printf("Generation: %d Model: %d\n",generation,model);
654
printf("Extended feature flags %08lx:\n",edx);
656
if(family == 5 && model == 0 && i == 9){
657
printf("Global Paging Extensions\n");
660
printf("%s\n",AMD_feature_flags[i]);
666
if(maxei >= 0x80000002){
667
/* Processor identification string */
669
printf("Processor name string: ");
670
for(j=0x80000002;j<=0x80000004;j++){
671
unsigned long eax,ebx,ecx,edx;
673
cpuid(j,eax,ebx,ecx,edx);
674
printregs(eax,ebx,ecx,edx);
678
if(maxei >= 0x80000005){
679
/* TLB and cache info */
680
unsigned long eax,ebx,ecx,edx;
682
cpuid(0x80000005,eax,ebx,ecx,edx);
683
printf("L1 Cache Information:\n");
685
printf("2/4-MB Pages:\n");
686
printf(" Data TLB: associativity %ld-way #entries %ld\n",
687
(eax >> 24) & 0xff,(eax >> 16) & 0xff);
688
printf(" Instruction TLB: associativity %ld-way #entries %ld\n",
689
(eax >> 8) & 0xff,eax & 0xff);
691
printf("4-KB Pages:\n");
692
printf(" Data TLB: associativity %ld-way #entries %ld\n",
693
(ebx >> 24) & 0xff,(ebx >> 16) & 0xff);
694
printf(" Instruction TLB: associativity %ld-way #entries %ld\n",
695
(ebx >> 8) & 0xff,ebx & 0xff);
697
printf("L1 Data cache:\n");
698
printf(" size %ld KB associativity %lx-way lines per tag %ld line size %ld\n",
699
ecx >> 24,(ecx>>16) & 0xff,(ecx >> 8)&0xff,ecx&0xff);
701
printf("L1 Instruction cache:\n");
702
printf(" size %ld KB associativity %lx-way lines per tag %ld line size %ld\n",
703
edx >> 24,(edx>>16) & 0xff,(edx >> 8)&0xff,edx&0xff);
707
/* check K6-III (and later?) on-chip L2 cache size */
708
if (maxei >= 0x80000006) {
709
unsigned long eax,ebx,ecx,unused;
712
cpuid(0x80000006,eax,ebx,ecx,unused);
713
printf("L2 Cache Information:\n");
715
printf("2/4-MB Pages:\n");
716
assoc = (eax >> 24) & 0xff;
719
printf(" Data TLB: associativity %s #entries %ld\n",
720
Assoc[(eax >> 24) & 0xf],(eax >> 16) & 0xff);
721
assoc = (eax >> 16) & 0xff;
722
printf(" Instruction TLB: associativity %s #entries %ld\n",
723
Assoc[(eax >> 8) & 0xf],eax & 0xff);
725
printf("4-KB Pages:\n");
726
printf(" Data TLB: associativity %s #entries %ld\n",
727
Assoc[(ebx >> 24) & 0xf],(ebx >> 16) & 0xff);
728
printf(" Instruction TLB: associativity %s #entries %ld\n",
729
Assoc[(ebx >> 8) & 0xf],ebx & 0xff);
731
printf(" size %ld KB associativity %s lines per tag %ld line size %ld\n",
732
ecx >> 24,Assoc[(ecx>>16) & 0xf],(ecx >> 8)&0xff,ecx&0xff);
736
/* Check power management feature flags */
737
if(maxei >= 0x80000007){
738
unsigned long unused,edx;
740
printf("Advanced Power Management Feature Flags\n");
741
cpuid(0x80000007,unused,unused,unused,edx);
743
printf("Has temperature sensing diode\n");
745
printf("Supports Frequency ID control\n");
747
printf("Supports Voltage ID control\n");
749
/* Check phys address & linear address size */
750
if(maxei >= 0x80000008){
751
unsigned long unused,eax;
753
cpuid(0x80000008,eax,unused,unused,unused);
754
printf("Maximum linear address: %ld; maximum phys address %ld\n",
755
(eax>>8) & 0xff,eax&0xff);
759
char *Cyrix_standard_feature_flags_5[] = {
760
"FPU Floating Point Unit",
761
"V86 Virtual Mode Extensions",
764
"Time Stamp Counter",
765
"RDMSR/WRMSR (Model Specific Registers)",
767
"Machine Check Exception",
768
"COMPXCHG8B Instruction",
769
"APIC - On-chip Advanced Programmable Interrupt Controller present and enabled",
772
"MTRR Memory Type Range Registers",
775
"CMOV Conditional Move Instruction",
793
char *Cyrix_standard_feature_flags_not5[] = {
794
"FPU Floating Point Unit",
795
"V86 Virtual Mode Extensions",
798
"Time Stamp Counter",
799
"RDMSR/WRMSR (Model Specific Registers)",
801
"Machine Check Exception",
802
"COMPXCHG8B Instruction",
803
"APIC - On-chip Advanced Programmable Interrupt Controller present and enabled",
806
"MTRR Memory Type Range Registers",
807
"Global Paging Extension",
809
"CMOV Conditional Move Instruction",
828
char *Cyrix_extended_feature_flags[] = {
829
"FPU Floating Point Unit",
830
"V86 Virtual Mode Extensions",
832
"Page Size Extensions",
833
"Time Stamp Counter",
860
"3DNow instructions",
863
/* Cyrix-specific information */
864
void docyrix(int maxi){
865
unsigned long maxei,unused;
868
printf("Cyrix-specific functions\n");
869
cpuid(0x80000000,maxei,unused,unused,unused);
870
/* Dump extended info, if any, in raw hex */
871
for(i=0x80000000;i<=maxei;i++){
872
unsigned long eax,ebx,ecx,edx;
874
cpuid(i,eax,ebx,ecx,edx);
875
printf("eax in: 0x%x, eax = %08lx ebx = %08lx ecx = %08lx edx = %08lx\n",i,eax,ebx,ecx,edx);
878
/* Do standard stuff */
880
unsigned long eax,unused,edx;
881
int stepping,model,family,reserved;
883
cpuid(1,eax,unused,unused,edx);
884
stepping = eax & 0xf;
885
model = (eax >> 4) & 0xf;
886
family = (eax >> 8) & 0xf;
887
reserved = eax >> 12;
889
printf("Family: %d Model: %d [",family,model);
917
if(family == 5 && model == 0){
922
printf("%s\n",Cyrix_standard_feature_flags_5[i]);
930
printf("%s\n",Cyrix_standard_feature_flags_not5[i]);
936
/* TLB and L1 Cache info */
941
unsigned long eax,edx,unused;
943
cpuid(2,eax,unused,unused,edx);
945
decode_cyrix_tlb(eax >> 8);
946
decode_cyrix_tlb(eax >> 16);
947
decode_cyrix_tlb(eax >> 24);
949
/* ebx and ecx are reserved */
951
if((edx & 0x80000000) == 0){
952
decode_cyrix_tlb(edx);
953
decode_cyrix_tlb(edx >> 8);
954
decode_cyrix_tlb(edx >> 16);
955
decode_cyrix_tlb(edx >> 24);
960
/* Check for presence of extended info */
961
if(maxei < 0x80000000)
964
printf("\nExtended info:\n");
965
if(maxei >= 0x80000001){
966
unsigned long eax,ebx,ecx,edx;
967
int stepping,model,family,reserved,i;
969
cpuid(0x80000001,eax,ebx,ecx,edx);
970
stepping = eax & 0xf;
971
model = (eax >> 4) & 0xf;
972
family = (eax >> 8) & 0xf;
973
reserved = eax >> 12;
974
printf("Family: %d Model: %d [",family,model);
987
printf("Extended feature flags:\n");
990
printf("%s\n",Cyrix_extended_feature_flags[i]);
995
if(maxei >= 0x80000002){
996
/* Processor identification string */
997
char namestring[49],*cp;
1000
printf("Processor name string: ");
1001
for(j=0x80000002;j<=0x80000004;j++){
1002
unsigned long eax,ebx,ecx,edx;
1004
cpuid(j,eax,ebx,ecx,edx);
1005
printregs(eax,ebx,ecx,edx);
1008
if(maxei >= 0x80000005){
1009
/* TLB and L1 Cache info */
1013
for(i=0;i<ntlb;i++){
1014
unsigned long eax,ebx,ecx,unused;
1016
cpuid(0x80000005,eax,ebx,ecx,unused);
1018
decode_cyrix_tlb(ebx >> 8);
1019
decode_cyrix_tlb(ebx >> 16);
1020
decode_cyrix_tlb(ebx >> 24);
1022
/* eax and edx are reserved */
1024
if((ecx & 0x80000000) == 0){
1025
decode_cyrix_tlb(ecx);
1026
decode_cyrix_tlb(ecx >> 8);
1027
decode_cyrix_tlb(ecx >> 16);
1028
decode_cyrix_tlb(ecx >> 24);
1035
/* Decode Cyrix TLB and cache info descriptors */
1036
void decode_cyrix_tlb(int x){
1041
printf("TLB: 32 entries 4-way associative 4KB pages\n");
1044
printf("L1 Cache: 16KB 4-way associative 16 bytes/line\n");