]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/i386/i386/identcpu.c
add -n option to suppress clearing the build tree and add -DNO_CLEAN
[FreeBSD/FreeBSD.git] / sys / i386 / i386 / identcpu.c
1 /*-
2  * Copyright (c) 1992 Terrence R. Lambert.
3  * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
4  * Copyright (c) 1997 KATO Takenori.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * William Jolitz.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by the University of
21  *      California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  *      from: Id: machdep.c,v 1.193 1996/06/18 01:22:04 bde Exp
39  */
40
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD$");
43
44 #include "opt_cpu.h"
45
46 #include <sys/param.h>
47 #include <sys/bus.h>
48 #include <sys/cpu.h>
49 #include <sys/eventhandler.h>
50 #include <sys/systm.h>
51 #include <sys/kernel.h>
52 #include <sys/sysctl.h>
53 #include <sys/power.h>
54
55 #include <machine/asmacros.h>
56 #include <machine/clock.h>
57 #include <machine/cputypes.h>
58 #include <machine/intr_machdep.h>
59 #include <machine/md_var.h>
60 #include <machine/segments.h>
61 #include <machine/specialreg.h>
62
63 #define IDENTBLUE_CYRIX486      0
64 #define IDENTBLUE_IBMCPU        1
65 #define IDENTBLUE_CYRIXM2       2
66
67 /* XXX - should be in header file: */
68 void printcpuinfo(void);
69 void finishidentcpu(void);
70 void earlysetcpuclass(void);
71 #if defined(I586_CPU) && defined(CPU_WT_ALLOC)
72 void    enable_K5_wt_alloc(void);
73 void    enable_K6_wt_alloc(void);
74 void    enable_K6_2_wt_alloc(void);
75 #endif
76 void panicifcpuunsupported(void);
77
78 static void identifycyrix(void);
79 static void init_exthigh(void);
80 static void print_AMD_info(void);
81 static void print_INTEL_info(void);
82 static void print_INTEL_TLB(u_int data);
83 static void print_AMD_assoc(int i);
84 static void print_transmeta_info(void);
85 static void print_via_padlock_info(void);
86
87 int     cpu_class;
88 u_int   cpu_exthigh;            /* Highest arg to extended CPUID */
89 u_int   cyrix_did;              /* Device ID of Cyrix CPU */
90 char machine[] = MACHINE;
91 SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, 
92     machine, 0, "Machine class");
93
94 static char cpu_model[128];
95 SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, 
96     cpu_model, 0, "Machine model");
97
98 static int hw_clockrate;
99 SYSCTL_INT(_hw, OID_AUTO, clockrate, CTLFLAG_RD, 
100     &hw_clockrate, 0, "CPU instruction clock rate");
101
102 static char cpu_brand[48];
103
104 #define MAX_BRAND_INDEX 8
105
106 static const char *cpu_brandtable[MAX_BRAND_INDEX + 1] = {
107         NULL,                   /* No brand */
108         "Intel Celeron",
109         "Intel Pentium III",
110         "Intel Pentium III Xeon",
111         NULL,
112         NULL,
113         NULL,
114         NULL,
115         "Intel Pentium 4"
116 };
117
118 static struct {
119         char    *cpu_name;
120         int     cpu_class;
121 } i386_cpus[] = {
122         { "Intel 80286",        CPUCLASS_286 },         /* CPU_286   */
123         { "i386SX",             CPUCLASS_386 },         /* CPU_386SX */
124         { "i386DX",             CPUCLASS_386 },         /* CPU_386   */
125         { "i486SX",             CPUCLASS_486 },         /* CPU_486SX */
126         { "i486DX",             CPUCLASS_486 },         /* CPU_486   */
127         { "Pentium",            CPUCLASS_586 },         /* CPU_586   */
128         { "Cyrix 486",          CPUCLASS_486 },         /* CPU_486DLC */
129         { "Pentium Pro",        CPUCLASS_686 },         /* CPU_686 */
130         { "Cyrix 5x86",         CPUCLASS_486 },         /* CPU_M1SC */
131         { "Cyrix 6x86",         CPUCLASS_486 },         /* CPU_M1 */
132         { "Blue Lightning",     CPUCLASS_486 },         /* CPU_BLUE */
133         { "Cyrix 6x86MX",       CPUCLASS_686 },         /* CPU_M2 */
134         { "NexGen 586",         CPUCLASS_386 },         /* CPU_NX586 (XXX) */
135         { "Cyrix 486S/DX",      CPUCLASS_486 },         /* CPU_CY486DX */
136         { "Pentium II",         CPUCLASS_686 },         /* CPU_PII */
137         { "Pentium III",        CPUCLASS_686 },         /* CPU_PIII */
138         { "Pentium 4",          CPUCLASS_686 },         /* CPU_P4 */
139 };
140
141 int cpu_cores;
142 int cpu_logical;
143
144 #if defined(I586_CPU) && !defined(NO_F00F_HACK)
145 int has_f00f_bug = 0;           /* Initialized so that it can be patched. */
146 #endif
147
148 static void
149 init_exthigh(void)
150 {
151         static int done = 0;
152         u_int regs[4];
153
154         if (done == 0) {
155                 if (cpu_high > 0 &&
156                     (strcmp(cpu_vendor, "GenuineIntel") == 0 ||
157                     strcmp(cpu_vendor, "AuthenticAMD") == 0 ||
158                     strcmp(cpu_vendor, "GenuineTMx86") == 0 ||
159                     strcmp(cpu_vendor, "TransmetaCPU") == 0 ||
160                     strcmp(cpu_vendor, "CentaurHauls") == 0 ||
161                     strcmp(cpu_vendor, "Geode by NSC") == 0)) {
162                         do_cpuid(0x80000000, regs);
163                         if (regs[0] >= 0x80000000)
164                                 cpu_exthigh = regs[0];
165                 }
166
167                 done = 1;
168         }
169 }
170
171 void
172 printcpuinfo(void)
173 {
174         u_int regs[4], i;
175         char *brand;
176
177         cpu_class = i386_cpus[cpu].cpu_class;
178         printf("CPU: ");
179         strncpy(cpu_model, i386_cpus[cpu].cpu_name, sizeof (cpu_model));
180
181         /* Check for extended CPUID information and a processor name. */
182         init_exthigh();
183         if (cpu_exthigh >= 0x80000004) {
184                 brand = cpu_brand;
185                 for (i = 0x80000002; i < 0x80000005; i++) {
186                         do_cpuid(i, regs);
187                         memcpy(brand, regs, sizeof(regs));
188                         brand += sizeof(regs);
189                 }
190         }
191
192         if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
193                 if ((cpu_id & 0xf00) > 0x300) {
194                         u_int brand_index;
195                         u_int model;
196
197                         cpu_model[0] = '\0';
198
199                         switch (cpu_id & 0x3000) {
200                         case 0x1000:
201                                 strcpy(cpu_model, "Overdrive ");
202                                 break;
203                         case 0x2000:
204                                 strcpy(cpu_model, "Dual ");
205                                 break;
206                         }
207
208                         switch (cpu_id & 0xf00) {
209                         case 0x400:
210                                 strcat(cpu_model, "i486 ");
211                                 /* Check the particular flavor of 486 */
212                                 switch (cpu_id & 0xf0) {
213                                 case 0x00:
214                                 case 0x10:
215                                         strcat(cpu_model, "DX");
216                                         break;
217                                 case 0x20:
218                                         strcat(cpu_model, "SX");
219                                         break;
220                                 case 0x30:
221                                         strcat(cpu_model, "DX2");
222                                         break;
223                                 case 0x40:
224                                         strcat(cpu_model, "SL");
225                                         break;
226                                 case 0x50:
227                                         strcat(cpu_model, "SX2");
228                                         break;
229                                 case 0x70:
230                                         strcat(cpu_model,
231                                             "DX2 Write-Back Enhanced");
232                                         break;
233                                 case 0x80:
234                                         strcat(cpu_model, "DX4");
235                                         break;
236                                 }
237                                 break;
238                         case 0x500:
239                                 /* Check the particular flavor of 586 */
240                                 strcat(cpu_model, "Pentium");
241                                 switch (cpu_id & 0xf0) {
242                                 case 0x00:
243                                         strcat(cpu_model, " A-step");
244                                         break;
245                                 case 0x10:
246                                         strcat(cpu_model, "/P5");
247                                         break;
248                                 case 0x20:
249                                         strcat(cpu_model, "/P54C");
250                                         break;
251                                 case 0x30:
252                                         strcat(cpu_model, "/P54T Overdrive");
253                                         break;
254                                 case 0x40:
255                                         strcat(cpu_model, "/P55C");
256                                         break;
257                                 case 0x70:
258                                         strcat(cpu_model, "/P54C");
259                                         break;
260                                 case 0x80:
261                                         strcat(cpu_model, "/P55C (quarter-micron)");
262                                         break;
263                                 default:
264                                         /* nothing */
265                                         break;
266                                 }
267 #if defined(I586_CPU) && !defined(NO_F00F_HACK)
268                                 /*
269                                  * XXX - If/when Intel fixes the bug, this
270                                  * should also check the version of the
271                                  * CPU, not just that it's a Pentium.
272                                  */
273                                 has_f00f_bug = 1;
274 #endif
275                                 break;
276                         case 0x600:
277                                 /* Check the particular flavor of 686 */
278                                 switch (cpu_id & 0xf0) {
279                                 case 0x00:
280                                         strcat(cpu_model, "Pentium Pro A-step");
281                                         break;
282                                 case 0x10:
283                                         strcat(cpu_model, "Pentium Pro");
284                                         break;
285                                 case 0x30:
286                                 case 0x50:
287                                 case 0x60:
288                                         strcat(cpu_model,
289                                 "Pentium II/Pentium II Xeon/Celeron");
290                                         cpu = CPU_PII;
291                                         break;
292                                 case 0x70:
293                                 case 0x80:
294                                 case 0xa0:
295                                 case 0xb0:
296                                         strcat(cpu_model,
297                                         "Pentium III/Pentium III Xeon/Celeron");
298                                         cpu = CPU_PIII;
299                                         break;
300                                 default:
301                                         strcat(cpu_model, "Unknown 80686");
302                                         break;
303                                 }
304                                 break;
305                         case 0xf00:
306                                 strcat(cpu_model, "Pentium 4");
307                                 cpu = CPU_P4;
308                                 model = (cpu_id & 0x0f0) >> 4;
309                                 if (model == 3 || model == 4 || model == 6) {
310                                         uint64_t tmp;
311
312                                         tmp = rdmsr(MSR_IA32_MISC_ENABLE);
313                                         wrmsr(MSR_IA32_MISC_ENABLE,
314                                               tmp & ~(1LL << 22));
315                                         do_cpuid(0, regs);
316                                         cpu_high = regs[0];
317                                 }
318                                 break;
319                         default:
320                                 strcat(cpu_model, "unknown");
321                                 break;
322                         }
323
324                         /*
325                          * If we didn't get a brand name from the extended
326                          * CPUID, try to look it up in the brand table.
327                          */
328                         if (cpu_high > 0 && *cpu_brand == '\0') {
329                                 brand_index = cpu_procinfo & CPUID_BRAND_INDEX;
330                                 if (brand_index <= MAX_BRAND_INDEX &&
331                                     cpu_brandtable[brand_index] != NULL)
332                                         strcpy(cpu_brand,
333                                             cpu_brandtable[brand_index]);
334                         }
335                 }
336         } else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
337                 /*
338                  * Values taken from AMD Processor Recognition
339                  * http://www.amd.com/K6/k6docs/pdf/20734g.pdf
340                  * (also describes ``Features'' encodings.
341                  */
342                 strcpy(cpu_model, "AMD ");
343                 switch (cpu_id & 0xFF0) {
344                 case 0x410:
345                         strcat(cpu_model, "Standard Am486DX");
346                         break;
347                 case 0x430:
348                         strcat(cpu_model, "Enhanced Am486DX2 Write-Through");
349                         break;
350                 case 0x470:
351                         strcat(cpu_model, "Enhanced Am486DX2 Write-Back");
352                         break;
353                 case 0x480:
354                         strcat(cpu_model, "Enhanced Am486DX4/Am5x86 Write-Through");
355                         break;
356                 case 0x490:
357                         strcat(cpu_model, "Enhanced Am486DX4/Am5x86 Write-Back");
358                         break;
359                 case 0x4E0:
360                         strcat(cpu_model, "Am5x86 Write-Through");
361                         break;
362                 case 0x4F0:
363                         strcat(cpu_model, "Am5x86 Write-Back");
364                         break;
365                 case 0x500:
366                         strcat(cpu_model, "K5 model 0");
367                         tsc_is_broken = 1;
368                         break;
369                 case 0x510:
370                         strcat(cpu_model, "K5 model 1");
371                         break;
372                 case 0x520:
373                         strcat(cpu_model, "K5 PR166 (model 2)");
374                         break;
375                 case 0x530:
376                         strcat(cpu_model, "K5 PR200 (model 3)");
377                         break;
378                 case 0x560:
379                         strcat(cpu_model, "K6");
380                         break;
381                 case 0x570:
382                         strcat(cpu_model, "K6 266 (model 1)");
383                         break;
384                 case 0x580:
385                         strcat(cpu_model, "K6-2");
386                         break;
387                 case 0x590:
388                         strcat(cpu_model, "K6-III");
389                         break;
390                 case 0x5a0:
391                         strcat(cpu_model, "Geode LX");
392                         /*
393                          * Make sure the TSC runs through suspension,
394                          * otherwise we can't use it as timecounter
395                          */
396                         wrmsr(0x1900, rdmsr(0x1900) | 0x20ULL);
397                         break;
398                 default:
399                         strcat(cpu_model, "Unknown");
400                         break;
401                 }
402 #if defined(I586_CPU) && defined(CPU_WT_ALLOC)
403                 if ((cpu_id & 0xf00) == 0x500) {
404                         if (((cpu_id & 0x0f0) > 0)
405                             && ((cpu_id & 0x0f0) < 0x60)
406                             && ((cpu_id & 0x00f) > 3))
407                                 enable_K5_wt_alloc();
408                         else if (((cpu_id & 0x0f0) > 0x80)
409                                  || (((cpu_id & 0x0f0) == 0x80)
410                                      && (cpu_id & 0x00f) > 0x07))
411                                 enable_K6_2_wt_alloc();
412                         else if ((cpu_id & 0x0f0) > 0x50)
413                                 enable_K6_wt_alloc();
414                 }
415 #endif
416         } else if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
417                 strcpy(cpu_model, "Cyrix ");
418                 switch (cpu_id & 0xff0) {
419                 case 0x440:
420                         strcat(cpu_model, "MediaGX");
421                         break;
422                 case 0x520:
423                         strcat(cpu_model, "6x86");
424                         break;
425                 case 0x540:
426                         cpu_class = CPUCLASS_586;
427                         strcat(cpu_model, "GXm");
428                         break;
429                 case 0x600:
430                         strcat(cpu_model, "6x86MX");
431                         break;
432                 default:
433                         /*
434                          * Even though CPU supports the cpuid
435                          * instruction, it can be disabled.
436                          * Therefore, this routine supports all Cyrix
437                          * CPUs.
438                          */
439                         switch (cyrix_did & 0xf0) {
440                         case 0x00:
441                                 switch (cyrix_did & 0x0f) {
442                                 case 0x00:
443                                         strcat(cpu_model, "486SLC");
444                                         break;
445                                 case 0x01:
446                                         strcat(cpu_model, "486DLC");
447                                         break;
448                                 case 0x02:
449                                         strcat(cpu_model, "486SLC2");
450                                         break;
451                                 case 0x03:
452                                         strcat(cpu_model, "486DLC2");
453                                         break;
454                                 case 0x04:
455                                         strcat(cpu_model, "486SRx");
456                                         break;
457                                 case 0x05:
458                                         strcat(cpu_model, "486DRx");
459                                         break;
460                                 case 0x06:
461                                         strcat(cpu_model, "486SRx2");
462                                         break;
463                                 case 0x07:
464                                         strcat(cpu_model, "486DRx2");
465                                         break;
466                                 case 0x08:
467                                         strcat(cpu_model, "486SRu");
468                                         break;
469                                 case 0x09:
470                                         strcat(cpu_model, "486DRu");
471                                         break;
472                                 case 0x0a:
473                                         strcat(cpu_model, "486SRu2");
474                                         break;
475                                 case 0x0b:
476                                         strcat(cpu_model, "486DRu2");
477                                         break;
478                                 default:
479                                         strcat(cpu_model, "Unknown");
480                                         break;
481                                 }
482                                 break;
483                         case 0x10:
484                                 switch (cyrix_did & 0x0f) {
485                                 case 0x00:
486                                         strcat(cpu_model, "486S");
487                                         break;
488                                 case 0x01:
489                                         strcat(cpu_model, "486S2");
490                                         break;
491                                 case 0x02:
492                                         strcat(cpu_model, "486Se");
493                                         break;
494                                 case 0x03:
495                                         strcat(cpu_model, "486S2e");
496                                         break;
497                                 case 0x0a:
498                                         strcat(cpu_model, "486DX");
499                                         break;
500                                 case 0x0b:
501                                         strcat(cpu_model, "486DX2");
502                                         break;
503                                 case 0x0f:
504                                         strcat(cpu_model, "486DX4");
505                                         break;
506                                 default:
507                                         strcat(cpu_model, "Unknown");
508                                         break;
509                                 }
510                                 break;
511                         case 0x20:
512                                 if ((cyrix_did & 0x0f) < 8)
513                                         strcat(cpu_model, "6x86");      /* Where did you get it? */
514                                 else
515                                         strcat(cpu_model, "5x86");
516                                 break;
517                         case 0x30:
518                                 strcat(cpu_model, "6x86");
519                                 break;
520                         case 0x40:
521                                 if ((cyrix_did & 0xf000) == 0x3000) {
522                                         cpu_class = CPUCLASS_586;
523                                         strcat(cpu_model, "GXm");
524                                 } else
525                                         strcat(cpu_model, "MediaGX");
526                                 break;
527                         case 0x50:
528                                 strcat(cpu_model, "6x86MX");
529                                 break;
530                         case 0xf0:
531                                 switch (cyrix_did & 0x0f) {
532                                 case 0x0d:
533                                         strcat(cpu_model, "Overdrive CPU");
534                                         break;
535                                 case 0x0e:
536                                         strcpy(cpu_model, "Texas Instruments 486SXL");
537                                         break;
538                                 case 0x0f:
539                                         strcat(cpu_model, "486SLC/DLC");
540                                         break;
541                                 default:
542                                         strcat(cpu_model, "Unknown");
543                                         break;
544                                 }
545                                 break;
546                         default:
547                                 strcat(cpu_model, "Unknown");
548                                 break;
549                         }
550                         break;
551                 }
552         } else if (strcmp(cpu_vendor, "RiseRiseRise") == 0) {
553                 strcpy(cpu_model, "Rise ");
554                 switch (cpu_id & 0xff0) {
555                 case 0x500:
556                         strcat(cpu_model, "mP6");
557                         break;
558                 default:
559                         strcat(cpu_model, "Unknown");
560                 }
561         } else if (strcmp(cpu_vendor, "CentaurHauls") == 0) {
562                 switch (cpu_id & 0xff0) {
563                 case 0x540:
564                         strcpy(cpu_model, "IDT WinChip C6");
565                         tsc_is_broken = 1;
566                         break;
567                 case 0x580:
568                         strcpy(cpu_model, "IDT WinChip 2");
569                         break;
570                 case 0x660:
571                         strcpy(cpu_model, "VIA C3 Samuel");
572                         break;
573                 case 0x670:
574                         if (cpu_id & 0x8)
575                                 strcpy(cpu_model, "VIA C3 Ezra");
576                         else
577                                 strcpy(cpu_model, "VIA C3 Samuel 2");
578                         break;
579                 case 0x680:
580                         strcpy(cpu_model, "VIA C3 Ezra-T");
581                         break;
582                 case 0x690:
583                         strcpy(cpu_model, "VIA C3 Nehemiah");
584                         break;
585                 case 0x6a0:
586                 case 0x6d0:
587                         strcpy(cpu_model, "VIA C7 Esther");
588                         break;
589                 default:
590                         strcpy(cpu_model, "VIA/IDT Unknown");
591                 }
592         } else if (strcmp(cpu_vendor, "IBM") == 0) {
593                 strcpy(cpu_model, "Blue Lightning CPU");
594         } else if (strcmp(cpu_vendor, "Geode by NSC") == 0) {
595                 switch (cpu_id & 0xfff) {
596                 case 0x540:
597                         strcpy(cpu_model, "Geode SC1100");
598                         cpu = CPU_GEODE1100;
599                         tsc_is_broken = 1;
600                         break;
601                 default:
602                         strcpy(cpu_model, "Geode/NSC unknown");
603                         break;
604                 }
605         }
606
607         /*
608          * Replace cpu_model with cpu_brand minus leading spaces if
609          * we have one.
610          */
611         brand = cpu_brand;
612         while (*brand == ' ')
613                 ++brand;
614         if (*brand != '\0')
615                 strcpy(cpu_model, brand);
616
617         printf("%s (", cpu_model);
618         switch(cpu_class) {
619         case CPUCLASS_286:
620                 printf("286");
621                 break;
622         case CPUCLASS_386:
623                 printf("386");
624                 break;
625 #if defined(I486_CPU)
626         case CPUCLASS_486:
627                 printf("486");
628                 bzero_vector = i486_bzero;
629                 break;
630 #endif
631 #if defined(I586_CPU)
632         case CPUCLASS_586:
633                 hw_clockrate = (tsc_freq + 5000) / 1000000;
634                 printf("%jd.%02d-MHz ",
635                        (intmax_t)(tsc_freq + 4999) / 1000000,
636                        (u_int)((tsc_freq + 4999) / 10000) % 100);
637                 printf("586");
638                 break;
639 #endif
640 #if defined(I686_CPU)
641         case CPUCLASS_686:
642                 hw_clockrate = (tsc_freq + 5000) / 1000000;
643                 printf("%jd.%02d-MHz ",
644                        (intmax_t)(tsc_freq + 4999) / 1000000,
645                        (u_int)((tsc_freq + 4999) / 10000) % 100);
646                 printf("686");
647                 break;
648 #endif
649         default:
650                 printf("Unknown");      /* will panic below... */
651         }
652         printf("-class CPU)\n");
653         if(*cpu_vendor)
654                 printf("  Origin = \"%s\"",cpu_vendor);
655         if(cpu_id)
656                 printf("  Id = 0x%x", cpu_id);
657
658         if (strcmp(cpu_vendor, "GenuineIntel") == 0 ||
659             strcmp(cpu_vendor, "AuthenticAMD") == 0 ||
660             strcmp(cpu_vendor, "GenuineTMx86") == 0 ||
661             strcmp(cpu_vendor, "TransmetaCPU") == 0 ||
662             strcmp(cpu_vendor, "RiseRiseRise") == 0 ||
663             strcmp(cpu_vendor, "CentaurHauls") == 0 ||
664             strcmp(cpu_vendor, "Geode by NSC") == 0 ||
665                 ((strcmp(cpu_vendor, "CyrixInstead") == 0) &&
666                  ((cpu_id & 0xf00) > 0x500))) {
667                 printf("  Stepping = %u", cpu_id & 0xf);
668                 if (strcmp(cpu_vendor, "CyrixInstead") == 0)
669                         printf("  DIR=0x%04x", cyrix_did);
670                 if (cpu_high > 0) {
671                         u_int cmp = 1, htt = 1;
672
673                         /*
674                          * Here we should probably set up flags indicating
675                          * whether or not various features are available.
676                          * The interesting ones are probably VME, PSE, PAE,
677                          * and PGE.  The code already assumes without bothering
678                          * to check that all CPUs >= Pentium have a TSC and
679                          * MSRs.
680                          */
681                         printf("\n  Features=0x%b", cpu_feature,
682                         "\020"
683                         "\001FPU"       /* Integral FPU */
684                         "\002VME"       /* Extended VM86 mode support */
685                         "\003DE"        /* Debugging Extensions (CR4.DE) */
686                         "\004PSE"       /* 4MByte page tables */
687                         "\005TSC"       /* Timestamp counter */
688                         "\006MSR"       /* Machine specific registers */
689                         "\007PAE"       /* Physical address extension */
690                         "\010MCE"       /* Machine Check support */
691                         "\011CX8"       /* CMPEXCH8 instruction */
692                         "\012APIC"      /* SMP local APIC */
693                         "\013oldMTRR"   /* Previous implementation of MTRR */
694                         "\014SEP"       /* Fast System Call */
695                         "\015MTRR"      /* Memory Type Range Registers */
696                         "\016PGE"       /* PG_G (global bit) support */
697                         "\017MCA"       /* Machine Check Architecture */
698                         "\020CMOV"      /* CMOV instruction */
699                         "\021PAT"       /* Page attributes table */
700                         "\022PSE36"     /* 36 bit address space support */
701                         "\023PN"        /* Processor Serial number */
702                         "\024CLFLUSH"   /* Has the CLFLUSH instruction */
703                         "\025<b20>"
704                         "\026DTS"       /* Debug Trace Store */
705                         "\027ACPI"      /* ACPI support */
706                         "\030MMX"       /* MMX instructions */
707                         "\031FXSR"      /* FXSAVE/FXRSTOR */
708                         "\032SSE"       /* Streaming SIMD Extensions */
709                         "\033SSE2"      /* Streaming SIMD Extensions #2 */
710                         "\034SS"        /* Self snoop */
711                         "\035HTT"       /* Hyperthreading (see EBX bit 16-23) */
712                         "\036TM"        /* Thermal Monitor clock slowdown */
713                         "\037IA64"      /* CPU can execute IA64 instructions */
714                         "\040PBE"       /* Pending Break Enable */
715                         );
716
717                         if (cpu_feature2 != 0) {
718                                 printf("\n  Features2=0x%b", cpu_feature2,
719                                 "\020"
720                                 "\001SSE3"      /* SSE3 */
721                                 "\002<b1>"
722                                 "\003DTES64"    /* 64-bit Debug Trace */
723                                 "\004MON"       /* MONITOR/MWAIT Instructions */
724                                 "\005DS_CPL"    /* CPL Qualified Debug Store */
725                                 "\006VMX"       /* Virtual Machine Extensions */
726                                 "\007SMX"       /* Safer Mode Extensions */
727                                 "\010EST"       /* Enhanced SpeedStep */
728                                 "\011TM2"       /* Thermal Monitor 2 */
729                                 "\012SSSE3"     /* SSSE3 */
730                                 "\013CNXT-ID"   /* L1 context ID available */
731                                 "\014<b11>"
732                                 "\015<b12>"
733                                 "\016CX16"      /* CMPXCHG16B Instruction */
734                                 "\017xTPR"      /* Send Task Priority Messages*/
735                                 "\020PDCM"      /* Perf/Debug Capability MSR */
736                                 "\021<b16>"
737                                 "\022<b17>"
738                                 "\023DCA"       /* Direct Cache Access */
739                                 "\024SSE4.1"
740                                 "\025SSE4.2"
741                                 "\026x2APIC"    /* xAPIC Extensions */
742                                 "\027<b22>"
743                                 "\030POPCNT"
744                                 "\031<b24>"
745                                 "\032<b25>"
746                                 "\033XSAVE"
747                                 "\034OSXSAVE"
748                                 "\035<b28>"
749                                 "\036<b29>"
750                                 "\037<b30>"
751                                 "\040<b31>"
752                                 );
753                         }
754
755                         /*
756                          * AMD64 Architecture Programmer's Manual Volume 3:
757                          * General-Purpose and System Instructions
758                          * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/24594.pdf
759                          *
760                          * IA-32 Intel Architecture Software Developer's Manual,
761                          * Volume 2A: Instruction Set Reference, A-M
762                          * ftp://download.intel.com/design/Pentium4/manuals/25366617.pdf
763                          */
764                         if (amd_feature != 0) {
765                                 printf("\n  AMD Features=0x%b", amd_feature,
766                                 "\020"          /* in hex */
767                                 "\001<s0>"      /* Same */
768                                 "\002<s1>"      /* Same */
769                                 "\003<s2>"      /* Same */
770                                 "\004<s3>"      /* Same */
771                                 "\005<s4>"      /* Same */
772                                 "\006<s5>"      /* Same */
773                                 "\007<s6>"      /* Same */
774                                 "\010<s7>"      /* Same */
775                                 "\011<s8>"      /* Same */
776                                 "\012<s9>"      /* Same */
777                                 "\013<b10>"     /* Undefined */
778                                 "\014SYSCALL"   /* Have SYSCALL/SYSRET */
779                                 "\015<s12>"     /* Same */
780                                 "\016<s13>"     /* Same */
781                                 "\017<s14>"     /* Same */
782                                 "\020<s15>"     /* Same */
783                                 "\021<s16>"     /* Same */
784                                 "\022<s17>"     /* Same */
785                                 "\023<b18>"     /* Reserved, unknown */
786                                 "\024MP"        /* Multiprocessor Capable */
787                                 "\025NX"        /* Has EFER.NXE, NX */
788                                 "\026<b21>"     /* Undefined */
789                                 "\027MMX+"      /* AMD MMX Extensions */
790                                 "\030<s23>"     /* Same */
791                                 "\031<s24>"     /* Same */
792                                 "\032FFXSR"     /* Fast FXSAVE/FXRSTOR */
793                                 "\033Page1GB"   /* 1-GB large page support */
794                                 "\034RDTSCP"    /* RDTSCP */
795                                 "\035<b28>"     /* Undefined */
796                                 "\036LM"        /* 64 bit long mode */
797                                 "\0373DNow!+"   /* AMD 3DNow! Extensions */
798                                 "\0403DNow!"    /* AMD 3DNow! */
799                                 );
800                         }
801
802                         if (amd_feature2 != 0) {
803                                 printf("\n  AMD Features2=0x%b", amd_feature2,
804                                 "\020"
805                                 "\001LAHF"      /* LAHF/SAHF in long mode */
806                                 "\002CMP"       /* CMP legacy */
807                                 "\003SVM"       /* Secure Virtual Mode */
808                                 "\004ExtAPIC"   /* Extended APIC register */
809                                 "\005CR8"       /* CR8 in legacy mode */
810                                 "\006<b5>"
811                                 "\007<b6>"
812                                 "\010<b7>"
813                                 "\011Prefetch"  /* 3DNow! Prefetch/PrefetchW */
814                                 "\012<b9>"
815                                 "\013<b10>"
816                                 "\014<b11>"
817                                 "\015<b12>"
818                                 "\016<b13>"
819                                 "\017<b14>"
820                                 "\020<b15>"
821                                 "\021<b16>"
822                                 "\022<b17>"
823                                 "\023<b18>"
824                                 "\024<b19>"
825                                 "\025<b20>"
826                                 "\026<b21>"
827                                 "\027<b22>"
828                                 "\030<b23>"
829                                 "\031<b24>"
830                                 "\032<b25>"
831                                 "\033<b26>"
832                                 "\034<b27>"
833                                 "\035<b28>"
834                                 "\036<b29>"
835                                 "\037<b30>"
836                                 "\040<b31>"
837                                 );
838                         }
839
840                         if (cpu_feature & CPUID_HTT && strcmp(cpu_vendor,
841                             "AuthenticAMD") == 0)
842                                 cpu_feature &= ~CPUID_HTT;
843
844                         /*
845                          * If this CPU supports HTT or CMP then mention the
846                          * number of physical/logical cores it contains.
847                          */
848                         if (cpu_feature & CPUID_HTT)
849                                 htt = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
850                         if (strcmp(cpu_vendor, "AuthenticAMD") == 0 &&
851                             (amd_feature2 & AMDID2_CMP))
852                                 cmp = (cpu_procinfo2 & AMDID_CMP_CORES) + 1;
853                         else if (strcmp(cpu_vendor, "GenuineIntel") == 0 &&
854                             (cpu_high >= 4)) {
855                                 cpuid_count(4, 0, regs);
856                                 if ((regs[0] & 0x1f) != 0)
857                                         cmp = ((regs[0] >> 26) & 0x3f) + 1;
858                         }
859                         cpu_cores = cmp;
860                         cpu_logical = htt / cmp;
861                         if (cmp > 1)
862                                 printf("\n  Cores per package: %d", cmp);
863                         if ((htt / cmp) > 1)
864                                 printf("\n  Logical CPUs per core: %d",
865                                     cpu_logical);
866                 }
867         } else if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
868                 printf("  DIR=0x%04x", cyrix_did);
869                 printf("  Stepping=%u", (cyrix_did & 0xf000) >> 12);
870                 printf("  Revision=%u", (cyrix_did & 0x0f00) >> 8);
871 #ifndef CYRIX_CACHE_REALLY_WORKS
872                 if (cpu == CPU_M1 && (cyrix_did & 0xff00) < 0x1700)
873                         printf("\n  CPU cache: write-through mode");
874 #endif
875         }
876         if (strcmp(cpu_vendor, "CentaurHauls") == 0)
877                 print_via_padlock_info();
878
879         /* Avoid ugly blank lines: only print newline when we have to. */
880         if (*cpu_vendor || cpu_id)
881                 printf("\n");
882
883         if (!bootverbose)
884                 return;
885
886         if (strcmp(cpu_vendor, "AuthenticAMD") == 0)
887                 print_AMD_info();
888         else if (strcmp(cpu_vendor, "GenuineIntel") == 0)
889                 print_INTEL_info();
890         else if (strcmp(cpu_vendor, "GenuineTMx86") == 0 ||
891                  strcmp(cpu_vendor, "TransmetaCPU") == 0)
892                 print_transmeta_info();
893 }
894
895 void
896 panicifcpuunsupported(void)
897 {
898
899 #if !defined(lint)
900 #if !defined(I486_CPU) && !defined(I586_CPU) && !defined(I686_CPU)
901 #error This kernel is not configured for one of the supported CPUs
902 #endif
903 #else /* lint */
904 #endif /* lint */
905         /*
906          * Now that we have told the user what they have,
907          * let them know if that machine type isn't configured.
908          */
909         switch (cpu_class) {
910         case CPUCLASS_286:      /* a 286 should not make it this far, anyway */
911         case CPUCLASS_386:
912 #if !defined(I486_CPU)
913         case CPUCLASS_486:
914 #endif
915 #if !defined(I586_CPU)
916         case CPUCLASS_586:
917 #endif
918 #if !defined(I686_CPU)
919         case CPUCLASS_686:
920 #endif
921                 panic("CPU class not configured");
922         default:
923                 break;
924         }
925 }
926
927
928 static  volatile u_int trap_by_rdmsr;
929
930 /*
931  * Special exception 6 handler.
932  * The rdmsr instruction generates invalid opcodes fault on 486-class
933  * Cyrix CPU.  Stacked eip register points the rdmsr instruction in the
934  * function identblue() when this handler is called.  Stacked eip should
935  * be advanced.
936  */
937 inthand_t       bluetrap6;
938 #ifdef __GNUCLIKE_ASM
939 __asm
940 ("                                                                      \n\
941         .text                                                           \n\
942         .p2align 2,0x90                                                 \n\
943         .type   " __XSTRING(CNAME(bluetrap6)) ",@function               \n\
944 " __XSTRING(CNAME(bluetrap6)) ":                                        \n\
945         ss                                                              \n\
946         movl    $0xa8c1d," __XSTRING(CNAME(trap_by_rdmsr)) "            \n\
947         addl    $2, (%esp)      /* rdmsr is a 2-byte instruction */     \n\
948         iret                                                            \n\
949 ");
950 #endif
951
952 /*
953  * Special exception 13 handler.
954  * Accessing non-existent MSR generates general protection fault.
955  */
956 inthand_t       bluetrap13;
957 #ifdef __GNUCLIKE_ASM
958 __asm
959 ("                                                                      \n\
960         .text                                                           \n\
961         .p2align 2,0x90                                                 \n\
962         .type   " __XSTRING(CNAME(bluetrap13)) ",@function              \n\
963 " __XSTRING(CNAME(bluetrap13)) ":                                       \n\
964         ss                                                              \n\
965         movl    $0xa89c4," __XSTRING(CNAME(trap_by_rdmsr)) "            \n\
966         popl    %eax            /* discard error code */                \n\
967         addl    $2, (%esp)      /* rdmsr is a 2-byte instruction */     \n\
968         iret                                                            \n\
969 ");
970 #endif
971
972 /*
973  * Distinguish IBM Blue Lightning CPU from Cyrix CPUs that does not
974  * support cpuid instruction.  This function should be called after
975  * loading interrupt descriptor table register.
976  *
977  * I don't like this method that handles fault, but I couldn't get
978  * information for any other methods.  Does blue giant know?
979  */
980 static int
981 identblue(void)
982 {
983
984         trap_by_rdmsr = 0;
985
986         /*
987          * Cyrix 486-class CPU does not support rdmsr instruction.
988          * The rdmsr instruction generates invalid opcode fault, and exception
989          * will be trapped by bluetrap6() on Cyrix 486-class CPU.  The
990          * bluetrap6() set the magic number to trap_by_rdmsr.
991          */
992         setidt(IDT_UD, bluetrap6, SDT_SYS386TGT, SEL_KPL,
993             GSEL(GCODE_SEL, SEL_KPL));
994
995         /*
996          * Certain BIOS disables cpuid instruction of Cyrix 6x86MX CPU.
997          * In this case, rdmsr generates general protection fault, and
998          * exception will be trapped by bluetrap13().
999          */
1000         setidt(IDT_GP, bluetrap13, SDT_SYS386TGT, SEL_KPL,
1001             GSEL(GCODE_SEL, SEL_KPL));
1002
1003         rdmsr(0x1002);          /* Cyrix CPU generates fault. */
1004
1005         if (trap_by_rdmsr == 0xa8c1d)
1006                 return IDENTBLUE_CYRIX486;
1007         else if (trap_by_rdmsr == 0xa89c4)
1008                 return IDENTBLUE_CYRIXM2;
1009         return IDENTBLUE_IBMCPU;
1010 }
1011
1012
1013 /*
1014  * identifycyrix() set lower 16 bits of cyrix_did as follows:
1015  *
1016  *  F E D C B A 9 8 7 6 5 4 3 2 1 0
1017  * +-------+-------+---------------+
1018  * |  SID  |  RID  |   Device ID   |
1019  * |    (DIR 1)    |    (DIR 0)    |
1020  * +-------+-------+---------------+
1021  */
1022 static void
1023 identifycyrix(void)
1024 {
1025         u_int   eflags;
1026         int     ccr2_test = 0, dir_test = 0;
1027         u_char  ccr2, ccr3;
1028
1029         eflags = read_eflags();
1030         disable_intr();
1031
1032         ccr2 = read_cyrix_reg(CCR2);
1033         write_cyrix_reg(CCR2, ccr2 ^ CCR2_LOCK_NW);
1034         read_cyrix_reg(CCR2);
1035         if (read_cyrix_reg(CCR2) != ccr2)
1036                 ccr2_test = 1;
1037         write_cyrix_reg(CCR2, ccr2);
1038
1039         ccr3 = read_cyrix_reg(CCR3);
1040         write_cyrix_reg(CCR3, ccr3 ^ CCR3_MAPEN3);
1041         read_cyrix_reg(CCR3);
1042         if (read_cyrix_reg(CCR3) != ccr3)
1043                 dir_test = 1;                                   /* CPU supports DIRs. */
1044         write_cyrix_reg(CCR3, ccr3);
1045
1046         if (dir_test) {
1047                 /* Device ID registers are available. */
1048                 cyrix_did = read_cyrix_reg(DIR1) << 8;
1049                 cyrix_did += read_cyrix_reg(DIR0);
1050         } else if (ccr2_test)
1051                 cyrix_did = 0x0010;             /* 486S A-step */
1052         else
1053                 cyrix_did = 0x00ff;             /* Old 486SLC/DLC and TI486SXLC/SXL */
1054
1055         write_eflags(eflags);
1056 }
1057
1058 /* Update TSC freq with the value indicated by the caller. */
1059 static void
1060 tsc_freq_changed(void *arg, const struct cf_level *level, int status)
1061 {
1062         /* If there was an error during the transition, don't do anything. */
1063         if (status != 0)
1064                 return;
1065
1066         /* Total setting for this level gives the new frequency in MHz. */
1067         hw_clockrate = level->total_set.freq;
1068 }
1069
1070 EVENTHANDLER_DEFINE(cpufreq_post_change, tsc_freq_changed, NULL,
1071     EVENTHANDLER_PRI_ANY);
1072
1073 /*
1074  * Final stage of CPU identification. -- Should I check TI?
1075  */
1076 void
1077 finishidentcpu(void)
1078 {
1079         int     isblue = 0;
1080         u_char  ccr3;
1081         u_int   regs[4];
1082
1083         /* Detect AMD features (PTE no-execute bit, 3dnow, 64 bit mode etc) */
1084         if (strcmp(cpu_vendor, "GenuineIntel") == 0 ||
1085             strcmp(cpu_vendor, "AuthenticAMD") == 0) {
1086                 init_exthigh();
1087                 if (cpu_exthigh >= 0x80000001) {
1088                         do_cpuid(0x80000001, regs);
1089                         amd_feature = regs[3] & ~(cpu_feature & 0x0183f3ff);
1090                         amd_feature2 = regs[2];
1091                 }
1092                 if (cpu_exthigh >= 0x80000008) {
1093                         do_cpuid(0x80000008, regs);
1094                         cpu_procinfo2 = regs[2];
1095                 }
1096         } else if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
1097                 if (cpu == CPU_486) {
1098                         /*
1099                          * These conditions are equivalent to:
1100                          *     - CPU does not support cpuid instruction.
1101                          *     - Cyrix/IBM CPU is detected.
1102                          */
1103                         isblue = identblue();
1104                         if (isblue == IDENTBLUE_IBMCPU) {
1105                                 strcpy(cpu_vendor, "IBM");
1106                                 cpu = CPU_BLUE;
1107                                 return;
1108                         }
1109                 }
1110                 switch (cpu_id & 0xf00) {
1111                 case 0x600:
1112                         /*
1113                          * Cyrix's datasheet does not describe DIRs.
1114                          * Therefor, I assume it does not have them
1115                          * and use the result of the cpuid instruction.
1116                          * XXX they seem to have it for now at least. -Peter
1117                          */
1118                         identifycyrix();
1119                         cpu = CPU_M2;
1120                         break;
1121                 default:
1122                         identifycyrix();
1123                         /*
1124                          * This routine contains a trick.
1125                          * Don't check (cpu_id & 0x00f0) == 0x50 to detect M2, now.
1126                          */
1127                         switch (cyrix_did & 0x00f0) {
1128                         case 0x00:
1129                         case 0xf0:
1130                                 cpu = CPU_486DLC;
1131                                 break;
1132                         case 0x10:
1133                                 cpu = CPU_CY486DX;
1134                                 break;
1135                         case 0x20:
1136                                 if ((cyrix_did & 0x000f) < 8)
1137                                         cpu = CPU_M1;
1138                                 else
1139                                         cpu = CPU_M1SC;
1140                                 break;
1141                         case 0x30:
1142                                 cpu = CPU_M1;
1143                                 break;
1144                         case 0x40:
1145                                 /* MediaGX CPU */
1146                                 cpu = CPU_M1SC;
1147                                 break;
1148                         default:
1149                                 /* M2 and later CPUs are treated as M2. */
1150                                 cpu = CPU_M2;
1151
1152                                 /*
1153                                  * enable cpuid instruction.
1154                                  */
1155                                 ccr3 = read_cyrix_reg(CCR3);
1156                                 write_cyrix_reg(CCR3, CCR3_MAPEN0);
1157                                 write_cyrix_reg(CCR4, read_cyrix_reg(CCR4) | CCR4_CPUID);
1158                                 write_cyrix_reg(CCR3, ccr3);
1159
1160                                 do_cpuid(0, regs);
1161                                 cpu_high = regs[0];     /* eax */
1162                                 do_cpuid(1, regs);
1163                                 cpu_id = regs[0];       /* eax */
1164                                 cpu_feature = regs[3];  /* edx */
1165                                 break;
1166                         }
1167                 }
1168         } else if (cpu == CPU_486 && *cpu_vendor == '\0') {
1169                 /*
1170                  * There are BlueLightning CPUs that do not change
1171                  * undefined flags by dividing 5 by 2.  In this case,
1172                  * the CPU identification routine in locore.s leaves
1173                  * cpu_vendor null string and puts CPU_486 into the
1174                  * cpu.
1175                  */
1176                 isblue = identblue();
1177                 if (isblue == IDENTBLUE_IBMCPU) {
1178                         strcpy(cpu_vendor, "IBM");
1179                         cpu = CPU_BLUE;
1180                         return;
1181                 }
1182         }
1183 }
1184
1185 static void
1186 print_AMD_assoc(int i)
1187 {
1188         if (i == 255)
1189                 printf(", fully associative\n");
1190         else
1191                 printf(", %d-way associative\n", i);
1192 }
1193
1194 static void
1195 print_AMD_info(void)
1196 {
1197         quad_t amd_whcr;
1198
1199         if (cpu_exthigh >= 0x80000005) {
1200                 u_int regs[4];
1201
1202                 do_cpuid(0x80000005, regs);
1203                 printf("Data TLB: %d entries", (regs[1] >> 16) & 0xff);
1204                 print_AMD_assoc(regs[1] >> 24);
1205                 printf("Instruction TLB: %d entries", regs[1] & 0xff);
1206                 print_AMD_assoc((regs[1] >> 8) & 0xff);
1207                 printf("L1 data cache: %d kbytes", regs[2] >> 24);
1208                 printf(", %d bytes/line", regs[2] & 0xff);
1209                 printf(", %d lines/tag", (regs[2] >> 8) & 0xff);
1210                 print_AMD_assoc((regs[2] >> 16) & 0xff);
1211                 printf("L1 instruction cache: %d kbytes", regs[3] >> 24);
1212                 printf(", %d bytes/line", regs[3] & 0xff);
1213                 printf(", %d lines/tag", (regs[3] >> 8) & 0xff);
1214                 print_AMD_assoc((regs[3] >> 16) & 0xff);
1215                 if (cpu_exthigh >= 0x80000006) {        /* K6-III only */
1216                         do_cpuid(0x80000006, regs);
1217                         printf("L2 internal cache: %d kbytes", regs[2] >> 16);
1218                         printf(", %d bytes/line", regs[2] & 0xff);
1219                         printf(", %d lines/tag", (regs[2] >> 8) & 0x0f);
1220                         print_AMD_assoc((regs[2] >> 12) & 0x0f);        
1221                 }
1222         }
1223         if (((cpu_id & 0xf00) == 0x500)
1224             && (((cpu_id & 0x0f0) > 0x80)
1225                 || (((cpu_id & 0x0f0) == 0x80)
1226                     && (cpu_id & 0x00f) > 0x07))) {
1227                 /* K6-2(new core [Stepping 8-F]), K6-III or later */
1228                 amd_whcr = rdmsr(0xc0000082);
1229                 if (!(amd_whcr & (0x3ff << 22))) {
1230                         printf("Write Allocate Disable\n");
1231                 } else {
1232                         printf("Write Allocate Enable Limit: %dM bytes\n",
1233                             (u_int32_t)((amd_whcr & (0x3ff << 22)) >> 22) * 4);
1234                         printf("Write Allocate 15-16M bytes: %s\n",
1235                             (amd_whcr & (1 << 16)) ? "Enable" : "Disable");
1236                 }
1237         } else if (((cpu_id & 0xf00) == 0x500)
1238                    && ((cpu_id & 0x0f0) > 0x50)) {
1239                 /* K6, K6-2(old core) */
1240                 amd_whcr = rdmsr(0xc0000082);
1241                 if (!(amd_whcr & (0x7f << 1))) {
1242                         printf("Write Allocate Disable\n");
1243                 } else {
1244                         printf("Write Allocate Enable Limit: %dM bytes\n",
1245                             (u_int32_t)((amd_whcr & (0x7f << 1)) >> 1) * 4);
1246                         printf("Write Allocate 15-16M bytes: %s\n",
1247                             (amd_whcr & 0x0001) ? "Enable" : "Disable");
1248                         printf("Hardware Write Allocate Control: %s\n",
1249                             (amd_whcr & 0x0100) ? "Enable" : "Disable");
1250                 }
1251         }
1252 }
1253
1254 static void
1255 print_INTEL_info(void)
1256 {
1257         u_int regs[4];
1258         u_int rounds, regnum;
1259         u_int nwaycode, nway;
1260
1261         if (cpu_high >= 2) {
1262                 rounds = 0;
1263                 do {
1264                         do_cpuid(0x2, regs);
1265                         if (rounds == 0 && (rounds = (regs[0] & 0xff)) == 0)
1266                                 break;  /* we have a buggy CPU */
1267
1268                         for (regnum = 0; regnum <= 3; ++regnum) {
1269                                 if (regs[regnum] & (1<<31))
1270                                         continue;
1271                                 if (regnum != 0)
1272                                         print_INTEL_TLB(regs[regnum] & 0xff);
1273                                 print_INTEL_TLB((regs[regnum] >> 8) & 0xff);
1274                                 print_INTEL_TLB((regs[regnum] >> 16) & 0xff);
1275                                 print_INTEL_TLB((regs[regnum] >> 24) & 0xff);
1276                         }
1277                 } while (--rounds > 0);
1278         }
1279
1280         if (cpu_exthigh >= 0x80000006) {
1281                 do_cpuid(0x80000006, regs);
1282                 nwaycode = (regs[2] >> 12) & 0x0f;
1283                 if (nwaycode >= 0x02 && nwaycode <= 0x08)
1284                         nway = 1 << (nwaycode / 2);
1285                 else
1286                         nway = 0;
1287                 printf("\nL2 cache: %u kbytes, %u-way associative, %u bytes/line",
1288                     (regs[2] >> 16) & 0xffff, nway, regs[2] & 0xff);
1289         }
1290
1291         printf("\n");
1292 }
1293
1294 static void
1295 print_INTEL_TLB(u_int data)
1296 {
1297         switch (data) {
1298         case 0x0:
1299         case 0x40:
1300         default:
1301                 break;
1302         case 0x1:
1303                 printf("\nInstruction TLB: 4 KB pages, 4-way set associative, 32 entries");
1304                 break;
1305         case 0x2:
1306                 printf("\nInstruction TLB: 4 MB pages, fully associative, 2 entries");
1307                 break;
1308         case 0x3:
1309                 printf("\nData TLB: 4 KB pages, 4-way set associative, 64 entries");
1310                 break;
1311         case 0x4:
1312                 printf("\nData TLB: 4 MB Pages, 4-way set associative, 8 entries");
1313                 break;
1314         case 0x6:
1315                 printf("\n1st-level instruction cache: 8 KB, 4-way set associative, 32 byte line size");
1316                 break;
1317         case 0x8:
1318                 printf("\n1st-level instruction cache: 16 KB, 4-way set associative, 32 byte line size");
1319                 break;
1320         case 0xa:
1321                 printf("\n1st-level data cache: 8 KB, 2-way set associative, 32 byte line size");
1322                 break;
1323         case 0xc:
1324                 printf("\n1st-level data cache: 16 KB, 4-way set associative, 32 byte line size");
1325                 break;
1326         case 0x22:
1327                 printf("\n3rd-level cache: 512 KB, 4-way set associative, sectored cache, 64 byte line size");
1328                 break;
1329         case 0x23:
1330                 printf("\n3rd-level cache: 1 MB, 8-way set associative, sectored cache, 64 byte line size");
1331                 break;
1332         case 0x25:
1333                 printf("\n3rd-level cache: 2 MB, 8-way set associative, sectored cache, 64 byte line size");
1334                 break;
1335         case 0x29:
1336                 printf("\n3rd-level cache: 4 MB, 8-way set associative, sectored cache, 64 byte line size");
1337                 break;
1338         case 0x2c:
1339                 printf("\n1st-level data cache: 32 KB, 8-way set associative, 64 byte line size");
1340                 break;
1341         case 0x30:
1342                 printf("\n1st-level instruction cache: 32 KB, 8-way set associative, 64 byte line size");
1343                 break;
1344         case 0x39:
1345                 printf("\n2nd-level cache: 128 KB, 4-way set associative, sectored cache, 64 byte line size");
1346                 break;
1347         case 0x3b:
1348                 printf("\n2nd-level cache: 128 KB, 2-way set associative, sectored cache, 64 byte line size");
1349                 break;
1350         case 0x3c:
1351                 printf("\n2nd-level cache: 256 KB, 4-way set associative, sectored cache, 64 byte line size");
1352                 break;
1353         case 0x41:
1354                 printf("\n2nd-level cache: 128 KB, 4-way set associative, 32 byte line size");
1355                 break;
1356         case 0x42:
1357                 printf("\n2nd-level cache: 256 KB, 4-way set associative, 32 byte line size");
1358                 break;
1359         case 0x43:
1360                 printf("\n2nd-level cache: 512 KB, 4-way set associative, 32 byte line size");
1361                 break;
1362         case 0x44:
1363                 printf("\n2nd-level cache: 1 MB, 4-way set associative, 32 byte line size");
1364                 break;
1365         case 0x45:
1366                 printf("\n2nd-level cache: 2 MB, 4-way set associative, 32 byte line size");
1367                 break;
1368         case 0x46:
1369                 printf("\n3rd-level cache: 4 MB, 4-way set associative, 64 byte line size");
1370                 break;
1371         case 0x47:
1372                 printf("\n3rd-level cache: 8 MB, 8-way set associative, 64 byte line size");
1373                 break;
1374         case 0x50:
1375                 printf("\nInstruction TLB: 4 KB, 2 MB or 4 MB pages, fully associative, 64 entries");
1376                 break;
1377         case 0x51:
1378                 printf("\nInstruction TLB: 4 KB, 2 MB or 4 MB pages, fully associative, 128 entries");
1379                 break;
1380         case 0x52:
1381                 printf("\nInstruction TLB: 4 KB, 2 MB or 4 MB pages, fully associative, 256 entries");
1382                 break;
1383         case 0x5b:
1384                 printf("\nData TLB: 4 KB or 4 MB pages, fully associative, 64 entries");
1385                 break;
1386         case 0x5c:
1387                 printf("\nData TLB: 4 KB or 4 MB pages, fully associative, 128 entries");
1388                 break;
1389         case 0x5d:
1390                 printf("\nData TLB: 4 KB or 4 MB pages, fully associative, 256 entries");
1391                 break;
1392         case 0x60:
1393                 printf("\n1st-level data cache: 16 KB, 8-way set associative, sectored cache, 64 byte line size");
1394                 break;
1395         case 0x66:
1396                 printf("\n1st-level data cache: 8 KB, 4-way set associative, sectored cache, 64 byte line size");
1397                 break;
1398         case 0x67:
1399                 printf("\n1st-level data cache: 16 KB, 4-way set associative, sectored cache, 64 byte line size");
1400                 break;
1401         case 0x68:
1402                 printf("\n1st-level data cache: 32 KB, 4 way set associative, sectored cache, 64 byte line size");
1403                 break;
1404         case 0x70:
1405                 printf("\nTrace cache: 12K-uops, 8-way set associative");
1406                 break;
1407         case 0x71:
1408                 printf("\nTrace cache: 16K-uops, 8-way set associative");
1409                 break;
1410         case 0x72:
1411                 printf("\nTrace cache: 32K-uops, 8-way set associative");
1412                 break;
1413         case 0x78:
1414                 printf("\n2nd-level cache: 1 MB, 4-way set associative, 64-byte line size");
1415                 break;
1416         case 0x79:
1417                 printf("\n2nd-level cache: 128 KB, 8-way set associative, sectored cache, 64 byte line size");
1418                 break;
1419         case 0x7a:
1420                 printf("\n2nd-level cache: 256 KB, 8-way set associative, sectored cache, 64 byte line size");
1421                 break;
1422         case 0x7b:
1423                 printf("\n2nd-level cache: 512 KB, 8-way set associative, sectored cache, 64 byte line size");
1424                 break;
1425         case 0x7c:
1426                 printf("\n2nd-level cache: 1 MB, 8-way set associative, sectored cache, 64 byte line size");
1427                 break;
1428         case 0x7d:
1429                 printf("\n2nd-level cache: 2-MB, 8-way set associative, 64-byte line size");
1430                 break;
1431         case 0x7f:
1432                 printf("\n2nd-level cache: 512-KB, 2-way set associative, 64-byte line size");
1433                 break;
1434         case 0x82:
1435                 printf("\n2nd-level cache: 256 KB, 8-way set associative, 32 byte line size");
1436                 break;
1437         case 0x83:
1438                 printf("\n2nd-level cache: 512 KB, 8-way set associative, 32 byte line size");
1439                 break;
1440         case 0x84:
1441                 printf("\n2nd-level cache: 1 MB, 8-way set associative, 32 byte line size");
1442                 break;
1443         case 0x85:
1444                 printf("\n2nd-level cache: 2 MB, 8-way set associative, 32 byte line size");
1445                 break;
1446         case 0x86:
1447                 printf("\n2nd-level cache: 512 KB, 4-way set associative, 64 byte line size");
1448                 break;
1449         case 0x87:
1450                 printf("\n2nd-level cache: 1 MB, 8-way set associative, 64 byte line size");
1451                 break;
1452         case 0xb0:
1453                 printf("\nInstruction TLB: 4 KB Pages, 4-way set associative, 128 entries");
1454                 break;
1455         case 0xb3:
1456                 printf("\nData TLB: 4 KB Pages, 4-way set associative, 128 entries");
1457                 break;
1458         }
1459 }
1460
1461 static void
1462 print_transmeta_info(void)
1463 {
1464         u_int regs[4], nreg = 0;
1465
1466         do_cpuid(0x80860000, regs);
1467         nreg = regs[0];
1468         if (nreg >= 0x80860001) {
1469                 do_cpuid(0x80860001, regs);
1470                 printf("  Processor revision %u.%u.%u.%u\n",
1471                        (regs[1] >> 24) & 0xff,
1472                        (regs[1] >> 16) & 0xff,
1473                        (regs[1] >> 8) & 0xff,
1474                        regs[1] & 0xff);
1475         }
1476         if (nreg >= 0x80860002) {
1477                 do_cpuid(0x80860002, regs);
1478                 printf("  Code Morphing Software revision %u.%u.%u-%u-%u\n",
1479                        (regs[1] >> 24) & 0xff,
1480                        (regs[1] >> 16) & 0xff,
1481                        (regs[1] >> 8) & 0xff,
1482                        regs[1] & 0xff,
1483                        regs[2]);
1484         }
1485         if (nreg >= 0x80860006) {
1486                 char info[65];
1487                 do_cpuid(0x80860003, (u_int*) &info[0]);
1488                 do_cpuid(0x80860004, (u_int*) &info[16]);
1489                 do_cpuid(0x80860005, (u_int*) &info[32]);
1490                 do_cpuid(0x80860006, (u_int*) &info[48]);
1491                 info[64] = 0;
1492                 printf("  %s\n", info);
1493         }
1494 }
1495
1496 static void
1497 print_via_padlock_info(void)
1498 {
1499         u_int regs[4];
1500
1501         /* Check for supported models. */
1502         switch (cpu_id & 0xff0) {
1503         case 0x690:
1504                 if ((cpu_id & 0xf) < 3)
1505                         return;
1506         case 0x6a0:
1507         case 0x6d0:
1508                 break;
1509         default:
1510                 return;
1511         }
1512         
1513         do_cpuid(0xc0000000, regs);
1514         if (regs[0] >= 0xc0000001)
1515                 do_cpuid(0xc0000001, regs);
1516         else
1517                 return;
1518
1519         printf("\n  VIA Padlock Features=0x%b", regs[3],
1520         "\020"
1521         "\003RNG"               /* RNG */
1522         "\007AES"               /* ACE */
1523         "\011AES-CTR"           /* ACE2 */
1524         "\013SHA1,SHA256"       /* PHE */
1525         "\015RSA"               /* PMM */
1526         );
1527 }