1 /* $NetBSD: identcpu.c,v 1.50 2016/01/01 19:46:48 tls 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 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.50 2016/01/01 19:46:48 tls Exp $"); 34 35 #include "opt_xen.h" 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/device.h> 40 #include <sys/cpu.h> 41 42 #include <uvm/uvm_extern.h> 43 44 #include <machine/specialreg.h> 45 #include <machine/pio.h> 46 #include <machine/cpu.h> 47 48 #include <x86/cputypes.h> 49 #include <x86/cacheinfo.h> 50 #include <x86/cpuvar.h> 51 #include <x86/cpu_msr.h> 52 53 static const struct x86_cache_info intel_cpuid_cache_info[] = INTEL_CACHE_INFO; 54 55 static const struct x86_cache_info amd_cpuid_l2cache_assoc_info[] = 56 AMD_L2CACHE_INFO; 57 58 static const struct x86_cache_info amd_cpuid_l3cache_assoc_info[] = 59 AMD_L3CACHE_INFO; 60 61 int cpu_vendor; 62 char cpu_brand_string[49]; 63 64 int x86_fpu_save = FPU_SAVE_FSAVE; 65 unsigned int x86_fpu_save_size = 512; 66 uint64_t x86_xsave_features = 0; 67 68 /* 69 * Note: these are just the ones that may not have a cpuid instruction. 70 * We deal with the rest in a different way. 71 */ 72 const int i386_nocpuid_cpus[] = { 73 CPUVENDOR_INTEL, CPUCLASS_386, /* CPU_386SX */ 74 CPUVENDOR_INTEL, CPUCLASS_386, /* CPU_386 */ 75 CPUVENDOR_INTEL, CPUCLASS_486, /* CPU_486SX */ 76 CPUVENDOR_INTEL, CPUCLASS_486, /* CPU_486 */ 77 CPUVENDOR_CYRIX, CPUCLASS_486, /* CPU_486DLC */ 78 CPUVENDOR_CYRIX, CPUCLASS_486, /* CPU_6x86 */ 79 CPUVENDOR_NEXGEN, CPUCLASS_386, /* CPU_NX586 */ 80 }; 81 82 static const char cpu_vendor_names[][10] = { 83 "Unknown", "Intel", "NS/Cyrix", "NexGen", "AMD", "IDT/VIA", "Transmeta", 84 "Vortex86" 85 }; 86 87 static const struct x86_cache_info * 88 cache_info_lookup(const struct x86_cache_info *cai, uint8_t desc) 89 { 90 int i; 91 92 for (i = 0; cai[i].cai_desc != 0; i++) { 93 if (cai[i].cai_desc == desc) 94 return (&cai[i]); 95 } 96 97 return (NULL); 98 } 99 100 static void 101 cpu_probe_intel_cache(struct cpu_info *ci) 102 { 103 const struct x86_cache_info *cai; 104 u_int descs[4]; 105 int iterations, i, j; 106 uint8_t desc; 107 108 if (cpuid_level >= 2) { 109 /* Parse the cache info from `cpuid leaf 2', if we have it. */ 110 x86_cpuid(2, descs); 111 iterations = descs[0] & 0xff; 112 while (iterations-- > 0) { 113 for (i = 0; i < 4; i++) { 114 if (descs[i] & 0x80000000) 115 continue; 116 for (j = 0; j < 4; j++) { 117 if (i == 0 && j == 0) 118 continue; 119 desc = (descs[i] >> (j * 8)) & 0xff; 120 if (desc == 0) 121 continue; 122 cai = cache_info_lookup( 123 intel_cpuid_cache_info, desc); 124 if (cai != NULL) { 125 ci->ci_cinfo[cai->cai_index] = 126 *cai; 127 } 128 } 129 } 130 } 131 } 132 133 if (cpuid_level >= 4) { 134 int type, level; 135 int ways, partitions, linesize, sets; 136 int caitype = -1; 137 int totalsize; 138 139 /* Parse the cache info from `cpuid leaf 4', if we have it. */ 140 for (i = 0; ; i++) { 141 x86_cpuid2(4, i, descs); 142 type = __SHIFTOUT(descs[0], CPUID_DCP_CACHETYPE); 143 if (type == CPUID_DCP_CACHETYPE_N) 144 break; 145 level = __SHIFTOUT(descs[0], CPUID_DCP_CACHELEVEL); 146 switch (level) { 147 case 1: 148 if (type == CPUID_DCP_CACHETYPE_I) 149 caitype = CAI_ICACHE; 150 else if (type == CPUID_DCP_CACHETYPE_D) 151 caitype = CAI_DCACHE; 152 else 153 caitype = -1; 154 break; 155 case 2: 156 if (type == CPUID_DCP_CACHETYPE_U) 157 caitype = CAI_L2CACHE; 158 else 159 caitype = -1; 160 break; 161 case 3: 162 if (type == CPUID_DCP_CACHETYPE_U) 163 caitype = CAI_L3CACHE; 164 else 165 caitype = -1; 166 break; 167 default: 168 caitype = -1; 169 break; 170 } 171 if (caitype == -1) 172 continue; 173 174 ways = __SHIFTOUT(descs[1], CPUID_DCP_WAYS) + 1; 175 partitions =__SHIFTOUT(descs[1], CPUID_DCP_PARTITIONS) 176 + 1; 177 linesize = __SHIFTOUT(descs[1], CPUID_DCP_LINESIZE) 178 + 1; 179 sets = descs[2] + 1; 180 totalsize = ways * partitions * linesize * sets; 181 ci->ci_cinfo[caitype].cai_totalsize = totalsize; 182 ci->ci_cinfo[caitype].cai_associativity = ways; 183 ci->ci_cinfo[caitype].cai_linesize = linesize; 184 } 185 } 186 } 187 188 static void 189 cpu_probe_intel(struct cpu_info *ci) 190 { 191 192 if (cpu_vendor != CPUVENDOR_INTEL) 193 return; 194 195 cpu_probe_intel_cache(ci); 196 } 197 198 static void 199 cpu_probe_amd_cache(struct cpu_info *ci) 200 { 201 const struct x86_cache_info *cp; 202 struct x86_cache_info *cai; 203 int family, model; 204 u_int descs[4]; 205 u_int lfunc; 206 207 family = CPUID_TO_FAMILY(ci->ci_signature); 208 model = CPUID_TO_MODEL(ci->ci_signature); 209 210 /* 211 * K5 model 0 has none of this info. 212 */ 213 if (family == 5 && model == 0) 214 return; 215 216 /* 217 * Determine the largest extended function value. 218 */ 219 x86_cpuid(0x80000000, descs); 220 lfunc = descs[0]; 221 222 /* 223 * Determine L1 cache/TLB info. 224 */ 225 if (lfunc < 0x80000005) { 226 /* No L1 cache info available. */ 227 return; 228 } 229 230 x86_cpuid(0x80000005, descs); 231 232 /* 233 * K6-III and higher have large page TLBs. 234 */ 235 if ((family == 5 && model >= 9) || family >= 6) { 236 cai = &ci->ci_cinfo[CAI_ITLB2]; 237 cai->cai_totalsize = AMD_L1_EAX_ITLB_ENTRIES(descs[0]); 238 cai->cai_associativity = AMD_L1_EAX_ITLB_ASSOC(descs[0]); 239 cai->cai_linesize = (4 * 1024 * 1024); 240 241 cai = &ci->ci_cinfo[CAI_DTLB2]; 242 cai->cai_totalsize = AMD_L1_EAX_DTLB_ENTRIES(descs[0]); 243 cai->cai_associativity = AMD_L1_EAX_DTLB_ASSOC(descs[0]); 244 cai->cai_linesize = (4 * 1024 * 1024); 245 } 246 247 cai = &ci->ci_cinfo[CAI_ITLB]; 248 cai->cai_totalsize = AMD_L1_EBX_ITLB_ENTRIES(descs[1]); 249 cai->cai_associativity = AMD_L1_EBX_ITLB_ASSOC(descs[1]); 250 cai->cai_linesize = (4 * 1024); 251 252 cai = &ci->ci_cinfo[CAI_DTLB]; 253 cai->cai_totalsize = AMD_L1_EBX_DTLB_ENTRIES(descs[1]); 254 cai->cai_associativity = AMD_L1_EBX_DTLB_ASSOC(descs[1]); 255 cai->cai_linesize = (4 * 1024); 256 257 cai = &ci->ci_cinfo[CAI_DCACHE]; 258 cai->cai_totalsize = AMD_L1_ECX_DC_SIZE(descs[2]); 259 cai->cai_associativity = AMD_L1_ECX_DC_ASSOC(descs[2]); 260 cai->cai_linesize = AMD_L1_ECX_DC_LS(descs[2]); 261 262 cai = &ci->ci_cinfo[CAI_ICACHE]; 263 cai->cai_totalsize = AMD_L1_EDX_IC_SIZE(descs[3]); 264 cai->cai_associativity = AMD_L1_EDX_IC_ASSOC(descs[3]); 265 cai->cai_linesize = AMD_L1_EDX_IC_LS(descs[3]); 266 267 /* 268 * Determine L2 cache/TLB info. 269 */ 270 if (lfunc < 0x80000006) { 271 /* No L2 cache info available. */ 272 return; 273 } 274 275 x86_cpuid(0x80000006, descs); 276 277 cai = &ci->ci_cinfo[CAI_L2CACHE]; 278 cai->cai_totalsize = AMD_L2_ECX_C_SIZE(descs[2]); 279 cai->cai_associativity = AMD_L2_ECX_C_ASSOC(descs[2]); 280 cai->cai_linesize = AMD_L2_ECX_C_LS(descs[2]); 281 282 cp = cache_info_lookup(amd_cpuid_l2cache_assoc_info, 283 cai->cai_associativity); 284 if (cp != NULL) 285 cai->cai_associativity = cp->cai_associativity; 286 else 287 cai->cai_associativity = 0; /* XXX Unknown/reserved */ 288 289 if (family < 0xf) { 290 /* No L3 cache info available. */ 291 return; 292 } 293 294 cai = &ci->ci_cinfo[CAI_L3CACHE]; 295 cai->cai_totalsize = AMD_L3_EDX_C_SIZE(descs[3]); 296 cai->cai_associativity = AMD_L3_EDX_C_ASSOC(descs[3]); 297 cai->cai_linesize = AMD_L3_EDX_C_LS(descs[3]); 298 299 cp = cache_info_lookup(amd_cpuid_l3cache_assoc_info, 300 cai->cai_associativity); 301 if (cp != NULL) 302 cai->cai_associativity = cp->cai_associativity; 303 else 304 cai->cai_associativity = 0; /* XXX Unknown reserved */ 305 306 if (lfunc < 0x80000019) { 307 /* No 1GB Page TLB */ 308 return; 309 } 310 311 x86_cpuid(0x80000019, descs); 312 313 cai = &ci->ci_cinfo[CAI_L1_1GBDTLB]; 314 cai->cai_totalsize = AMD_L1_1GB_EAX_DTLB_ENTRIES(descs[1]); 315 cai->cai_associativity = AMD_L1_1GB_EAX_DTLB_ASSOC(descs[1]); 316 cai->cai_linesize = (1 * 1024); 317 318 cai = &ci->ci_cinfo[CAI_L1_1GBITLB]; 319 cai->cai_totalsize = AMD_L1_1GB_EAX_IUTLB_ENTRIES(descs[0]); 320 cai->cai_associativity = AMD_L1_1GB_EAX_IUTLB_ASSOC(descs[0]); 321 cai->cai_linesize = (1 * 1024); 322 323 cai = &ci->ci_cinfo[CAI_L2_1GBDTLB]; 324 cai->cai_totalsize = AMD_L2_1GB_EBX_DUTLB_ENTRIES(descs[1]); 325 cai->cai_associativity = AMD_L2_1GB_EBX_DUTLB_ASSOC(descs[1]); 326 cai->cai_linesize = (1 * 1024); 327 328 cai = &ci->ci_cinfo[CAI_L2_1GBITLB]; 329 cai->cai_totalsize = AMD_L2_1GB_EBX_IUTLB_ENTRIES(descs[0]); 330 cai->cai_associativity = AMD_L2_1GB_EBX_IUTLB_ASSOC(descs[0]); 331 cai->cai_linesize = (1 * 1024); 332 } 333 334 static void 335 cpu_probe_k5(struct cpu_info *ci) 336 { 337 int flag; 338 339 if (cpu_vendor != CPUVENDOR_AMD || 340 CPUID_TO_FAMILY(ci->ci_signature) != 5) 341 return; 342 343 if (CPUID_TO_MODEL(ci->ci_signature) == 0) { 344 /* 345 * According to the AMD Processor Recognition App Note, 346 * the AMD-K5 Model 0 uses the wrong bit to indicate 347 * support for global PTEs, instead using bit 9 (APIC) 348 * rather than bit 13 (i.e. "0x200" vs. 0x2000". Oops!). 349 */ 350 flag = ci->ci_feat_val[0]; 351 if ((flag & CPUID_APIC) != 0) 352 flag = (flag & ~CPUID_APIC) | CPUID_PGE; 353 ci->ci_feat_val[0] = flag; 354 } 355 356 cpu_probe_amd_cache(ci); 357 } 358 359 static void 360 cpu_probe_k678(struct cpu_info *ci) 361 { 362 363 if (cpu_vendor != CPUVENDOR_AMD || 364 CPUID_TO_FAMILY(ci->ci_signature) < 6) 365 return; 366 367 cpu_probe_amd_cache(ci); 368 } 369 370 static inline uint8_t 371 cyrix_read_reg(uint8_t reg) 372 { 373 374 outb(0x22, reg); 375 return inb(0x23); 376 } 377 378 static inline void 379 cyrix_write_reg(uint8_t reg, uint8_t data) 380 { 381 382 outb(0x22, reg); 383 outb(0x23, data); 384 } 385 386 static void 387 cpu_probe_cyrix_cmn(struct cpu_info *ci) 388 { 389 /* 390 * i8254 latch check routine: 391 * National Geode (formerly Cyrix MediaGX) has a serious bug in 392 * its built-in i8254-compatible clock module (cs5510 cs5520). 393 * Set the variable 'clock_broken_latch' to indicate it. 394 * 395 * This bug is not present in the cs5530, and the flag 396 * is disabled again in sys/arch/i386/pci/pcib.c if this later 397 * model device is detected. Ideally, this work-around should not 398 * even be in here, it should be in there. XXX 399 */ 400 uint8_t c3; 401 #ifndef XEN 402 extern int clock_broken_latch; 403 404 switch (ci->ci_signature) { 405 case 0x440: /* Cyrix MediaGX */ 406 case 0x540: /* GXm */ 407 clock_broken_latch = 1; 408 break; 409 } 410 #endif 411 412 /* set up various cyrix registers */ 413 /* 414 * Enable suspend on halt (powersave mode). 415 * When powersave mode is enabled, the TSC stops counting 416 * while the CPU is halted in idle() waiting for an interrupt. 417 * This means we can't use the TSC for interval time in 418 * microtime(9), and thus it is disabled here. 419 * 420 * It still makes a perfectly good cycle counter 421 * for program profiling, so long as you remember you're 422 * counting cycles, and not time. Further, if you don't 423 * mind not using powersave mode, the TSC works just fine, 424 * so this should really be optional. XXX 425 */ 426 cyrix_write_reg(0xc2, cyrix_read_reg(0xc2) | 0x08); 427 428 /* 429 * Do not disable the TSC on the Geode GX, it's reported to 430 * work fine. 431 */ 432 if (ci->ci_signature != 0x552) 433 ci->ci_feat_val[0] &= ~CPUID_TSC; 434 435 /* enable access to ccr4/ccr5 */ 436 c3 = cyrix_read_reg(0xC3); 437 cyrix_write_reg(0xC3, c3 | 0x10); 438 /* cyrix's workaround for the "coma bug" */ 439 cyrix_write_reg(0x31, cyrix_read_reg(0x31) | 0xf8); 440 cyrix_write_reg(0x32, cyrix_read_reg(0x32) | 0x7f); 441 cyrix_write_reg(0x33, cyrix_read_reg(0x33) & ~0xff); 442 cyrix_write_reg(0x3c, cyrix_read_reg(0x3c) | 0x87); 443 /* disable access to ccr4/ccr5 */ 444 cyrix_write_reg(0xC3, c3); 445 } 446 447 static void 448 cpu_probe_cyrix(struct cpu_info *ci) 449 { 450 451 if (cpu_vendor != CPUVENDOR_CYRIX || 452 CPUID_TO_FAMILY(ci->ci_signature) < 4 || 453 CPUID_TO_FAMILY(ci->ci_signature) > 6) 454 return; 455 456 cpu_probe_cyrix_cmn(ci); 457 } 458 459 static void 460 cpu_probe_winchip(struct cpu_info *ci) 461 { 462 463 if (cpu_vendor != CPUVENDOR_IDT) 464 return; 465 466 switch (CPUID_TO_FAMILY(ci->ci_signature)) { 467 case 5: 468 /* WinChip C6 */ 469 if (CPUID_TO_MODEL(ci->ci_signature) == 4) 470 ci->ci_feat_val[0] &= ~CPUID_TSC; 471 break; 472 case 6: 473 /* 474 * VIA Eden ESP 475 * 476 * Quoting from page 3-4 of: "VIA Eden ESP Processor Datasheet" 477 * http://www.via.com.tw/download/mainboards/6/14/Eden20v115.pdf 478 * 479 * 1. The CMPXCHG8B instruction is provided and always enabled, 480 * however, it appears disabled in the corresponding CPUID 481 * function bit 0 to avoid a bug in an early version of 482 * Windows NT. However, this default can be changed via a 483 * bit in the FCR MSR. 484 */ 485 ci->ci_feat_val[0] |= CPUID_CX8; 486 wrmsr(MSR_VIA_FCR, rdmsr(MSR_VIA_FCR) | 0x00000001); 487 break; 488 } 489 } 490 491 static void 492 cpu_probe_c3(struct cpu_info *ci) 493 { 494 u_int family, model, stepping, descs[4], lfunc, msr; 495 struct x86_cache_info *cai; 496 497 if (cpu_vendor != CPUVENDOR_IDT || 498 CPUID_TO_FAMILY(ci->ci_signature) < 6) 499 return; 500 501 family = CPUID_TO_FAMILY(ci->ci_signature); 502 model = CPUID_TO_MODEL(ci->ci_signature); 503 stepping = CPUID_TO_STEPPING(ci->ci_signature); 504 505 /* Determine the largest extended function value. */ 506 x86_cpuid(0x80000000, descs); 507 lfunc = descs[0]; 508 509 if (family > 6 || model > 0x9 || (model == 0x9 && stepping >= 3)) { 510 /* Nehemiah or Esther */ 511 x86_cpuid(0xc0000000, descs); 512 lfunc = descs[0]; 513 if (lfunc >= 0xc0000001) { /* has ACE, RNG */ 514 int rng_enable = 0, ace_enable = 0; 515 x86_cpuid(0xc0000001, descs); 516 lfunc = descs[3]; 517 ci->ci_feat_val[4] = lfunc; 518 /* Check for and enable RNG */ 519 if (lfunc & CPUID_VIA_HAS_RNG) { 520 if (!(lfunc & CPUID_VIA_DO_RNG)) { 521 rng_enable++; 522 ci->ci_feat_val[4] |= CPUID_VIA_DO_RNG; 523 } 524 } 525 /* Check for and enable ACE (AES-CBC) */ 526 if (lfunc & CPUID_VIA_HAS_ACE) { 527 if (!(lfunc & CPUID_VIA_DO_ACE)) { 528 ace_enable++; 529 ci->ci_feat_val[4] |= CPUID_VIA_DO_ACE; 530 } 531 } 532 /* Check for and enable SHA */ 533 if (lfunc & CPUID_VIA_HAS_PHE) { 534 if (!(lfunc & CPUID_VIA_DO_PHE)) { 535 ace_enable++; 536 ci->ci_feat_val[4] |= CPUID_VIA_DO_PHE; 537 } 538 } 539 /* Check for and enable ACE2 (AES-CTR) */ 540 if (lfunc & CPUID_VIA_HAS_ACE2) { 541 if (!(lfunc & CPUID_VIA_DO_ACE2)) { 542 ace_enable++; 543 ci->ci_feat_val[4] |= CPUID_VIA_DO_ACE2; 544 } 545 } 546 /* Check for and enable PMM (modmult engine) */ 547 if (lfunc & CPUID_VIA_HAS_PMM) { 548 if (!(lfunc & CPUID_VIA_DO_PMM)) { 549 ace_enable++; 550 ci->ci_feat_val[4] |= CPUID_VIA_DO_PMM; 551 } 552 } 553 554 /* Actually do the enables. */ 555 if (rng_enable) { 556 msr = rdmsr(MSR_VIA_RNG); 557 msr |= MSR_VIA_RNG_ENABLE; 558 /* C7 stepping 8 and subsequent CPUs have dual RNG */ 559 if (model > 0xA || (model == 0xA && stepping > 0x7)) { 560 msr |= MSR_VIA_RNG_2NOISE; 561 } 562 wrmsr(MSR_VIA_RNG, msr); 563 } 564 565 if (ace_enable) { 566 msr = rdmsr(MSR_VIA_ACE); 567 wrmsr(MSR_VIA_ACE, msr | MSR_VIA_ACE_ENABLE); 568 } 569 570 } 571 } 572 573 /* 574 * Determine L1 cache/TLB info. 575 */ 576 if (lfunc < 0x80000005) { 577 /* No L1 cache info available. */ 578 return; 579 } 580 581 x86_cpuid(0x80000005, descs); 582 583 cai = &ci->ci_cinfo[CAI_ITLB]; 584 cai->cai_totalsize = VIA_L1_EBX_ITLB_ENTRIES(descs[1]); 585 cai->cai_associativity = VIA_L1_EBX_ITLB_ASSOC(descs[1]); 586 cai->cai_linesize = (4 * 1024); 587 588 cai = &ci->ci_cinfo[CAI_DTLB]; 589 cai->cai_totalsize = VIA_L1_EBX_DTLB_ENTRIES(descs[1]); 590 cai->cai_associativity = VIA_L1_EBX_DTLB_ASSOC(descs[1]); 591 cai->cai_linesize = (4 * 1024); 592 593 cai = &ci->ci_cinfo[CAI_DCACHE]; 594 cai->cai_totalsize = VIA_L1_ECX_DC_SIZE(descs[2]); 595 cai->cai_associativity = VIA_L1_ECX_DC_ASSOC(descs[2]); 596 cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[2]); 597 if (family == 6 && model == 9 && stepping == 8) { 598 /* Erratum: stepping 8 reports 4 when it should be 2 */ 599 cai->cai_associativity = 2; 600 } 601 602 cai = &ci->ci_cinfo[CAI_ICACHE]; 603 cai->cai_totalsize = VIA_L1_EDX_IC_SIZE(descs[3]); 604 cai->cai_associativity = VIA_L1_EDX_IC_ASSOC(descs[3]); 605 cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[3]); 606 if (family == 6 && model == 9 && stepping == 8) { 607 /* Erratum: stepping 8 reports 4 when it should be 2 */ 608 cai->cai_associativity = 2; 609 } 610 611 /* 612 * Determine L2 cache/TLB info. 613 */ 614 if (lfunc < 0x80000006) { 615 /* No L2 cache info available. */ 616 return; 617 } 618 619 x86_cpuid(0x80000006, descs); 620 621 cai = &ci->ci_cinfo[CAI_L2CACHE]; 622 if (family > 6 || model >= 9) { 623 cai->cai_totalsize = VIA_L2N_ECX_C_SIZE(descs[2]); 624 cai->cai_associativity = VIA_L2N_ECX_C_ASSOC(descs[2]); 625 cai->cai_linesize = VIA_L2N_ECX_C_LS(descs[2]); 626 } else { 627 cai->cai_totalsize = VIA_L2_ECX_C_SIZE(descs[2]); 628 cai->cai_associativity = VIA_L2_ECX_C_ASSOC(descs[2]); 629 cai->cai_linesize = VIA_L2_ECX_C_LS(descs[2]); 630 } 631 } 632 633 static void 634 cpu_probe_geode(struct cpu_info *ci) 635 { 636 637 if (memcmp("Geode by NSC", ci->ci_vendor, 12) != 0 || 638 CPUID_TO_FAMILY(ci->ci_signature) != 5) 639 return; 640 641 cpu_probe_cyrix_cmn(ci); 642 cpu_probe_amd_cache(ci); 643 } 644 645 static void 646 cpu_probe_vortex86(struct cpu_info *ci) 647 { 648 #define PCI_MODE1_ADDRESS_REG 0x0cf8 649 #define PCI_MODE1_DATA_REG 0x0cfc 650 #define PCI_MODE1_ENABLE 0x80000000UL 651 652 uint32_t reg; 653 654 if (cpu_vendor != CPUVENDOR_VORTEX86) 655 return; 656 /* 657 * CPU model available from "Customer ID register" in 658 * North Bridge Function 0 PCI space 659 * we can't use pci_conf_read() because the PCI subsystem is not 660 * not initialised early enough 661 */ 662 663 outl(PCI_MODE1_ADDRESS_REG, PCI_MODE1_ENABLE | 0x90); 664 reg = inl(PCI_MODE1_DATA_REG); 665 666 switch(reg) { 667 case 0x31504d44: 668 strcpy(cpu_brand_string, "Vortex86SX"); 669 break; 670 case 0x32504d44: 671 strcpy(cpu_brand_string, "Vortex86DX"); 672 break; 673 case 0x33504d44: 674 strcpy(cpu_brand_string, "Vortex86MX"); 675 break; 676 case 0x37504d44: 677 strcpy(cpu_brand_string, "Vortex86EX"); 678 break; 679 default: 680 strcpy(cpu_brand_string, "Unknown Vortex86"); 681 break; 682 } 683 684 #undef PCI_MODE1_ENABLE 685 #undef PCI_MODE1_ADDRESS_REG 686 #undef PCI_MODE1_DATA_REG 687 } 688 689 #if !defined(__i386__) || defined(XEN) 690 #define cpu_probe_old_fpu(ci) 691 #else 692 static void 693 cpu_probe_old_fpu(struct cpu_info *ci) 694 { 695 uint16_t control; 696 697 /* Check that there really is an fpu (496SX) */ 698 clts(); 699 fninit(); 700 /* Read default control word */ 701 fnstcw(&control); 702 if (control != __INITIAL_NPXCW__) { 703 /* Must be a 486SX, trap FP instructions */ 704 lcr0((rcr0() & ~CR0_MP) | CR0_EM); 705 i386_fpu_present = 0; 706 return; 707 } 708 709 /* Check for 'FDIV' bug on the original Pentium */ 710 if (npx586bug1(4195835, 3145727) != 0) 711 /* NB 120+MHz cpus are not affected */ 712 i386_fpu_fdivbug = 1; 713 714 stts(); 715 } 716 #endif 717 718 static void 719 cpu_probe_fpu(struct cpu_info *ci) 720 { 721 u_int descs[4]; 722 723 #ifdef i386 /* amd64 always has fxsave, sse and sse2 */ 724 /* If we have FXSAVE/FXRESTOR, use them. */ 725 if ((ci->ci_feat_val[0] & CPUID_FXSR) == 0) { 726 i386_use_fxsave = 0; 727 /* Allow for no fpu even if cpuid is supported */ 728 cpu_probe_old_fpu(ci); 729 return; 730 } 731 732 i386_use_fxsave = 1; 733 /* 734 * If we have SSE/SSE2, enable XMM exceptions, and 735 * notify userland. 736 */ 737 if (ci->ci_feat_val[0] & CPUID_SSE) 738 i386_has_sse = 1; 739 if (ci->ci_feat_val[0] & CPUID_SSE2) 740 i386_has_sse2 = 1; 741 #else 742 /* 743 * For amd64 i386_use_fxsave, i386_has_sse and i386_has_sse2 are 744 * #defined to 1. 745 */ 746 #endif /* i386 */ 747 748 x86_fpu_save = FPU_SAVE_FXSAVE; 749 750 /* See if xsave (for AVX is supported) */ 751 if ((ci->ci_feat_val[1] & CPUID2_XSAVE) == 0) 752 return; 753 754 x86_fpu_save = FPU_SAVE_XSAVE; 755 756 /* xsaveopt ought to be faster than xsave */ 757 x86_cpuid2(0xd, 1, descs); 758 if (descs[0] & CPUID_PES1_XSAVEOPT) 759 x86_fpu_save = FPU_SAVE_XSAVEOPT; 760 761 /* Get features and maximum size of the save area */ 762 x86_cpuid(0xd, descs); 763 /* XXX these probably ought to be per-cpu */ 764 if (descs[2] > 512) 765 x86_fpu_save_size = descs[2]; 766 #ifndef XEN 767 x86_xsave_features = (uint64_t)descs[3] << 32 | descs[0]; 768 #endif 769 } 770 771 void 772 cpu_probe(struct cpu_info *ci) 773 { 774 u_int descs[4]; 775 int i; 776 uint32_t miscbytes; 777 uint32_t brand[12]; 778 779 cpu_vendor = i386_nocpuid_cpus[cputype << 1]; 780 cpu_class = i386_nocpuid_cpus[(cputype << 1) + 1]; 781 782 if (cpuid_level < 0) { 783 /* cpuid instruction not supported */ 784 cpu_probe_old_fpu(ci); 785 return; 786 } 787 788 for (i = 0; i < __arraycount(ci->ci_feat_val); i++) { 789 ci->ci_feat_val[i] = 0; 790 } 791 792 x86_cpuid(0, descs); 793 cpuid_level = descs[0]; 794 ci->ci_max_cpuid = descs[0]; 795 796 ci->ci_vendor[0] = descs[1]; 797 ci->ci_vendor[2] = descs[2]; 798 ci->ci_vendor[1] = descs[3]; 799 ci->ci_vendor[3] = 0; 800 801 if (memcmp(ci->ci_vendor, "GenuineIntel", 12) == 0) 802 cpu_vendor = CPUVENDOR_INTEL; 803 else if (memcmp(ci->ci_vendor, "AuthenticAMD", 12) == 0) 804 cpu_vendor = CPUVENDOR_AMD; 805 else if (memcmp(ci->ci_vendor, "CyrixInstead", 12) == 0) 806 cpu_vendor = CPUVENDOR_CYRIX; 807 else if (memcmp(ci->ci_vendor, "Geode by NSC", 12) == 0) 808 cpu_vendor = CPUVENDOR_CYRIX; 809 else if (memcmp(ci->ci_vendor, "CentaurHauls", 12) == 0) 810 cpu_vendor = CPUVENDOR_IDT; 811 else if (memcmp(ci->ci_vendor, "GenuineTMx86", 12) == 0) 812 cpu_vendor = CPUVENDOR_TRANSMETA; 813 else if (memcmp(ci->ci_vendor, "Vortex86 SoC", 12) == 0) 814 cpu_vendor = CPUVENDOR_VORTEX86; 815 else 816 cpu_vendor = CPUVENDOR_UNKNOWN; 817 818 if (cpuid_level >= 1) { 819 x86_cpuid(1, descs); 820 ci->ci_signature = descs[0]; 821 miscbytes = descs[1]; 822 ci->ci_feat_val[1] = descs[2]; 823 ci->ci_feat_val[0] = descs[3]; 824 825 /* Determine family + class. */ 826 cpu_class = CPUID_TO_FAMILY(ci->ci_signature) 827 + (CPUCLASS_386 - 3); 828 if (cpu_class > CPUCLASS_686) 829 cpu_class = CPUCLASS_686; 830 831 /* CLFLUSH line size is next 8 bits */ 832 if (ci->ci_feat_val[0] & CPUID_CFLUSH) 833 ci->ci_cflush_lsize = ((miscbytes >> 8) & 0xff) << 3; 834 ci->ci_initapicid = (miscbytes >> 24) & 0xff; 835 } 836 837 /* 838 * Get the basic information from the extended cpuid leafs. 839 * These were first implemented by amd, but most of the values 840 * match with those generated by modern intel cpus. 841 */ 842 x86_cpuid(0x80000000, descs); 843 if (descs[0] >= 0x80000000) 844 ci->ci_max_ext_cpuid = descs[0]; 845 else 846 ci->ci_max_ext_cpuid = 0; 847 848 if (ci->ci_max_ext_cpuid >= 0x80000001) { 849 /* Determine the extended feature flags. */ 850 x86_cpuid(0x80000001, descs); 851 ci->ci_feat_val[3] = descs[2]; /* %ecx */ 852 ci->ci_feat_val[2] = descs[3]; /* %edx */ 853 } 854 855 if (ci->ci_max_ext_cpuid >= 0x80000004) { 856 x86_cpuid(0x80000002, brand); 857 x86_cpuid(0x80000003, brand + 4); 858 x86_cpuid(0x80000004, brand + 8); 859 /* Skip leading spaces on brand */ 860 for (i = 0; i < 48; i++) { 861 if (((char *) brand)[i] != ' ') 862 break; 863 } 864 memcpy(cpu_brand_string, ((char *) brand) + i, 48 - i); 865 } 866 867 /* 868 * Get the structured extended features. 869 */ 870 if (cpuid_level >= 7) { 871 x86_cpuid(7, descs); 872 ci->ci_feat_val[5] = descs[1]; /* %ebx */ 873 ci->ci_feat_val[6] = descs[2]; /* %ecx */ 874 } 875 876 cpu_probe_intel(ci); 877 cpu_probe_k5(ci); 878 cpu_probe_k678(ci); 879 cpu_probe_cyrix(ci); 880 cpu_probe_winchip(ci); 881 cpu_probe_c3(ci); 882 cpu_probe_geode(ci); 883 cpu_probe_vortex86(ci); 884 885 cpu_probe_fpu(ci); 886 887 x86_cpu_topology(ci); 888 889 if (cpu_vendor != CPUVENDOR_AMD && (ci->ci_feat_val[0] & CPUID_TM) && 890 (rdmsr(MSR_MISC_ENABLE) & (1 << 3)) == 0) { 891 /* Enable thermal monitor 1. */ 892 wrmsr(MSR_MISC_ENABLE, rdmsr(MSR_MISC_ENABLE) | (1<<3)); 893 } 894 895 ci->ci_feat_val[0] &= ~CPUID_FEAT_BLACKLIST; 896 if (ci == &cpu_info_primary) { 897 /* If first. Boot Processor is the cpu_feature reference. */ 898 for (i = 0; i < __arraycount(cpu_feature); i++) { 899 cpu_feature[i] = ci->ci_feat_val[i]; 900 } 901 #ifndef XEN 902 /* Early patch of text segment. */ 903 x86_patch(true); 904 #endif 905 } else { 906 /* 907 * If not first. Warn about cpu_feature mismatch for 908 * secondary CPUs. 909 */ 910 for (i = 0; i < __arraycount(cpu_feature); i++) { 911 if (cpu_feature[i] != ci->ci_feat_val[i]) 912 aprint_error_dev(ci->ci_dev, 913 "feature mismatch: cpu_feature[%d] is " 914 "%#x, but CPU reported %#x\n", 915 i, cpu_feature[i], ci->ci_feat_val[i]); 916 } 917 } 918 } 919 920 /* Write what we know about the cpu to the console... */ 921 void 922 cpu_identify(struct cpu_info *ci) 923 { 924 925 cpu_setmodel("%s %d86-class", 926 cpu_vendor_names[cpu_vendor], cpu_class + 3); 927 if (cpu_brand_string[0] != '\0') { 928 aprint_normal_dev(ci->ci_dev, "%s", cpu_brand_string); 929 } else { 930 aprint_normal_dev(ci->ci_dev, "%s", cpu_getmodel()); 931 if (ci->ci_data.cpu_cc_freq != 0) 932 aprint_normal(", %dMHz", 933 (int)(ci->ci_data.cpu_cc_freq / 1000000)); 934 } 935 if (ci->ci_signature != 0) 936 aprint_normal(", id 0x%x", ci->ci_signature); 937 aprint_normal("\n"); 938 939 if (cpu_brand_string[0] == '\0') { 940 strlcpy(cpu_brand_string, cpu_getmodel(), 941 sizeof(cpu_brand_string)); 942 } 943 if (cpu_class == CPUCLASS_386) { 944 panic("NetBSD requires an 80486DX or later processor"); 945 } 946 if (cputype == CPU_486DLC) { 947 aprint_error("WARNING: BUGGY CYRIX CACHE\n"); 948 } 949 950 #if !defined(XEN) || defined(DOM0OPS) /* on Xen rdmsr is for Dom0 only */ 951 if (cpu_vendor == CPUVENDOR_AMD /* check enablement of an */ 952 && device_unit(ci->ci_dev) == 0 /* AMD feature only once */ 953 && ((cpu_feature[3] & CPUID_SVM) == CPUID_SVM)) { 954 uint64_t val; 955 956 val = rdmsr(MSR_VMCR); 957 if (((val & VMCR_SVMED) == VMCR_SVMED) 958 && ((val & VMCR_LOCK) == VMCR_LOCK)) { 959 aprint_normal_dev(ci->ci_dev, 960 "SVM disabled by the BIOS\n"); 961 } 962 } 963 #endif 964 965 #ifdef i386 966 if (i386_fpu_present == 0) 967 aprint_normal_dev(ci->ci_dev, "no fpu\n"); 968 969 if (i386_fpu_fdivbug == 1) 970 aprint_normal_dev(ci->ci_dev, 971 "WARNING: Pentium FDIV bug detected!\n"); 972 973 if (cpu_vendor == CPUVENDOR_TRANSMETA) { 974 u_int descs[4]; 975 x86_cpuid(0x80860000, descs); 976 if (descs[0] >= 0x80860007) 977 /* Create longrun sysctls */ 978 tmx86_init_longrun(); 979 } 980 #endif /* i386 */ 981 982 } 983