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/systm.h>
49 #include <sys/kernel.h>
50 #include <sys/sysctl.h>
51 #include <sys/power.h>
52
53 #include <machine/asmacros.h>
54 #include <machine/clock.h>
55 #include <machine/cputypes.h>
56 #include <machine/intr_machdep.h>
57 #include <machine/md_var.h>
58 #include <machine/segments.h>
59 #include <machine/specialreg.h>
60
61 #define IDENTBLUE_CYRIX486 0
62 #define IDENTBLUE_IBMCPU 1
63 #define IDENTBLUE_CYRIXM2 2
64
65 /* XXX - should be in header file: */
66 void printcpuinfo(void);
67 void finishidentcpu(void);
68 void earlysetcpuclass(void);
69 #if defined(I586_CPU) && defined(CPU_WT_ALLOC)
70 void enable_K5_wt_alloc(void);
71 void enable_K6_wt_alloc(void);
72 void enable_K6_2_wt_alloc(void);
73 #endif
74 void panicifcpuunsupported(void);
75
76 static void identifycyrix(void);
77 static void print_AMD_info(void);
78 static void print_AMD_assoc(int i);
79 static void print_transmeta_info(void);
80 static void print_via_padlock_info(void);
81
82 int cpu_class;
83 u_int cpu_exthigh; /* Highest arg to extended CPUID */
84 u_int cyrix_did; /* Device ID of Cyrix CPU */
85 char machine[] = "i386";
86 SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD,
87 machine, 0, "Machine class");
88
89 static char cpu_model[128];
90 SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD,
91 cpu_model, 0, "Machine model");
92
93 static int hw_clockrate;
94 SYSCTL_INT(_hw, OID_AUTO, clockrate, CTLFLAG_RD,
95 &hw_clockrate, 0, "CPU instruction clock rate");
96
97 #if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
98 static char cpu_brand[48];
99
100 #define MAX_BRAND_INDEX 8
101
102 static const char *cpu_brandtable[MAX_BRAND_INDEX + 1] = {
103 NULL, /* No brand */
104 "Intel Celeron",
105 "Intel Pentium III",
106 "Intel Pentium III Xeon",
107 NULL,
108 NULL,
109 NULL,
110 NULL,
111 "Intel Pentium 4"
112 };
113 #endif
114
115 static struct {
116 char *cpu_name;
117 int cpu_class;
118 } i386_cpus[] = {
119 { "Intel 80286", CPUCLASS_286 }, /* CPU_286 */
120 { "i386SX", CPUCLASS_386 }, /* CPU_386SX */
121 { "i386DX", CPUCLASS_386 }, /* CPU_386 */
122 { "i486SX", CPUCLASS_486 }, /* CPU_486SX */
123 { "i486DX", CPUCLASS_486 }, /* CPU_486 */
124 { "Pentium", CPUCLASS_586 }, /* CPU_586 */
125 { "Cyrix 486", CPUCLASS_486 }, /* CPU_486DLC */
126 { "Pentium Pro", CPUCLASS_686 }, /* CPU_686 */
127 { "Cyrix 5x86", CPUCLASS_486 }, /* CPU_M1SC */
128 { "Cyrix 6x86", CPUCLASS_486 }, /* CPU_M1 */
129 { "Blue Lightning", CPUCLASS_486 }, /* CPU_BLUE */
130 { "Cyrix 6x86MX", CPUCLASS_686 }, /* CPU_M2 */
131 { "NexGen 586", CPUCLASS_386 }, /* CPU_NX586 (XXX) */
132 { "Cyrix 486S/DX", CPUCLASS_486 }, /* CPU_CY486DX */
133 { "Pentium II", CPUCLASS_686 }, /* CPU_PII */
134 { "Pentium III", CPUCLASS_686 }, /* CPU_PIII */
135 { "Pentium 4", CPUCLASS_686 }, /* CPU_P4 */
136 };
137
138 #if defined(I586_CPU) && !defined(NO_F00F_HACK)
139 int has_f00f_bug = 0; /* Initialized so that it can be patched. */
140 #endif
141
142 void
143 printcpuinfo(void)
144 {
145 #if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
146 u_int regs[4], i;
147 char *brand;
148 #endif
149
150 cpu_class = i386_cpus[cpu].cpu_class;
151 printf("CPU: ");
152 strncpy(cpu_model, i386_cpus[cpu].cpu_name, sizeof (cpu_model));
153
154 #if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
155 /* Check for extended CPUID information and a processor name. */
156 if (cpu_high > 0 &&
157 (strcmp(cpu_vendor, "GenuineIntel") == 0 ||
158 strcmp(cpu_vendor, "AuthenticAMD") == 0 ||
159 strcmp(cpu_vendor, "GenuineTMx86") == 0 ||
160 strcmp(cpu_vendor, "TransmetaCPU") == 0 ||
161 strcmp(cpu_vendor, "CentaurHauls") == 0 ||
162 strcmp(cpu_vendor, "Geode by NSC") == 0)) {
163 do_cpuid(0x80000000, regs);
164 if (regs[0] >= 0x80000000) {
165 cpu_exthigh = regs[0];
166 if (cpu_exthigh >= 0x80000004) {
167 brand = cpu_brand;
168 for (i = 0x80000002; i < 0x80000005; i++) {
169 do_cpuid(i, regs);
170 memcpy(brand, regs, sizeof(regs));
171 brand += sizeof(regs);
172 }
173 }
174 }
175 }
176
177 /* Detect AMD features (PTE no-execute bit, 3dnow, 64 bit mode etc) */
178 if (strcmp(cpu_vendor, "GenuineIntel") == 0 ||
179 strcmp(cpu_vendor, "AuthenticAMD") == 0) {
180 if (cpu_exthigh >= 0x80000001) {
181 do_cpuid(0x80000001, regs);
182 amd_feature = regs[3] & ~(cpu_feature & 0x0183f3ff);
183 amd_feature2 = regs[2];
184 }
185 if (cpu_exthigh >= 0x80000008) {
186 do_cpuid(0x80000008, regs);
187 cpu_procinfo2 = regs[2];
188 }
189 }
190
191 if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
192 if ((cpu_id & 0xf00) > 0x300) {
193 u_int brand_index;
194
195 cpu_model[0] = '\0';
196
197 switch (cpu_id & 0x3000) {
198 case 0x1000:
199 strcpy(cpu_model, "Overdrive ");
200 break;
201 case 0x2000:
202 strcpy(cpu_model, "Dual ");
203 break;
204 }
205
206 switch (cpu_id & 0xf00) {
207 case 0x400:
208 strcat(cpu_model, "i486 ");
209 /* Check the particular flavor of 486 */
210 switch (cpu_id & 0xf0) {
211 case 0x00:
212 case 0x10:
213 strcat(cpu_model, "DX");
214 break;
215 case 0x20:
216 strcat(cpu_model, "SX");
217 break;
218 case 0x30:
219 strcat(cpu_model, "DX2");
220 break;
221 case 0x40:
222 strcat(cpu_model, "SL");
223 break;
224 case 0x50:
225 strcat(cpu_model, "SX2");
226 break;
227 case 0x70:
228 strcat(cpu_model,
229 "DX2 Write-Back Enhanced");
230 break;
231 case 0x80:
232 strcat(cpu_model, "DX4");
233 break;
234 }
235 break;
236 case 0x500:
237 /* Check the particular flavor of 586 */
238 strcat(cpu_model, "Pentium");
239 switch (cpu_id & 0xf0) {
240 case 0x00:
241 strcat(cpu_model, " A-step");
242 break;
243 case 0x10:
244 strcat(cpu_model, "/P5");
245 break;
246 case 0x20:
247 strcat(cpu_model, "/P54C");
248 break;
249 case 0x30:
250 strcat(cpu_model, "/P24T");
251 break;
252 case 0x40:
253 strcat(cpu_model, "/P55C");
254 break;
255 case 0x70:
256 strcat(cpu_model, "/P54C");
257 break;
258 case 0x80:
259 strcat(cpu_model, "/P55C (quarter-micron)");
260 break;
261 default:
262 /* nothing */
263 break;
264 }
265 #if defined(I586_CPU) && !defined(NO_F00F_HACK)
266 /*
267 * XXX - If/when Intel fixes the bug, this
268 * should also check the version of the
269 * CPU, not just that it's a Pentium.
270 */
271 has_f00f_bug = 1;
272 #endif
273 break;
274 case 0x600:
275 /* Check the particular flavor of 686 */
276 switch (cpu_id & 0xf0) {
277 case 0x00:
278 strcat(cpu_model, "Pentium Pro A-step");
279 break;
280 case 0x10:
281 strcat(cpu_model, "Pentium Pro");
282 break;
283 case 0x30:
284 case 0x50:
285 case 0x60:
286 strcat(cpu_model,
287 "Pentium II/Pentium II Xeon/Celeron");
288 cpu = CPU_PII;
289 break;
290 case 0x70:
291 case 0x80:
292 case 0xa0:
293 case 0xb0:
294 strcat(cpu_model,
295 "Pentium III/Pentium III Xeon/Celeron");
296 cpu = CPU_PIII;
297 break;
298 default:
299 strcat(cpu_model, "Unknown 80686");
300 break;
301 }
302 break;
303 case 0xf00:
304 strcat(cpu_model, "Pentium 4");
305 cpu = CPU_P4;
306 break;
307 default:
308 strcat(cpu_model, "unknown");
309 break;
310 }
311
312 /*
313 * If we didn't get a brand name from the extended
314 * CPUID, try to look it up in the brand table.
315 */
316 if (cpu_high > 0 && *cpu_brand == '\0') {
317 brand_index = cpu_procinfo & CPUID_BRAND_INDEX;
318 if (brand_index <= MAX_BRAND_INDEX &&
319 cpu_brandtable[brand_index] != NULL)
320 strcpy(cpu_brand,
321 cpu_brandtable[brand_index]);
322 }
323 }
324 } else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
325 /*
326 * Values taken from AMD Processor Recognition
327 * http://www.amd.com/K6/k6docs/pdf/20734g.pdf
328 * (also describes ``Features'' encodings.
329 */
330 strcpy(cpu_model, "AMD ");
331 switch (cpu_id & 0xFF0) {
332 case 0x410:
333 strcat(cpu_model, "Standard Am486DX");
334 break;
335 case 0x430:
336 strcat(cpu_model, "Enhanced Am486DX2 Write-Through");
337 break;
338 case 0x470:
339 strcat(cpu_model, "Enhanced Am486DX2 Write-Back");
340 break;
341 case 0x480:
342 strcat(cpu_model, "Enhanced Am486DX4/Am5x86 Write-Through");
343 break;
344 case 0x490:
345 strcat(cpu_model, "Enhanced Am486DX4/Am5x86 Write-Back");
346 break;
347 case 0x4E0:
348 strcat(cpu_model, "Am5x86 Write-Through");
349 break;
350 case 0x4F0:
351 strcat(cpu_model, "Am5x86 Write-Back");
352 break;
353 case 0x500:
354 strcat(cpu_model, "K5 model 0");
355 tsc_is_broken = 1;
356 break;
357 case 0x510:
358 strcat(cpu_model, "K5 model 1");
359 break;
360 case 0x520:
361 strcat(cpu_model, "K5 PR166 (model 2)");
362 break;
363 case 0x530:
364 strcat(cpu_model, "K5 PR200 (model 3)");
365 break;
366 case 0x560:
367 strcat(cpu_model, "K6");
368 break;
369 case 0x570:
370 strcat(cpu_model, "K6 266 (model 1)");
371 break;
372 case 0x580:
373 strcat(cpu_model, "K6-2");
374 break;
375 case 0x590:
376 strcat(cpu_model, "K6-III");
377 break;
378 default:
379 strcat(cpu_model, "Unknown");
380 break;
381 }
382 #if defined(I586_CPU) && defined(CPU_WT_ALLOC)
383 if ((cpu_id & 0xf00) == 0x500) {
384 if (((cpu_id & 0x0f0) > 0)
385 && ((cpu_id & 0x0f0) < 0x60)
386 && ((cpu_id & 0x00f) > 3))
387 enable_K5_wt_alloc();
388 else if (((cpu_id & 0x0f0) > 0x80)
389 || (((cpu_id & 0x0f0) == 0x80)
390 && (cpu_id & 0x00f) > 0x07))
391 enable_K6_2_wt_alloc();
392 else if ((cpu_id & 0x0f0) > 0x50)
393 enable_K6_wt_alloc();
394 }
395 #endif
396 } else if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
397 strcpy(cpu_model, "Cyrix ");
398 switch (cpu_id & 0xff0) {
399 case 0x440:
400 strcat(cpu_model, "MediaGX");
401 break;
402 case 0x520:
403 strcat(cpu_model, "6x86");
404 break;
405 case 0x540:
406 cpu_class = CPUCLASS_586;
407 strcat(cpu_model, "GXm");
408 break;
409 case 0x600:
410 strcat(cpu_model, "6x86MX");
411 break;
412 default:
413 /*
414 * Even though CPU supports the cpuid
415 * instruction, it can be disabled.
416 * Therefore, this routine supports all Cyrix
417 * CPUs.
418 */
419 switch (cyrix_did & 0xf0) {
420 case 0x00:
421 switch (cyrix_did & 0x0f) {
422 case 0x00:
423 strcat(cpu_model, "486SLC");
424 break;
425 case 0x01:
426 strcat(cpu_model, "486DLC");
427 break;
428 case 0x02:
429 strcat(cpu_model, "486SLC2");
430 break;
431 case 0x03:
432 strcat(cpu_model, "486DLC2");
433 break;
434 case 0x04:
435 strcat(cpu_model, "486SRx");
436 break;
437 case 0x05:
438 strcat(cpu_model, "486DRx");
439 break;
440 case 0x06:
441 strcat(cpu_model, "486SRx2");
442 break;
443 case 0x07:
444 strcat(cpu_model, "486DRx2");
445 break;
446 case 0x08:
447 strcat(cpu_model, "486SRu");
448 break;
449 case 0x09:
450 strcat(cpu_model, "486DRu");
451 break;
452 case 0x0a:
453 strcat(cpu_model, "486SRu2");
454 break;
455 case 0x0b:
456 strcat(cpu_model, "486DRu2");
457 break;
458 default:
459 strcat(cpu_model, "Unknown");
460 break;
461 }
462 break;
463 case 0x10:
464 switch (cyrix_did & 0x0f) {
465 case 0x00:
466 strcat(cpu_model, "486S");
467 break;
468 case 0x01:
469 strcat(cpu_model, "486S2");
470 break;
471 case 0x02:
472 strcat(cpu_model, "486Se");
473 break;
474 case 0x03:
475 strcat(cpu_model, "486S2e");
476 break;
477 case 0x0a:
478 strcat(cpu_model, "486DX");
479 break;
480 case 0x0b:
481 strcat(cpu_model, "486DX2");
482 break;
483 case 0x0f:
484 strcat(cpu_model, "486DX4");
485 break;
486 default:
487 strcat(cpu_model, "Unknown");
488 break;
489 }
490 break;
491 case 0x20:
492 if ((cyrix_did & 0x0f) < 8)
493 strcat(cpu_model, "6x86"); /* Where did you get it? */
494 else
495 strcat(cpu_model, "5x86");
496 break;
497 case 0x30:
498 strcat(cpu_model, "6x86");
499 break;
500 case 0x40:
501 if ((cyrix_did & 0xf000) == 0x3000) {
502 cpu_class = CPUCLASS_586;
503 strcat(cpu_model, "GXm");
504 } else
505 strcat(cpu_model, "MediaGX");
506 break;
507 case 0x50:
508 strcat(cpu_model, "6x86MX");
509 break;
510 case 0xf0:
511 switch (cyrix_did & 0x0f) {
512 case 0x0d:
513 strcat(cpu_model, "Overdrive CPU");
514 break;
515 case 0x0e:
516 strcpy(cpu_model, "Texas Instruments 486SXL");
517 break;
518 case 0x0f:
519 strcat(cpu_model, "486SLC/DLC");
520 break;
521 default:
522 strcat(cpu_model, "Unknown");
523 break;
524 }
525 break;
526 default:
527 strcat(cpu_model, "Unknown");
528 break;
529 }
530 break;
531 }
532 } else if (strcmp(cpu_vendor, "RiseRiseRise") == 0) {
533 strcpy(cpu_model, "Rise ");
534 switch (cpu_id & 0xff0) {
535 case 0x500:
536 strcat(cpu_model, "mP6");
537 break;
538 default:
539 strcat(cpu_model, "Unknown");
540 }
541 } else if (strcmp(cpu_vendor, "CentaurHauls") == 0) {
542 switch (cpu_id & 0xff0) {
543 case 0x540:
544 strcpy(cpu_model, "IDT WinChip C6");
545 tsc_is_broken = 1;
546 break;
547 case 0x580:
548 strcpy(cpu_model, "IDT WinChip 2");
549 break;
550 case 0x660:
551 strcpy(cpu_model, "VIA C3 Samuel");
552 break;
553 case 0x670:
554 if (cpu_id & 0x8)
555 strcpy(cpu_model, "VIA C3 Ezra");
556 else
557 strcpy(cpu_model, "VIA C3 Samuel 2");
558 break;
559 case 0x680:
560 strcpy(cpu_model, "VIA C3 Ezra-T");
561 break;
562 case 0x690:
563 strcpy(cpu_model, "VIA C3 Nehemiah");
564 break;
565 case 0x6a0:
566 case 0x6d0:
567 strcpy(cpu_model, "VIA C7 Esther");
568 break;
569 default:
570 strcpy(cpu_model, "VIA/IDT Unknown");
571 }
572 } else if (strcmp(cpu_vendor, "IBM") == 0) {
573 strcpy(cpu_model, "Blue Lightning CPU");
574 } else if (strcmp(cpu_vendor, "Geode by NSC") == 0) {
575 switch (cpu_id & 0xfff) {
576 case 0x540:
577 strcpy(cpu_model, "Geode SC1100");
578 cpu = CPU_GEODE1100;
579 tsc_is_broken = 1;
580 break;
581 default:
582 strcpy(cpu_model, "Geode/NSC unknown");
583 break;
584 }
585 }
586
587 /*
588 * Replace cpu_model with cpu_brand minus leading spaces if
589 * we have one.
590 */
591 brand = cpu_brand;
592 while (*brand == ' ')
593 ++brand;
594 if (*brand != '\0')
595 strcpy(cpu_model, brand);
596
597 #endif
598
599 printf("%s (", cpu_model);
600 switch(cpu_class) {
601 case CPUCLASS_286:
602 printf("286");
603 break;
604 case CPUCLASS_386:
605 printf("386");
606 break;
607 #if defined(I486_CPU)
608 case CPUCLASS_486:
609 printf("486");
610 bzero_vector = i486_bzero;
611 break;
612 #endif
613 #if defined(I586_CPU)
614 case CPUCLASS_586:
615 hw_clockrate = (tsc_freq + 5000) / 1000000;
616 printf("%jd.%02d-MHz ",
617 (intmax_t)(tsc_freq + 4999) / 1000000,
618 (u_int)((tsc_freq + 4999) / 10000) % 100);
619 printf("586");
620 break;
621 #endif
622 #if defined(I686_CPU)
623 case CPUCLASS_686:
624 hw_clockrate = (tsc_freq + 5000) / 1000000;
625 printf("%jd.%02d-MHz ",
626 (intmax_t)(tsc_freq + 4999) / 1000000,
627 (u_int)((tsc_freq + 4999) / 10000) % 100);
628 printf("686");
629 break;
630 #endif
631 default:
632 printf("Unknown"); /* will panic below... */
633 }
634 printf("-class CPU)\n");
635 #if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
636 if(*cpu_vendor)
637 printf(" Origin = \"%s\"",cpu_vendor);
638 if(cpu_id)
639 printf(" Id = 0x%x", cpu_id);
640
641 if (strcmp(cpu_vendor, "GenuineIntel") == 0 ||
642 strcmp(cpu_vendor, "AuthenticAMD") == 0 ||
643 strcmp(cpu_vendor, "GenuineTMx86") == 0 ||
644 strcmp(cpu_vendor, "TransmetaCPU") == 0 ||
645 strcmp(cpu_vendor, "RiseRiseRise") == 0 ||
646 strcmp(cpu_vendor, "CentaurHauls") == 0 ||
647 strcmp(cpu_vendor, "Geode by NSC") == 0 ||
648 ((strcmp(cpu_vendor, "CyrixInstead") == 0) &&
649 ((cpu_id & 0xf00) > 0x500))) {
650 printf(" Stepping = %u", cpu_id & 0xf);
651 if (strcmp(cpu_vendor, "CyrixInstead") == 0)
652 printf(" DIR=0x%04x", cyrix_did);
653 if (cpu_high > 0) {
654 u_int cmp = 1, htt = 1;
655
656 /*
657 * Here we should probably set up flags indicating
658 * whether or not various features are available.
659 * The interesting ones are probably VME, PSE, PAE,
660 * and PGE. The code already assumes without bothering
661 * to check that all CPUs >= Pentium have a TSC and
662 * MSRs.
663 */
664 printf("\n Features=0x%b", cpu_feature,
665 "\020"
666 "\001FPU" /* Integral FPU */
667 "\002VME" /* Extended VM86 mode support */
668 "\003DE" /* Debugging Extensions (CR4.DE) */
669 "\004PSE" /* 4MByte page tables */
670 "\005TSC" /* Timestamp counter */
671 "\006MSR" /* Machine specific registers */
672 "\007PAE" /* Physical address extension */
673 "\010MCE" /* Machine Check support */
674 "\011CX8" /* CMPEXCH8 instruction */
675 "\012APIC" /* SMP local APIC */
676 "\013oldMTRR" /* Previous implementation of MTRR */
677 "\014SEP" /* Fast System Call */
678 "\015MTRR" /* Memory Type Range Registers */
679 "\016PGE" /* PG_G (global bit) support */
680 "\017MCA" /* Machine Check Architecture */
681 "\020CMOV" /* CMOV instruction */
682 "\021PAT" /* Page attributes table */
683 "\022PSE36" /* 36 bit address space support */
684 "\023PN" /* Processor Serial number */
685 "\024CLFLUSH" /* Has the CLFLUSH instruction */
686 "\025<b20>"
687 "\026DTS" /* Debug Trace Store */
688 "\027ACPI" /* ACPI support */
689 "\030MMX" /* MMX instructions */
690 "\031FXSR" /* FXSAVE/FXRSTOR */
691 "\032SSE" /* Streaming SIMD Extensions */
692 "\033SSE2" /* Streaming SIMD Extensions #2 */
693 "\034SS" /* Self snoop */
694 "\035HTT" /* Hyperthreading (see EBX bit 16-23) */
695 "\036TM" /* Thermal Monitor clock slowdown */
696 "\037IA64" /* CPU can execute IA64 instructions */
697 "\040PBE" /* Pending Break Enable */
698 );
699
700 if (cpu_feature2 != 0) {
701 printf("\n Features2=0x%b", cpu_feature2,
702 "\020"
703 "\001SSE3" /* SSE3 */
704 "\002<b1>"
705 "\003RSVD2" /* "Reserved" bit 2 */
706 "\004MON" /* MONITOR/MWAIT Instructions */
707 "\005DS_CPL" /* CPL Qualified Debug Store */
708 "\006VMX" /* Virtual Machine Extensions */
709 "\007SMX" /* Safer Mode Extensions */
710 "\010EST" /* Enhanced SpeedStep */
711 "\011TM2" /* Thermal Monitor 2 */
712 "\012SSSE3" /* SSSE3 */
713 "\013CNXT-ID" /* L1 context ID available */
714 "\014<b11>"
715 "\015<b12>"
716 "\016CX16" /* CMPXCHG16B Instruction */
717 "\017xTPR" /* Send Task Priority Messages*/
718 "\020PDCM" /* Perf/Debug Capability MSR */
719 "\021<b16>"
720 "\022<b17>"
721 "\023DCA" /* Direct Cache Access */
722 "\024<b19>"
723 "\025<b20>"
724 "\026<b21>"
725 "\027<b22>"
726 "\030<b23>"
727 "\031<b24>"
728 "\032<b25>"
729 "\033<b26>"
730 "\034<b27>"
731 "\035<b28>"
732 "\036<b29>"
733 "\037<b30>"
734 "\040<b31>"
735 );
736 }
737
738 /*
739 * AMD64 Architecture Programmer's Manual Volume 3:
740 * General-Purpose and System Instructions
741 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/24594.pdf
742 *
743 * IA-32 Intel Architecture Software Developer's Manual,
744 * Volume 2A: Instruction Set Reference, A-M
745 * ftp://download.intel.com/design/Pentium4/manuals/25366617.pdf
746 */
747 if (amd_feature != 0) {
748 printf("\n AMD Features=0x%b", amd_feature,
749 "\020" /* in hex */
750 "\001<s0>" /* Same */
751 "\002<s1>" /* Same */
752 "\003<s2>" /* Same */
753 "\004<s3>" /* Same */
754 "\005<s4>" /* Same */
755 "\006<s5>" /* Same */
756 "\007<s6>" /* Same */
757 "\010<s7>" /* Same */
758 "\011<s8>" /* Same */
759 "\012<s9>" /* Same */
760 "\013<b10>" /* Undefined */
761 "\014SYSCALL" /* Have SYSCALL/SYSRET */
762 "\015<s12>" /* Same */
763 "\016<s13>" /* Same */
764 "\017<s14>" /* Same */
765 "\020<s15>" /* Same */
766 "\021<s16>" /* Same */
767 "\022<s17>" /* Same */
768 "\023<b18>" /* Reserved, unknown */
769 "\024MP" /* Multiprocessor Capable */
770 "\025NX" /* Has EFER.NXE, NX */
771 "\026<b21>" /* Undefined */
772 "\027MMX+" /* AMD MMX Extensions */
773 "\030<s23>" /* Same */
774 "\031<s24>" /* Same */
775 "\032FFXSR" /* Fast FXSAVE/FXRSTOR */
776 "\033<b26>" /* Undefined */
777 "\034RDTSCP" /* RDTSCP */
778 "\035<b28>" /* Undefined */
779 "\036LM" /* 64 bit long mode */
780 "\0373DNow!+" /* AMD 3DNow! Extensions */
781 "\0403DNow!" /* AMD 3DNow! */
782 );
783 }
784
785 if (amd_feature2 != 0) {
786 printf("\n AMD Features2=0x%b", amd_feature2,
787 "\020"
788 "\001LAHF" /* LAHF/SAHF in long mode */
789 "\002CMP" /* CMP legacy */
790 "\003SVM" /* Secure Virtual Mode */
791 "\004ExtAPIC" /* Extended APIC register */
792 "\005CR8" /* CR8 in legacy mode */
793 "\006<b5>"
794 "\007<b6>"
795 "\010<b7>"
796 "\011Prefetch" /* 3DNow! Prefetch/PrefetchW */
797 "\012<b9>"
798 "\013<b10>"
799 "\014<b11>"
800 "\015<b12>"
801 "\016<b13>"
802 "\017<b14>"
803 "\020<b15>"
804 "\021<b16>"
805 "\022<b17>"
806 "\023<b18>"
807 "\024<b19>"
808 "\025<b20>"
809 "\026<b21>"
810 "\027<b22>"
811 "\030<b23>"
812 "\031<b24>"
813 "\032<b25>"
814 "\033<b26>"
815 "\034<b27>"
816 "\035<b28>"
817 "\036<b29>"
818 "\037<b30>"
819 "\040<b31>"
820 );
821 }
822
823 if (cpu_feature & CPUID_HTT && strcmp(cpu_vendor,
824 "AuthenticAMD") == 0)
825 cpu_feature &= ~CPUID_HTT;
826
827 /*
828 * If this CPU supports HTT or CMP then mention the
829 * number of physical/logical cores it contains.
830 */
831 if (cpu_feature & CPUID_HTT)
832 htt = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
833 if (strcmp(cpu_vendor, "AuthenticAMD") == 0 &&
834 (amd_feature2 & AMDID2_CMP))
835 cmp = (cpu_procinfo2 & AMDID_CMP_CORES) + 1;
836 else if (strcmp(cpu_vendor, "GenuineIntel") == 0 &&
837 (cpu_high >= 4)) {
838 cpuid_count(4, 0, regs);
839 cmp = ((regs[0] & 0xfc000000) >> 26) + 1;
840 }
841 if (cmp > 1)
842 printf("\n Cores per package: %d", cmp);
843 if ((htt / cmp) > 1)
844 printf("\n Logical CPUs per core: %d",
845 htt / cmp);
846 }
847 } else if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
848 printf(" DIR=0x%04x", cyrix_did);
849 printf(" Stepping=%u", (cyrix_did & 0xf000) >> 12);
850 printf(" Revision=%u", (cyrix_did & 0x0f00) >> 8);
851 #ifndef CYRIX_CACHE_REALLY_WORKS
852 if (cpu == CPU_M1 && (cyrix_did & 0xff00) < 0x1700)
853 printf("\n CPU cache: write-through mode");
854 #endif
855 }
856 if (strcmp(cpu_vendor, "CentaurHauls") == 0)
857 print_via_padlock_info();
858
859 /* Avoid ugly blank lines: only print newline when we have to. */
860 if (*cpu_vendor || cpu_id)
861 printf("\n");
862
863 #endif
864
865 if (!bootverbose)
866 return;
867
868 if (strcmp(cpu_vendor, "AuthenticAMD") == 0)
869 print_AMD_info();
870 else if (strcmp(cpu_vendor, "GenuineTMx86") == 0 ||
871 strcmp(cpu_vendor, "TransmetaCPU") == 0)
872 print_transmeta_info();
873
874 #ifdef I686_CPU
875 /*
876 * XXX - Do PPro CPUID level=2 stuff here?
877 *
878 * No, but maybe in a print_Intel_info() function called from here.
879 */
880 #endif
881 }
882
883 void
884 panicifcpuunsupported(void)
885 {
886
887 #if !defined(lint)
888 #if !defined(I486_CPU) && !defined(I586_CPU) && !defined(I686_CPU)
889 #error This kernel is not configured for one of the supported CPUs
890 #endif
891 #else /* lint */
892 #endif /* lint */
893 /*
894 * Now that we have told the user what they have,
895 * let them know if that machine type isn't configured.
896 */
897 switch (cpu_class) {
898 case CPUCLASS_286: /* a 286 should not make it this far, anyway */
899 case CPUCLASS_386:
900 #if !defined(I486_CPU)
901 case CPUCLASS_486:
902 #endif
903 #if !defined(I586_CPU)
904 case CPUCLASS_586:
905 #endif
906 #if !defined(I686_CPU)
907 case CPUCLASS_686:
908 #endif
909 panic("CPU class not configured");
910 default:
911 break;
912 }
913 }
914
915
916 static volatile u_int trap_by_rdmsr;
917
918 /*
919 * Special exception 6 handler.
920 * The rdmsr instruction generates invalid opcodes fault on 486-class
921 * Cyrix CPU. Stacked eip register points the rdmsr instruction in the
922 * function identblue() when this handler is called. Stacked eip should
923 * be advanced.
924 */
925 inthand_t bluetrap6;
926 #ifdef __GNUCLIKE_ASM
927 __asm
928 (" \n\
929 .text \n\
930 .p2align 2,0x90 \n\
931 .type " __XSTRING(CNAME(bluetrap6)) ",@function \n\
932 " __XSTRING(CNAME(bluetrap6)) ": \n\
933 ss \n\
934 movl $0xa8c1d," __XSTRING(CNAME(trap_by_rdmsr)) " \n\
935 addl $2, (%esp) /* rdmsr is a 2-byte instruction */ \n\
936 iret \n\
937 ");
938 #endif
939
940 /*
941 * Special exception 13 handler.
942 * Accessing non-existent MSR generates general protection fault.
943 */
944 inthand_t bluetrap13;
945 #ifdef __GNUCLIKE_ASM
946 __asm
947 (" \n\
948 .text \n\
949 .p2align 2,0x90 \n\
950 .type " __XSTRING(CNAME(bluetrap13)) ",@function \n\
951 " __XSTRING(CNAME(bluetrap13)) ": \n\
952 ss \n\
953 movl $0xa89c4," __XSTRING(CNAME(trap_by_rdmsr)) " \n\
954 popl %eax /* discard error code */ \n\
955 addl $2, (%esp) /* rdmsr is a 2-byte instruction */ \n\
956 iret \n\
957 ");
958 #endif
959
960 /*
961 * Distinguish IBM Blue Lightning CPU from Cyrix CPUs that does not
962 * support cpuid instruction. This function should be called after
963 * loading interrupt descriptor table register.
964 *
965 * I don't like this method that handles fault, but I couldn't get
966 * information for any other methods. Does blue giant know?
967 */
968 static int
969 identblue(void)
970 {
971
972 trap_by_rdmsr = 0;
973
974 /*
975 * Cyrix 486-class CPU does not support rdmsr instruction.
976 * The rdmsr instruction generates invalid opcode fault, and exception
977 * will be trapped by bluetrap6() on Cyrix 486-class CPU. The
978 * bluetrap6() set the magic number to trap_by_rdmsr.
979 */
980 setidt(IDT_UD, bluetrap6, SDT_SYS386TGT, SEL_KPL,
981 GSEL(GCODE_SEL, SEL_KPL));
982
983 /*
984 * Certain BIOS disables cpuid instruction of Cyrix 6x86MX CPU.
985 * In this case, rdmsr generates general protection fault, and
986 * exception will be trapped by bluetrap13().
987 */
988 setidt(IDT_GP, bluetrap13, SDT_SYS386TGT, SEL_KPL,
989 GSEL(GCODE_SEL, SEL_KPL));
990
991 rdmsr(0x1002); /* Cyrix CPU generates fault. */
992
993 if (trap_by_rdmsr == 0xa8c1d)
994 return IDENTBLUE_CYRIX486;
995 else if (trap_by_rdmsr == 0xa89c4)
996 return IDENTBLUE_CYRIXM2;
997 return IDENTBLUE_IBMCPU;
998 }
999
1000
1001 /*
1002 * identifycyrix() set lower 16 bits of cyrix_did as follows:
1003 *
1004 * F E D C B A 9 8 7 6 5 4 3 2 1 0
1005 * +-------+-------+---------------+
1006 * | SID | RID | Device ID |
1007 * | (DIR 1) | (DIR 0) |
1008 * +-------+-------+---------------+
1009 */
1010 static void
1011 identifycyrix(void)
1012 {
1013 u_int eflags;
1014 int ccr2_test = 0, dir_test = 0;
1015 u_char ccr2, ccr3;
1016
1017 eflags = read_eflags();
1018 disable_intr();
1019
1020 ccr2 = read_cyrix_reg(CCR2);
1021 write_cyrix_reg(CCR2, ccr2 ^ CCR2_LOCK_NW);
1022 read_cyrix_reg(CCR2);
1023 if (read_cyrix_reg(CCR2) != ccr2)
1024 ccr2_test = 1;
1025 write_cyrix_reg(CCR2, ccr2);
1026
1027 ccr3 = read_cyrix_reg(CCR3);
1028 write_cyrix_reg(CCR3, ccr3 ^ CCR3_MAPEN3);
1029 read_cyrix_reg(CCR3);
1030 if (read_cyrix_reg(CCR3) != ccr3)
1031 dir_test = 1; /* CPU supports DIRs. */
1032 write_cyrix_reg(CCR3, ccr3);
1033
1034 if (dir_test) {
1035 /* Device ID registers are available. */
1036 cyrix_did = read_cyrix_reg(DIR1) << 8;
1037 cyrix_did += read_cyrix_reg(DIR0);
1038 } else if (ccr2_test)
1039 cyrix_did = 0x0010; /* 486S A-step */
1040 else
1041 cyrix_did = 0x00ff; /* Old 486SLC/DLC and TI486SXLC/SXL */
1042
1043 write_eflags(eflags);
1044 }
1045
1046 /*
1047 * Final stage of CPU identification. -- Should I check TI?
1048 */
1049 void
1050 finishidentcpu(void)
1051 {
1052 int isblue = 0;
1053 u_char ccr3;
1054 u_int regs[4];
1055
1056 if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
1057 if (cpu == CPU_486) {
1058 /*
1059 * These conditions are equivalent to:
1060 * - CPU does not support cpuid instruction.
1061 * - Cyrix/IBM CPU is detected.
1062 */
1063 isblue = identblue();
1064 if (isblue == IDENTBLUE_IBMCPU) {
1065 strcpy(cpu_vendor, "IBM");
1066 cpu = CPU_BLUE;
1067 return;
1068 }
1069 }
1070 switch (cpu_id & 0xf00) {
1071 case 0x600:
1072 /*
1073 * Cyrix's datasheet does not describe DIRs.
1074 * Therefor, I assume it does not have them
1075 * and use the result of the cpuid instruction.
1076 * XXX they seem to have it for now at least. -Peter
1077 */
1078 identifycyrix();
1079 cpu = CPU_M2;
1080 break;
1081 default:
1082 identifycyrix();
1083 /*
1084 * This routine contains a trick.
1085 * Don't check (cpu_id & 0x00f0) == 0x50 to detect M2, now.
1086 */
1087 switch (cyrix_did & 0x00f0) {
1088 case 0x00:
1089 case 0xf0:
1090 cpu = CPU_486DLC;
1091 break;
1092 case 0x10:
1093 cpu = CPU_CY486DX;
1094 break;
1095 case 0x20:
1096 if ((cyrix_did & 0x000f) < 8)
1097 cpu = CPU_M1;
1098 else
1099 cpu = CPU_M1SC;
1100 break;
1101 case 0x30:
1102 cpu = CPU_M1;
1103 break;
1104 case 0x40:
1105 /* MediaGX CPU */
1106 cpu = CPU_M1SC;
1107 break;
1108 default:
1109 /* M2 and later CPUs are treated as M2. */
1110 cpu = CPU_M2;
1111
1112 /*
1113 * enable cpuid instruction.
1114 */
1115 ccr3 = read_cyrix_reg(CCR3);
1116 write_cyrix_reg(CCR3, CCR3_MAPEN0);
1117 write_cyrix_reg(CCR4, read_cyrix_reg(CCR4) | CCR4_CPUID);
1118 write_cyrix_reg(CCR3, ccr3);
1119
1120 do_cpuid(0, regs);
1121 cpu_high = regs[0]; /* eax */
1122 do_cpuid(1, regs);
1123 cpu_id = regs[0]; /* eax */
1124 cpu_feature = regs[3]; /* edx */
1125 break;
1126 }
1127 }
1128 } else if (cpu == CPU_486 && *cpu_vendor == '\0') {
1129 /*
1130 * There are BlueLightning CPUs that do not change
1131 * undefined flags by dividing 5 by 2. In this case,
1132 * the CPU identification routine in locore.s leaves
1133 * cpu_vendor null string and puts CPU_486 into the
1134 * cpu.
1135 */
1136 isblue = identblue();
1137 if (isblue == IDENTBLUE_IBMCPU) {
1138 strcpy(cpu_vendor, "IBM");
1139 cpu = CPU_BLUE;
1140 return;
1141 }
1142 }
1143 }
1144
1145 static void
1146 print_AMD_assoc(int i)
1147 {
1148 if (i == 255)
1149 printf(", fully associative\n");
1150 else
1151 printf(", %d-way associative\n", i);
1152 }
1153
1154 static void
1155 print_AMD_info(void)
1156 {
1157 quad_t amd_whcr;
1158
1159 if (cpu_exthigh >= 0x80000005) {
1160 u_int regs[4];
1161
1162 do_cpuid(0x80000005, regs);
1163 printf("Data TLB: %d entries", (regs[1] >> 16) & 0xff);
1164 print_AMD_assoc(regs[1] >> 24);
1165 printf("Instruction TLB: %d entries", regs[1] & 0xff);
1166 print_AMD_assoc((regs[1] >> 8) & 0xff);
1167 printf("L1 data cache: %d kbytes", regs[2] >> 24);
1168 printf(", %d bytes/line", regs[2] & 0xff);
1169 printf(", %d lines/tag", (regs[2] >> 8) & 0xff);
1170 print_AMD_assoc((regs[2] >> 16) & 0xff);
1171 printf("L1 instruction cache: %d kbytes", regs[3] >> 24);
1172 printf(", %d bytes/line", regs[3] & 0xff);
1173 printf(", %d lines/tag", (regs[3] >> 8) & 0xff);
1174 print_AMD_assoc((regs[3] >> 16) & 0xff);
1175 if (cpu_exthigh >= 0x80000006) { /* K6-III only */
1176 do_cpuid(0x80000006, regs);
1177 printf("L2 internal cache: %d kbytes", regs[2] >> 16);
1178 printf(", %d bytes/line", regs[2] & 0xff);
1179 printf(", %d lines/tag", (regs[2] >> 8) & 0x0f);
1180 print_AMD_assoc((regs[2] >> 12) & 0x0f);
1181 }
1182 }
1183 if (((cpu_id & 0xf00) == 0x500)
1184 && (((cpu_id & 0x0f0) > 0x80)
1185 || (((cpu_id & 0x0f0) == 0x80)
1186 && (cpu_id & 0x00f) > 0x07))) {
1187 /* K6-2(new core [Stepping 8-F]), K6-III or later */
1188 amd_whcr = rdmsr(0xc0000082);
1189 if (!(amd_whcr & (0x3ff << 22))) {
1190 printf("Write Allocate Disable\n");
1191 } else {
1192 printf("Write Allocate Enable Limit: %dM bytes\n",
1193 (u_int32_t)((amd_whcr & (0x3ff << 22)) >> 22) * 4);
1194 printf("Write Allocate 15-16M bytes: %s\n",
1195 (amd_whcr & (1 << 16)) ? "Enable" : "Disable");
1196 }
1197 } else if (((cpu_id & 0xf00) == 0x500)
1198 && ((cpu_id & 0x0f0) > 0x50)) {
1199 /* K6, K6-2(old core) */
1200 amd_whcr = rdmsr(0xc0000082);
1201 if (!(amd_whcr & (0x7f << 1))) {
1202 printf("Write Allocate Disable\n");
1203 } else {
1204 printf("Write Allocate Enable Limit: %dM bytes\n",
1205 (u_int32_t)((amd_whcr & (0x7f << 1)) >> 1) * 4);
1206 printf("Write Allocate 15-16M bytes: %s\n",
1207 (amd_whcr & 0x0001) ? "Enable" : "Disable");
1208 printf("Hardware Write Allocate Control: %s\n",
1209 (amd_whcr & 0x0100) ? "Enable" : "Disable");
1210 }
1211 }
1212 }
1213
1214 static void
1215 print_transmeta_info(void)
1216 {
1217 u_int regs[4], nreg = 0;
1218
1219 do_cpuid(0x80860000, regs);
1220 nreg = regs[0];
1221 if (nreg >= 0x80860001) {
1222 do_cpuid(0x80860001, regs);
1223 printf(" Processor revision %u.%u.%u.%u\n",
1224 (regs[1] >> 24) & 0xff,
1225 (regs[1] >> 16) & 0xff,
1226 (regs[1] >> 8) & 0xff,
1227 regs[1] & 0xff);
1228 }
1229 if (nreg >= 0x80860002) {
1230 do_cpuid(0x80860002, regs);
1231 printf(" Code Morphing Software revision %u.%u.%u-%u-%u\n",
1232 (regs[1] >> 24) & 0xff,
1233 (regs[1] >> 16) & 0xff,
1234 (regs[1] >> 8) & 0xff,
1235 regs[1] & 0xff,
1236 regs[2]);
1237 }
1238 if (nreg >= 0x80860006) {
1239 char info[65];
1240 do_cpuid(0x80860003, (u_int*) &info[0]);
1241 do_cpuid(0x80860004, (u_int*) &info[16]);
1242 do_cpuid(0x80860005, (u_int*) &info[32]);
1243 do_cpuid(0x80860006, (u_int*) &info[48]);
1244 info[64] = 0;
1245 printf(" %s\n", info);
1246 }
1247 }
1248
1249 static void
1250 print_via_padlock_info(void)
1251 {
1252 u_int regs[4];
1253
1254 /* Check for supported models. */
1255 switch (cpu_id & 0xff0) {
1256 case 0x690:
1257 if ((cpu_id & 0xf) < 3)
1258 return;
1259 case 0x6a0:
1260 case 0x6d0:
1261 break;
1262 default:
1263 return;
1264 }
1265
1266 do_cpuid(0xc0000000, regs);
1267 if (regs[0] >= 0xc0000001)
1268 do_cpuid(0xc0000001, regs);
1269 else
1270 return;
1271
1272 printf("\n VIA Padlock Features=0x%b", regs[3],
1273 "\020"
1274 "\003RNG" /* RNG */
1275 "\007AES" /* ACE */
1276 "\011AES-CTR" /* ACE2 */
1277 "\013SHA1,SHA256" /* PHE */
1278 "\015RSA" /* PMM */
1279 );
1280 }
Cache object: 3be71324e42e941bb3b66257fbd4fc63
|