1 /* $NetBSD: i386.c,v 1.14 2008/12/16 22:44:51 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Frank van der Linden, and by Jason R. Thorpe. 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 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /*- 33 * Copyright (c)2008 YAMAMOTO Takashi, 34 * All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 55 * SUCH DAMAGE. 56 */ 57 58 #include <sys/cdefs.h> 59 #ifndef lint 60 __RCSID("$NetBSD: i386.c,v 1.14 2008/12/16 22:44:51 christos Exp $"); 61 #endif /* not lint */ 62 63 #include <sys/types.h> 64 #include <sys/param.h> 65 #include <sys/bitops.h> 66 #include <sys/sysctl.h> 67 68 #include <string.h> 69 #include <stdio.h> 70 #include <stdlib.h> 71 #include <err.h> 72 #include <assert.h> 73 #include <math.h> 74 #include <util.h> 75 76 #include <machine/specialreg.h> 77 #include <machine/cpu.h> 78 79 #include <x86/cpuvar.h> 80 #include <x86/cputypes.h> 81 #include <x86/cacheinfo.h> 82 83 #include "../cpuctl.h" 84 85 /* Size of buffer for printing humanized numbers */ 86 #define HUMAN_BUFSIZE 5 87 88 #define x86_cpuid(a,b) x86_cpuid2((a),0,(b)) 89 90 void x86_cpuid2(uint32_t, uint32_t, uint32_t *); 91 void x86_identify(void); 92 93 struct cpu_info { 94 const char *ci_dev; 95 int32_t ci_cpuid_level; 96 uint32_t ci_signature; /* X86 cpuid type */ 97 uint32_t ci_feature_flags;/* X86 %edx CPUID feature bits */ 98 uint32_t ci_feature2_flags;/* X86 %ecx CPUID feature bits */ 99 uint32_t ci_feature3_flags;/* X86 extended %edx feature bits */ 100 uint32_t ci_feature4_flags;/* X86 extended %ecx feature bits */ 101 uint32_t ci_padlock_flags;/* VIA PadLock feature bits */ 102 uint32_t ci_cpu_class; /* CPU class */ 103 uint32_t ci_brand_id; /* Intel brand id */ 104 uint32_t ci_vendor[4]; /* vendor string */ 105 uint32_t ci_cpu_serial[3]; /* PIII serial number */ 106 uint64_t ci_tsc_freq; /* cpu cycles/second */ 107 uint8_t ci_packageid; 108 uint8_t ci_coreid; 109 uint8_t ci_smtid; 110 uint32_t ci_initapicid; 111 struct x86_cache_info ci_cinfo[CAI_COUNT]; 112 void (*ci_info)(struct cpu_info *); 113 }; 114 115 struct cpu_nocpuid_nameclass { 116 int cpu_vendor; 117 const char *cpu_vendorname; 118 const char *cpu_name; 119 int cpu_class; 120 void (*cpu_setup)(struct cpu_info *); 121 void (*cpu_cacheinfo)(struct cpu_info *); 122 void (*cpu_info)(struct cpu_info *); 123 }; 124 125 126 struct cpu_cpuid_nameclass { 127 const char *cpu_id; 128 int cpu_vendor; 129 const char *cpu_vendorname; 130 struct cpu_cpuid_family { 131 int cpu_class; 132 const char *cpu_models[CPU_MAXMODEL+2]; 133 void (*cpu_setup)(struct cpu_info *); 134 void (*cpu_probe)(struct cpu_info *); 135 void (*cpu_info)(struct cpu_info *); 136 } cpu_family[CPU_MAXFAMILY - CPU_MINFAMILY + 1]; 137 }; 138 139 static const struct x86_cache_info intel_cpuid_cache_info[] = INTEL_CACHE_INFO; 140 141 /* 142 * Map Brand ID from cpuid instruction to brand name. 143 * Source: Intel Processor Identification and the CPUID Instruction, AP-485 144 */ 145 static const char * const i386_intel_brand[] = { 146 "", /* Unsupported */ 147 "Celeron", /* Intel (R) Celeron (TM) processor */ 148 "Pentium III", /* Intel (R) Pentium (R) III processor */ 149 "Pentium III Xeon", /* Intel (R) Pentium (R) III Xeon (TM) processor */ 150 "Pentium III", /* Intel (R) Pentium (R) III processor */ 151 "", /* Reserved */ 152 "Mobile Pentium III", /* Mobile Intel (R) Pentium (R) III processor-M */ 153 "Mobile Celeron", /* Mobile Intel (R) Celeron (R) processor */ 154 "Pentium 4", /* Intel (R) Pentium (R) 4 processor */ 155 "Pentium 4", /* Intel (R) Pentium (R) 4 processor */ 156 "Celeron", /* Intel (R) Celeron (TM) processor */ 157 "Xeon", /* Intel (R) Xeon (TM) processor */ 158 "Xeon MP", /* Intel (R) Xeon (TM) processor MP */ 159 "", /* Reserved */ 160 "Mobile Pentium 4", /* Mobile Intel (R) Pentium (R) 4 processor-M */ 161 "Mobile Celeron", /* Mobile Intel (R) Celeron (R) processor */ 162 }; 163 164 /* 165 * AMD processors don't have Brand IDs, so we need these names for probe. 166 */ 167 static const char * const amd_brand[] = { 168 "", 169 "Duron", /* AMD Duron(tm) */ 170 "MP", /* AMD Athlon(tm) MP */ 171 "XP", /* AMD Athlon(tm) XP */ 172 "4" /* AMD Athlon(tm) 4 */ 173 }; 174 175 static int cpu_vendor; 176 static char cpu_brand_string[49]; 177 static char amd_brand_name[48]; 178 179 static void via_cpu_probe(struct cpu_info *); 180 static void amd_family6_probe(struct cpu_info *); 181 static void intel_family_new_probe(struct cpu_info *); 182 static const char *intel_family6_name(struct cpu_info *); 183 static const char *amd_amd64_name(struct cpu_info *); 184 static void amd_family5_setup(struct cpu_info *); 185 static void transmeta_cpu_info(struct cpu_info *); 186 static const char *print_cache_config(struct cpu_info *, int, const char *, 187 const char *); 188 static const char *print_tlb_config(struct cpu_info *, int, const char *, 189 const char *); 190 static void amd_cpu_cacheinfo(struct cpu_info *); 191 static void via_cpu_cacheinfo(struct cpu_info *); 192 static void x86_print_cacheinfo(struct cpu_info *); 193 static const struct x86_cache_info *cache_info_lookup( 194 const struct x86_cache_info *, uint8_t); 195 static void cyrix6x86_cpu_setup(struct cpu_info *); 196 static void winchip_cpu_setup(struct cpu_info *); 197 static void amd_family5_setup(struct cpu_info *); 198 static void powernow_probe(struct cpu_info *); 199 200 /* 201 * Info for CTL_HW 202 */ 203 static char cpu_model[120]; 204 205 /* 206 * Note: these are just the ones that may not have a cpuid instruction. 207 * We deal with the rest in a different way. 208 */ 209 const struct cpu_nocpuid_nameclass i386_nocpuid_cpus[] = { 210 { CPUVENDOR_INTEL, "Intel", "386SX", CPUCLASS_386, 211 NULL, NULL, NULL }, /* CPU_386SX */ 212 { CPUVENDOR_INTEL, "Intel", "386DX", CPUCLASS_386, 213 NULL, NULL, NULL }, /* CPU_386 */ 214 { CPUVENDOR_INTEL, "Intel", "486SX", CPUCLASS_486, 215 NULL, NULL, NULL }, /* CPU_486SX */ 216 { CPUVENDOR_INTEL, "Intel", "486DX", CPUCLASS_486, 217 NULL, NULL, NULL }, /* CPU_486 */ 218 { CPUVENDOR_CYRIX, "Cyrix", "486DLC", CPUCLASS_486, 219 NULL, NULL, NULL }, /* CPU_486DLC */ 220 { CPUVENDOR_CYRIX, "Cyrix", "6x86", CPUCLASS_486, 221 NULL, NULL, NULL }, /* CPU_6x86 */ 222 { CPUVENDOR_NEXGEN,"NexGen","586", CPUCLASS_386, 223 NULL, NULL, NULL }, /* CPU_NX586 */ 224 }; 225 226 const char *classnames[] = { 227 "386", 228 "486", 229 "586", 230 "686" 231 }; 232 233 const char *modifiers[] = { 234 "", 235 "OverDrive", 236 "Dual", 237 "" 238 }; 239 240 const struct cpu_cpuid_nameclass i386_cpuid_cpus[] = { 241 { 242 "GenuineIntel", 243 CPUVENDOR_INTEL, 244 "Intel", 245 /* Family 4 */ 246 { { 247 CPUCLASS_486, 248 { 249 "486DX", "486DX", "486SX", "486DX2", "486SL", 250 "486SX2", 0, "486DX2 W/B Enhanced", 251 "486DX4", 0, 0, 0, 0, 0, 0, 0, 252 "486" /* Default */ 253 }, 254 NULL, 255 NULL, 256 NULL, 257 }, 258 /* Family 5 */ 259 { 260 CPUCLASS_586, 261 { 262 "Pentium (P5 A-step)", "Pentium (P5)", 263 "Pentium (P54C)", "Pentium (P24T)", 264 "Pentium/MMX", "Pentium", 0, 265 "Pentium (P54C)", "Pentium/MMX (Tillamook)", 266 0, 0, 0, 0, 0, 0, 0, 267 "Pentium" /* Default */ 268 }, 269 NULL, 270 NULL, 271 NULL, 272 }, 273 /* Family 6 */ 274 { 275 CPUCLASS_686, 276 { 277 "Pentium Pro (A-step)", "Pentium Pro", 0, 278 "Pentium II (Klamath)", "Pentium Pro", 279 "Pentium II/Celeron (Deschutes)", 280 "Celeron (Mendocino)", 281 "Pentium III (Katmai)", 282 "Pentium III (Coppermine)", 283 "Pentium M (Banias)", 284 "Pentium III Xeon (Cascades)", 285 "Pentium III (Tualatin)", 0, 286 "Pentium M (Dothan)", 287 "Pentium M (Yonah)", 288 "Core 2 (Merom)", 289 "Pentium Pro, II or III" /* Default */ 290 }, 291 NULL, 292 intel_family_new_probe, 293 NULL, 294 }, 295 /* Family > 6 */ 296 { 297 CPUCLASS_686, 298 { 299 0, 0, 0, 0, 0, 0, 0, 0, 300 0, 0, 0, 0, 0, 0, 0, 0, 301 "Pentium 4" /* Default */ 302 }, 303 NULL, 304 intel_family_new_probe, 305 NULL, 306 } } 307 }, 308 { 309 "AuthenticAMD", 310 CPUVENDOR_AMD, 311 "AMD", 312 /* Family 4 */ 313 { { 314 CPUCLASS_486, 315 { 316 0, 0, 0, "Am486DX2 W/T", 317 0, 0, 0, "Am486DX2 W/B", 318 "Am486DX4 W/T or Am5x86 W/T 150", 319 "Am486DX4 W/B or Am5x86 W/B 150", 0, 0, 320 0, 0, "Am5x86 W/T 133/160", 321 "Am5x86 W/B 133/160", 322 "Am486 or Am5x86" /* Default */ 323 }, 324 NULL, 325 NULL, 326 NULL, 327 }, 328 /* Family 5 */ 329 { 330 CPUCLASS_586, 331 { 332 "K5", "K5", "K5", "K5", 0, 0, "K6", 333 "K6", "K6-2", "K6-III", "Geode LX", 0, 0, 334 "K6-2+/III+", 0, 0, 335 "K5 or K6" /* Default */ 336 }, 337 amd_family5_setup, 338 NULL, 339 amd_cpu_cacheinfo, 340 }, 341 /* Family 6 */ 342 { 343 CPUCLASS_686, 344 { 345 0, "Athlon Model 1", "Athlon Model 2", 346 "Duron", "Athlon Model 4 (Thunderbird)", 347 0, "Athlon", "Duron", "Athlon", 0, 348 "Athlon", 0, 0, 0, 0, 0, 349 "K7 (Athlon)" /* Default */ 350 }, 351 NULL, 352 amd_family6_probe, 353 amd_cpu_cacheinfo, 354 }, 355 /* Family > 6 */ 356 { 357 CPUCLASS_686, 358 { 359 0, 0, 0, 0, 0, 0, 0, 0, 360 0, 0, 0, 0, 0, 0, 0, 0, 361 "Unknown K8 (Athlon)" /* Default */ 362 }, 363 NULL, 364 amd_family6_probe, 365 amd_cpu_cacheinfo, 366 } } 367 }, 368 { 369 "CyrixInstead", 370 CPUVENDOR_CYRIX, 371 "Cyrix", 372 /* Family 4 */ 373 { { 374 CPUCLASS_486, 375 { 376 0, 0, 0, 377 "MediaGX", 378 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 379 "486" /* Default */ 380 }, 381 cyrix6x86_cpu_setup, /* XXX ?? */ 382 NULL, 383 NULL, 384 }, 385 /* Family 5 */ 386 { 387 CPUCLASS_586, 388 { 389 0, 0, "6x86", 0, 390 "MMX-enhanced MediaGX (GXm)", /* or Geode? */ 391 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 392 "6x86" /* Default */ 393 }, 394 cyrix6x86_cpu_setup, 395 NULL, 396 NULL, 397 }, 398 /* Family 6 */ 399 { 400 CPUCLASS_686, 401 { 402 "6x86MX", 0, 0, 0, 0, 0, 0, 0, 403 0, 0, 0, 0, 0, 0, 0, 0, 404 "6x86MX" /* Default */ 405 }, 406 cyrix6x86_cpu_setup, 407 NULL, 408 NULL, 409 }, 410 /* Family > 6 */ 411 { 412 CPUCLASS_686, 413 { 414 0, 0, 0, 0, 0, 0, 0, 0, 415 0, 0, 0, 0, 0, 0, 0, 0, 416 "Unknown 6x86MX" /* Default */ 417 }, 418 NULL, 419 NULL, 420 NULL, 421 } } 422 }, 423 { /* MediaGX is now owned by National Semiconductor */ 424 "Geode by NSC", 425 CPUVENDOR_CYRIX, /* XXX */ 426 "National Semiconductor", 427 /* Family 4, NSC never had any of these */ 428 { { 429 CPUCLASS_486, 430 { 431 0, 0, 0, 0, 0, 0, 0, 0, 432 0, 0, 0, 0, 0, 0, 0, 0, 433 "486 compatible" /* Default */ 434 }, 435 NULL, 436 NULL, 437 NULL, 438 }, 439 /* Family 5: Geode family, formerly MediaGX */ 440 { 441 CPUCLASS_586, 442 { 443 0, 0, 0, 0, 444 "Geode GX1", 445 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 446 "Geode" /* Default */ 447 }, 448 cyrix6x86_cpu_setup, 449 NULL, 450 amd_cpu_cacheinfo, 451 }, 452 /* Family 6, not yet available from NSC */ 453 { 454 CPUCLASS_686, 455 { 456 0, 0, 0, 0, 0, 0, 0, 0, 457 0, 0, 0, 0, 0, 0, 0, 0, 458 "Pentium Pro compatible" /* Default */ 459 }, 460 NULL, 461 NULL, 462 NULL, 463 }, 464 /* Family > 6, not yet available from NSC */ 465 { 466 CPUCLASS_686, 467 { 468 0, 0, 0, 0, 0, 0, 0, 0, 469 0, 0, 0, 0, 0, 0, 0, 0, 470 "Pentium Pro compatible" /* Default */ 471 }, 472 NULL, 473 NULL, 474 NULL, 475 } } 476 }, 477 { 478 "CentaurHauls", 479 CPUVENDOR_IDT, 480 "IDT", 481 /* Family 4, IDT never had any of these */ 482 { { 483 CPUCLASS_486, 484 { 485 0, 0, 0, 0, 0, 0, 0, 0, 486 0, 0, 0, 0, 0, 0, 0, 0, 487 "486 compatible" /* Default */ 488 }, 489 NULL, 490 NULL, 491 NULL, 492 }, 493 /* Family 5 */ 494 { 495 CPUCLASS_586, 496 { 497 0, 0, 0, 0, "WinChip C6", 0, 0, 0, 498 "WinChip 2", "WinChip 3", 0, 0, 0, 0, 0, 0, 499 "WinChip" /* Default */ 500 }, 501 winchip_cpu_setup, 502 NULL, 503 NULL, 504 }, 505 /* Family 6, VIA acquired IDT Centaur design subsidiary */ 506 { 507 CPUCLASS_686, 508 { 509 0, 0, 0, 0, 0, 0, "C3 Samuel", 510 "C3 Samuel 2/Ezra", "C3 Ezra-T", 511 "C3 Nehemiah", "C7 Esther", 0, 0, 0, 0, 0, 512 "C3" /* Default */ 513 }, 514 NULL, 515 via_cpu_probe, 516 via_cpu_cacheinfo, 517 }, 518 /* Family > 6, not yet available from VIA */ 519 { 520 CPUCLASS_686, 521 { 522 0, 0, 0, 0, 0, 0, 0, 0, 523 0, 0, 0, 0, 0, 0, 0, 0, 524 "Pentium Pro compatible" /* Default */ 525 }, 526 NULL, 527 NULL, 528 NULL, 529 } } 530 }, 531 { 532 "GenuineTMx86", 533 CPUVENDOR_TRANSMETA, 534 "Transmeta", 535 /* Family 4, Transmeta never had any of these */ 536 { { 537 CPUCLASS_486, 538 { 539 0, 0, 0, 0, 0, 0, 0, 0, 540 0, 0, 0, 0, 0, 0, 0, 0, 541 "486 compatible" /* Default */ 542 }, 543 NULL, 544 NULL, 545 NULL, 546 }, 547 /* Family 5 */ 548 { 549 CPUCLASS_586, 550 { 551 0, 0, 0, 0, 0, 0, 0, 0, 552 0, 0, 0, 0, 0, 0, 0, 0, 553 "Crusoe" /* Default */ 554 }, 555 NULL, 556 NULL, 557 transmeta_cpu_info, 558 }, 559 /* Family 6, not yet available from Transmeta */ 560 { 561 CPUCLASS_686, 562 { 563 0, 0, 0, 0, 0, 0, 0, 0, 564 0, 0, 0, 0, 0, 0, 0, 0, 565 "Pentium Pro compatible" /* Default */ 566 }, 567 NULL, 568 NULL, 569 NULL, 570 }, 571 /* Family > 6, not yet available from Transmeta */ 572 { 573 CPUCLASS_686, 574 { 575 0, 0, 0, 0, 0, 0, 0, 0, 576 0, 0, 0, 0, 0, 0, 0, 0, 577 "Pentium Pro compatible" /* Default */ 578 }, 579 NULL, 580 NULL, 581 NULL, 582 } } 583 } 584 }; 585 586 /* 587 * disable the TSC such that we don't use the TSC in microtime(9) 588 * because some CPUs got the implementation wrong. 589 */ 590 static void 591 disable_tsc(struct cpu_info *ci) 592 { 593 if (ci->ci_feature_flags & CPUID_TSC) { 594 ci->ci_feature_flags &= ~CPUID_TSC; 595 aprint_error("WARNING: broken TSC disabled\n"); 596 } 597 } 598 599 static void 600 cyrix6x86_cpu_setup(struct cpu_info *ci) 601 { 602 603 /* 604 * Do not disable the TSC on the Geode GX, it's reported to 605 * work fine. 606 */ 607 if (ci->ci_signature != 0x552) 608 disable_tsc(ci); 609 } 610 611 void 612 winchip_cpu_setup(struct cpu_info *ci) 613 { 614 switch (CPUID2MODEL(ci->ci_signature)) { /* model */ 615 case 4: /* WinChip C6 */ 616 disable_tsc(ci); 617 } 618 } 619 620 621 static void 622 identifycpu_cpuids(struct cpu_info *ci) 623 { 624 const char *cpuname = ci->ci_dev; 625 u_int lp_max = 1; /* logical processors per package */ 626 u_int smt_max; /* smt per core */ 627 u_int core_max = 1; /* core per package */ 628 int smt_bits, core_bits; 629 uint32_t descs[4]; 630 631 aprint_verbose("%s: Initial APIC ID %u\n", cpuname, ci->ci_initapicid); 632 ci->ci_packageid = ci->ci_initapicid; 633 ci->ci_coreid = 0; 634 ci->ci_smtid = 0; 635 if (cpu_vendor != CPUVENDOR_INTEL) { 636 return; 637 } 638 639 /* 640 * 253668.pdf 7.10.2 641 */ 642 643 if ((ci->ci_feature_flags & CPUID_HTT) != 0) { 644 x86_cpuid(1, descs); 645 lp_max = (descs[1] >> 16) & 0xff; 646 } 647 x86_cpuid(0, descs); 648 if (descs[0] >= 4) { 649 x86_cpuid2(4, 0, descs); 650 core_max = (descs[0] >> 26) + 1; 651 } 652 assert(lp_max >= core_max); 653 smt_max = lp_max / core_max; 654 smt_bits = ilog2(smt_max - 1) + 1; 655 core_bits = ilog2(core_max - 1) + 1; 656 if (smt_bits + core_bits) { 657 ci->ci_packageid = ci->ci_initapicid >> (smt_bits + core_bits); 658 } 659 aprint_verbose("%s: Cluster/Package ID %u\n", cpuname, 660 ci->ci_packageid); 661 if (core_bits) { 662 u_int core_mask = __BITS(smt_bits, smt_bits + core_bits - 1); 663 664 ci->ci_coreid = 665 __SHIFTOUT(ci->ci_initapicid, core_mask); 666 aprint_verbose("%s: Core ID %u\n", cpuname, ci->ci_coreid); 667 } 668 if (smt_bits) { 669 u_int smt_mask = __BITS(0, smt_bits - 1); 670 671 ci->ci_smtid = __SHIFTOUT(ci->ci_initapicid, smt_mask); 672 aprint_verbose("%s: SMT ID %u\n", cpuname, ci->ci_smtid); 673 } 674 } 675 676 static void 677 via_cpu_probe(struct cpu_info *ci) 678 { 679 u_int model = CPUID2MODEL(ci->ci_signature); 680 u_int stepping = CPUID2STEPPING(ci->ci_signature); 681 u_int descs[4]; 682 u_int lfunc; 683 684 /* 685 * Determine the largest extended function value. 686 */ 687 x86_cpuid(0x80000000, descs); 688 lfunc = descs[0]; 689 690 /* 691 * Determine the extended feature flags. 692 */ 693 if (lfunc >= 0x80000001) { 694 x86_cpuid(0x80000001, descs); 695 ci->ci_feature3_flags |= descs[3]; 696 } 697 698 if (model < 0x9) 699 return; 700 701 /* Nehemiah or Esther */ 702 x86_cpuid(0xc0000000, descs); 703 lfunc = descs[0]; 704 if (lfunc < 0xc0000001) /* no ACE, no RNG */ 705 return; 706 707 x86_cpuid(0xc0000001, descs); 708 lfunc = descs[3]; 709 if (model > 0x9 || stepping >= 8) { /* ACE */ 710 if (lfunc & CPUID_VIA_HAS_ACE) { 711 ci->ci_padlock_flags = lfunc; 712 } 713 } 714 } 715 716 static const char * 717 intel_family6_name(struct cpu_info *ci) 718 { 719 int model = CPUID2MODEL(ci->ci_signature); 720 const char *ret = NULL; 721 u_int l2cache = ci->ci_cinfo[CAI_L2CACHE].cai_totalsize; 722 723 if (model == 5) { 724 switch (l2cache) { 725 case 0: 726 case 128 * 1024: 727 ret = "Celeron (Covington)"; 728 break; 729 case 256 * 1024: 730 ret = "Mobile Pentium II (Dixon)"; 731 break; 732 case 512 * 1024: 733 ret = "Pentium II"; 734 break; 735 case 1 * 1024 * 1024: 736 case 2 * 1024 * 1024: 737 ret = "Pentium II Xeon"; 738 break; 739 } 740 } else if (model == 6) { 741 switch (l2cache) { 742 case 256 * 1024: 743 case 512 * 1024: 744 ret = "Mobile Pentium II"; 745 break; 746 } 747 } else if (model == 7) { 748 switch (l2cache) { 749 case 512 * 1024: 750 ret = "Pentium III"; 751 break; 752 case 1 * 1024 * 1024: 753 case 2 * 1024 * 1024: 754 ret = "Pentium III Xeon"; 755 break; 756 } 757 } else if (model >= 8) { 758 if (ci->ci_brand_id && ci->ci_brand_id < 0x10) { 759 switch (ci->ci_brand_id) { 760 case 0x3: 761 if (ci->ci_signature == 0x6B1) 762 ret = "Celeron"; 763 break; 764 case 0x8: 765 if (ci->ci_signature >= 0xF13) 766 ret = "genuine processor"; 767 break; 768 case 0xB: 769 if (ci->ci_signature >= 0xF13) 770 ret = "Xeon MP"; 771 break; 772 case 0xE: 773 if (ci->ci_signature < 0xF13) 774 ret = "Xeon"; 775 break; 776 } 777 if (ret == NULL) 778 ret = i386_intel_brand[ci->ci_brand_id]; 779 } 780 } 781 782 return ret; 783 } 784 785 /* 786 * Identify AMD64 CPU names from cpuid. 787 * 788 * Based on: 789 * "Revision Guide for AMD Athlon 64 and AMD Opteron Processors" 790 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25759.pdf 791 * "Revision Guide for AMD NPT Family 0Fh Processors" 792 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/33610.pdf 793 * and other miscellaneous reports. 794 */ 795 static const char * 796 amd_amd64_name(struct cpu_info *ci) 797 { 798 int extfamily, extmodel, model; 799 const char *ret = NULL; 800 801 model = CPUID2MODEL(ci->ci_signature); 802 extfamily = CPUID2EXTFAMILY(ci->ci_signature); 803 extmodel = CPUID2EXTMODEL(ci->ci_signature); 804 805 switch (extfamily) { 806 case 0x00: 807 switch (model) { 808 case 0x1: 809 switch (extmodel) { 810 case 0x2: /* rev JH-E1/E6 */ 811 case 0x4: /* rev JH-F2 */ 812 ret = "Dual-Core Opteron"; 813 break; 814 } 815 break; 816 case 0x3: 817 switch (extmodel) { 818 case 0x2: /* rev JH-E6 (Toledo) */ 819 ret = "Dual-Core Opteron or Athlon 64 X2"; 820 break; 821 case 0x4: /* rev JH-F2 (Windsor) */ 822 ret = "Athlon 64 FX or Athlon 64 X2"; 823 break; 824 } 825 break; 826 case 0x4: 827 switch (extmodel) { 828 case 0x0: /* rev SH-B0/C0/CG (ClawHammer) */ 829 case 0x1: /* rev SH-D0 */ 830 ret = "Athlon 64"; 831 break; 832 case 0x2: /* rev SH-E5 (Lancaster?) */ 833 ret = "Mobile Athlon 64 or Turion 64"; 834 break; 835 } 836 break; 837 case 0x5: 838 switch (extmodel) { 839 case 0x0: /* rev SH-B0/B3/C0/CG (SledgeHammer?) */ 840 ret = "Opteron or Athlon 64 FX"; 841 break; 842 case 0x1: /* rev SH-D0 */ 843 case 0x2: /* rev SH-E4 */ 844 ret = "Opteron"; 845 break; 846 } 847 break; 848 case 0x7: 849 switch (extmodel) { 850 case 0x0: /* rev SH-CG (ClawHammer) */ 851 case 0x1: /* rev SH-D0 */ 852 ret = "Athlon 64"; 853 break; 854 case 0x2: /* rev DH-E4, SH-E4 */ 855 ret = "Athlon 64 or Athlon 64 FX or Opteron"; 856 break; 857 } 858 break; 859 case 0x8: 860 switch (extmodel) { 861 case 0x0: /* rev CH-CG */ 862 case 0x1: /* rev CH-D0 */ 863 ret = "Athlon 64 or Sempron"; 864 break; 865 case 0x4: /* rev BH-F2 */ 866 ret = "Turion 64 X2"; 867 break; 868 } 869 break; 870 case 0xb: 871 switch (extmodel) { 872 case 0x0: /* rev CH-CG */ 873 case 0x1: /* rev CH-D0 */ 874 ret = "Athlon 64"; 875 break; 876 case 0x2: /* rev BH-E4 (Manchester) */ 877 case 0x4: /* rev BH-F2 (Windsor) */ 878 ret = "Athlon 64 X2"; 879 break; 880 case 0x6: /* rev BH-G1 (Brisbane) */ 881 ret = "Athlon X2 or Athlon 64 X2"; 882 break; 883 } 884 break; 885 case 0xc: 886 switch (extmodel) { 887 case 0x0: /* rev DH-CG (Newcastle) */ 888 case 0x1: /* rev DH-D0 (Winchester) */ 889 case 0x2: /* rev DH-E3/E6 */ 890 ret = "Athlon 64 or Sempron"; 891 break; 892 } 893 break; 894 case 0xe: 895 switch (extmodel) { 896 case 0x0: /* rev DH-CG (Newcastle?) */ 897 ret = "Athlon 64 or Sempron"; 898 break; 899 } 900 break; 901 case 0xf: 902 switch (extmodel) { 903 case 0x0: /* rev DH-CG (Newcastle/Paris) */ 904 case 0x1: /* rev DH-D0 (Winchester/Victoria) */ 905 case 0x2: /* rev DH-E3/E6 (Venice/Palermo) */ 906 case 0x4: /* rev DH-F2 (Orleans/Manila) */ 907 case 0x5: /* rev DH-F2 (Orleans/Manila) */ 908 case 0x6: /* rev DH-G1 */ 909 ret = "Athlon 64 or Sempron"; 910 break; 911 } 912 break; 913 default: 914 ret = "Unknown AMD64 CPU"; 915 } 916 break; 917 case 0x01: 918 switch (model) { 919 case 0x02: 920 ret = "Family 10h"; 921 break; 922 default: 923 ret = "Unknown AMD64 CPU"; 924 break; 925 } 926 break; 927 } 928 929 return ret; 930 } 931 932 static void 933 cpu_probe_base_features(struct cpu_info *ci) 934 { 935 const struct x86_cache_info *cai; 936 u_int descs[4]; 937 int iterations, i, j; 938 uint8_t desc; 939 uint32_t miscbytes; 940 uint32_t brand[12]; 941 942 if (ci->ci_cpuid_level < 0) 943 return; 944 945 x86_cpuid(0, descs); 946 ci->ci_cpuid_level = descs[0]; 947 ci->ci_vendor[0] = descs[1]; 948 ci->ci_vendor[2] = descs[2]; 949 ci->ci_vendor[1] = descs[3]; 950 ci->ci_vendor[3] = 0; 951 952 x86_cpuid(0x80000000, brand); 953 if (brand[0] >= 0x80000004) { 954 x86_cpuid(0x80000002, brand); 955 x86_cpuid(0x80000003, brand + 4); 956 x86_cpuid(0x80000004, brand + 8); 957 for (i = 0; i < 48; i++) 958 if (((char *) brand)[i] != ' ') 959 break; 960 memcpy(cpu_brand_string, ((char *) brand) + i, 48 - i); 961 } 962 963 if (ci->ci_cpuid_level < 1) 964 return; 965 966 x86_cpuid(1, descs); 967 ci->ci_signature = descs[0]; 968 miscbytes = descs[1]; 969 ci->ci_feature2_flags = descs[2]; 970 ci->ci_feature_flags = descs[3]; 971 972 /* Brand is low order 8 bits of ebx */ 973 ci->ci_brand_id = miscbytes & 0xff; 974 ci->ci_initapicid = (miscbytes >> 24) & 0xff; 975 if (ci->ci_cpuid_level < 2) 976 return; 977 978 /* 979 * Parse the cache info from `cpuid', if we have it. 980 * XXX This is kinda ugly, but hey, so is the architecture... 981 */ 982 983 x86_cpuid(2, descs); 984 985 iterations = descs[0] & 0xff; 986 while (iterations-- > 0) { 987 for (i = 0; i < 4; i++) { 988 if (descs[i] & 0x80000000) 989 continue; 990 for (j = 0; j < 4; j++) { 991 if (i == 0 && j == 0) 992 continue; 993 desc = (descs[i] >> (j * 8)) & 0xff; 994 if (desc == 0) 995 continue; 996 cai = cache_info_lookup(intel_cpuid_cache_info, 997 desc); 998 if (cai != NULL) 999 ci->ci_cinfo[cai->cai_index] = *cai; 1000 } 1001 } 1002 x86_cpuid(2, descs); 1003 } 1004 1005 if (ci->ci_cpuid_level < 3) 1006 return; 1007 1008 /* 1009 * If the processor serial number misfeature is present and supported, 1010 * extract it here. 1011 */ 1012 if ((ci->ci_feature_flags & CPUID_PN) != 0) { 1013 ci->ci_cpu_serial[0] = ci->ci_signature; 1014 x86_cpuid(3, descs); 1015 ci->ci_cpu_serial[2] = descs[2]; 1016 ci->ci_cpu_serial[1] = descs[3]; 1017 } 1018 } 1019 1020 static void 1021 cpu_probe_features(struct cpu_info *ci) 1022 { 1023 const struct cpu_cpuid_nameclass *cpup = NULL; 1024 int i, xmax, family; 1025 1026 cpu_probe_base_features(ci); 1027 1028 if (ci->ci_cpuid_level < 1) 1029 return; 1030 1031 xmax = __arraycount(i386_cpuid_cpus); 1032 for (i = 0; i < xmax; i++) { 1033 if (!strncmp((char *)ci->ci_vendor, 1034 i386_cpuid_cpus[i].cpu_id, 12)) { 1035 cpup = &i386_cpuid_cpus[i]; 1036 break; 1037 } 1038 } 1039 1040 if (cpup == NULL) 1041 return; 1042 1043 family = (ci->ci_signature >> 8) & 0xf; 1044 1045 if (family > CPU_MAXFAMILY) { 1046 family = CPU_MAXFAMILY; 1047 } 1048 i = family - CPU_MINFAMILY; 1049 1050 if (cpup->cpu_family[i].cpu_probe == NULL) 1051 return; 1052 1053 (*cpup->cpu_family[i].cpu_probe)(ci); 1054 } 1055 1056 static void 1057 intel_family_new_probe(struct cpu_info *ci) 1058 { 1059 uint32_t descs[4]; 1060 1061 x86_cpuid(0x80000000, descs); 1062 1063 /* 1064 * Determine extended feature flags. 1065 */ 1066 if (descs[0] >= 0x80000001) { 1067 x86_cpuid(0x80000001, descs); 1068 ci->ci_feature3_flags |= descs[3]; 1069 } 1070 } 1071 1072 static void 1073 amd_family6_probe(struct cpu_info *ci) 1074 { 1075 uint32_t descs[4]; 1076 char *p; 1077 int i; 1078 1079 x86_cpuid(0x80000000, descs); 1080 1081 /* 1082 * Determine the extended feature flags. 1083 */ 1084 if (descs[0] >= 0x80000001) { 1085 x86_cpuid(0x80000001, descs); 1086 ci->ci_feature3_flags |= descs[3]; /* %edx */ 1087 ci->ci_feature4_flags = descs[2]; /* %ecx */ 1088 } 1089 1090 if (*cpu_brand_string == '\0') 1091 return; 1092 1093 for (i = 1; i < __arraycount(amd_brand); i++) 1094 if ((p = strstr(cpu_brand_string, amd_brand[i])) != NULL) { 1095 ci->ci_brand_id = i; 1096 strlcpy(amd_brand_name, p, sizeof(amd_brand_name)); 1097 break; 1098 } 1099 } 1100 1101 static void 1102 amd_family5_setup(struct cpu_info *ci) 1103 { 1104 1105 switch (CPUID2MODEL(ci->ci_signature)) { 1106 case 0: /* AMD-K5 Model 0 */ 1107 /* 1108 * According to the AMD Processor Recognition App Note, 1109 * the AMD-K5 Model 0 uses the wrong bit to indicate 1110 * support for global PTEs, instead using bit 9 (APIC) 1111 * rather than bit 13 (i.e. "0x200" vs. 0x2000". Oops!). 1112 */ 1113 if (ci->ci_feature_flags & CPUID_APIC) 1114 ci->ci_feature_flags = (ci->ci_feature_flags & ~CPUID_APIC) | CPUID_PGE; 1115 /* 1116 * XXX But pmap_pg_g is already initialized -- need to kick 1117 * XXX the pmap somehow. How does the MP branch do this? 1118 */ 1119 break; 1120 } 1121 } 1122 1123 static void 1124 tmx86_get_longrun_status(u_int *frequency, u_int *voltage, u_int *percentage) 1125 { 1126 u_int descs[4]; 1127 1128 x86_cpuid(0x80860007, descs); 1129 *frequency = descs[0]; 1130 *voltage = descs[1]; 1131 *percentage = descs[2]; 1132 } 1133 1134 static void 1135 transmeta_cpu_info(struct cpu_info *ci) 1136 { 1137 u_int descs[4], nreg; 1138 u_int frequency, voltage, percentage; 1139 1140 x86_cpuid(0x80860000, descs); 1141 nreg = descs[0]; 1142 if (nreg >= 0x80860001) { 1143 x86_cpuid(0x80860001, descs); 1144 aprint_verbose_dev(ci->ci_dev, "Processor revision %u.%u.%u.%u\n", 1145 (descs[1] >> 24) & 0xff, 1146 (descs[1] >> 16) & 0xff, 1147 (descs[1] >> 8) & 0xff, 1148 descs[1] & 0xff); 1149 } 1150 if (nreg >= 0x80860002) { 1151 x86_cpuid(0x80860002, descs); 1152 aprint_verbose_dev(ci->ci_dev, "Code Morphing Software Rev: %u.%u.%u-%u-%u\n", 1153 (descs[1] >> 24) & 0xff, 1154 (descs[1] >> 16) & 0xff, 1155 (descs[1] >> 8) & 0xff, 1156 descs[1] & 0xff, 1157 descs[2]); 1158 } 1159 if (nreg >= 0x80860006) { 1160 union { 1161 char text[65]; 1162 u_int descs[4][4]; 1163 } info; 1164 int i; 1165 1166 for (i=0; i<4; i++) { 1167 x86_cpuid(0x80860003 + i, info.descs[i]); 1168 } 1169 info.text[64] = '\0'; 1170 aprint_verbose_dev(ci->ci_dev, "%s\n", info.text); 1171 } 1172 1173 if (nreg >= 0x80860007) { 1174 tmx86_get_longrun_status(&frequency, 1175 &voltage, &percentage); 1176 aprint_verbose_dev(ci->ci_dev, "LongRun <%dMHz %dmV %d%%>\n", 1177 frequency, voltage, percentage); 1178 } 1179 } 1180 1181 void 1182 identifycpu(const char *cpuname) 1183 { 1184 const char *name, *modifier, *vendorname, *brand = ""; 1185 int class = CPUCLASS_386, i, xmax; 1186 int modif, family, model; 1187 const struct cpu_cpuid_nameclass *cpup = NULL; 1188 const struct cpu_cpuid_family *cpufam; 1189 const char *feature_str[5]; 1190 struct cpu_info *ci, cistore; 1191 extern int cpu; 1192 extern int cpu_info_level; 1193 size_t sz; 1194 char buf[256]; 1195 1196 ci = &cistore; 1197 memset(ci, 0, sizeof(*ci)); 1198 ci->ci_dev = cpuname; 1199 1200 x86_identify(); 1201 ci->ci_cpuid_level = cpu_info_level; 1202 cpu_probe_features(ci); 1203 1204 if (ci->ci_cpuid_level == -1) { 1205 if (cpu < 0 || cpu >= __arraycount(i386_nocpuid_cpus)) 1206 errx(1, "unknown cpu type %d", cpu); 1207 name = i386_nocpuid_cpus[cpu].cpu_name; 1208 cpu_vendor = i386_nocpuid_cpus[cpu].cpu_vendor; 1209 vendorname = i386_nocpuid_cpus[cpu].cpu_vendorname; 1210 class = i386_nocpuid_cpus[cpu].cpu_class; 1211 ci->ci_info = i386_nocpuid_cpus[cpu].cpu_info; 1212 modifier = ""; 1213 } else { 1214 xmax = __arraycount(i386_cpuid_cpus); 1215 modif = (ci->ci_signature >> 12) & 0x3; 1216 family = CPUID2FAMILY(ci->ci_signature); 1217 if (family < CPU_MINFAMILY) 1218 errx(1, "identifycpu: strange family value"); 1219 model = CPUID2MODEL(ci->ci_signature); 1220 1221 for (i = 0; i < xmax; i++) { 1222 if (!strncmp((char *)ci->ci_vendor, 1223 i386_cpuid_cpus[i].cpu_id, 12)) { 1224 cpup = &i386_cpuid_cpus[i]; 1225 break; 1226 } 1227 } 1228 1229 if (cpup == NULL) { 1230 cpu_vendor = CPUVENDOR_UNKNOWN; 1231 if (ci->ci_vendor[0] != '\0') 1232 vendorname = (char *)&ci->ci_vendor[0]; 1233 else 1234 vendorname = "Unknown"; 1235 if (family >= CPU_MAXFAMILY) 1236 family = CPU_MINFAMILY; 1237 class = family - 3; 1238 modifier = ""; 1239 name = ""; 1240 ci->ci_info = NULL; 1241 } else { 1242 cpu_vendor = cpup->cpu_vendor; 1243 vendorname = cpup->cpu_vendorname; 1244 modifier = modifiers[modif]; 1245 if (family > CPU_MAXFAMILY) { 1246 family = CPU_MAXFAMILY; 1247 model = CPU_DEFMODEL; 1248 } else if (model > CPU_MAXMODEL) 1249 model = CPU_DEFMODEL; 1250 cpufam = &cpup->cpu_family[family - CPU_MINFAMILY]; 1251 name = cpufam->cpu_models[model]; 1252 if (name == NULL) 1253 name = cpufam->cpu_models[CPU_DEFMODEL]; 1254 class = cpufam->cpu_class; 1255 ci->ci_info = cpufam->cpu_info; 1256 1257 if (cpu_vendor == CPUVENDOR_INTEL) { 1258 if (family == 6 && model >= 5) { 1259 const char *tmp; 1260 tmp = intel_family6_name(ci); 1261 if (tmp != NULL) 1262 name = tmp; 1263 } 1264 if (family == CPU_MAXFAMILY && 1265 ci->ci_brand_id < 1266 __arraycount(i386_intel_brand) && 1267 i386_intel_brand[ci->ci_brand_id]) 1268 name = 1269 i386_intel_brand[ci->ci_brand_id]; 1270 } 1271 1272 if (cpu_vendor == CPUVENDOR_AMD) { 1273 if (family == 6 && model >= 6) { 1274 if (ci->ci_brand_id == 1) 1275 /* 1276 * It's Duron. We override the 1277 * name, since it might have 1278 * been misidentified as Athlon. 1279 */ 1280 name = 1281 amd_brand[ci->ci_brand_id]; 1282 else 1283 brand = amd_brand_name; 1284 } 1285 if (CPUID2FAMILY(ci->ci_signature) == 0xf) { 1286 /* 1287 * Identify AMD64 CPU names. 1288 * Note family value is clipped by 1289 * CPU_MAXFAMILY. 1290 */ 1291 const char *tmp; 1292 tmp = amd_amd64_name(ci); 1293 if (tmp != NULL) 1294 name = tmp; 1295 } 1296 } 1297 1298 if (cpu_vendor == CPUVENDOR_IDT && family >= 6) 1299 vendorname = "VIA"; 1300 } 1301 } 1302 1303 ci->ci_cpu_class = class; 1304 1305 sz = sizeof(ci->ci_tsc_freq); 1306 (void)sysctlbyname("machdep.tsc_freq", &ci->ci_tsc_freq, &sz, NULL, 0); 1307 1308 snprintf(cpu_model, sizeof(cpu_model), "%s%s%s%s%s%s%s (%s-class)", 1309 vendorname, 1310 *modifier ? " " : "", modifier, 1311 *name ? " " : "", name, 1312 *brand ? " " : "", brand, 1313 classnames[class]); 1314 aprint_normal("%s: %s", cpuname, cpu_model); 1315 1316 if (ci->ci_tsc_freq != 0) 1317 aprint_normal(", %qd.%02qd MHz", 1318 (ci->ci_tsc_freq + 4999) / 1000000, 1319 ((ci->ci_tsc_freq + 4999) / 10000) % 100); 1320 if (ci->ci_signature != 0) 1321 aprint_normal(", id 0x%x", ci->ci_signature); 1322 aprint_normal("\n"); 1323 1324 if (ci->ci_info) 1325 (*ci->ci_info)(ci); 1326 1327 feature_str[0] = CPUID_FLAGS1; 1328 feature_str[1] = CPUID_FLAGS2; 1329 feature_str[2] = CPUID_FLAGS3; 1330 1331 switch (cpu_vendor) { 1332 case CPUVENDOR_AMD: 1333 feature_str[3] = CPUID_EXT_FLAGS; 1334 feature_str[4] = CPUID_AMD_FLAGS4; 1335 break; 1336 case CPUVENDOR_INTEL: 1337 feature_str[3] = CPUID_INTEL_FLAGS4; 1338 break; 1339 default: 1340 feature_str[3] = CPUID_EXT_FLAGS; 1341 break; 1342 } 1343 1344 if (ci->ci_feature_flags) { 1345 if ((ci->ci_feature_flags & CPUID_MASK1) != 0) { 1346 snprintb(buf, sizeof(buf), feature_str[0], 1347 ci->ci_feature_flags); 1348 aprint_verbose("%s: features %s\n", cpuname, buf); 1349 } 1350 if ((ci->ci_feature_flags & CPUID_MASK2) != 0) { 1351 snprintb(buf, sizeof(buf), feature_str[1], 1352 ci->ci_feature_flags); 1353 aprint_verbose("%s: features %s\n", cpuname, buf); 1354 } 1355 if ((ci->ci_feature_flags & CPUID_MASK3) != 0) { 1356 snprintb(buf, sizeof(buf), feature_str[2], 1357 ci->ci_feature_flags); 1358 aprint_verbose("%s: features %s\n", cpuname, buf); 1359 } 1360 } 1361 1362 if (ci->ci_feature2_flags) { 1363 snprintb(buf, sizeof(buf), CPUID2_FLAGS, ci->ci_feature2_flags); 1364 aprint_verbose("%s: features2 %s\n", cpuname, buf); 1365 } 1366 1367 if (ci->ci_feature3_flags) { 1368 snprintb(buf, sizeof(buf), feature_str[3], 1369 ci->ci_feature3_flags); 1370 aprint_verbose("%s: features3 %s\n", cpuname, buf); 1371 } 1372 1373 if (ci->ci_feature4_flags) { 1374 snprintb(buf, sizeof(buf), feature_str[4], 1375 ci->ci_feature4_flags); 1376 aprint_verbose("%s: features4 %s\n", cpuname, buf); 1377 } 1378 1379 if (ci->ci_padlock_flags) { 1380 snprintb(buf, sizeof(buf), CPUID_FLAGS_PADLOCK, 1381 ci->ci_padlock_flags); 1382 aprint_verbose("%s: padlock features %s\n", cpuname, buf); 1383 } 1384 1385 if (*cpu_brand_string != '\0') 1386 aprint_normal("%s: \"%s\"\n", cpuname, cpu_brand_string); 1387 1388 x86_print_cacheinfo(ci); 1389 1390 if (ci->ci_cpuid_level >= 3 && (ci->ci_feature_flags & CPUID_PN)) { 1391 aprint_verbose("%s: serial number %04X-%04X-%04X-%04X-%04X-%04X\n", 1392 cpuname, 1393 ci->ci_cpu_serial[0] / 65536, ci->ci_cpu_serial[0] % 65536, 1394 ci->ci_cpu_serial[1] / 65536, ci->ci_cpu_serial[1] % 65536, 1395 ci->ci_cpu_serial[2] / 65536, ci->ci_cpu_serial[2] % 65536); 1396 } 1397 1398 if (ci->ci_cpu_class == CPUCLASS_386) { 1399 errx(1, "NetBSD requires an 80486 or later processor"); 1400 } 1401 1402 if (cpu == CPU_486DLC) { 1403 #ifndef CYRIX_CACHE_WORKS 1404 aprint_error("WARNING: CYRIX 486DLC CACHE UNCHANGED.\n"); 1405 #else 1406 #ifndef CYRIX_CACHE_REALLY_WORKS 1407 aprint_error("WARNING: CYRIX 486DLC CACHE ENABLED IN HOLD-FLUSH MODE.\n"); 1408 #else 1409 aprint_error("WARNING: CYRIX 486DLC CACHE ENABLED.\n"); 1410 #endif 1411 #endif 1412 } 1413 1414 /* 1415 * Everything past this point requires a Pentium or later. 1416 */ 1417 if (ci->ci_cpuid_level < 0) 1418 return; 1419 1420 identifycpu_cpuids(ci); 1421 1422 #ifdef INTEL_CORETEMP 1423 if (cpu_vendor == CPUVENDOR_INTEL && ci->ci_cpuid_level >= 0x06) 1424 coretemp_register(ci); 1425 #endif 1426 1427 if (cpu_vendor == CPUVENDOR_AMD) { 1428 powernow_probe(ci); 1429 } 1430 1431 #ifdef INTEL_ONDEMAND_CLOCKMOD 1432 clockmod_init(); 1433 #endif 1434 1435 aprint_normal_dev(ci->ci_dev, "family %02x model %02x " 1436 "extfamily %02x extmodel %02x\n", CPUID2FAMILY(ci->ci_signature), 1437 CPUID2MODEL(ci->ci_signature), CPUID2EXTFAMILY(ci->ci_signature), 1438 CPUID2EXTMODEL(ci->ci_signature)); 1439 } 1440 1441 static const char * 1442 print_cache_config(struct cpu_info *ci, int cache_tag, const char *name, 1443 const char *sep) 1444 { 1445 struct x86_cache_info *cai = &ci->ci_cinfo[cache_tag]; 1446 char human_num[HUMAN_BUFSIZE]; 1447 1448 if (cai->cai_totalsize == 0) 1449 return sep; 1450 1451 if (sep == NULL) 1452 aprint_verbose_dev(ci->ci_dev, ""); 1453 else 1454 aprint_verbose("%s", sep); 1455 if (name != NULL) 1456 aprint_verbose("%s ", name); 1457 1458 if (cai->cai_string != NULL) { 1459 aprint_verbose("%s ", cai->cai_string); 1460 } else { 1461 (void)humanize_number(human_num, sizeof(human_num), 1462 cai->cai_totalsize, "B", HN_AUTOSCALE, HN_NOSPACE); 1463 aprint_verbose("%s %dB/line ", human_num, cai->cai_linesize); 1464 } 1465 switch (cai->cai_associativity) { 1466 case 0: 1467 aprint_verbose("disabled"); 1468 break; 1469 case 1: 1470 aprint_verbose("direct-mapped"); 1471 break; 1472 case 0xff: 1473 aprint_verbose("fully associative"); 1474 break; 1475 default: 1476 aprint_verbose("%d-way", cai->cai_associativity); 1477 break; 1478 } 1479 return ", "; 1480 } 1481 1482 static const char * 1483 print_tlb_config(struct cpu_info *ci, int cache_tag, const char *name, 1484 const char *sep) 1485 { 1486 struct x86_cache_info *cai = &ci->ci_cinfo[cache_tag]; 1487 char human_num[HUMAN_BUFSIZE]; 1488 1489 if (cai->cai_totalsize == 0) 1490 return sep; 1491 1492 if (sep == NULL) 1493 aprint_verbose_dev(ci->ci_dev, ""); 1494 else 1495 aprint_verbose("%s", sep); 1496 if (name != NULL) 1497 aprint_verbose("%s ", name); 1498 1499 if (cai->cai_string != NULL) { 1500 aprint_verbose("%s", cai->cai_string); 1501 } else { 1502 (void)humanize_number(human_num, sizeof(human_num), 1503 cai->cai_linesize, "B", HN_AUTOSCALE, HN_NOSPACE); 1504 aprint_verbose("%d %s entries ", cai->cai_totalsize, 1505 human_num); 1506 switch (cai->cai_associativity) { 1507 case 0: 1508 aprint_verbose("disabled"); 1509 break; 1510 case 1: 1511 aprint_verbose("direct-mapped"); 1512 break; 1513 case 0xff: 1514 aprint_verbose("fully associative"); 1515 break; 1516 default: 1517 aprint_verbose("%d-way", cai->cai_associativity); 1518 break; 1519 } 1520 } 1521 return ", "; 1522 } 1523 1524 static const struct x86_cache_info * 1525 cache_info_lookup(const struct x86_cache_info *cai, uint8_t desc) 1526 { 1527 int i; 1528 1529 for (i = 0; cai[i].cai_desc != 0; i++) { 1530 if (cai[i].cai_desc == desc) 1531 return (&cai[i]); 1532 } 1533 1534 return (NULL); 1535 } 1536 1537 static const struct x86_cache_info amd_cpuid_l2cache_assoc_info[] = 1538 AMD_L2CACHE_INFO; 1539 1540 static const struct x86_cache_info amd_cpuid_l3cache_assoc_info[] = 1541 AMD_L3CACHE_INFO; 1542 1543 static void 1544 amd_cpu_cacheinfo(struct cpu_info *ci) 1545 { 1546 const struct x86_cache_info *cp; 1547 struct x86_cache_info *cai; 1548 int family, model; 1549 u_int descs[4]; 1550 u_int lfunc; 1551 1552 family = (ci->ci_signature >> 8) & 15; 1553 model = CPUID2MODEL(ci->ci_signature); 1554 1555 /* 1556 * K5 model 0 has none of this info. 1557 */ 1558 if (family == 5 && model == 0) 1559 return; 1560 1561 /* 1562 * Get extended values for K8 and up. 1563 */ 1564 if (family == 0xf) { 1565 family += CPUID2EXTFAMILY(ci->ci_signature); 1566 model += CPUID2EXTMODEL(ci->ci_signature); 1567 } 1568 1569 /* 1570 * Determine the largest extended function value. 1571 */ 1572 x86_cpuid(0x80000000, descs); 1573 lfunc = descs[0]; 1574 1575 /* 1576 * Determine L1 cache/TLB info. 1577 */ 1578 if (lfunc < 0x80000005) { 1579 /* No L1 cache info available. */ 1580 return; 1581 } 1582 1583 x86_cpuid(0x80000005, descs); 1584 1585 /* 1586 * K6-III and higher have large page TLBs. 1587 */ 1588 if ((family == 5 && model >= 9) || family >= 6) { 1589 cai = &ci->ci_cinfo[CAI_ITLB2]; 1590 cai->cai_totalsize = AMD_L1_EAX_ITLB_ENTRIES(descs[0]); 1591 cai->cai_associativity = AMD_L1_EAX_ITLB_ASSOC(descs[0]); 1592 cai->cai_linesize = (4 * 1024 * 1024); 1593 1594 cai = &ci->ci_cinfo[CAI_DTLB2]; 1595 cai->cai_totalsize = AMD_L1_EAX_DTLB_ENTRIES(descs[0]); 1596 cai->cai_associativity = AMD_L1_EAX_DTLB_ASSOC(descs[0]); 1597 cai->cai_linesize = (4 * 1024 * 1024); 1598 } 1599 1600 cai = &ci->ci_cinfo[CAI_ITLB]; 1601 cai->cai_totalsize = AMD_L1_EBX_ITLB_ENTRIES(descs[1]); 1602 cai->cai_associativity = AMD_L1_EBX_ITLB_ASSOC(descs[1]); 1603 cai->cai_linesize = (4 * 1024); 1604 1605 cai = &ci->ci_cinfo[CAI_DTLB]; 1606 cai->cai_totalsize = AMD_L1_EBX_DTLB_ENTRIES(descs[1]); 1607 cai->cai_associativity = AMD_L1_EBX_DTLB_ASSOC(descs[1]); 1608 cai->cai_linesize = (4 * 1024); 1609 1610 cai = &ci->ci_cinfo[CAI_DCACHE]; 1611 cai->cai_totalsize = AMD_L1_ECX_DC_SIZE(descs[2]); 1612 cai->cai_associativity = AMD_L1_ECX_DC_ASSOC(descs[2]); 1613 cai->cai_linesize = AMD_L1_EDX_IC_LS(descs[2]); 1614 1615 cai = &ci->ci_cinfo[CAI_ICACHE]; 1616 cai->cai_totalsize = AMD_L1_EDX_IC_SIZE(descs[3]); 1617 cai->cai_associativity = AMD_L1_EDX_IC_ASSOC(descs[3]); 1618 cai->cai_linesize = AMD_L1_EDX_IC_LS(descs[3]); 1619 1620 /* 1621 * Determine L2 cache/TLB info. 1622 */ 1623 if (lfunc < 0x80000006) { 1624 /* No L2 cache info available. */ 1625 return; 1626 } 1627 1628 x86_cpuid(0x80000006, descs); 1629 1630 cai = &ci->ci_cinfo[CAI_L2CACHE]; 1631 cai->cai_totalsize = AMD_L2_ECX_C_SIZE(descs[2]); 1632 cai->cai_associativity = AMD_L2_ECX_C_ASSOC(descs[2]); 1633 cai->cai_linesize = AMD_L2_ECX_C_LS(descs[2]); 1634 1635 cp = cache_info_lookup(amd_cpuid_l2cache_assoc_info, 1636 cai->cai_associativity); 1637 if (cp != NULL) 1638 cai->cai_associativity = cp->cai_associativity; 1639 else 1640 cai->cai_associativity = 0; /* XXX Unknown/reserved */ 1641 1642 /* 1643 * Determine L3 cache info on AMD Family 10h processors 1644 */ 1645 if (family == 0x10) { 1646 cai = &ci->ci_cinfo[CAI_L3CACHE]; 1647 cai->cai_totalsize = AMD_L3_EDX_C_SIZE(descs[3]); 1648 cai->cai_associativity = AMD_L3_EDX_C_ASSOC(descs[3]); 1649 cai->cai_linesize = AMD_L3_EDX_C_LS(descs[3]); 1650 1651 cp = cache_info_lookup(amd_cpuid_l3cache_assoc_info, 1652 cai->cai_associativity); 1653 if (cp != NULL) 1654 cai->cai_associativity = cp->cai_associativity; 1655 else 1656 cai->cai_associativity = 0; /* XXX Unkn/Rsvd */ 1657 } 1658 } 1659 1660 static void 1661 via_cpu_cacheinfo(struct cpu_info *ci) 1662 { 1663 struct x86_cache_info *cai; 1664 int family, model, stepping; 1665 u_int descs[4]; 1666 u_int lfunc; 1667 1668 family = (ci->ci_signature >> 8) & 15; 1669 model = CPUID2MODEL(ci->ci_signature); 1670 stepping = CPUID2STEPPING(ci->ci_signature); 1671 1672 /* 1673 * Determine the largest extended function value. 1674 */ 1675 x86_cpuid(0x80000000, descs); 1676 lfunc = descs[0]; 1677 1678 /* 1679 * Determine L1 cache/TLB info. 1680 */ 1681 if (lfunc < 0x80000005) { 1682 /* No L1 cache info available. */ 1683 return; 1684 } 1685 1686 x86_cpuid(0x80000005, descs); 1687 1688 cai = &ci->ci_cinfo[CAI_ITLB]; 1689 cai->cai_totalsize = VIA_L1_EBX_ITLB_ENTRIES(descs[1]); 1690 cai->cai_associativity = VIA_L1_EBX_ITLB_ASSOC(descs[1]); 1691 cai->cai_linesize = (4 * 1024); 1692 1693 cai = &ci->ci_cinfo[CAI_DTLB]; 1694 cai->cai_totalsize = VIA_L1_EBX_DTLB_ENTRIES(descs[1]); 1695 cai->cai_associativity = VIA_L1_EBX_DTLB_ASSOC(descs[1]); 1696 cai->cai_linesize = (4 * 1024); 1697 1698 cai = &ci->ci_cinfo[CAI_DCACHE]; 1699 cai->cai_totalsize = VIA_L1_ECX_DC_SIZE(descs[2]); 1700 cai->cai_associativity = VIA_L1_ECX_DC_ASSOC(descs[2]); 1701 cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[2]); 1702 if (model == 9 && stepping == 8) { 1703 /* Erratum: stepping 8 reports 4 when it should be 2 */ 1704 cai->cai_associativity = 2; 1705 } 1706 1707 cai = &ci->ci_cinfo[CAI_ICACHE]; 1708 cai->cai_totalsize = VIA_L1_EDX_IC_SIZE(descs[3]); 1709 cai->cai_associativity = VIA_L1_EDX_IC_ASSOC(descs[3]); 1710 cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[3]); 1711 if (model == 9 && stepping == 8) { 1712 /* Erratum: stepping 8 reports 4 when it should be 2 */ 1713 cai->cai_associativity = 2; 1714 } 1715 1716 /* 1717 * Determine L2 cache/TLB info. 1718 */ 1719 if (lfunc < 0x80000006) { 1720 /* No L2 cache info available. */ 1721 return; 1722 } 1723 1724 x86_cpuid(0x80000006, descs); 1725 1726 cai = &ci->ci_cinfo[CAI_L2CACHE]; 1727 if (model >= 9) { 1728 cai->cai_totalsize = VIA_L2N_ECX_C_SIZE(descs[2]); 1729 cai->cai_associativity = VIA_L2N_ECX_C_ASSOC(descs[2]); 1730 cai->cai_linesize = VIA_L2N_ECX_C_LS(descs[2]); 1731 } else { 1732 cai->cai_totalsize = VIA_L2_ECX_C_SIZE(descs[2]); 1733 cai->cai_associativity = VIA_L2_ECX_C_ASSOC(descs[2]); 1734 cai->cai_linesize = VIA_L2_ECX_C_LS(descs[2]); 1735 } 1736 } 1737 1738 static void 1739 x86_print_cacheinfo(struct cpu_info *ci) 1740 { 1741 const char *sep; 1742 1743 if (ci->ci_cinfo[CAI_ICACHE].cai_totalsize != 0 || 1744 ci->ci_cinfo[CAI_DCACHE].cai_totalsize != 0) { 1745 sep = print_cache_config(ci, CAI_ICACHE, "I-cache", NULL); 1746 sep = print_cache_config(ci, CAI_DCACHE, "D-cache", sep); 1747 if (sep != NULL) 1748 aprint_verbose("\n"); 1749 } 1750 if (ci->ci_cinfo[CAI_L2CACHE].cai_totalsize != 0) { 1751 sep = print_cache_config(ci, CAI_L2CACHE, "L2 cache", NULL); 1752 if (sep != NULL) 1753 aprint_verbose("\n"); 1754 } 1755 if (ci->ci_cinfo[CAI_ITLB].cai_totalsize != 0) { 1756 sep = print_tlb_config(ci, CAI_ITLB, "ITLB", NULL); 1757 sep = print_tlb_config(ci, CAI_ITLB2, NULL, sep); 1758 if (sep != NULL) 1759 aprint_verbose("\n"); 1760 } 1761 if (ci->ci_cinfo[CAI_DTLB].cai_totalsize != 0) { 1762 sep = print_tlb_config(ci, CAI_DTLB, "DTLB", NULL); 1763 sep = print_tlb_config(ci, CAI_DTLB2, NULL, sep); 1764 if (sep != NULL) 1765 aprint_verbose("\n"); 1766 } 1767 if (ci->ci_cinfo[CAI_L3CACHE].cai_totalsize != 0) { 1768 sep = print_cache_config(ci, CAI_L3CACHE, "L3 cache", NULL); 1769 if (sep != NULL) 1770 aprint_verbose("\n"); 1771 } 1772 } 1773 1774 static void 1775 powernow_probe(struct cpu_info *ci) 1776 { 1777 uint32_t regs[4]; 1778 char buf[256]; 1779 1780 x86_cpuid(0x80000000, regs); 1781 1782 /* We need CPUID(0x80000007) */ 1783 if (regs[0] < 0x80000007) 1784 return; 1785 x86_cpuid(0x80000007, regs); 1786 1787 snprintb(buf, sizeof(buf), CPUID_APM_FLAGS, regs[3]); 1788 aprint_normal_dev(ci->ci_dev, "AMD Power Management features: %s\n", 1789 buf); 1790 } 1791