make sure termlen is not used uninitialized.
[AROS-Contrib.git] / gnu / cpuid / cpuid.c
blobff5210aecadad721ae5a2e11554c59f7b9b4aab3
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)
8 * Reference documents:
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
16 #include <stdio.h>
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);
23 #define MAXBRANDS 9
24 char *Brands[MAXBRANDS] = {
25 "brand 0",
26 "Celeron processor",
27 "Pentium III processor",
28 "Intel Pentium III Xeon processor",
29 "brand 4",
30 "brand 5",
31 "brand 6",
32 "brand 7",
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));
39 int main(){
40 int i;
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");
49 for(i=0;i<=maxi;i++){
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);
62 printf("\n");
64 /* Vendor ID and max CPUID level supported */
65 cpuid(0,unused,ebx,ecx,edx);
66 printf("Vendor ID: \"");
67 for(i=0;i<4;i++)
68 putchar(ebx >> (8*i));
69 for(i=0;i<4;i++)
70 putchar(edx >> (8*i));
71 for(i=0;i<4;i++)
72 putchar(ecx >> (8*i));
73 printf("\"; CPUID level %ld\n\n",maxi);
75 switch(ebx){
76 case 0x756e6547: /* Intel */
77 dointel(maxi);
78 break;
79 case 0x68747541: /* AMD */
80 doamd(maxi);
81 break;
82 case 0x69727943: /* Cyrix */
83 docyrix(maxi);
84 break;
85 default:
86 printf("Unknown vendor\n");
87 break;
89 return(0);
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",
103 "10 Reserved",
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",
113 "20 reserved",
114 "DS Debug store",
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",
120 "SS Self Snoop",
121 "HT Hyper Threading",
122 "TM Thermal monitor",
123 "30 reserved",
124 "31 reserved",
127 /* Intel-specific information */
128 void dointel(int maxi){
129 printf("Intel-specific functions:\n");
131 if(maxi >= 1){
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;
137 int i;
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;
149 feature_flags = edx;
151 printf("Type %d - ",type);
152 switch(type){
153 case 0:
154 printf("Original OEM");
155 break;
156 case 1:
157 printf("Overdrive");
158 break;
159 case 2:
160 printf("Dual-capable");
161 break;
162 case 3:
163 printf("Reserved");
164 break;
166 printf("\n");
168 printf("Family %d - ",family);
169 switch(family){
170 case 3:
171 printf("i386");
172 break;
173 case 4:
174 printf("i486");
175 break;
176 case 5:
177 printf("Pentium");
178 break;
179 case 6:
180 printf("Pentium Pro");
181 break;
182 case 15:
183 printf("Pentium 4");
185 printf("\n");
186 if(family == 15){
187 extended_family = (eax >> 20) & 0xff;
188 printf("Extended family %d\n",extended_family);
190 printf("Model %d - ",model);
191 switch(family){
192 case 3:
193 break;
194 case 4:
195 switch(model){
196 case 0:
197 case 1:
198 printf("DX");
199 break;
200 case 2:
201 printf("SX");
202 break;
203 case 3:
204 printf("487/DX2");
205 break;
206 case 4:
207 printf("SL");
208 break;
209 case 5:
210 printf("SX2");
211 break;
212 case 7:
213 printf("write-back enhanced DX2");
214 break;
215 case 8:
216 printf("DX4");
217 break;
219 break;
220 case 5:
221 switch(model){
222 case 1:
223 printf("60/66");
224 break;
225 case 2:
226 printf("75-200");
227 break;
228 case 3:
229 printf("for 486 system");
230 break;
231 case 4:
232 printf("MMX");
233 break;
235 break;
236 case 6:
237 switch(model){
238 case 1:
239 printf("Pentium Pro");
240 break;
241 case 3:
242 printf("Pentium II Model 3");
243 break;
244 case 5:
245 printf("Pentium II Model 5/Xeon/Celeron");
246 break;
247 case 6:
248 printf("Celeron");
249 break;
250 case 7:
251 printf("Pentium III/Pentium III Xeon - external L2 cache");
252 break;
253 case 8:
254 printf("Pentium III/Pentium III Xeon - internal L2 cache");
255 break;
257 break;
258 case 15:
259 break;
261 printf("\n");
262 if(model == 15){
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);
270 brand = ebx & 0xff;
271 if(brand > 0){
272 printf("Brand index: %d [",brand);
273 if(brand < MAXBRANDS){
274 printf("%s]\n",Brands[brand]);
275 } else {
276 printf("not in table]\n");
279 cpuid(0x80000000,eax,ebx,unused,edx);
280 if(eax & 0x80000000){
281 /* Extended feature/signature bits supported */
282 int maxe = eax;
283 if(maxe >= 0x80000004){
284 int i;
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);
293 printf("\"\n");
296 if(clf)
297 printf("CLFLUSH instruction cache line size: %d\n",clf);
299 if(apic_id)
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);
307 for(i=0;i<32;i++){
308 if(feature_flags & (1<<i)){
309 printf("%s\n",Intel_feature_flags[i]);
312 printf("\n");
314 if(maxi >= 2){
315 /* Decode TLB and cache info */
316 int ntlb,i;
318 ntlb = 255;
319 printf("TLB and cache info:\n");
320 for(i=0;i<ntlb;i++){
321 unsigned long eax,ebx,ecx,edx;
323 cpuid(2,eax,ebx,ecx,edx);
324 ntlb = eax & 0xff;
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);
349 if(maxi >= 3){
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){
365 int j;
366 char string[17];
368 string[16] = '\0';
369 for(j=0;j<4;j++){
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);
375 printf("%s",string);
379 /* Decode Intel TLB and cache info descriptors */
380 void decode_intel_tlb(int x){
381 x &= 0xff;
382 if(x != 0)
383 printf("%02x: ",x);
384 switch(x){
385 case 0:
386 break;
387 case 0x1:
388 printf("Instruction TLB: 4KB pages, 4-way set assoc, 32 entries\n");
389 break;
390 case 0x2:
391 printf("Instruction TLB: 4MB pages, 4-way set assoc, 2 entries\n");
392 break;
393 case 0x3:
394 printf("Data TLB: 4KB pages, 4-way set assoc, 64 entries\n");
395 break;
396 case 0x4:
397 printf("Data TLB: 4MB pages, 4-way set assoc, 8 entries\n");
398 break;
399 case 0x6:
400 printf("1st-level instruction cache: 8KB, 4-way set assoc, 32 byte line size\n");
401 break;
402 case 0x8:
403 printf("1st-level instruction cache: 16KB, 4-way set assoc, 32 byte line size\n");
404 break;
405 case 0xa:
406 printf("1st-level data cache: 8KB, 2-way set assoc, 32 byte line size\n");
407 break;
408 case 0xc:
409 printf("1st-level data cache: 16KB, 4-way set assoc, 32 byte line size\n");
410 break;
411 case 0x40:
412 printf("No 2nd-level cache, or if 2nd-level cache exists, no 3rd-level cache\n");
413 break;
414 case 0x41:
415 printf("2nd-level cache: 128KB, 4-way set assoc, 32 byte line size\n");
416 break;
417 case 0x42:
418 printf("2nd-level cache: 256KB, 4-way set assoc, 32 byte line size\n");
419 break;
420 case 0x43:
421 printf("2nd-level cache: 512KB, 4-way set assoc, 32 byte line size\n");
422 break;
423 case 0x44:
424 printf("2nd-level cache: 1MB, 4-way set assoc, 32 byte line size\n");
425 break;
426 case 0x45:
427 printf("2nd-level cache: 2MB, 4-way set assoc, 32 byte line size\n");
428 break;
429 case 0x50:
430 printf("Instruction TLB: 4KB and 2MB or 4MB pages, 64 entries\n");
431 break;
432 case 0x51:
433 printf("Instruction TLB: 4KB and 2MB or 4MB pages, 128 entries\n");
434 break;
435 case 0x52:
436 printf("Instruction TLB: 4KB and 2MB or 4MB pages, 256 entries\n");
437 break;
438 case 0x5b:
439 printf("Data TLB: 4KB and 4MB pages, 64 entries\n");
440 break;
441 case 0x5c:
442 printf("Data TLB: 4KB and 4MB pages, 128 entries\n");
443 break;
444 case 0x5d:
445 printf("Data TLB: 4KB and 4MB pages, 256 entries\n");
446 break;
447 case 0x66:
448 printf("1st-level data cache: 8KB, 4-way set assoc, 64 byte line size\n");
449 break;
450 case 0x67:
451 printf("1st-level data cache: 16KB, 4-way set assoc, 64 byte line size\n");
452 break;
453 case 0x68:
454 printf("1st-level data cache: 32KB, 4-way set assoc, 64 byte line size\n");
455 break;
456 case 0x70:
457 printf("Trace cache: 12K-micro-op, 4-way set assoc\n");
458 break;
459 case 0x71:
460 printf("Trace cache: 16K-micro-op, 4-way set assoc\n");
461 break;
462 case 0x72:
463 printf("Trace cache: 32K-micro-op, 4-way set assoc\n");
464 break;
465 case 0x79:
466 printf("2nd-level cache: 128KB, 8-way set assoc, sectored, 64 byte line size\n");
467 break;
468 case 0x7a:
469 printf("2nd-level cache: 256KB, 8-way set assoc, sectored, 64 byte line size\n");
470 break;
471 case 0x7b:
472 printf("2nd-level cache: 512KB, 8-way set assoc, sectored, 64 byte line size\n");
473 break;
474 case 0x7c:
475 printf("2nd-level cache: 1MB, 8-way set assoc, sectored, 64 byte line size\n");
476 break;
477 case 0x82:
478 printf("2nd-level cache: 256KB, 8-way set assoc, 32 byte line size\n");
479 break;
480 case 0x83:
481 printf("2nd-level cache: 512KB, 8-way set assoc 32 byte line size\n");
482 break;
483 case 0x84:
484 printf("2nd-level cache: 1MB, 8-way set assoc, 32 byte line size\n");
485 break;
486 case 0x85:
487 printf("2nd-level cache: 2MB, 8-way set assoc, 32 byte line size\n");
488 break;
489 default:
490 printf("unknown TLB/cache descriptor\n");
491 break;
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",
504 "APIC",
505 "10 - Reserved",
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",
513 "18 - reserved",
514 "19 - reserved",
515 "20 - reserved",
516 "21 - reserved",
517 "AMD MMX Instruction Extensions",
518 "MMX instructions",
519 "FXSAVE/FXRSTOR",
520 "25 - reserved",
521 "26 - reserved",
522 "27 - reserved",
523 "28 - reserved",
524 "29 - reserved",
525 "3DNow! Instruction Extensions",
526 "3DNow instructions",
529 char *Assoc[] = {
530 "L2 off",
531 "Direct mapped",
532 "2-way",
533 "reserved",
534 "4-way",
535 "reserved",
536 "8-way",
537 "reserved",
538 "16-way",
539 "reserved",
540 "reserved",
541 "reserved",
542 "reserved",
543 "reserved",
544 "reserved",
545 "full",
550 /* AMD-specific information */
551 void doamd(int maxi){
552 unsigned long maxei,unused;
553 int family = 0;
555 printf("AMD-specific functions\n");
557 /* Do standard stuff */
558 if(maxi >= 1){
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);
570 switch(family){
571 case 4:
572 printf("486 model %d",model);
573 break;
574 case 5:
575 switch(model){
576 case 0:
577 case 1:
578 case 2:
579 case 3:
580 case 6:
581 case 7:
582 printf("K6 Model %d",model);
583 break;
584 case 8:
585 printf("K6-2 Model 8");
586 break;
587 case 9:
588 printf("K6-III Model 9");
589 break;
590 default:
591 printf("K5/K6 model %d",model);
592 break;
594 break;
595 case 6:
596 switch(model){
597 case 1:
598 case 2:
599 case 4:
600 printf("Athlon model %d",model);
601 break;
602 case 3:
603 printf("Duron model 3");
604 break;
605 case 6:
606 printf("Athlon MP/Mobile Athlon model 6");
607 break;
608 case 7:
609 printf("Mobile Duron Model 7");
610 break;
611 default:
612 printf("Duron/Athlon model %d",model);
613 break;
616 break;
618 printf("]\n\n");
620 int i;
622 printf("Standard feature flags %08lx:\n",edx);
623 for(i=0;i<32;i++){
624 if(family == 5 && model == 0){
625 if(i == 9)
626 printf("Global Paging Extensions\n");
627 else if(i == 13)
628 printf("13 - reserved\n");
629 } else {
630 if(edx & (1<<i)){
631 printf("%s\n",AMD_feature_flags[i]);
637 /* Check for presence of extended info */
638 cpuid(0x80000000,maxei,unused,unused,unused);
639 if(maxei == 0)
640 return;
642 if(maxei >= 0x80000001){
643 unsigned long eax,ebx,ecx,edx;
644 int stepping,model,generation,reserved;
645 int i;
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);
655 for(i=0;i<32;i++){
656 if(family == 5 && model == 0 && i == 9){
657 printf("Global Paging Extensions\n");
658 } else {
659 if(edx & (1<<i)){
660 printf("%s\n",AMD_feature_flags[i]);
665 printf("\n");
666 if(maxei >= 0x80000002){
667 /* Processor identification string */
668 int j;
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);
676 printf("\n");
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");
684 if(family >= 6){
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);
704 printf("\n");
707 /* check K6-III (and later?) on-chip L2 cache size */
708 if (maxei >= 0x80000006) {
709 unsigned long eax,ebx,ecx,unused;
710 int assoc;
712 cpuid(0x80000006,eax,ebx,ecx,unused);
713 printf("L2 Cache Information:\n");
714 if(family >= 6){
715 printf("2/4-MB Pages:\n");
716 assoc = (eax >> 24) & 0xff;
717 if(assoc == 6)
718 assoc = 8;
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);
734 printf("\n");
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);
742 if(edx & 1)
743 printf("Has temperature sensing diode\n");
744 if(edx & 2)
745 printf("Supports Frequency ID control\n");
746 if(edx & 4)
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",
762 "Debug Extension",
763 "4MB Page Size",
764 "Time Stamp Counter",
765 "RDMSR/WRMSR (Model Specific Registers)",
766 "PAE",
767 "Machine Check Exception",
768 "COMPXCHG8B Instruction",
769 "APIC - On-chip Advanced Programmable Interrupt Controller present and enabled",
770 "10 - Reserved",
771 "11 - Reserved",
772 "MTRR Memory Type Range Registers",
773 "13 - reserved",
774 "Machine Check",
775 "CMOV Conditional Move Instruction",
776 "16 - reserved",
777 "17 - reserved",
778 "18 - reserved",
779 "19 - reserved",
780 "20 - reserved",
781 "21 - reserved",
782 "22 - reserved",
783 "MMX instructions",
784 "24 - reserved",
785 "25 - reserved",
786 "26 - reserved",
787 "27 - reserved",
788 "28 - reserved",
789 "29 - reserved",
790 "30 - reserved",
793 char *Cyrix_standard_feature_flags_not5[] = {
794 "FPU Floating Point Unit",
795 "V86 Virtual Mode Extensions",
796 "Debug Extension",
797 "4MB Page Size",
798 "Time Stamp Counter",
799 "RDMSR/WRMSR (Model Specific Registers)",
800 "PAE",
801 "Machine Check Exception",
802 "COMPXCHG8B Instruction",
803 "APIC - On-chip Advanced Programmable Interrupt Controller present and enabled",
804 "10 - Reserved",
805 "11 - Reserved",
806 "MTRR Memory Type Range Registers",
807 "Global Paging Extension",
808 "Machine Check",
809 "CMOV Conditional Move Instruction",
810 "16 - reserved",
811 "17 - reserved",
812 "18 - reserved",
813 "19 - reserved",
814 "20 - reserved",
815 "21 - reserved",
816 "22 - reserved",
817 "MMX instructions",
818 "24 - reserved",
819 "25 - reserved",
820 "26 - reserved",
821 "27 - reserved",
822 "28 - reserved",
823 "29 - reserved",
824 "30 - reserved",
828 char *Cyrix_extended_feature_flags[] = {
829 "FPU Floating Point Unit",
830 "V86 Virtual Mode Extensions",
831 "Debug Extension",
832 "Page Size Extensions",
833 "Time Stamp Counter",
834 "Cyrix MSR",
835 "PAE",
836 "MC Exception",
837 "COMPXCHG8B",
838 "APIC on chip",
839 "SYSCALL/SYSRET",
840 "11 - reserved",
841 "MTRR",
842 "Global bit",
843 "Machine Check",
844 "CMOV",
845 "FPU CMOV",
846 "17 - reserved",
847 "18 - reserved",
848 "19 - reserved",
849 "20 - reserved",
850 "21 - reserved",
851 "22 - reserved",
852 "MMX",
853 "Extended MMX",
854 "25 - reserved",
855 "26 - reserved",
856 "27 - reserved",
857 "28 - reserved",
858 "29 - reserved",
859 "30 - reserved",
860 "3DNow instructions",
863 /* Cyrix-specific information */
864 void docyrix(int maxi){
865 unsigned long maxei,unused;
866 int i;
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 */
879 if(maxi >= 1){
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);
890 switch(family){
891 case 4:
892 switch(model){
893 case 4:
894 printf("MediaGX");
895 break;
897 break;
898 case 5:
899 switch(model){
900 case 2:
901 printf("6x86");
902 break;
903 case 4:
904 printf("BXm");
905 break;
907 break;
908 case 6:
909 switch(model){
910 case 0:
911 printf("6x86/MX");
912 break;
914 break;
916 printf("]\n\n");
917 if(family == 5 && model == 0){
918 int i;
920 for(i=0;i<32;i++){
921 if(edx & (1<<i)){
922 printf("%s\n",Cyrix_standard_feature_flags_5[i]);
925 } else {
926 int i;
928 for(i=0;i<32;i++){
929 if(edx & (1<<i)){
930 printf("%s\n",Cyrix_standard_feature_flags_not5[i]);
935 if(maxi >= 2){
936 /* TLB and L1 Cache info */
937 int ntlb = 255;
938 int i;
940 for(i=0;i<ntlb;i++){
941 unsigned long eax,edx,unused;
943 cpuid(2,eax,unused,unused,edx);
944 ntlb = eax & 0xff;
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)
962 return;
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);
975 switch(family){
976 case 4:
977 printf("MediaGX");
978 break;
979 case 5:
980 printf("6x86/GXm");
981 break;
982 case 6:
983 printf("6x86/MX");
985 printf("]\n\n");
987 printf("Extended feature flags:\n");
988 for(i=0;i<32;i++){
989 if(edx & (1<<i)){
990 printf("%s\n",Cyrix_extended_feature_flags[i]);
994 printf("\n");
995 if(maxei >= 0x80000002){
996 /* Processor identification string */
997 char namestring[49],*cp;
998 int j;
999 cp = namestring;
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 */
1010 int ntlb = 255;
1011 int i;
1013 for(i=0;i<ntlb;i++){
1014 unsigned long eax,ebx,ecx,unused;
1016 cpuid(0x80000005,eax,ebx,ecx,unused);
1017 ntlb = eax & 0xff;
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){
1037 switch(x & 0xff){
1038 case 0:
1039 break;
1040 case 0x70:
1041 printf("TLB: 32 entries 4-way associative 4KB pages\n");
1042 break;
1043 case 0x80:
1044 printf("L1 Cache: 16KB 4-way associative 16 bytes/line\n");
1045 break;