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