1 /* $NetBSD: i386.c,v 1.38 2013/01/07 23:20:42 dsl 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.38 2013/01/07 23:20:42 dsl 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 #include <sys/ioctl.h> 68 #include <sys/cpuio.h> 69 70 #include <errno.h> 71 #include <string.h> 72 #include <stdio.h> 73 #include <stdlib.h> 74 #include <err.h> 75 #include <assert.h> 76 #include <math.h> 77 #include <util.h> 78 79 #include <machine/specialreg.h> 80 #include <machine/cpu.h> 81 82 #include <x86/cpuvar.h> 83 #include <x86/cputypes.h> 84 #include <x86/cacheinfo.h> 85 #include <x86/cpu_ucode.h> 86 87 #include "../cpuctl.h" 88 #include "cpuctl_i386.h" 89 90 /* Size of buffer for printing humanized numbers */ 91 #define HUMAN_BUFSIZE sizeof("999KB") 92 93 struct cpu_info { 94 const char *ci_dev; 95 int32_t ci_cpu_type; /* for cpu's without cpuid */ 96 int32_t ci_cpuid_level; /* highest cpuid supported */ 97 uint32_t ci_signature; /* X86 cpuid type */ 98 uint32_t ci_family; /* from ci_signature */ 99 uint32_t ci_model; /* from ci_signature */ 100 uint32_t ci_feat_val[8]; /* X86 CPUID feature bits 101 * [0] basic features %edx 102 * [1] basic features %ecx 103 * [2] extended features %edx 104 * [3] extended features %ecx 105 * [4] VIA padlock features 106 * [5] XCR0 bits (d:0 %eax) 107 * [6] xsave flags (d:1 %eax) 108 */ 109 uint32_t ci_cpu_class; /* CPU class */ 110 uint32_t ci_brand_id; /* Intel brand id */ 111 uint32_t ci_vendor[4]; /* vendor string */ 112 uint32_t ci_cpu_serial[3]; /* PIII serial number */ 113 uint64_t ci_tsc_freq; /* cpu cycles/second */ 114 uint8_t ci_packageid; 115 uint8_t ci_coreid; 116 uint8_t ci_smtid; 117 uint32_t ci_initapicid; 118 119 uint32_t ci_cur_xsave; 120 uint32_t ci_max_xsave; 121 122 struct x86_cache_info ci_cinfo[CAI_COUNT]; 123 void (*ci_info)(struct cpu_info *); 124 }; 125 126 struct cpu_nocpuid_nameclass { 127 int cpu_vendor; 128 const char *cpu_vendorname; 129 const char *cpu_name; 130 int cpu_class; 131 void (*cpu_setup)(struct cpu_info *); 132 void (*cpu_cacheinfo)(struct cpu_info *); 133 void (*cpu_info)(struct cpu_info *); 134 }; 135 136 struct cpu_cpuid_nameclass { 137 const char *cpu_id; 138 int cpu_vendor; 139 const char *cpu_vendorname; 140 struct cpu_cpuid_family { 141 int cpu_class; 142 const char *cpu_models[256]; 143 const char *cpu_model_default; 144 void (*cpu_setup)(struct cpu_info *); 145 void (*cpu_probe)(struct cpu_info *); 146 void (*cpu_info)(struct cpu_info *); 147 } cpu_family[CPU_MAXFAMILY - CPU_MINFAMILY + 1]; 148 }; 149 150 static const struct x86_cache_info intel_cpuid_cache_info[] = INTEL_CACHE_INFO; 151 152 /* 153 * Map Brand ID from cpuid instruction to brand name. 154 * Source: Intel Processor Identification and the CPUID Instruction, AP-485 155 */ 156 static const char * const i386_intel_brand[] = { 157 "", /* Unsupported */ 158 "Celeron", /* Intel (R) Celeron (TM) processor */ 159 "Pentium III", /* Intel (R) Pentium (R) III processor */ 160 "Pentium III Xeon", /* Intel (R) Pentium (R) III Xeon (TM) processor */ 161 "Pentium III", /* Intel (R) Pentium (R) III processor */ 162 "", /* Reserved */ 163 "Mobile Pentium III", /* Mobile Intel (R) Pentium (R) III processor-M */ 164 "Mobile Celeron", /* Mobile Intel (R) Celeron (R) processor */ 165 "Pentium 4", /* Intel (R) Pentium (R) 4 processor */ 166 "Pentium 4", /* Intel (R) Pentium (R) 4 processor */ 167 "Celeron", /* Intel (R) Celeron (TM) processor */ 168 "Xeon", /* Intel (R) Xeon (TM) processor */ 169 "Xeon MP", /* Intel (R) Xeon (TM) processor MP */ 170 "", /* Reserved */ 171 "Mobile Pentium 4", /* Mobile Intel (R) Pentium (R) 4 processor-M */ 172 "Mobile Celeron", /* Mobile Intel (R) Celeron (R) processor */ 173 }; 174 175 /* 176 * AMD processors don't have Brand IDs, so we need these names for probe. 177 */ 178 static const char * const amd_brand[] = { 179 "", 180 "Duron", /* AMD Duron(tm) */ 181 "MP", /* AMD Athlon(tm) MP */ 182 "XP", /* AMD Athlon(tm) XP */ 183 "4" /* AMD Athlon(tm) 4 */ 184 }; 185 186 static int cpu_vendor; 187 static char cpu_brand_string[49]; 188 static char amd_brand_name[48]; 189 static int use_pae, largepagesize; 190 191 static void via_cpu_probe(struct cpu_info *); 192 static void amd_family6_probe(struct cpu_info *); 193 static void intel_family_new_probe(struct cpu_info *); 194 static const char *intel_family6_name(struct cpu_info *); 195 static const char *amd_amd64_name(struct cpu_info *); 196 static void amd_family5_setup(struct cpu_info *); 197 static void transmeta_cpu_info(struct cpu_info *); 198 static const char *print_cache_config(struct cpu_info *, int, const char *, 199 const char *); 200 static const char *print_tlb_config(struct cpu_info *, int, const char *, 201 const char *); 202 static void amd_cpu_cacheinfo(struct cpu_info *); 203 static void via_cpu_cacheinfo(struct cpu_info *); 204 static void x86_print_cacheinfo(struct cpu_info *); 205 static const struct x86_cache_info *cache_info_lookup( 206 const struct x86_cache_info *, uint8_t); 207 static void cyrix6x86_cpu_setup(struct cpu_info *); 208 static void winchip_cpu_setup(struct cpu_info *); 209 static void amd_family5_setup(struct cpu_info *); 210 static void powernow_probe(struct cpu_info *); 211 212 /* 213 * Note: these are just the ones that may not have a cpuid instruction. 214 * We deal with the rest in a different way. 215 */ 216 const struct cpu_nocpuid_nameclass i386_nocpuid_cpus[] = { 217 { CPUVENDOR_INTEL, "Intel", "386SX", CPUCLASS_386, 218 NULL, NULL, NULL }, /* CPU_386SX */ 219 { CPUVENDOR_INTEL, "Intel", "386DX", CPUCLASS_386, 220 NULL, NULL, NULL }, /* CPU_386 */ 221 { CPUVENDOR_INTEL, "Intel", "486SX", CPUCLASS_486, 222 NULL, NULL, NULL }, /* CPU_486SX */ 223 { CPUVENDOR_INTEL, "Intel", "486DX", CPUCLASS_486, 224 NULL, NULL, NULL }, /* CPU_486 */ 225 { CPUVENDOR_CYRIX, "Cyrix", "486DLC", CPUCLASS_486, 226 NULL, NULL, NULL }, /* CPU_486DLC */ 227 { CPUVENDOR_CYRIX, "Cyrix", "6x86", CPUCLASS_486, 228 NULL, NULL, NULL }, /* CPU_6x86 */ 229 { CPUVENDOR_NEXGEN,"NexGen","586", CPUCLASS_386, 230 NULL, NULL, NULL }, /* CPU_NX586 */ 231 }; 232 233 const char *classnames[] = { 234 "386", 235 "486", 236 "586", 237 "686" 238 }; 239 240 const char *modifiers[] = { 241 "", 242 "OverDrive", 243 "Dual", 244 "" 245 }; 246 247 const struct cpu_cpuid_nameclass i386_cpuid_cpus[] = { 248 { 249 "GenuineIntel", 250 CPUVENDOR_INTEL, 251 "Intel", 252 /* Family 4 */ 253 { { 254 CPUCLASS_486, 255 { 256 "486DX", "486DX", "486SX", "486DX2", "486SL", 257 "486SX2", 0, "486DX2 W/B Enhanced", 258 "486DX4", 0, 0, 0, 0, 0, 0, 0, 259 }, 260 "486", /* Default */ 261 NULL, 262 NULL, 263 NULL, 264 }, 265 /* Family 5 */ 266 { 267 CPUCLASS_586, 268 { 269 "Pentium (P5 A-step)", "Pentium (P5)", 270 "Pentium (P54C)", "Pentium (P24T)", 271 "Pentium/MMX", "Pentium", 0, 272 "Pentium (P54C)", "Pentium/MMX (Tillamook)", 273 0, 0, 0, 0, 0, 0, 0, 274 }, 275 "Pentium", /* Default */ 276 NULL, 277 NULL, 278 NULL, 279 }, 280 /* Family 6 */ 281 { 282 CPUCLASS_686, 283 { 284 /* Updated from intel_x86_325486.pdf Aug 2012 */ 285 [0x00] = "Pentium Pro (A-step)", 286 [0x01] = "Pentium Pro", 287 [0x03] = "Pentium II (Klamath)", 288 [0x04] = "Pentium Pro", 289 [0x05] = "Pentium II/Celeron (Deschutes)", 290 [0x06] = "Celeron (Mendocino)", 291 [0x07] = "Pentium III (Katmai)", 292 [0x08] = "Pentium III (Coppermine)", 293 [0x09] = "Pentium M (Banias)", 294 [0x0a] = "Pentium III Xeon (Cascades)", 295 [0x0b] = "Pentium III (Tualatin)", 296 [0x0d] = "Pentium M (Dothan)", 297 [0x0e] = "Pentium Core Duo", // "M (Yonah)", 298 [0x0f] = "Core 2", 299 [0x15] = "EP80579 Integrated Processor", 300 [0x16] = "Celeron (45nm)", 301 [0x17] = "Core 2 Extreme", 302 [0x1a] = "Core i7 (Nehalem)", 303 [0x1c] = "Atom Family", 304 [0x1d] = "XeonMP 74xx (Nehalem)", 305 [0x1e] = "Core i7 and i5", 306 [0x1f] = "Core i7 and i5", 307 [0x25] = "Xeon 36xx & 56xx, i7, i5 and i3", 308 [0x26] = "Atom Family", 309 [0x27] = "Atom Family", 310 [0x2a] = "Xeon E3-12xx, 2nd gen i7, i5, i3 2xxx", 311 [0x2c] = "Xeon 36xx & 56xx, i7, i5 and i3", 312 [0x2e] = "Xeon 75xx & 65xx", 313 [0x2d] = "Xeon E5 Sandy bridy family", 314 [0x2f] = "Xeon E7 family", 315 [0x3a] = "Xeon E3-1200v2 and 3rd gen core, Ivy bridge", 316 [0x3c] = "Next Intel Core", 317 [0x3e] = "Next gen Xeon E5, Ivy bridge", 318 [0x45] = "Next Intel Core", 319 }, 320 "Pentium Pro, II or III", /* Default */ 321 NULL, 322 intel_family_new_probe, 323 NULL, 324 }, 325 /* Family > 6 */ 326 { 327 CPUCLASS_686, 328 { 329 0, 0, 0, 0, 0, 0, 0, 0, 330 0, 0, 0, 0, 0, 0, 0, 0, 331 }, 332 "Pentium 4", /* Default */ 333 NULL, 334 intel_family_new_probe, 335 NULL, 336 } } 337 }, 338 { 339 "AuthenticAMD", 340 CPUVENDOR_AMD, 341 "AMD", 342 /* Family 4 */ 343 { { 344 CPUCLASS_486, 345 { 346 0, 0, 0, "Am486DX2 W/T", 347 0, 0, 0, "Am486DX2 W/B", 348 "Am486DX4 W/T or Am5x86 W/T 150", 349 "Am486DX4 W/B or Am5x86 W/B 150", 0, 0, 350 0, 0, "Am5x86 W/T 133/160", 351 "Am5x86 W/B 133/160", 352 }, 353 "Am486 or Am5x86", /* Default */ 354 NULL, 355 NULL, 356 NULL, 357 }, 358 /* Family 5 */ 359 { 360 CPUCLASS_586, 361 { 362 "K5", "K5", "K5", "K5", 0, 0, "K6", 363 "K6", "K6-2", "K6-III", "Geode LX", 0, 0, 364 "K6-2+/III+", 0, 0, 365 }, 366 "K5 or K6", /* Default */ 367 amd_family5_setup, 368 NULL, 369 amd_cpu_cacheinfo, 370 }, 371 /* Family 6 */ 372 { 373 CPUCLASS_686, 374 { 375 0, "Athlon Model 1", "Athlon Model 2", 376 "Duron", "Athlon Model 4 (Thunderbird)", 377 0, "Athlon", "Duron", "Athlon", 0, 378 "Athlon", 0, 0, 0, 0, 0, 379 }, 380 "K7 (Athlon)", /* Default */ 381 NULL, 382 amd_family6_probe, 383 amd_cpu_cacheinfo, 384 }, 385 /* Family > 6 */ 386 { 387 CPUCLASS_686, 388 { 389 0, 0, 0, 0, 0, 0, 0, 0, 390 0, 0, 0, 0, 0, 0, 0, 0, 391 }, 392 "Unknown K8 (Athlon)", /* Default */ 393 NULL, 394 amd_family6_probe, 395 amd_cpu_cacheinfo, 396 } } 397 }, 398 { 399 "CyrixInstead", 400 CPUVENDOR_CYRIX, 401 "Cyrix", 402 /* Family 4 */ 403 { { 404 CPUCLASS_486, 405 { 406 0, 0, 0, 407 "MediaGX", 408 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 409 }, 410 "486", /* Default */ 411 cyrix6x86_cpu_setup, /* XXX ?? */ 412 NULL, 413 NULL, 414 }, 415 /* Family 5 */ 416 { 417 CPUCLASS_586, 418 { 419 0, 0, "6x86", 0, 420 "MMX-enhanced MediaGX (GXm)", /* or Geode? */ 421 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 422 }, 423 "6x86", /* Default */ 424 cyrix6x86_cpu_setup, 425 NULL, 426 NULL, 427 }, 428 /* Family 6 */ 429 { 430 CPUCLASS_686, 431 { 432 "6x86MX", 0, 0, 0, 0, 0, 0, 0, 433 0, 0, 0, 0, 0, 0, 0, 0, 434 }, 435 "6x86MX", /* Default */ 436 cyrix6x86_cpu_setup, 437 NULL, 438 NULL, 439 }, 440 /* Family > 6 */ 441 { 442 CPUCLASS_686, 443 { 444 0, 0, 0, 0, 0, 0, 0, 0, 445 0, 0, 0, 0, 0, 0, 0, 0, 446 }, 447 "Unknown 6x86MX", /* Default */ 448 NULL, 449 NULL, 450 NULL, 451 } } 452 }, 453 { /* MediaGX is now owned by National Semiconductor */ 454 "Geode by NSC", 455 CPUVENDOR_CYRIX, /* XXX */ 456 "National Semiconductor", 457 /* Family 4, NSC never had any of these */ 458 { { 459 CPUCLASS_486, 460 { 461 0, 0, 0, 0, 0, 0, 0, 0, 462 0, 0, 0, 0, 0, 0, 0, 0, 463 }, 464 "486 compatible", /* Default */ 465 NULL, 466 NULL, 467 NULL, 468 }, 469 /* Family 5: Geode family, formerly MediaGX */ 470 { 471 CPUCLASS_586, 472 { 473 0, 0, 0, 0, 474 "Geode GX1", 475 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 476 }, 477 "Geode", /* Default */ 478 cyrix6x86_cpu_setup, 479 NULL, 480 amd_cpu_cacheinfo, 481 }, 482 /* Family 6, not yet available from NSC */ 483 { 484 CPUCLASS_686, 485 { 486 0, 0, 0, 0, 0, 0, 0, 0, 487 0, 0, 0, 0, 0, 0, 0, 0, 488 }, 489 "Pentium Pro compatible", /* Default */ 490 NULL, 491 NULL, 492 NULL, 493 }, 494 /* Family > 6, not yet available from NSC */ 495 { 496 CPUCLASS_686, 497 { 498 0, 0, 0, 0, 0, 0, 0, 0, 499 0, 0, 0, 0, 0, 0, 0, 0, 500 }, 501 "Pentium Pro compatible", /* Default */ 502 NULL, 503 NULL, 504 NULL, 505 } } 506 }, 507 { 508 "CentaurHauls", 509 CPUVENDOR_IDT, 510 "IDT", 511 /* Family 4, IDT never had any of these */ 512 { { 513 CPUCLASS_486, 514 { 515 0, 0, 0, 0, 0, 0, 0, 0, 516 0, 0, 0, 0, 0, 0, 0, 0, 517 }, 518 "486 compatible", /* Default */ 519 NULL, 520 NULL, 521 NULL, 522 }, 523 /* Family 5 */ 524 { 525 CPUCLASS_586, 526 { 527 0, 0, 0, 0, "WinChip C6", 0, 0, 0, 528 "WinChip 2", "WinChip 3", 0, 0, 0, 0, 0, 0, 529 }, 530 "WinChip", /* Default */ 531 winchip_cpu_setup, 532 NULL, 533 NULL, 534 }, 535 /* Family 6, VIA acquired IDT Centaur design subsidiary */ 536 { 537 CPUCLASS_686, 538 { 539 0, 0, 0, 0, 0, 0, "C3 Samuel", 540 "C3 Samuel 2/Ezra", "C3 Ezra-T", 541 "C3 Nehemiah", "C7 Esther", 0, 0, "C7 Esther", 542 0, "VIA Nano", 543 }, 544 "Unknown VIA/IDT", /* Default */ 545 NULL, 546 via_cpu_probe, 547 via_cpu_cacheinfo, 548 }, 549 /* Family > 6, not yet available from VIA */ 550 { 551 CPUCLASS_686, 552 { 553 0, 0, 0, 0, 0, 0, 0, 0, 554 0, 0, 0, 0, 0, 0, 0, 0, 555 }, 556 "Pentium Pro compatible", /* Default */ 557 NULL, 558 NULL, 559 NULL, 560 } } 561 }, 562 { 563 "GenuineTMx86", 564 CPUVENDOR_TRANSMETA, 565 "Transmeta", 566 /* Family 4, Transmeta never had any of these */ 567 { { 568 CPUCLASS_486, 569 { 570 0, 0, 0, 0, 0, 0, 0, 0, 571 0, 0, 0, 0, 0, 0, 0, 0, 572 }, 573 "486 compatible", /* Default */ 574 NULL, 575 NULL, 576 NULL, 577 }, 578 /* Family 5 */ 579 { 580 CPUCLASS_586, 581 { 582 0, 0, 0, 0, 0, 0, 0, 0, 583 0, 0, 0, 0, 0, 0, 0, 0, 584 }, 585 "Crusoe", /* Default */ 586 NULL, 587 NULL, 588 transmeta_cpu_info, 589 }, 590 /* Family 6, not yet available from Transmeta */ 591 { 592 CPUCLASS_686, 593 { 594 0, 0, 0, 0, 0, 0, 0, 0, 595 0, 0, 0, 0, 0, 0, 0, 0, 596 }, 597 "Pentium Pro compatible", /* Default */ 598 NULL, 599 NULL, 600 NULL, 601 }, 602 /* Family > 6, not yet available from Transmeta */ 603 { 604 CPUCLASS_686, 605 { 606 0, 0, 0, 0, 0, 0, 0, 0, 607 0, 0, 0, 0, 0, 0, 0, 0, 608 }, 609 "Pentium Pro compatible", /* Default */ 610 NULL, 611 NULL, 612 NULL, 613 } } 614 } 615 }; 616 617 /* 618 * disable the TSC such that we don't use the TSC in microtime(9) 619 * because some CPUs got the implementation wrong. 620 */ 621 static void 622 disable_tsc(struct cpu_info *ci) 623 { 624 if (ci->ci_feat_val[0] & CPUID_TSC) { 625 ci->ci_feat_val[0] &= ~CPUID_TSC; 626 aprint_error("WARNING: broken TSC disabled\n"); 627 } 628 } 629 630 static void 631 cyrix6x86_cpu_setup(struct cpu_info *ci) 632 { 633 634 /* 635 * Do not disable the TSC on the Geode GX, it's reported to 636 * work fine. 637 */ 638 if (ci->ci_signature != 0x552) 639 disable_tsc(ci); 640 } 641 642 void 643 winchip_cpu_setup(struct cpu_info *ci) 644 { 645 switch (ci->ci_model) { 646 case 4: /* WinChip C6 */ 647 disable_tsc(ci); 648 } 649 } 650 651 652 static void 653 identifycpu_cpuids(struct cpu_info *ci) 654 { 655 const char *cpuname = ci->ci_dev; 656 u_int lp_max = 1; /* logical processors per package */ 657 u_int smt_max; /* smt per core */ 658 u_int core_max = 1; /* core per package */ 659 u_int smt_bits, core_bits; 660 uint32_t descs[4]; 661 662 aprint_verbose("%s: Initial APIC ID %u\n", cpuname, ci->ci_initapicid); 663 ci->ci_packageid = ci->ci_initapicid; 664 ci->ci_coreid = 0; 665 ci->ci_smtid = 0; 666 if (cpu_vendor != CPUVENDOR_INTEL) { 667 return; 668 } 669 670 /* 671 * 253668.pdf 7.10.2 672 */ 673 674 if ((ci->ci_feat_val[0] & CPUID_HTT) != 0) { 675 x86_cpuid(1, descs); 676 lp_max = (descs[1] >> 16) & 0xff; 677 } 678 x86_cpuid(0, descs); 679 if (descs[0] >= 4) { 680 x86_cpuid2(4, 0, descs); 681 core_max = (descs[0] >> 26) + 1; 682 } 683 assert(lp_max >= core_max); 684 smt_max = lp_max / core_max; 685 smt_bits = ilog2(smt_max - 1) + 1; 686 core_bits = ilog2(core_max - 1) + 1; 687 if (smt_bits + core_bits) { 688 ci->ci_packageid = ci->ci_initapicid >> (smt_bits + core_bits); 689 } 690 aprint_verbose("%s: Cluster/Package ID %u\n", cpuname, 691 ci->ci_packageid); 692 if (core_bits) { 693 u_int core_mask = __BITS(smt_bits, smt_bits + core_bits - 1); 694 695 ci->ci_coreid = 696 __SHIFTOUT(ci->ci_initapicid, core_mask); 697 aprint_verbose("%s: Core ID %u\n", cpuname, ci->ci_coreid); 698 } 699 if (smt_bits) { 700 u_int smt_mask = __BITS((int)0, (int)(smt_bits - 1)); 701 702 ci->ci_smtid = __SHIFTOUT(ci->ci_initapicid, smt_mask); 703 aprint_verbose("%s: SMT ID %u\n", cpuname, ci->ci_smtid); 704 } 705 } 706 707 static void 708 via_cpu_probe(struct cpu_info *ci) 709 { 710 u_int stepping = CPUID2STEPPING(ci->ci_signature); 711 u_int descs[4]; 712 u_int lfunc; 713 714 /* 715 * Determine the largest extended function value. 716 */ 717 x86_cpuid(0x80000000, descs); 718 lfunc = descs[0]; 719 720 /* 721 * Determine the extended feature flags. 722 */ 723 if (lfunc >= 0x80000001) { 724 x86_cpuid(0x80000001, descs); 725 ci->ci_feat_val[2] |= descs[3]; 726 } 727 728 if (ci->ci_model < 0x9 || (ci->ci_model == 0x9 && stepping < 3)) 729 return; 730 731 /* Nehemiah or Esther */ 732 x86_cpuid(0xc0000000, descs); 733 lfunc = descs[0]; 734 if (lfunc < 0xc0000001) /* no ACE, no RNG */ 735 return; 736 737 x86_cpuid(0xc0000001, descs); 738 lfunc = descs[3]; 739 ci->ci_feat_val[4] = lfunc; 740 } 741 742 static const char * 743 intel_family6_name(struct cpu_info *ci) 744 { 745 const char *ret = NULL; 746 u_int l2cache = ci->ci_cinfo[CAI_L2CACHE].cai_totalsize; 747 748 if (ci->ci_model == 5) { 749 switch (l2cache) { 750 case 0: 751 case 128 * 1024: 752 ret = "Celeron (Covington)"; 753 break; 754 case 256 * 1024: 755 ret = "Mobile Pentium II (Dixon)"; 756 break; 757 case 512 * 1024: 758 ret = "Pentium II"; 759 break; 760 case 1 * 1024 * 1024: 761 case 2 * 1024 * 1024: 762 ret = "Pentium II Xeon"; 763 break; 764 } 765 } else if (ci->ci_model == 6) { 766 switch (l2cache) { 767 case 256 * 1024: 768 case 512 * 1024: 769 ret = "Mobile Pentium II"; 770 break; 771 } 772 } else if (ci->ci_model == 7) { 773 switch (l2cache) { 774 case 512 * 1024: 775 ret = "Pentium III"; 776 break; 777 case 1 * 1024 * 1024: 778 case 2 * 1024 * 1024: 779 ret = "Pentium III Xeon"; 780 break; 781 } 782 } else if (ci->ci_model >= 8) { 783 if (ci->ci_brand_id && ci->ci_brand_id < 0x10) { 784 switch (ci->ci_brand_id) { 785 case 0x3: 786 if (ci->ci_signature == 0x6B1) 787 ret = "Celeron"; 788 break; 789 case 0x8: 790 if (ci->ci_signature >= 0xF13) 791 ret = "genuine processor"; 792 break; 793 case 0xB: 794 if (ci->ci_signature >= 0xF13) 795 ret = "Xeon MP"; 796 break; 797 case 0xE: 798 if (ci->ci_signature < 0xF13) 799 ret = "Xeon"; 800 break; 801 } 802 if (ret == NULL) 803 ret = i386_intel_brand[ci->ci_brand_id]; 804 } 805 } 806 807 return ret; 808 } 809 810 /* 811 * Identify AMD64 CPU names from cpuid. 812 * 813 * Based on: 814 * "Revision Guide for AMD Athlon 64 and AMD Opteron Processors" 815 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25759.pdf 816 * "Revision Guide for AMD NPT Family 0Fh Processors" 817 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/33610.pdf 818 * and other miscellaneous reports. 819 * 820 * This is all rather pointless, these are cross 'brand' since the raw 821 * silicon is shared. 822 */ 823 static const char * 824 amd_amd64_name(struct cpu_info *ci) 825 { 826 static char family_str[32]; 827 828 /* Only called if family >= 15 */ 829 830 switch (ci->ci_family) { 831 case 15: 832 switch (ci->ci_model) { 833 case 0x21: /* rev JH-E1/E6 */ 834 case 0x41: /* rev JH-F2 */ 835 return "Dual-Core Opteron"; 836 case 0x23: /* rev JH-E6 (Toledo) */ 837 return "Dual-Core Opteron or Athlon 64 X2"; 838 case 0x43: /* rev JH-F2 (Windsor) */ 839 return "Athlon 64 FX or Athlon 64 X2"; 840 case 0x24: /* rev SH-E5 (Lancaster?) */ 841 return "Mobile Athlon 64 or Turion 64"; 842 case 0x05: /* rev SH-B0/B3/C0/CG (SledgeHammer?) */ 843 return "Opteron or Athlon 64 FX"; 844 case 0x15: /* rev SH-D0 */ 845 case 0x25: /* rev SH-E4 */ 846 return "Opteron"; 847 case 0x27: /* rev DH-E4, SH-E4 */ 848 return "Athlon 64 or Athlon 64 FX or Opteron"; 849 case 0x48: /* rev BH-F2 */ 850 return "Turion 64 X2"; 851 case 0x04: /* rev SH-B0/C0/CG (ClawHammer) */ 852 case 0x07: /* rev SH-CG (ClawHammer) */ 853 case 0x0b: /* rev CH-CG */ 854 case 0x14: /* rev SH-D0 */ 855 case 0x17: /* rev SH-D0 */ 856 case 0x1b: /* rev CH-D0 */ 857 return "Athlon 64"; 858 case 0x2b: /* rev BH-E4 (Manchester) */ 859 case 0x4b: /* rev BH-F2 (Windsor) */ 860 return "Athlon 64 X2"; 861 case 0x6b: /* rev BH-G1 (Brisbane) */ 862 return "Athlon X2 or Athlon 64 X2"; 863 case 0x08: /* rev CH-CG */ 864 case 0x0c: /* rev DH-CG (Newcastle) */ 865 case 0x0e: /* rev DH-CG (Newcastle?) */ 866 case 0x0f: /* rev DH-CG (Newcastle/Paris) */ 867 case 0x18: /* rev CH-D0 */ 868 case 0x1c: /* rev DH-D0 (Winchester) */ 869 case 0x1f: /* rev DH-D0 (Winchester/Victoria) */ 870 case 0x2c: /* rev DH-E3/E6 */ 871 case 0x2f: /* rev DH-E3/E6 (Venice/Palermo) */ 872 case 0x4f: /* rev DH-F2 (Orleans/Manila) */ 873 case 0x5f: /* rev DH-F2 (Orleans/Manila) */ 874 case 0x6f: /* rev DH-G1 */ 875 return "Athlon 64 or Sempron"; 876 default: 877 break; 878 } 879 return "Unknown AMD64 CPU"; 880 881 #if 0 882 case 16: 883 return "Family 10h"; 884 case 17: 885 return "Family 11h"; 886 case 18: 887 return "Family 12h"; 888 case 19: 889 return "Family 14h"; 890 case 20: 891 return "Family 15h"; 892 #endif 893 894 default: 895 break; 896 } 897 898 snprintf(family_str, sizeof family_str, "Family %xh", ci->ci_family); 899 return family_str; 900 } 901 902 static void 903 cpu_probe_base_features(struct cpu_info *ci, const char *cpuname) 904 { 905 const struct x86_cache_info *cai; 906 u_int descs[4]; 907 int iterations, i, j; 908 uint8_t desc; 909 uint32_t brand[12]; 910 911 memset(ci, 0, sizeof(*ci)); 912 ci->ci_dev = cpuname; 913 914 ci->ci_cpu_type = x86_identify(); 915 if (ci->ci_cpu_type >= 0) { 916 /* Old pre-cpuid instruction cpu */ 917 ci->ci_cpuid_level = -1; 918 return; 919 } 920 921 x86_cpuid(0, descs); 922 ci->ci_cpuid_level = descs[0]; 923 ci->ci_vendor[0] = descs[1]; 924 ci->ci_vendor[2] = descs[2]; 925 ci->ci_vendor[1] = descs[3]; 926 ci->ci_vendor[3] = 0; 927 928 x86_cpuid(0x80000000, brand); 929 if (brand[0] >= 0x80000004) { 930 x86_cpuid(0x80000002, brand); 931 x86_cpuid(0x80000003, brand + 4); 932 x86_cpuid(0x80000004, brand + 8); 933 for (i = 0; i < 48; i++) 934 if (((char *) brand)[i] != ' ') 935 break; 936 memcpy(cpu_brand_string, ((char *) brand) + i, 48 - i); 937 } 938 939 if (ci->ci_cpuid_level < 1) 940 return; 941 942 x86_cpuid(1, descs); 943 ci->ci_signature = descs[0]; 944 945 /* Extract full family/model values */ 946 ci->ci_family = CPUID2FAMILY(ci->ci_signature); 947 ci->ci_model = CPUID2MODEL(ci->ci_signature); 948 if (ci->ci_family == 15) 949 ci->ci_family += CPUID2EXTFAMILY(ci->ci_signature); 950 if (ci->ci_family == 6 || ci->ci_family == 15) 951 ci->ci_model += CPUID2EXTMODEL(ci->ci_signature) << 4; 952 953 /* Brand is low order 8 bits of ebx */ 954 ci->ci_brand_id = descs[1] & 0xff; 955 ci->ci_initapicid = (descs[1] >> 24) & 0xff; 956 957 ci->ci_feat_val[1] = descs[2]; 958 ci->ci_feat_val[0] = descs[3]; 959 960 if (ci->ci_cpuid_level < 2) 961 return; 962 963 /* 964 * Parse the cache info from `cpuid', if we have it. 965 * XXX This is kinda ugly, but hey, so is the architecture... 966 */ 967 968 x86_cpuid(2, descs); 969 970 iterations = descs[0] & 0xff; 971 while (iterations-- > 0) { 972 for (i = 0; i < 4; i++) { 973 if (descs[i] & 0x80000000) 974 continue; 975 for (j = 0; j < 4; j++) { 976 if (i == 0 && j == 0) 977 continue; 978 desc = (descs[i] >> (j * 8)) & 0xff; 979 if (desc == 0) 980 continue; 981 cai = cache_info_lookup(intel_cpuid_cache_info, 982 desc); 983 if (cai != NULL) 984 ci->ci_cinfo[cai->cai_index] = *cai; 985 } 986 } 987 x86_cpuid(2, descs); 988 } 989 990 if (ci->ci_cpuid_level < 3) 991 return; 992 993 /* 994 * If the processor serial number misfeature is present and supported, 995 * extract it here. 996 */ 997 if ((ci->ci_feat_val[0] & CPUID_PN) != 0) { 998 ci->ci_cpu_serial[0] = ci->ci_signature; 999 x86_cpuid(3, descs); 1000 ci->ci_cpu_serial[2] = descs[2]; 1001 ci->ci_cpu_serial[1] = descs[3]; 1002 } 1003 1004 if (ci->ci_cpuid_level < 0xd) 1005 return; 1006 1007 /* Get support XRC0 bits */ 1008 x86_cpuid2(0xd, 0, descs); 1009 ci->ci_feat_val[5] = descs[0]; /* Actually 64 bits */ 1010 ci->ci_cur_xsave = descs[1]; 1011 ci->ci_max_xsave = descs[2]; 1012 1013 /* Additional flags (eg xsaveopt support) */ 1014 x86_cpuid2(0xd, 1, descs); 1015 ci->ci_feat_val[6] = descs[0]; /* Actually 64 bits */ 1016 } 1017 1018 static void 1019 cpu_probe_features(struct cpu_info *ci) 1020 { 1021 const struct cpu_cpuid_nameclass *cpup = NULL; 1022 unsigned int i; 1023 1024 if (ci->ci_cpuid_level < 1) 1025 return; 1026 1027 for (i = 0; i < __arraycount(i386_cpuid_cpus); i++) { 1028 if (!strncmp((char *)ci->ci_vendor, 1029 i386_cpuid_cpus[i].cpu_id, 12)) { 1030 cpup = &i386_cpuid_cpus[i]; 1031 break; 1032 } 1033 } 1034 1035 if (cpup == NULL) 1036 return; 1037 1038 i = ci->ci_family - CPU_MINFAMILY; 1039 1040 if (i >= __arraycount(cpup->cpu_family)) 1041 i = __arraycount(cpup->cpu_family) - 1; 1042 1043 if (cpup->cpu_family[i].cpu_probe == NULL) 1044 return; 1045 1046 (*cpup->cpu_family[i].cpu_probe)(ci); 1047 } 1048 1049 static void 1050 intel_family_new_probe(struct cpu_info *ci) 1051 { 1052 uint32_t descs[4]; 1053 1054 x86_cpuid(0x80000000, descs); 1055 1056 /* 1057 * Determine extended feature flags. 1058 */ 1059 if (descs[0] >= 0x80000001) { 1060 x86_cpuid(0x80000001, descs); 1061 ci->ci_feat_val[2] |= descs[3]; 1062 ci->ci_feat_val[3] |= descs[2]; 1063 } 1064 } 1065 1066 static void 1067 amd_family6_probe(struct cpu_info *ci) 1068 { 1069 uint32_t descs[4]; 1070 char *p; 1071 size_t i; 1072 1073 x86_cpuid(0x80000000, descs); 1074 1075 /* 1076 * Determine the extended feature flags. 1077 */ 1078 if (descs[0] >= 0x80000001) { 1079 x86_cpuid(0x80000001, descs); 1080 ci->ci_feat_val[2] |= descs[3]; /* %edx */ 1081 ci->ci_feat_val[3] = descs[2]; /* %ecx */ 1082 } 1083 1084 if (*cpu_brand_string == '\0') 1085 return; 1086 1087 for (i = 1; i < __arraycount(amd_brand); i++) 1088 if ((p = strstr(cpu_brand_string, amd_brand[i])) != NULL) { 1089 ci->ci_brand_id = i; 1090 strlcpy(amd_brand_name, p, sizeof(amd_brand_name)); 1091 break; 1092 } 1093 } 1094 1095 static void 1096 amd_family5_setup(struct cpu_info *ci) 1097 { 1098 1099 switch (ci->ci_model) { 1100 case 0: /* AMD-K5 Model 0 */ 1101 /* 1102 * According to the AMD Processor Recognition App Note, 1103 * the AMD-K5 Model 0 uses the wrong bit to indicate 1104 * support for global PTEs, instead using bit 9 (APIC) 1105 * rather than bit 13 (i.e. "0x200" vs. 0x2000". Oops!). 1106 */ 1107 if (ci->ci_feat_val[0] & CPUID_APIC) 1108 ci->ci_feat_val[0] = 1109 (ci->ci_feat_val[0] & ~CPUID_APIC) | CPUID_PGE; 1110 /* 1111 * XXX But pmap_pg_g is already initialized -- need to kick 1112 * XXX the pmap somehow. How does the MP branch do this? 1113 */ 1114 break; 1115 } 1116 } 1117 1118 static void 1119 tmx86_get_longrun_status(u_int *frequency, u_int *voltage, u_int *percentage) 1120 { 1121 u_int descs[4]; 1122 1123 x86_cpuid(0x80860007, descs); 1124 *frequency = descs[0]; 1125 *voltage = descs[1]; 1126 *percentage = descs[2]; 1127 } 1128 1129 static void 1130 transmeta_cpu_info(struct cpu_info *ci) 1131 { 1132 u_int descs[4], nreg; 1133 u_int frequency, voltage, percentage; 1134 1135 x86_cpuid(0x80860000, descs); 1136 nreg = descs[0]; 1137 if (nreg >= 0x80860001) { 1138 x86_cpuid(0x80860001, descs); 1139 aprint_verbose_dev(ci->ci_dev, "Processor revision %u.%u.%u.%u\n", 1140 (descs[1] >> 24) & 0xff, 1141 (descs[1] >> 16) & 0xff, 1142 (descs[1] >> 8) & 0xff, 1143 descs[1] & 0xff); 1144 } 1145 if (nreg >= 0x80860002) { 1146 x86_cpuid(0x80860002, descs); 1147 aprint_verbose_dev(ci->ci_dev, "Code Morphing Software Rev: %u.%u.%u-%u-%u\n", 1148 (descs[1] >> 24) & 0xff, 1149 (descs[1] >> 16) & 0xff, 1150 (descs[1] >> 8) & 0xff, 1151 descs[1] & 0xff, 1152 descs[2]); 1153 } 1154 if (nreg >= 0x80860006) { 1155 union { 1156 char text[65]; 1157 u_int descs[4][4]; 1158 } info; 1159 int i; 1160 1161 for (i=0; i<4; i++) { 1162 x86_cpuid(0x80860003 + i, info.descs[i]); 1163 } 1164 info.text[64] = '\0'; 1165 aprint_verbose_dev(ci->ci_dev, "%s\n", info.text); 1166 } 1167 1168 if (nreg >= 0x80860007) { 1169 tmx86_get_longrun_status(&frequency, 1170 &voltage, &percentage); 1171 aprint_verbose_dev(ci->ci_dev, "LongRun <%dMHz %dmV %d%%>\n", 1172 frequency, voltage, percentage); 1173 } 1174 } 1175 1176 static void 1177 print_bits(const char *cpuname, const char *hdr, const char *fmt, uint32_t val) 1178 { 1179 char buf[32 * 16]; 1180 char *bp; 1181 1182 #define MAX_LINE_LEN 79 /* get from command arg or 'stty cols' ? */ 1183 1184 if (val == 0 || fmt == NULL) 1185 return; 1186 1187 snprintb_m(buf, sizeof(buf), fmt, val, 1188 MAX_LINE_LEN - strlen(cpuname) - 2 - strlen(hdr) - 1); 1189 bp = buf; 1190 while (*bp != '\0') { 1191 aprint_verbose("%s: %s %s\n", cpuname, hdr, bp); 1192 bp += strlen(bp) + 1; 1193 } 1194 } 1195 1196 void 1197 identifycpu(int fd, const char *cpuname) 1198 { 1199 const char *name = "", *modifier, *vendorname, *brand = ""; 1200 int class = CPUCLASS_386; 1201 unsigned int i; 1202 int modif, family; 1203 const struct cpu_cpuid_nameclass *cpup = NULL; 1204 const struct cpu_cpuid_family *cpufam; 1205 struct cpu_info *ci, cistore; 1206 size_t sz; 1207 struct cpu_ucode_version ucode; 1208 union { 1209 struct cpu_ucode_version_amd amd; 1210 struct cpu_ucode_version_intel1 intel1; 1211 } ucvers; 1212 1213 ci = &cistore; 1214 cpu_probe_base_features(ci, cpuname); 1215 cpu_probe_features(ci); 1216 1217 if (ci->ci_cpu_type >= 0) { 1218 if (ci->ci_cpu_type >= (int)__arraycount(i386_nocpuid_cpus)) 1219 errx(1, "unknown cpu type %d", ci->ci_cpu_type); 1220 name = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_name; 1221 cpu_vendor = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_vendor; 1222 vendorname = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_vendorname; 1223 class = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_class; 1224 ci->ci_info = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_info; 1225 modifier = ""; 1226 } else { 1227 modif = (ci->ci_signature >> 12) & 0x3; 1228 family = ci->ci_family; 1229 if (family < CPU_MINFAMILY) 1230 errx(1, "identifycpu: strange family value"); 1231 if (family > CPU_MAXFAMILY) 1232 family = CPU_MAXFAMILY; 1233 1234 for (i = 0; i < __arraycount(i386_cpuid_cpus); i++) { 1235 if (!strncmp((char *)ci->ci_vendor, 1236 i386_cpuid_cpus[i].cpu_id, 12)) { 1237 cpup = &i386_cpuid_cpus[i]; 1238 break; 1239 } 1240 } 1241 1242 if (cpup == NULL) { 1243 cpu_vendor = CPUVENDOR_UNKNOWN; 1244 if (ci->ci_vendor[0] != '\0') 1245 vendorname = (char *)&ci->ci_vendor[0]; 1246 else 1247 vendorname = "Unknown"; 1248 class = family - 3; 1249 modifier = ""; 1250 name = ""; 1251 ci->ci_info = NULL; 1252 } else { 1253 cpu_vendor = cpup->cpu_vendor; 1254 vendorname = cpup->cpu_vendorname; 1255 modifier = modifiers[modif]; 1256 cpufam = &cpup->cpu_family[family - CPU_MINFAMILY]; 1257 name = cpufam->cpu_models[ci->ci_model]; 1258 if (name == NULL || *name == '\0') 1259 name = cpufam->cpu_model_default; 1260 class = cpufam->cpu_class; 1261 ci->ci_info = cpufam->cpu_info; 1262 1263 if (cpu_vendor == CPUVENDOR_INTEL) { 1264 if (ci->ci_family == 6 && ci->ci_model >= 5) { 1265 const char *tmp; 1266 tmp = intel_family6_name(ci); 1267 if (tmp != NULL) 1268 name = tmp; 1269 } 1270 if (ci->ci_family == 15 && 1271 ci->ci_brand_id < 1272 __arraycount(i386_intel_brand) && 1273 i386_intel_brand[ci->ci_brand_id]) 1274 name = 1275 i386_intel_brand[ci->ci_brand_id]; 1276 } 1277 1278 if (cpu_vendor == CPUVENDOR_AMD) { 1279 if (ci->ci_family == 6 && ci->ci_model >= 6) { 1280 if (ci->ci_brand_id == 1) 1281 /* 1282 * It's Duron. We override the 1283 * name, since it might have 1284 * been misidentified as Athlon. 1285 */ 1286 name = 1287 amd_brand[ci->ci_brand_id]; 1288 else 1289 brand = amd_brand_name; 1290 } 1291 if (CPUID2FAMILY(ci->ci_signature) == 0xf) { 1292 /* Identify AMD64 CPU names. */ 1293 const char *tmp; 1294 tmp = amd_amd64_name(ci); 1295 if (tmp != NULL) 1296 name = tmp; 1297 } 1298 } 1299 1300 if (cpu_vendor == CPUVENDOR_IDT && ci->ci_family >= 6) 1301 vendorname = "VIA"; 1302 } 1303 } 1304 1305 ci->ci_cpu_class = class; 1306 1307 sz = sizeof(ci->ci_tsc_freq); 1308 (void)sysctlbyname("machdep.tsc_freq", &ci->ci_tsc_freq, &sz, NULL, 0); 1309 sz = sizeof(use_pae); 1310 (void)sysctlbyname("machdep.pae", &use_pae, &sz, NULL, 0); 1311 largepagesize = (use_pae ? 2 * 1024 * 1024 : 4 * 1024 * 1024); 1312 1313 /* 1314 * The 'cpu_brand_string' is much more useful than the 'cpu_model' 1315 * we try to determine from the family/model values. 1316 */ 1317 if (*cpu_brand_string != '\0') 1318 aprint_normal("%s: \"%s\"\n", cpuname, cpu_brand_string); 1319 1320 aprint_normal("%s: %s", cpuname, vendorname); 1321 if (*modifier) 1322 aprint_normal(" %s", modifier); 1323 if (*name) 1324 aprint_normal(" %s", name); 1325 if (*brand) 1326 aprint_normal(" %s", brand); 1327 aprint_normal(" (%s-class)", classnames[class]); 1328 1329 if (ci->ci_tsc_freq != 0) 1330 aprint_normal(", %ju.%02ju MHz\n", 1331 ((uintmax_t)ci->ci_tsc_freq + 4999) / 1000000, 1332 (((uintmax_t)ci->ci_tsc_freq + 4999) / 10000) % 100); 1333 1334 aprint_normal_dev(ci->ci_dev, "family %#x model %#x stepping %#x", 1335 ci->ci_family, ci->ci_model, CPUID2STEPPING(ci->ci_signature)); 1336 if (ci->ci_signature != 0) 1337 aprint_normal(" (id %#x)", ci->ci_signature); 1338 aprint_normal("\n"); 1339 1340 if (ci->ci_info) 1341 (*ci->ci_info)(ci); 1342 1343 /* 1344 * display CPU feature flags 1345 */ 1346 1347 print_bits(cpuname, "features", CPUID_FLAGS1, ci->ci_feat_val[0]); 1348 print_bits(cpuname, "features1", CPUID2_FLAGS1, ci->ci_feat_val[1]); 1349 1350 /* These next two are actually common definitions! */ 1351 print_bits(cpuname, "features2", 1352 cpu_vendor == CPUVENDOR_INTEL ? CPUID_INTEL_EXT_FLAGS 1353 : CPUID_EXT_FLAGS, ci->ci_feat_val[2]); 1354 print_bits(cpuname, "features3", 1355 cpu_vendor == CPUVENDOR_INTEL ? CPUID_INTEL_FLAGS4 1356 : CPUID_AMD_FLAGS4, ci->ci_feat_val[3]); 1357 1358 print_bits(cpuname, "padloack features", CPUID_FLAGS_PADLOCK, 1359 ci->ci_feat_val[4]); 1360 1361 print_bits(cpuname, "xsave features", XCR0_FLAGS1, ci->ci_feat_val[5]); 1362 print_bits(cpuname, "xsave instructions", CPUID_PES1_FLAGS, 1363 ci->ci_feat_val[6]); 1364 1365 if (ci->ci_max_xsave != 0) { 1366 aprint_normal("%s: xsave area size: current %d, maximum %d", 1367 cpuname, ci->ci_cur_xsave, ci->ci_max_xsave); 1368 aprint_normal(", xgetbv %sabled\n", 1369 ci->ci_feat_val[1] & CPUID2_OSXSAVE ? "en" : "dis"); 1370 if (ci->ci_feat_val[1] & CPUID2_OSXSAVE) 1371 print_bits(cpuname, "enabled xsave", XCR0_FLAGS1, 1372 x86_xgetbv()); 1373 } 1374 1375 x86_print_cacheinfo(ci); 1376 1377 if (ci->ci_cpuid_level >= 3 && (ci->ci_feat_val[0] & CPUID_PN)) { 1378 aprint_verbose("%s: serial number %04X-%04X-%04X-%04X-%04X-%04X\n", 1379 cpuname, 1380 ci->ci_cpu_serial[0] / 65536, ci->ci_cpu_serial[0] % 65536, 1381 ci->ci_cpu_serial[1] / 65536, ci->ci_cpu_serial[1] % 65536, 1382 ci->ci_cpu_serial[2] / 65536, ci->ci_cpu_serial[2] % 65536); 1383 } 1384 1385 if (ci->ci_cpu_class == CPUCLASS_386) { 1386 errx(1, "NetBSD requires an 80486 or later processor"); 1387 } 1388 1389 if (ci->ci_cpu_type == CPU_486DLC) { 1390 #ifndef CYRIX_CACHE_WORKS 1391 aprint_error("WARNING: CYRIX 486DLC CACHE UNCHANGED.\n"); 1392 #else 1393 #ifndef CYRIX_CACHE_REALLY_WORKS 1394 aprint_error("WARNING: CYRIX 486DLC CACHE ENABLED IN HOLD-FLUSH MODE.\n"); 1395 #else 1396 aprint_error("WARNING: CYRIX 486DLC CACHE ENABLED.\n"); 1397 #endif 1398 #endif 1399 } 1400 1401 /* 1402 * Everything past this point requires a Pentium or later. 1403 */ 1404 if (ci->ci_cpuid_level < 0) 1405 return; 1406 1407 identifycpu_cpuids(ci); 1408 1409 #ifdef INTEL_CORETEMP 1410 if (cpu_vendor == CPUVENDOR_INTEL && ci->ci_cpuid_level >= 0x06) 1411 coretemp_register(ci); 1412 #endif 1413 1414 if (cpu_vendor == CPUVENDOR_AMD) { 1415 uint32_t data[4]; 1416 1417 x86_cpuid(0x80000000, data); 1418 if (data[0] >= 0x80000007) 1419 powernow_probe(ci); 1420 1421 if ((data[0] >= 0x8000000a) 1422 && (ci->ci_feat_val[3] & CPUID_SVM) != 0) { 1423 x86_cpuid(0x8000000a, data); 1424 aprint_verbose("%s: SVM Rev. %d\n", cpuname, 1425 data[0] & 0xf); 1426 aprint_verbose("%s: SVM NASID %d\n", cpuname, data[1]); 1427 print_bits(cpuname, "SVM features", CPUID_AMD_SVM_FLAGS, 1428 data[3]); 1429 } 1430 } 1431 1432 #ifdef INTEL_ONDEMAND_CLOCKMOD 1433 clockmod_init(); 1434 #endif 1435 1436 if (cpu_vendor == CPUVENDOR_AMD) 1437 ucode.loader_version = CPU_UCODE_LOADER_AMD; 1438 else if (cpu_vendor == CPUVENDOR_INTEL) 1439 ucode.loader_version = CPU_UCODE_LOADER_INTEL1; 1440 else 1441 return; 1442 1443 ucode.data = &ucvers; 1444 if (ioctl(fd, IOC_CPU_UCODE_GET_VERSION, &ucode) < 0) { 1445 #ifdef __i386__ 1446 struct cpu_ucode_version_64 ucode_64; 1447 if (errno != ENOTTY) 1448 return; 1449 /* Try the 64 bit ioctl */ 1450 memset(&ucode_64, 0, sizeof ucode_64); 1451 ucode_64.data = &ucvers; 1452 ucode_64.loader_version = ucode.loader_version; 1453 if (ioctl(fd, IOC_CPU_UCODE_GET_VERSION_64, &ucode_64) < 0) 1454 return; 1455 #endif 1456 } 1457 1458 if (cpu_vendor == CPUVENDOR_AMD) 1459 printf("%s: UCode version: 0x%"PRIx64"\n", cpuname, ucvers.amd.version); 1460 else if (cpu_vendor == CPUVENDOR_INTEL) 1461 printf("%s: microcode version 0x%x, platform ID %d\n", cpuname, 1462 ucvers.intel1.ucodeversion, ucvers.intel1.platformid); 1463 } 1464 1465 static const char * 1466 print_cache_config(struct cpu_info *ci, int cache_tag, const char *name, 1467 const char *sep) 1468 { 1469 struct x86_cache_info *cai = &ci->ci_cinfo[cache_tag]; 1470 char human_num[HUMAN_BUFSIZE]; 1471 1472 if (cai->cai_totalsize == 0) 1473 return sep; 1474 1475 if (sep == NULL) 1476 aprint_verbose_dev(ci->ci_dev, ""); 1477 else 1478 aprint_verbose("%s", sep); 1479 if (name != NULL) 1480 aprint_verbose("%s ", name); 1481 1482 if (cai->cai_string != NULL) { 1483 aprint_verbose("%s ", cai->cai_string); 1484 } else { 1485 (void)humanize_number(human_num, sizeof(human_num), 1486 cai->cai_totalsize, "B", HN_AUTOSCALE, HN_NOSPACE); 1487 aprint_verbose("%s %dB/line ", human_num, cai->cai_linesize); 1488 } 1489 switch (cai->cai_associativity) { 1490 case 0: 1491 aprint_verbose("disabled"); 1492 break; 1493 case 1: 1494 aprint_verbose("direct-mapped"); 1495 break; 1496 case 0xff: 1497 aprint_verbose("fully associative"); 1498 break; 1499 default: 1500 aprint_verbose("%d-way", cai->cai_associativity); 1501 break; 1502 } 1503 return ", "; 1504 } 1505 1506 static const char * 1507 print_tlb_config(struct cpu_info *ci, int cache_tag, const char *name, 1508 const char *sep) 1509 { 1510 struct x86_cache_info *cai = &ci->ci_cinfo[cache_tag]; 1511 char human_num[HUMAN_BUFSIZE]; 1512 1513 if (cai->cai_totalsize == 0) 1514 return sep; 1515 1516 if (sep == NULL) 1517 aprint_verbose_dev(ci->ci_dev, ""); 1518 else 1519 aprint_verbose("%s", sep); 1520 if (name != NULL) 1521 aprint_verbose("%s ", name); 1522 1523 if (cai->cai_string != NULL) { 1524 aprint_verbose("%s", cai->cai_string); 1525 } else { 1526 (void)humanize_number(human_num, sizeof(human_num), 1527 cai->cai_linesize, "B", HN_AUTOSCALE, HN_NOSPACE); 1528 aprint_verbose("%d %s entries ", cai->cai_totalsize, 1529 human_num); 1530 switch (cai->cai_associativity) { 1531 case 0: 1532 aprint_verbose("disabled"); 1533 break; 1534 case 1: 1535 aprint_verbose("direct-mapped"); 1536 break; 1537 case 0xff: 1538 aprint_verbose("fully associative"); 1539 break; 1540 default: 1541 aprint_verbose("%d-way", cai->cai_associativity); 1542 break; 1543 } 1544 } 1545 return ", "; 1546 } 1547 1548 static const struct x86_cache_info * 1549 cache_info_lookup(const struct x86_cache_info *cai, uint8_t desc) 1550 { 1551 int i; 1552 1553 for (i = 0; cai[i].cai_desc != 0; i++) { 1554 if (cai[i].cai_desc == desc) 1555 return (&cai[i]); 1556 } 1557 1558 return (NULL); 1559 } 1560 1561 static const struct x86_cache_info amd_cpuid_l2cache_assoc_info[] = 1562 AMD_L2CACHE_INFO; 1563 1564 static const struct x86_cache_info amd_cpuid_l3cache_assoc_info[] = 1565 AMD_L3CACHE_INFO; 1566 1567 static void 1568 amd_cpu_cacheinfo(struct cpu_info *ci) 1569 { 1570 const struct x86_cache_info *cp; 1571 struct x86_cache_info *cai; 1572 u_int descs[4]; 1573 u_int lfunc; 1574 1575 /* 1576 * K5 model 0 has none of this info. 1577 */ 1578 if (ci->ci_family == 5 && ci->ci_model == 0) 1579 return; 1580 1581 /* 1582 * Determine the largest extended function value. 1583 */ 1584 x86_cpuid(0x80000000, descs); 1585 lfunc = descs[0]; 1586 1587 /* 1588 * Determine L1 cache/TLB info. 1589 */ 1590 if (lfunc < 0x80000005) { 1591 /* No L1 cache info available. */ 1592 return; 1593 } 1594 1595 x86_cpuid(0x80000005, descs); 1596 1597 /* 1598 * K6-III and higher have large page TLBs. 1599 */ 1600 if ((ci->ci_family == 5 && ci->ci_model >= 9) || ci->ci_family >= 6) { 1601 cai = &ci->ci_cinfo[CAI_ITLB2]; 1602 cai->cai_totalsize = AMD_L1_EAX_ITLB_ENTRIES(descs[0]); 1603 cai->cai_associativity = AMD_L1_EAX_ITLB_ASSOC(descs[0]); 1604 cai->cai_linesize = largepagesize; 1605 1606 cai = &ci->ci_cinfo[CAI_DTLB2]; 1607 cai->cai_totalsize = AMD_L1_EAX_DTLB_ENTRIES(descs[0]); 1608 cai->cai_associativity = AMD_L1_EAX_DTLB_ASSOC(descs[0]); 1609 cai->cai_linesize = largepagesize; 1610 } 1611 1612 cai = &ci->ci_cinfo[CAI_ITLB]; 1613 cai->cai_totalsize = AMD_L1_EBX_ITLB_ENTRIES(descs[1]); 1614 cai->cai_associativity = AMD_L1_EBX_ITLB_ASSOC(descs[1]); 1615 cai->cai_linesize = (4 * 1024); 1616 1617 cai = &ci->ci_cinfo[CAI_DTLB]; 1618 cai->cai_totalsize = AMD_L1_EBX_DTLB_ENTRIES(descs[1]); 1619 cai->cai_associativity = AMD_L1_EBX_DTLB_ASSOC(descs[1]); 1620 cai->cai_linesize = (4 * 1024); 1621 1622 cai = &ci->ci_cinfo[CAI_DCACHE]; 1623 cai->cai_totalsize = AMD_L1_ECX_DC_SIZE(descs[2]); 1624 cai->cai_associativity = AMD_L1_ECX_DC_ASSOC(descs[2]); 1625 cai->cai_linesize = AMD_L1_ECX_DC_LS(descs[2]); 1626 1627 cai = &ci->ci_cinfo[CAI_ICACHE]; 1628 cai->cai_totalsize = AMD_L1_EDX_IC_SIZE(descs[3]); 1629 cai->cai_associativity = AMD_L1_EDX_IC_ASSOC(descs[3]); 1630 cai->cai_linesize = AMD_L1_EDX_IC_LS(descs[3]); 1631 1632 /* 1633 * Determine L2 cache/TLB info. 1634 */ 1635 if (lfunc < 0x80000006) { 1636 /* No L2 cache info available. */ 1637 return; 1638 } 1639 1640 x86_cpuid(0x80000006, descs); 1641 1642 cai = &ci->ci_cinfo[CAI_L2_ITLB]; 1643 cai->cai_totalsize = AMD_L2_EBX_IUTLB_ENTRIES(descs[1]); 1644 cai->cai_associativity = AMD_L2_EBX_IUTLB_ASSOC(descs[1]); 1645 cai->cai_linesize = (4 * 1024); 1646 cp = cache_info_lookup(amd_cpuid_l2cache_assoc_info, 1647 cai->cai_associativity); 1648 if (cp != NULL) 1649 cai->cai_associativity = cp->cai_associativity; 1650 else 1651 cai->cai_associativity = 0; /* XXX Unknown/reserved */ 1652 1653 cai = &ci->ci_cinfo[CAI_L2_ITLB2]; 1654 cai->cai_totalsize = AMD_L2_EAX_IUTLB_ENTRIES(descs[0]); 1655 cai->cai_associativity = AMD_L2_EAX_IUTLB_ASSOC(descs[0]); 1656 cai->cai_linesize = largepagesize; 1657 cp = cache_info_lookup(amd_cpuid_l2cache_assoc_info, 1658 cai->cai_associativity); 1659 if (cp != NULL) 1660 cai->cai_associativity = cp->cai_associativity; 1661 else 1662 cai->cai_associativity = 0; /* XXX Unknown/reserved */ 1663 1664 cai = &ci->ci_cinfo[CAI_L2_DTLB]; 1665 cai->cai_totalsize = AMD_L2_EBX_DTLB_ENTRIES(descs[1]); 1666 cai->cai_associativity = AMD_L2_EBX_DTLB_ASSOC(descs[1]); 1667 cai->cai_linesize = (4 * 1024); 1668 cp = cache_info_lookup(amd_cpuid_l2cache_assoc_info, 1669 cai->cai_associativity); 1670 if (cp != NULL) 1671 cai->cai_associativity = cp->cai_associativity; 1672 else 1673 cai->cai_associativity = 0; /* XXX Unknown/reserved */ 1674 1675 cai = &ci->ci_cinfo[CAI_L2_DTLB2]; 1676 cai->cai_totalsize = AMD_L2_EAX_DTLB_ENTRIES(descs[0]); 1677 cai->cai_associativity = AMD_L2_EAX_DTLB_ASSOC(descs[0]); 1678 cai->cai_linesize = largepagesize; 1679 cp = cache_info_lookup(amd_cpuid_l2cache_assoc_info, 1680 cai->cai_associativity); 1681 if (cp != NULL) 1682 cai->cai_associativity = cp->cai_associativity; 1683 else 1684 cai->cai_associativity = 0; /* XXX Unknown/reserved */ 1685 1686 cai = &ci->ci_cinfo[CAI_L2CACHE]; 1687 cai->cai_totalsize = AMD_L2_ECX_C_SIZE(descs[2]); 1688 cai->cai_associativity = AMD_L2_ECX_C_ASSOC(descs[2]); 1689 cai->cai_linesize = AMD_L2_ECX_C_LS(descs[2]); 1690 1691 cp = cache_info_lookup(amd_cpuid_l2cache_assoc_info, 1692 cai->cai_associativity); 1693 if (cp != NULL) 1694 cai->cai_associativity = cp->cai_associativity; 1695 else 1696 cai->cai_associativity = 0; /* XXX Unknown/reserved */ 1697 1698 /* 1699 * Determine L3 cache info on AMD Family 10h and newer processors 1700 */ 1701 if (ci->ci_family >= 0x10) { 1702 cai = &ci->ci_cinfo[CAI_L3CACHE]; 1703 cai->cai_totalsize = AMD_L3_EDX_C_SIZE(descs[3]); 1704 cai->cai_associativity = AMD_L3_EDX_C_ASSOC(descs[3]); 1705 cai->cai_linesize = AMD_L3_EDX_C_LS(descs[3]); 1706 1707 cp = cache_info_lookup(amd_cpuid_l3cache_assoc_info, 1708 cai->cai_associativity); 1709 if (cp != NULL) 1710 cai->cai_associativity = cp->cai_associativity; 1711 else 1712 cai->cai_associativity = 0; /* XXX Unkn/Rsvd */ 1713 } 1714 1715 /* 1716 * Determine 1GB TLB info. 1717 */ 1718 if (lfunc < 0x80000019) { 1719 /* No 1GB TLB info available. */ 1720 return; 1721 } 1722 1723 x86_cpuid(0x80000019, descs); 1724 1725 cai = &ci->ci_cinfo[CAI_L1_1GBITLB]; 1726 cai->cai_totalsize = AMD_L1_1GB_EAX_IUTLB_ENTRIES(descs[0]); 1727 cai->cai_associativity = AMD_L1_1GB_EAX_IUTLB_ASSOC(descs[0]); 1728 cai->cai_linesize = (1024 * 1024 * 1024); 1729 cp = cache_info_lookup(amd_cpuid_l2cache_assoc_info, 1730 cai->cai_associativity); 1731 if (cp != NULL) 1732 cai->cai_associativity = cp->cai_associativity; 1733 else 1734 cai->cai_associativity = 0; /* XXX Unknown/reserved */ 1735 1736 cai = &ci->ci_cinfo[CAI_L1_1GBDTLB]; 1737 cai->cai_totalsize = AMD_L1_1GB_EAX_DTLB_ENTRIES(descs[0]); 1738 cai->cai_associativity = AMD_L1_1GB_EAX_DTLB_ASSOC(descs[0]); 1739 cai->cai_linesize = (1024 * 1024 * 1024); 1740 cp = cache_info_lookup(amd_cpuid_l2cache_assoc_info, 1741 cai->cai_associativity); 1742 if (cp != NULL) 1743 cai->cai_associativity = cp->cai_associativity; 1744 else 1745 cai->cai_associativity = 0; /* XXX Unknown/reserved */ 1746 1747 cai = &ci->ci_cinfo[CAI_L2_1GBITLB]; 1748 cai->cai_totalsize = AMD_L2_1GB_EBX_IUTLB_ENTRIES(descs[1]); 1749 cai->cai_associativity = AMD_L2_1GB_EBX_IUTLB_ASSOC(descs[1]); 1750 cai->cai_linesize = (1024 * 1024 * 1024); 1751 cp = cache_info_lookup(amd_cpuid_l2cache_assoc_info, 1752 cai->cai_associativity); 1753 if (cp != NULL) 1754 cai->cai_associativity = cp->cai_associativity; 1755 else 1756 cai->cai_associativity = 0; /* XXX Unknown/reserved */ 1757 1758 cai = &ci->ci_cinfo[CAI_L2_1GBDTLB]; 1759 cai->cai_totalsize = AMD_L2_1GB_EBX_DUTLB_ENTRIES(descs[1]); 1760 cai->cai_associativity = AMD_L2_1GB_EBX_DUTLB_ASSOC(descs[1]); 1761 cai->cai_linesize = (1024 * 1024 * 1024); 1762 cp = cache_info_lookup(amd_cpuid_l2cache_assoc_info, 1763 cai->cai_associativity); 1764 if (cp != NULL) 1765 cai->cai_associativity = cp->cai_associativity; 1766 else 1767 cai->cai_associativity = 0; /* XXX Unknown/reserved */ 1768 } 1769 1770 static void 1771 via_cpu_cacheinfo(struct cpu_info *ci) 1772 { 1773 struct x86_cache_info *cai; 1774 int stepping; 1775 u_int descs[4]; 1776 u_int lfunc; 1777 1778 stepping = CPUID2STEPPING(ci->ci_signature); 1779 1780 /* 1781 * Determine the largest extended function value. 1782 */ 1783 x86_cpuid(0x80000000, descs); 1784 lfunc = descs[0]; 1785 1786 /* 1787 * Determine L1 cache/TLB info. 1788 */ 1789 if (lfunc < 0x80000005) { 1790 /* No L1 cache info available. */ 1791 return; 1792 } 1793 1794 x86_cpuid(0x80000005, descs); 1795 1796 cai = &ci->ci_cinfo[CAI_ITLB]; 1797 cai->cai_totalsize = VIA_L1_EBX_ITLB_ENTRIES(descs[1]); 1798 cai->cai_associativity = VIA_L1_EBX_ITLB_ASSOC(descs[1]); 1799 cai->cai_linesize = (4 * 1024); 1800 1801 cai = &ci->ci_cinfo[CAI_DTLB]; 1802 cai->cai_totalsize = VIA_L1_EBX_DTLB_ENTRIES(descs[1]); 1803 cai->cai_associativity = VIA_L1_EBX_DTLB_ASSOC(descs[1]); 1804 cai->cai_linesize = (4 * 1024); 1805 1806 cai = &ci->ci_cinfo[CAI_DCACHE]; 1807 cai->cai_totalsize = VIA_L1_ECX_DC_SIZE(descs[2]); 1808 cai->cai_associativity = VIA_L1_ECX_DC_ASSOC(descs[2]); 1809 cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[2]); 1810 if (ci->ci_model == 9 && stepping == 8) { 1811 /* Erratum: stepping 8 reports 4 when it should be 2 */ 1812 cai->cai_associativity = 2; 1813 } 1814 1815 cai = &ci->ci_cinfo[CAI_ICACHE]; 1816 cai->cai_totalsize = VIA_L1_EDX_IC_SIZE(descs[3]); 1817 cai->cai_associativity = VIA_L1_EDX_IC_ASSOC(descs[3]); 1818 cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[3]); 1819 if (ci->ci_model == 9 && stepping == 8) { 1820 /* Erratum: stepping 8 reports 4 when it should be 2 */ 1821 cai->cai_associativity = 2; 1822 } 1823 1824 /* 1825 * Determine L2 cache/TLB info. 1826 */ 1827 if (lfunc < 0x80000006) { 1828 /* No L2 cache info available. */ 1829 return; 1830 } 1831 1832 x86_cpuid(0x80000006, descs); 1833 1834 cai = &ci->ci_cinfo[CAI_L2CACHE]; 1835 if (ci->ci_model >= 9) { 1836 cai->cai_totalsize = VIA_L2N_ECX_C_SIZE(descs[2]); 1837 cai->cai_associativity = VIA_L2N_ECX_C_ASSOC(descs[2]); 1838 cai->cai_linesize = VIA_L2N_ECX_C_LS(descs[2]); 1839 } else { 1840 cai->cai_totalsize = VIA_L2_ECX_C_SIZE(descs[2]); 1841 cai->cai_associativity = VIA_L2_ECX_C_ASSOC(descs[2]); 1842 cai->cai_linesize = VIA_L2_ECX_C_LS(descs[2]); 1843 } 1844 } 1845 1846 static void 1847 x86_print_cacheinfo(struct cpu_info *ci) 1848 { 1849 const char *sep; 1850 1851 if (ci->ci_cinfo[CAI_ICACHE].cai_totalsize != 0 || 1852 ci->ci_cinfo[CAI_DCACHE].cai_totalsize != 0) { 1853 sep = print_cache_config(ci, CAI_ICACHE, "I-cache", NULL); 1854 sep = print_cache_config(ci, CAI_DCACHE, "D-cache", sep); 1855 if (sep != NULL) 1856 aprint_verbose("\n"); 1857 } 1858 if (ci->ci_cinfo[CAI_L2CACHE].cai_totalsize != 0) { 1859 sep = print_cache_config(ci, CAI_L2CACHE, "L2 cache", NULL); 1860 if (sep != NULL) 1861 aprint_verbose("\n"); 1862 } 1863 if (ci->ci_cinfo[CAI_L3CACHE].cai_totalsize != 0) { 1864 sep = print_cache_config(ci, CAI_L3CACHE, "L3 cache", NULL); 1865 if (sep != NULL) 1866 aprint_verbose("\n"); 1867 } 1868 if (ci->ci_cinfo[CAI_ITLB].cai_totalsize != 0) { 1869 sep = print_tlb_config(ci, CAI_ITLB, "ITLB", NULL); 1870 sep = print_tlb_config(ci, CAI_ITLB2, NULL, sep); 1871 if (sep != NULL) 1872 aprint_verbose("\n"); 1873 } 1874 if (ci->ci_cinfo[CAI_DTLB].cai_totalsize != 0) { 1875 sep = print_tlb_config(ci, CAI_DTLB, "DTLB", NULL); 1876 sep = print_tlb_config(ci, CAI_DTLB2, NULL, sep); 1877 if (sep != NULL) 1878 aprint_verbose("\n"); 1879 } 1880 if (ci->ci_cinfo[CAI_L2_ITLB].cai_totalsize != 0) { 1881 sep = print_tlb_config(ci, CAI_L2_ITLB, "L2 ITLB", NULL); 1882 sep = print_tlb_config(ci, CAI_L2_ITLB2, NULL, sep); 1883 if (sep != NULL) 1884 aprint_verbose("\n"); 1885 } 1886 if (ci->ci_cinfo[CAI_L2_DTLB].cai_totalsize != 0) { 1887 sep = print_tlb_config(ci, CAI_L2_DTLB, "L2 DTLB", NULL); 1888 sep = print_tlb_config(ci, CAI_L2_DTLB2, NULL, sep); 1889 if (sep != NULL) 1890 aprint_verbose("\n"); 1891 } 1892 if (ci->ci_cinfo[CAI_L1_1GBITLB].cai_totalsize != 0) { 1893 sep = print_tlb_config(ci, CAI_L1_1GBITLB, "L1 1GB page ITLB", NULL); 1894 if (sep != NULL) 1895 aprint_verbose("\n"); 1896 } 1897 if (ci->ci_cinfo[CAI_L1_1GBDTLB].cai_totalsize != 0) { 1898 sep = print_tlb_config(ci, CAI_L1_1GBDTLB, "L1 1GB page DTLB", NULL); 1899 if (sep != NULL) 1900 aprint_verbose("\n"); 1901 } 1902 if (ci->ci_cinfo[CAI_L2_1GBITLB].cai_totalsize != 0) { 1903 sep = print_tlb_config(ci, CAI_L2_1GBITLB, "L2 1GB page ITLB", NULL); 1904 if (sep != NULL) 1905 aprint_verbose("\n"); 1906 } 1907 if (ci->ci_cinfo[CAI_L2_1GBDTLB].cai_totalsize != 0) { 1908 sep = print_tlb_config(ci, CAI_L2_1GBDTLB, "L2 1GB page DTLB", NULL); 1909 if (sep != NULL) 1910 aprint_verbose("\n"); 1911 } 1912 } 1913 1914 static void 1915 powernow_probe(struct cpu_info *ci) 1916 { 1917 uint32_t regs[4]; 1918 char buf[256]; 1919 1920 x86_cpuid(0x80000007, regs); 1921 1922 snprintb(buf, sizeof(buf), CPUID_APM_FLAGS, regs[3]); 1923 aprint_normal_dev(ci->ci_dev, "AMD Power Management features: %s\n", 1924 buf); 1925 } 1926 1927 int 1928 ucodeupdate_check(int fd, struct cpu_ucode *uc) 1929 { 1930 struct cpu_info ci; 1931 int loader_version, res; 1932 struct cpu_ucode_version versreq; 1933 1934 cpu_probe_base_features(&ci, "unknown"); 1935 1936 if (!strcmp((char *)ci.ci_vendor, "AuthenticAMD")) 1937 loader_version = CPU_UCODE_LOADER_AMD; 1938 else if (!strcmp((char *)ci.ci_vendor, "GenuineIntel")) 1939 loader_version = CPU_UCODE_LOADER_INTEL1; 1940 else 1941 return -1; 1942 1943 /* check whether the kernel understands this loader version */ 1944 versreq.loader_version = loader_version; 1945 versreq.data = 0; 1946 res = ioctl(fd, IOC_CPU_UCODE_GET_VERSION, &versreq); 1947 if (res) 1948 return -1; 1949 1950 switch (loader_version) { 1951 case CPU_UCODE_LOADER_AMD: 1952 if (uc->cpu_nr != -1) { 1953 /* printf? */ 1954 return -1; 1955 } 1956 uc->cpu_nr = CPU_UCODE_ALL_CPUS; 1957 break; 1958 case CPU_UCODE_LOADER_INTEL1: 1959 if (uc->cpu_nr == -1) 1960 uc->cpu_nr = CPU_UCODE_ALL_CPUS; /* for Xen */ 1961 else 1962 uc->cpu_nr = CPU_UCODE_CURRENT_CPU; 1963 break; 1964 default: /* can't happen */ 1965 return -1; 1966 } 1967 uc->loader_version = loader_version; 1968 return 0; 1969 } 1970