identcpu.c revision 1.111
1/* $OpenBSD: identcpu.c,v 1.111 2019/05/17 19:07:15 guenther Exp $ */ 2/* $NetBSD: identcpu.c,v 1.1 2003/04/26 18:39:28 fvdl Exp $ */ 3 4/* 5 * Copyright (c) 2003 Wasabi Systems, Inc. 6 * All rights reserved. 7 * 8 * Written by Frank van der Linden for Wasabi Systems, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed for the NetBSD Project by 21 * Wasabi Systems, Inc. 22 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 23 * or promote products derived from this software without specific prior 24 * written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39#include <sys/param.h> 40#include <sys/systm.h> 41#include <sys/sysctl.h> 42 43#include "vmm.h" 44 45#include <machine/cpu.h> 46#include <machine/cpufunc.h> 47 48void replacesmap(void); 49void replacemeltdown(void); 50uint64_t cpu_freq(struct cpu_info *); 51void tsc_timecounter_init(struct cpu_info *, uint64_t); 52#if NVMM > 0 53void cpu_check_vmm_cap(struct cpu_info *); 54#endif /* NVMM > 0 */ 55 56/* sysctl wants this. */ 57char cpu_model[48]; 58int cpuspeed; 59 60int amd64_has_xcrypt; 61#ifdef CRYPTO 62int amd64_has_pclmul; 63int amd64_has_aesni; 64#endif 65int has_rdrand; 66int has_rdseed; 67 68#include "pvbus.h" 69#if NPVBUS > 0 70#include <dev/pv/pvvar.h> 71#endif 72 73const struct { 74 u_int32_t bit; 75 char str[12]; 76} cpu_cpuid_features[] = { 77 { CPUID_FPU, "FPU" }, 78 { CPUID_VME, "VME" }, 79 { CPUID_DE, "DE" }, 80 { CPUID_PSE, "PSE" }, 81 { CPUID_TSC, "TSC" }, 82 { CPUID_MSR, "MSR" }, 83 { CPUID_PAE, "PAE" }, 84 { CPUID_MCE, "MCE" }, 85 { CPUID_CX8, "CX8" }, 86 { CPUID_APIC, "APIC" }, 87 { CPUID_SEP, "SEP" }, 88 { CPUID_MTRR, "MTRR" }, 89 { CPUID_PGE, "PGE" }, 90 { CPUID_MCA, "MCA" }, 91 { CPUID_CMOV, "CMOV" }, 92 { CPUID_PAT, "PAT" }, 93 { CPUID_PSE36, "PSE36" }, 94 { CPUID_PSN, "PSN" }, 95 { CPUID_CFLUSH, "CFLUSH" }, 96 { CPUID_DS, "DS" }, 97 { CPUID_ACPI, "ACPI" }, 98 { CPUID_MMX, "MMX" }, 99 { CPUID_FXSR, "FXSR" }, 100 { CPUID_SSE, "SSE" }, 101 { CPUID_SSE2, "SSE2" }, 102 { CPUID_SS, "SS" }, 103 { CPUID_HTT, "HTT" }, 104 { CPUID_TM, "TM" }, 105 { CPUID_PBE, "PBE" } 106}, cpu_ecpuid_features[] = { 107 { CPUID_MPC, "MPC" }, 108 { CPUID_NXE, "NXE" }, 109 { CPUID_MMXX, "MMXX" }, 110 { CPUID_FFXSR, "FFXSR" }, 111 { CPUID_PAGE1GB, "PAGE1GB" }, 112 { CPUID_RDTSCP, "RDTSCP" }, 113 { CPUID_LONG, "LONG" }, 114 { CPUID_3DNOW2, "3DNOW2" }, 115 { CPUID_3DNOW, "3DNOW" } 116}, cpu_cpuid_ecxfeatures[] = { 117 { CPUIDECX_SSE3, "SSE3" }, 118 { CPUIDECX_PCLMUL, "PCLMUL" }, 119 { CPUIDECX_DTES64, "DTES64" }, 120 { CPUIDECX_MWAIT, "MWAIT" }, 121 { CPUIDECX_DSCPL, "DS-CPL" }, 122 { CPUIDECX_VMX, "VMX" }, 123 { CPUIDECX_SMX, "SMX" }, 124 { CPUIDECX_EST, "EST" }, 125 { CPUIDECX_TM2, "TM2" }, 126 { CPUIDECX_SSSE3, "SSSE3" }, 127 { CPUIDECX_CNXTID, "CNXT-ID" }, 128 { CPUIDECX_SDBG, "SDBG" }, 129 { CPUIDECX_FMA3, "FMA3" }, 130 { CPUIDECX_CX16, "CX16" }, 131 { CPUIDECX_XTPR, "xTPR" }, 132 { CPUIDECX_PDCM, "PDCM" }, 133 { CPUIDECX_PCID, "PCID" }, 134 { CPUIDECX_DCA, "DCA" }, 135 { CPUIDECX_SSE41, "SSE4.1" }, 136 { CPUIDECX_SSE42, "SSE4.2" }, 137 { CPUIDECX_X2APIC, "x2APIC" }, 138 { CPUIDECX_MOVBE, "MOVBE" }, 139 { CPUIDECX_POPCNT, "POPCNT" }, 140 { CPUIDECX_DEADLINE, "DEADLINE" }, 141 { CPUIDECX_AES, "AES" }, 142 { CPUIDECX_XSAVE, "XSAVE" }, 143 { CPUIDECX_OSXSAVE, "OSXSAVE" }, 144 { CPUIDECX_AVX, "AVX" }, 145 { CPUIDECX_F16C, "F16C" }, 146 { CPUIDECX_RDRAND, "RDRAND" }, 147 { CPUIDECX_HV, "HV" }, 148}, cpu_ecpuid_ecxfeatures[] = { 149 { CPUIDECX_LAHF, "LAHF" }, 150 { CPUIDECX_CMPLEG, "CMPLEG" }, 151 { CPUIDECX_SVM, "SVM" }, 152 { CPUIDECX_EAPICSP, "EAPICSP"}, 153 { CPUIDECX_AMCR8, "AMCR8"}, 154 { CPUIDECX_ABM, "ABM" }, 155 { CPUIDECX_SSE4A, "SSE4A" }, 156 { CPUIDECX_MASSE, "MASSE" }, 157 { CPUIDECX_3DNOWP, "3DNOWP" }, 158 { CPUIDECX_OSVW, "OSVW" }, 159 { CPUIDECX_IBS, "IBS" }, 160 { CPUIDECX_XOP, "XOP" }, 161 { CPUIDECX_SKINIT, "SKINIT" }, 162 { CPUIDECX_LWP, "WDT" }, 163 { CPUIDECX_FMA4, "FMA4" }, 164 { CPUIDECX_TCE, "TCE" }, 165 { CPUIDECX_NODEID, "NODEID" }, 166 { CPUIDECX_TBM, "TBM" }, 167 { CPUIDECX_TOPEXT, "TOPEXT" }, 168 { CPUIDECX_CPCTR, "CPCTR" }, 169 { CPUIDECX_DBKP, "DBKP" }, 170 { CPUIDECX_PERFTSC, "PERFTSC" }, 171 { CPUIDECX_PCTRL3, "PCTRL3" }, 172 { CPUIDECX_MWAITX, "MWAITX" }, 173}, cpu_seff0_ebxfeatures[] = { 174 { SEFF0EBX_FSGSBASE, "FSGSBASE" }, 175 { SEFF0EBX_SGX, "SGX" }, 176 { SEFF0EBX_BMI1, "BMI1" }, 177 { SEFF0EBX_HLE, "HLE" }, 178 { SEFF0EBX_AVX2, "AVX2" }, 179 { SEFF0EBX_SMEP, "SMEP" }, 180 { SEFF0EBX_BMI2, "BMI2" }, 181 { SEFF0EBX_ERMS, "ERMS" }, 182 { SEFF0EBX_INVPCID, "INVPCID" }, 183 { SEFF0EBX_RTM, "RTM" }, 184 { SEFF0EBX_PQM, "PQM" }, 185 { SEFF0EBX_MPX, "MPX" }, 186 { SEFF0EBX_AVX512F, "AVX512F" }, 187 { SEFF0EBX_AVX512DQ, "AVX512DQ" }, 188 { SEFF0EBX_RDSEED, "RDSEED" }, 189 { SEFF0EBX_ADX, "ADX" }, 190 { SEFF0EBX_SMAP, "SMAP" }, 191 { SEFF0EBX_AVX512IFMA, "AVX512IFMA" }, 192 { SEFF0EBX_PCOMMIT, "PCOMMIT" }, 193 { SEFF0EBX_CLFLUSHOPT, "CLFLUSHOPT" }, 194 { SEFF0EBX_CLWB, "CLWB" }, 195 { SEFF0EBX_PT, "PT" }, 196 { SEFF0EBX_AVX512PF, "AVX512PF" }, 197 { SEFF0EBX_AVX512ER, "AVX512ER" }, 198 { SEFF0EBX_AVX512CD, "AVX512CD" }, 199 { SEFF0EBX_SHA, "SHA" }, 200 { SEFF0EBX_AVX512BW, "AVX512BW" }, 201 { SEFF0EBX_AVX512VL, "AVX512VL" }, 202}, cpu_seff0_ecxfeatures[] = { 203 { SEFF0ECX_PREFETCHWT1, "PREFETCHWT1" }, 204 { SEFF0ECX_AVX512VBMI, "AVX512VBMI" }, 205 { SEFF0ECX_UMIP, "UMIP" }, 206 { SEFF0ECX_PKU, "PKU" }, 207}, cpu_seff0_edxfeatures[] = { 208 { SEFF0EDX_AVX512_4FNNIW, "AVX512FNNIW" }, 209 { SEFF0EDX_AVX512_4FMAPS, "AVX512FMAPS" }, 210 { SEFF0EDX_MD_CLEAR, "MD_CLEAR" }, 211 { SEFF0EDX_TSXFA, "TSXFA" }, 212 { SEFF0EDX_IBRS, "IBRS,IBPB" }, 213 { SEFF0EDX_STIBP, "STIBP" }, 214 { SEFF0EDX_L1DF, "L1DF" }, 215 /* SEFF0EDX_ARCH_CAP (not printed) */ 216 { SEFF0EDX_SSBD, "SSBD" }, 217}, cpu_tpm_eaxfeatures[] = { 218 { TPM_SENSOR, "SENSOR" }, 219 { TPM_ARAT, "ARAT" }, 220}, cpu_cpuid_perf_eax[] = { 221 { CPUIDEAX_VERID, "PERF" }, 222}, cpu_cpuid_apmi_edx[] = { 223 { CPUIDEDX_ITSC, "ITSC" }, 224}, cpu_amdspec_ebxfeatures[] = { 225 { CPUIDEBX_IBPB, "IBPB" }, 226 { CPUIDEBX_IBRS, "IBRS" }, 227 { CPUIDEBX_STIBP, "STIBP" }, 228 { CPUIDEBX_SSBD, "SSBD" }, 229 { CPUIDEBX_VIRT_SSBD, "VIRTSSBD" }, 230 { CPUIDEBX_SSBD_NOTREQ, "SSBDNR" }, 231}, cpu_xsave_extfeatures[] = { 232 { XSAVE_XSAVEOPT, "XSAVEOPT" }, 233 { XSAVE_XSAVEC, "XSAVEC" }, 234 { XSAVE_XGETBV1, "XGETBV1" }, 235 { XSAVE_XSAVES, "XSAVES" }, 236}; 237 238int 239cpu_amd64speed(int *freq) 240{ 241 *freq = cpuspeed; 242 return (0); 243} 244 245#ifndef SMALL_KERNEL 246void intelcore_update_sensor(void *args); 247/* 248 * Temperature read on the CPU is relative to the maximum 249 * temperature supported by the CPU, Tj(Max). 250 * Refer to: 251 * 64-ia-32-architectures-software-developer-vol-3c-part-3-manual.pdf 252 * Section 35 and 253 * http://www.intel.com/content/dam/www/public/us/en/documents/ 254 * white-papers/cpu-monitoring-dts-peci-paper.pdf 255 * 256 * The temperature on Intel CPUs can be between 70 and 105 degC, since 257 * Westmere we can read the TJmax from the die. For older CPUs we have 258 * to guess or use undocumented MSRs. Then we subtract the temperature 259 * portion of thermal status from max to get current temperature. 260 */ 261void 262intelcore_update_sensor(void *args) 263{ 264 struct cpu_info *ci = (struct cpu_info *) args; 265 u_int64_t msr; 266 int max = 100; 267 268 /* Only some Core family chips have MSR_TEMPERATURE_TARGET. */ 269 if (ci->ci_model == 0x0e && 270 (rdmsr(MSR_TEMPERATURE_TARGET_UNDOCUMENTED) & 271 MSR_TEMPERATURE_TARGET_LOW_BIT_UNDOCUMENTED)) 272 max = 85; 273 274 /* 275 * Newer CPUs can tell you what their max temperature is. 276 * See: '64-ia-32-architectures-software-developer- 277 * vol-3c-part-3-manual.pdf' 278 */ 279 if (ci->ci_model > 0x17 && ci->ci_model != 0x1c && 280 ci->ci_model != 0x26 && ci->ci_model != 0x27 && 281 ci->ci_model != 0x35 && ci->ci_model != 0x36) 282 max = MSR_TEMPERATURE_TARGET_TJMAX( 283 rdmsr(MSR_TEMPERATURE_TARGET)); 284 285 msr = rdmsr(MSR_THERM_STATUS); 286 if (msr & MSR_THERM_STATUS_VALID_BIT) { 287 ci->ci_sensor.value = max - MSR_THERM_STATUS_TEMP(msr); 288 /* micro degrees */ 289 ci->ci_sensor.value *= 1000000; 290 /* kelvin */ 291 ci->ci_sensor.value += 273150000; 292 ci->ci_sensor.flags &= ~SENSOR_FINVALID; 293 } else { 294 ci->ci_sensor.value = 0; 295 ci->ci_sensor.flags |= SENSOR_FINVALID; 296 } 297} 298 299#endif 300 301void (*setperf_setup)(struct cpu_info *); 302 303void via_nano_setup(struct cpu_info *ci); 304 305void cpu_topology(struct cpu_info *ci); 306 307void 308via_nano_setup(struct cpu_info *ci) 309{ 310 u_int32_t regs[4], val; 311 u_int64_t msreg; 312 int model = (ci->ci_signature >> 4) & 15; 313 314 if (model >= 9) { 315 CPUID(0xC0000000, regs[0], regs[1], regs[2], regs[3]); 316 val = regs[0]; 317 if (val >= 0xC0000001) { 318 CPUID(0xC0000001, regs[0], regs[1], regs[2], regs[3]); 319 val = regs[3]; 320 } else 321 val = 0; 322 323 if (val & (C3_CPUID_HAS_RNG | C3_CPUID_HAS_ACE)) 324 printf("%s:", ci->ci_dev->dv_xname); 325 326 /* Enable RNG if present and disabled */ 327 if (val & C3_CPUID_HAS_RNG) { 328 extern int viac3_rnd_present; 329 330 if (!(val & C3_CPUID_DO_RNG)) { 331 msreg = rdmsr(0x110B); 332 msreg |= 0x40; 333 wrmsr(0x110B, msreg); 334 } 335 viac3_rnd_present = 1; 336 printf(" RNG"); 337 } 338 339 /* Enable AES engine if present and disabled */ 340 if (val & C3_CPUID_HAS_ACE) { 341#ifdef CRYPTO 342 if (!(val & C3_CPUID_DO_ACE)) { 343 msreg = rdmsr(0x1107); 344 msreg |= (0x01 << 28); 345 wrmsr(0x1107, msreg); 346 } 347 amd64_has_xcrypt |= C3_HAS_AES; 348#endif /* CRYPTO */ 349 printf(" AES"); 350 } 351 352 /* Enable ACE2 engine if present and disabled */ 353 if (val & C3_CPUID_HAS_ACE2) { 354#ifdef CRYPTO 355 if (!(val & C3_CPUID_DO_ACE2)) { 356 msreg = rdmsr(0x1107); 357 msreg |= (0x01 << 28); 358 wrmsr(0x1107, msreg); 359 } 360 amd64_has_xcrypt |= C3_HAS_AESCTR; 361#endif /* CRYPTO */ 362 printf(" AES-CTR"); 363 } 364 365 /* Enable SHA engine if present and disabled */ 366 if (val & C3_CPUID_HAS_PHE) { 367#ifdef CRYPTO 368 if (!(val & C3_CPUID_DO_PHE)) { 369 msreg = rdmsr(0x1107); 370 msreg |= (0x01 << 28/**/); 371 wrmsr(0x1107, msreg); 372 } 373 amd64_has_xcrypt |= C3_HAS_SHA; 374#endif /* CRYPTO */ 375 printf(" SHA1 SHA256"); 376 } 377 378 /* Enable MM engine if present and disabled */ 379 if (val & C3_CPUID_HAS_PMM) { 380#ifdef CRYPTO 381 if (!(val & C3_CPUID_DO_PMM)) { 382 msreg = rdmsr(0x1107); 383 msreg |= (0x01 << 28/**/); 384 wrmsr(0x1107, msreg); 385 } 386 amd64_has_xcrypt |= C3_HAS_MM; 387#endif /* CRYPTO */ 388 printf(" RSA"); 389 } 390 391 printf("\n"); 392 } 393} 394 395#ifndef SMALL_KERNEL 396void via_update_sensor(void *args); 397void 398via_update_sensor(void *args) 399{ 400 struct cpu_info *ci = (struct cpu_info *) args; 401 u_int64_t msr; 402 403 msr = rdmsr(MSR_CENT_TMTEMPERATURE); 404 ci->ci_sensor.value = (msr & 0xffffff); 405 /* micro degrees */ 406 ci->ci_sensor.value *= 1000000; 407 ci->ci_sensor.value += 273150000; 408 ci->ci_sensor.flags &= ~SENSOR_FINVALID; 409} 410#endif 411 412uint64_t 413cpu_freq_ctr(struct cpu_info *ci) 414{ 415 uint64_t count, last_count, msr; 416 417 if ((ci->ci_flags & CPUF_CONST_TSC) == 0 || 418 (cpu_perf_eax & CPUIDEAX_VERID) <= 1 || 419 CPUIDEDX_NUM_FC(cpu_perf_edx) <= 1) 420 return (0); 421 422 msr = rdmsr(MSR_PERF_FIXED_CTR_CTRL); 423 if (msr & MSR_PERF_FIXED_CTR_FC(1, MSR_PERF_FIXED_CTR_FC_MASK)) { 424 /* some hypervisor is dicking us around */ 425 return (0); 426 } 427 428 msr |= MSR_PERF_FIXED_CTR_FC(1, MSR_PERF_FIXED_CTR_FC_1); 429 wrmsr(MSR_PERF_FIXED_CTR_CTRL, msr); 430 431 msr = rdmsr(MSR_PERF_GLOBAL_CTRL) | MSR_PERF_GLOBAL_CTR1_EN; 432 wrmsr(MSR_PERF_GLOBAL_CTRL, msr); 433 434 last_count = rdmsr(MSR_PERF_FIXED_CTR1); 435 delay(100000); 436 count = rdmsr(MSR_PERF_FIXED_CTR1); 437 438 msr = rdmsr(MSR_PERF_FIXED_CTR_CTRL); 439 msr &= MSR_PERF_FIXED_CTR_FC(1, MSR_PERF_FIXED_CTR_FC_MASK); 440 wrmsr(MSR_PERF_FIXED_CTR_CTRL, msr); 441 442 msr = rdmsr(MSR_PERF_GLOBAL_CTRL); 443 msr &= ~MSR_PERF_GLOBAL_CTR1_EN; 444 wrmsr(MSR_PERF_GLOBAL_CTRL, msr); 445 446 return ((count - last_count) * 10); 447} 448 449uint64_t 450cpu_freq(struct cpu_info *ci) 451{ 452 uint64_t last_count, count; 453 454 count = cpu_freq_ctr(ci); 455 if (count != 0) 456 return (count); 457 458 last_count = rdtsc(); 459 delay(100000); 460 count = rdtsc(); 461 462 return ((count - last_count) * 10); 463} 464 465void 466identifycpu(struct cpu_info *ci) 467{ 468 uint64_t freq = 0; 469 u_int32_t dummy, val; 470 char mycpu_model[48]; 471 int i; 472 char *brandstr_from, *brandstr_to; 473 int skipspace; 474 475 CPUID(1, ci->ci_signature, val, dummy, ci->ci_feature_flags); 476 CPUID(0x80000000, ci->ci_pnfeatset, dummy, dummy, dummy); 477 if (ci->ci_pnfeatset >= 0x80000001) { 478 CPUID(0x80000001, ci->ci_efeature_eax, dummy, 479 ci->ci_efeature_ecx, ci->ci_feature_eflags); 480 /* Other bits may clash */ 481 ci->ci_feature_flags |= (ci->ci_feature_eflags & CPUID_NXE); 482 if (ci->ci_flags & CPUF_PRIMARY) 483 ecpu_ecxfeature = ci->ci_efeature_ecx; 484 /* Let cpu_feature be the common bits */ 485 cpu_feature &= ci->ci_feature_flags; 486 } 487 488 CPUID(0x80000002, ci->ci_brand[0], 489 ci->ci_brand[1], ci->ci_brand[2], ci->ci_brand[3]); 490 CPUID(0x80000003, ci->ci_brand[4], 491 ci->ci_brand[5], ci->ci_brand[6], ci->ci_brand[7]); 492 CPUID(0x80000004, ci->ci_brand[8], 493 ci->ci_brand[9], ci->ci_brand[10], ci->ci_brand[11]); 494 strlcpy(mycpu_model, (char *)ci->ci_brand, sizeof(mycpu_model)); 495 496 /* Remove leading, trailing and duplicated spaces from mycpu_model */ 497 brandstr_from = brandstr_to = mycpu_model; 498 skipspace = 1; 499 while (*brandstr_from != '\0') { 500 if (!skipspace || *brandstr_from != ' ') { 501 skipspace = 0; 502 *(brandstr_to++) = *brandstr_from; 503 } 504 if (*brandstr_from == ' ') 505 skipspace = 1; 506 brandstr_from++; 507 } 508 if (skipspace && brandstr_to > mycpu_model) 509 brandstr_to--; 510 *brandstr_to = '\0'; 511 512 if (mycpu_model[0] == 0) 513 strlcpy(mycpu_model, "Opteron or Athlon 64", 514 sizeof(mycpu_model)); 515 516 /* If primary cpu, fill in the global cpu_model used by sysctl */ 517 if (ci->ci_flags & CPUF_PRIMARY) 518 strlcpy(cpu_model, mycpu_model, sizeof(cpu_model)); 519 520 ci->ci_family = (ci->ci_signature >> 8) & 0x0f; 521 ci->ci_model = (ci->ci_signature >> 4) & 0x0f; 522 if (ci->ci_family == 0x6 || ci->ci_family == 0xf) { 523 ci->ci_family += (ci->ci_signature >> 20) & 0xff; 524 ci->ci_model += ((ci->ci_signature >> 16) & 0x0f) << 4; 525 } 526 527 if (ci->ci_feature_flags && ci->ci_feature_flags & CPUID_TSC) { 528 /* Has TSC, check if it's constant */ 529 if (!strcmp(cpu_vendor, "GenuineIntel")) { 530 if ((ci->ci_family == 0x0f && ci->ci_model >= 0x03) || 531 (ci->ci_family == 0x06 && ci->ci_model >= 0x0e)) { 532 ci->ci_flags |= CPUF_CONST_TSC; 533 } 534 } else if (!strcmp(cpu_vendor, "CentaurHauls")) { 535 /* VIA */ 536 if (ci->ci_model >= 0x0f) { 537 ci->ci_flags |= CPUF_CONST_TSC; 538 } 539 } else if (!strcmp(cpu_vendor, "AuthenticAMD")) { 540 if (cpu_apmi_edx & CPUIDEDX_ITSC) { 541 /* Invariant TSC indicates constant TSC on 542 * AMD. 543 */ 544 ci->ci_flags |= CPUF_CONST_TSC; 545 } 546 } 547 548 /* Check if it's an invariant TSC */ 549 if (cpu_apmi_edx & CPUIDEDX_ITSC) 550 ci->ci_flags |= CPUF_INVAR_TSC; 551 } 552 553 freq = cpu_freq(ci); 554 555 amd_cpu_cacheinfo(ci); 556 557 printf("%s: %s", ci->ci_dev->dv_xname, mycpu_model); 558 559 if (freq != 0) 560 printf(", %llu.%02llu MHz", (freq + 4999) / 1000000, 561 ((freq + 4999) / 10000) % 100); 562 563 if (ci->ci_flags & CPUF_PRIMARY) { 564 cpuspeed = (freq + 4999) / 1000000; 565 cpu_cpuspeed = cpu_amd64speed; 566 } 567 568 printf(", %02x-%02x-%02x", ci->ci_family, ci->ci_model, 569 ci->ci_signature & 0x0f); 570 571 printf("\n%s: ", ci->ci_dev->dv_xname); 572 573 for (i = 0; i < nitems(cpu_cpuid_features); i++) 574 if (ci->ci_feature_flags & cpu_cpuid_features[i].bit) 575 printf("%s%s", i? "," : "", cpu_cpuid_features[i].str); 576 for (i = 0; i < nitems(cpu_cpuid_ecxfeatures); i++) 577 if (cpu_ecxfeature & cpu_cpuid_ecxfeatures[i].bit) 578 printf(",%s", cpu_cpuid_ecxfeatures[i].str); 579 for (i = 0; i < nitems(cpu_ecpuid_features); i++) 580 if (ci->ci_feature_eflags & cpu_ecpuid_features[i].bit) 581 printf(",%s", cpu_ecpuid_features[i].str); 582 for (i = 0; i < nitems(cpu_ecpuid_ecxfeatures); i++) 583 if (ecpu_ecxfeature & cpu_ecpuid_ecxfeatures[i].bit) 584 printf(",%s", cpu_ecpuid_ecxfeatures[i].str); 585 for (i = 0; i < nitems(cpu_cpuid_perf_eax); i++) 586 if (cpu_perf_eax & cpu_cpuid_perf_eax[i].bit) 587 printf(",%s", cpu_cpuid_perf_eax[i].str); 588 for (i = 0; i < nitems(cpu_cpuid_apmi_edx); i++) 589 if (cpu_apmi_edx & cpu_cpuid_apmi_edx[i].bit) 590 printf(",%s", cpu_cpuid_apmi_edx[i].str); 591 592 if (cpuid_level >= 0x07) { 593 /* "Structured Extended Feature Flags" */ 594 CPUID_LEAF(0x7, 0, dummy, ci->ci_feature_sefflags_ebx, 595 ci->ci_feature_sefflags_ecx, ci->ci_feature_sefflags_edx); 596 for (i = 0; i < nitems(cpu_seff0_ebxfeatures); i++) 597 if (ci->ci_feature_sefflags_ebx & 598 cpu_seff0_ebxfeatures[i].bit) 599 printf(",%s", cpu_seff0_ebxfeatures[i].str); 600 for (i = 0; i < nitems(cpu_seff0_ecxfeatures); i++) 601 if (ci->ci_feature_sefflags_ecx & 602 cpu_seff0_ecxfeatures[i].bit) 603 printf(",%s", cpu_seff0_ecxfeatures[i].str); 604 for (i = 0; i < nitems(cpu_seff0_edxfeatures); i++) 605 if (ci->ci_feature_sefflags_edx & 606 cpu_seff0_edxfeatures[i].bit) 607 printf(",%s", cpu_seff0_edxfeatures[i].str); 608 } 609 610 if (!strcmp(cpu_vendor, "GenuineIntel") && cpuid_level >= 0x06) { 611 CPUID(0x06, ci->ci_feature_tpmflags, dummy, dummy, dummy); 612 for (i = 0; i < nitems(cpu_tpm_eaxfeatures); i++) 613 if (ci->ci_feature_tpmflags & 614 cpu_tpm_eaxfeatures[i].bit) 615 printf(",%s", cpu_tpm_eaxfeatures[i].str); 616 } else if (!strcmp(cpu_vendor, "AuthenticAMD")) { 617 if (ci->ci_family >= 0x12) 618 ci->ci_feature_tpmflags |= TPM_ARAT; 619 } 620 621 /* AMD speculation control features */ 622 if (!strcmp(cpu_vendor, "AuthenticAMD")) { 623 if (ci->ci_pnfeatset >= 0x80000008) { 624 CPUID(0x80000008, dummy, ci->ci_feature_amdspec_ebx, 625 dummy, dummy); 626 for (i = 0; i < nitems(cpu_amdspec_ebxfeatures); i++) 627 if (ci->ci_feature_amdspec_ebx & 628 cpu_amdspec_ebxfeatures[i].bit) 629 printf(",%s", 630 cpu_amdspec_ebxfeatures[i].str); 631 } 632 } 633 634 /* xsave subfeatures */ 635 if (cpuid_level >= 0xd) { 636 CPUID_LEAF(0xd, 1, val, dummy, dummy, dummy); 637 for (i = 0; i < nitems(cpu_xsave_extfeatures); i++) 638 if (val & cpu_xsave_extfeatures[i].bit) 639 printf(",%s", cpu_xsave_extfeatures[i].str); 640 } 641 642 if (cpu_meltdown) 643 printf(",MELTDOWN"); 644 645 printf("\n"); 646 647 replacemeltdown(); 648 x86_print_cacheinfo(ci); 649 650 /* 651 * "Mitigation G-2" per AMD's Whitepaper "Software Techniques 652 * for Managing Speculation on AMD Processors" 653 * 654 * By setting MSR C001_1029[1]=1, LFENCE becomes a dispatch 655 * serializing instruction. 656 * 657 * This MSR is available on all AMD families >= 10h, except 11h 658 * where LFENCE is always serializing. 659 */ 660 if (!strcmp(cpu_vendor, "AuthenticAMD")) { 661 if (ci->ci_family >= 0x10 && ci->ci_family != 0x11) { 662 uint64_t msr; 663 664 msr = rdmsr(MSR_DE_CFG); 665 if ((msr & DE_CFG_SERIALIZE_LFENCE) == 0) { 666 msr |= DE_CFG_SERIALIZE_LFENCE; 667 wrmsr(MSR_DE_CFG, msr); 668 } 669 } 670 } 671 672 /* 673 * Attempt to disable Silicon Debug and lock the configuration 674 * if it's enabled and unlocked. 675 */ 676 if (!strcmp(cpu_vendor, "GenuineIntel") && 677 (cpu_ecxfeature & CPUIDECX_SDBG)) { 678 uint64_t msr; 679 680 msr = rdmsr(IA32_DEBUG_INTERFACE); 681 if ((msr & IA32_DEBUG_INTERFACE_ENABLE) && 682 (msr & IA32_DEBUG_INTERFACE_LOCK) == 0) { 683 msr &= IA32_DEBUG_INTERFACE_MASK; 684 msr |= IA32_DEBUG_INTERFACE_LOCK; 685 wrmsr(IA32_DEBUG_INTERFACE, msr); 686 } else if (msr & IA32_DEBUG_INTERFACE_ENABLE) 687 printf("%s: cannot disable silicon debug\n", 688 ci->ci_dev->dv_xname); 689 } 690 691 if (ci->ci_flags & CPUF_PRIMARY) { 692#ifndef SMALL_KERNEL 693 if (!strcmp(cpu_vendor, "AuthenticAMD") && 694 ci->ci_pnfeatset >= 0x80000007) { 695 CPUID(0x80000007, dummy, dummy, dummy, val); 696 697 if (val & 0x06) { 698 if ((ci->ci_signature & 0xF00) == 0xF00) 699 setperf_setup = k8_powernow_init; 700 } 701 if (ci->ci_family >= 0x10) 702 setperf_setup = k1x_init; 703 } 704 705 if (cpu_ecxfeature & CPUIDECX_EST) 706 setperf_setup = est_init; 707#endif 708 709 if (cpu_ecxfeature & CPUIDECX_RDRAND) 710 has_rdrand = 1; 711 712 if (ci->ci_feature_sefflags_ebx & SEFF0EBX_RDSEED) 713 has_rdseed = 1; 714 715 if (ci->ci_feature_sefflags_ebx & SEFF0EBX_SMAP) 716 replacesmap(); 717 } 718#ifndef SMALL_KERNEL 719 if (!strncmp(mycpu_model, "Intel", 5)) { 720 u_int32_t cflushsz; 721 722 CPUID(0x01, dummy, cflushsz, dummy, dummy); 723 /* cflush cacheline size is equal to bits 15-8 of ebx * 8 */ 724 ci->ci_cflushsz = ((cflushsz >> 8) & 0xff) * 8; 725 } 726 727 if (CPU_IS_PRIMARY(ci) && (ci->ci_feature_tpmflags & TPM_SENSOR)) { 728 strlcpy(ci->ci_sensordev.xname, ci->ci_dev->dv_xname, 729 sizeof(ci->ci_sensordev.xname)); 730 ci->ci_sensor.type = SENSOR_TEMP; 731 sensor_task_register(ci, intelcore_update_sensor, 5); 732 sensor_attach(&ci->ci_sensordev, &ci->ci_sensor); 733 sensordev_install(&ci->ci_sensordev); 734 } 735#endif 736 737#ifdef CRYPTO 738 if (ci->ci_flags & CPUF_PRIMARY) { 739 if (cpu_ecxfeature & CPUIDECX_PCLMUL) 740 amd64_has_pclmul = 1; 741 742 if (cpu_ecxfeature & CPUIDECX_AES) 743 amd64_has_aesni = 1; 744 } 745#endif 746 747 if (!strcmp(cpu_vendor, "AuthenticAMD")) 748 amd64_errata(ci); 749 750 if (CPU_IS_PRIMARY(ci) && !strcmp(cpu_vendor, "CentaurHauls")) { 751 ci->cpu_setup = via_nano_setup; 752#ifndef SMALL_KERNEL 753 strlcpy(ci->ci_sensordev.xname, ci->ci_dev->dv_xname, 754 sizeof(ci->ci_sensordev.xname)); 755 ci->ci_sensor.type = SENSOR_TEMP; 756 sensor_task_register(ci, via_update_sensor, 5); 757 sensor_attach(&ci->ci_sensordev, &ci->ci_sensor); 758 sensordev_install(&ci->ci_sensordev); 759#endif 760 } 761 762 tsc_timecounter_init(ci, freq); 763 764 cpu_topology(ci); 765#if NVMM > 0 766 cpu_check_vmm_cap(ci); 767#endif /* NVMM > 0 */ 768} 769 770#ifndef SMALL_KERNEL 771/* 772 * Base 2 logarithm of an int. returns 0 for 0 (yeye, I know). 773 */ 774static int 775log2(unsigned int i) 776{ 777 int ret = 0; 778 779 while (i >>= 1) 780 ret++; 781 782 return (ret); 783} 784 785static int 786mask_width(u_int x) 787{ 788 int bit; 789 int mask; 790 int powerof2; 791 792 powerof2 = ((x - 1) & x) == 0; 793 mask = (x << (1 - powerof2)) - 1; 794 795 /* fls */ 796 if (mask == 0) 797 return (0); 798 for (bit = 1; mask != 1; bit++) 799 mask = (unsigned int)mask >> 1; 800 801 return (bit); 802} 803#endif 804 805/* 806 * Build up cpu topology for given cpu, must run on the core itself. 807 */ 808void 809cpu_topology(struct cpu_info *ci) 810{ 811#ifndef SMALL_KERNEL 812 u_int32_t eax, ebx, ecx, edx; 813 u_int32_t apicid, max_apicid = 0, max_coreid = 0; 814 u_int32_t smt_bits = 0, core_bits, pkg_bits = 0; 815 u_int32_t smt_mask = 0, core_mask, pkg_mask = 0; 816 817 /* We need at least apicid at CPUID 1 */ 818 if (cpuid_level < 1) 819 goto no_topology; 820 821 /* Initial apicid */ 822 CPUID(1, eax, ebx, ecx, edx); 823 apicid = (ebx >> 24) & 0xff; 824 825 if (strcmp(cpu_vendor, "AuthenticAMD") == 0) { 826 /* We need at least apicid at CPUID 0x80000008 */ 827 if (ci->ci_pnfeatset < 0x80000008) 828 goto no_topology; 829 830 if (ci->ci_pnfeatset >= 0x8000001e) { 831 struct cpu_info *ci_other; 832 CPU_INFO_ITERATOR cii; 833 834 CPUID(0x8000001e, eax, ebx, ecx, edx); 835 ci->ci_core_id = ebx & 0xff; 836 ci->ci_pkg_id = ecx & 0xff; 837 ci->ci_smt_id = 0; 838 CPU_INFO_FOREACH(cii, ci_other) { 839 if (ci != ci_other && 840 ci_other->ci_core_id == ci->ci_core_id && 841 ci_other->ci_pkg_id == ci->ci_pkg_id) 842 ci->ci_smt_id++; 843 } 844 } else { 845 CPUID(0x80000008, eax, ebx, ecx, edx); 846 core_bits = (ecx >> 12) & 0xf; 847 if (core_bits == 0) 848 goto no_topology; 849 /* So coreidsize 2 gives 3, 3 gives 7... */ 850 core_mask = (1 << core_bits) - 1; 851 /* Core id is the least significant considering mask */ 852 ci->ci_core_id = apicid & core_mask; 853 /* Pkg id is the upper remaining bits */ 854 ci->ci_pkg_id = apicid & ~core_mask; 855 ci->ci_pkg_id >>= core_bits; 856 } 857 } else if (strcmp(cpu_vendor, "GenuineIntel") == 0) { 858 /* We only support leaf 1/4 detection */ 859 if (cpuid_level < 4) 860 goto no_topology; 861 /* Get max_apicid */ 862 CPUID(1, eax, ebx, ecx, edx); 863 max_apicid = (ebx >> 16) & 0xff; 864 /* Get max_coreid */ 865 CPUID_LEAF(4, 0, eax, ebx, ecx, edx); 866 max_coreid = ((eax >> 26) & 0x3f) + 1; 867 /* SMT */ 868 smt_bits = mask_width(max_apicid / max_coreid); 869 smt_mask = (1 << smt_bits) - 1; 870 /* Core */ 871 core_bits = log2(max_coreid); 872 core_mask = (1 << (core_bits + smt_bits)) - 1; 873 core_mask ^= smt_mask; 874 /* Pkg */ 875 pkg_bits = core_bits + smt_bits; 876 pkg_mask = -1 << core_bits; 877 878 ci->ci_smt_id = apicid & smt_mask; 879 ci->ci_core_id = (apicid & core_mask) >> smt_bits; 880 ci->ci_pkg_id = (apicid & pkg_mask) >> pkg_bits; 881 } else 882 goto no_topology; 883#ifdef DEBUG 884 printf("cpu%d: smt %u, core %u, pkg %u " 885 "(apicid 0x%x, max_apicid 0x%x, max_coreid 0x%x, smt_bits 0x%x, smt_mask 0x%x, " 886 "core_bits 0x%x, core_mask 0x%x, pkg_bits 0x%x, pkg_mask 0x%x)\n", 887 ci->ci_cpuid, ci->ci_smt_id, ci->ci_core_id, ci->ci_pkg_id, 888 apicid, max_apicid, max_coreid, smt_bits, smt_mask, core_bits, 889 core_mask, pkg_bits, pkg_mask); 890#else 891 printf("cpu%d: smt %u, core %u, package %u\n", ci->ci_cpuid, 892 ci->ci_smt_id, ci->ci_core_id, ci->ci_pkg_id); 893 894#endif 895 return; 896 /* We can't map, so consider ci_core_id as ci_cpuid */ 897no_topology: 898#endif 899 ci->ci_smt_id = 0; 900 ci->ci_core_id = ci->ci_cpuid; 901 ci->ci_pkg_id = 0; 902} 903 904#if NVMM > 0 905/* 906 * cpu_check_vmm_cap 907 * 908 * Checks for VMM capabilities for 'ci'. Initializes certain per-cpu VMM 909 * state in 'ci' if virtualization extensions are found. 910 * 911 * Parameters: 912 * ci: the cpu being checked 913 */ 914void 915cpu_check_vmm_cap(struct cpu_info *ci) 916{ 917 uint64_t msr; 918 uint32_t cap, dummy, edx; 919 920 /* 921 * Check for workable VMX 922 */ 923 if (cpu_ecxfeature & CPUIDECX_VMX) { 924 msr = rdmsr(MSR_IA32_FEATURE_CONTROL); 925 926 if (!(msr & IA32_FEATURE_CONTROL_LOCK)) 927 ci->ci_vmm_flags |= CI_VMM_VMX; 928 else { 929 if (msr & IA32_FEATURE_CONTROL_VMX_EN) 930 ci->ci_vmm_flags |= CI_VMM_VMX; 931 else 932 ci->ci_vmm_flags |= CI_VMM_DIS; 933 } 934 } 935 936 /* 937 * Check for EPT (Intel Nested Paging) and other secondary 938 * controls 939 */ 940 if (ci->ci_vmm_flags & CI_VMM_VMX) { 941 /* Secondary controls available? */ 942 /* XXX should we check true procbased ctls here if avail? */ 943 msr = rdmsr(IA32_VMX_PROCBASED_CTLS); 944 if (msr & (IA32_VMX_ACTIVATE_SECONDARY_CONTROLS) << 32) { 945 msr = rdmsr(IA32_VMX_PROCBASED2_CTLS); 946 /* EPT available? */ 947 if (msr & (IA32_VMX_ENABLE_EPT) << 32) 948 ci->ci_vmm_flags |= CI_VMM_EPT; 949 /* VM Functions available? */ 950 if (msr & (IA32_VMX_ENABLE_VM_FUNCTIONS) << 32) { 951 ci->ci_vmm_cap.vcc_vmx.vmx_vm_func = 952 rdmsr(IA32_VMX_VMFUNC); 953 } 954 } 955 } 956 957 /* 958 * Check startup config (VMX) 959 */ 960 if (ci->ci_vmm_flags & CI_VMM_VMX) { 961 /* CR0 fixed and flexible bits */ 962 msr = rdmsr(IA32_VMX_CR0_FIXED0); 963 ci->ci_vmm_cap.vcc_vmx.vmx_cr0_fixed0 = msr; 964 msr = rdmsr(IA32_VMX_CR0_FIXED1); 965 ci->ci_vmm_cap.vcc_vmx.vmx_cr0_fixed1 = msr; 966 967 /* CR4 fixed and flexible bits */ 968 msr = rdmsr(IA32_VMX_CR4_FIXED0); 969 ci->ci_vmm_cap.vcc_vmx.vmx_cr4_fixed0 = msr; 970 msr = rdmsr(IA32_VMX_CR4_FIXED1); 971 ci->ci_vmm_cap.vcc_vmx.vmx_cr4_fixed1 = msr; 972 973 /* VMXON region revision ID (bits 30:0 of IA32_VMX_BASIC) */ 974 msr = rdmsr(IA32_VMX_BASIC); 975 ci->ci_vmm_cap.vcc_vmx.vmx_vmxon_revision = 976 (uint32_t)(msr & 0x7FFFFFFF); 977 978 /* MSR save / load table size */ 979 msr = rdmsr(IA32_VMX_MISC); 980 ci->ci_vmm_cap.vcc_vmx.vmx_msr_table_size = 981 (uint32_t)(msr & IA32_VMX_MSR_LIST_SIZE_MASK) >> 25; 982 983 /* CR3 target count size */ 984 ci->ci_vmm_cap.vcc_vmx.vmx_cr3_tgt_count = 985 (uint32_t)(msr & IA32_VMX_CR3_TGT_SIZE_MASK) >> 16; 986 } 987 988 /* 989 * Check for workable SVM 990 */ 991 if (ecpu_ecxfeature & CPUIDECX_SVM) { 992 msr = rdmsr(MSR_AMD_VM_CR); 993 994 if (!(msr & AMD_SVMDIS)) 995 ci->ci_vmm_flags |= CI_VMM_SVM; 996 997 CPUID(CPUID_AMD_SVM_CAP, dummy, 998 ci->ci_vmm_cap.vcc_svm.svm_max_asid, dummy, edx); 999 1000 if (ci->ci_vmm_cap.vcc_svm.svm_max_asid > 0xFFF) 1001 ci->ci_vmm_cap.vcc_svm.svm_max_asid = 0xFFF; 1002 1003 if (edx & AMD_SVM_FLUSH_BY_ASID_CAP) 1004 ci->ci_vmm_cap.vcc_svm.svm_flush_by_asid = 1; 1005 1006 if (edx & AMD_SVM_VMCB_CLEAN_CAP) 1007 ci->ci_vmm_cap.vcc_svm.svm_vmcb_clean = 1; 1008 } 1009 1010 /* 1011 * Check for SVM Nested Paging 1012 */ 1013 if ((ci->ci_vmm_flags & CI_VMM_SVM) && 1014 ci->ci_pnfeatset >= CPUID_AMD_SVM_CAP) { 1015 CPUID(CPUID_AMD_SVM_CAP, dummy, dummy, dummy, cap); 1016 if (cap & AMD_SVM_NESTED_PAGING_CAP) 1017 ci->ci_vmm_flags |= CI_VMM_RVI; 1018 } 1019 1020 /* 1021 * Check "L1 flush on VM entry" (Intel L1TF vuln) semantics 1022 */ 1023 if (!strcmp(cpu_vendor, "GenuineIntel")) { 1024 if (ci->ci_feature_sefflags_edx & SEFF0EDX_L1DF) 1025 ci->ci_vmm_cap.vcc_vmx.vmx_has_l1_flush_msr = 1; 1026 else 1027 ci->ci_vmm_cap.vcc_vmx.vmx_has_l1_flush_msr = 0; 1028 1029 /* 1030 * Certain CPUs may have the vulnerability remedied in 1031 * hardware, check for that and override the setting 1032 * calculated above. 1033 */ 1034 if (ci->ci_feature_sefflags_edx & SEFF0EDX_ARCH_CAP) { 1035 msr = rdmsr(MSR_ARCH_CAPABILITIES); 1036 if (msr & ARCH_CAPABILITIES_SKIP_L1DFL_VMENTRY) 1037 ci->ci_vmm_cap.vcc_vmx.vmx_has_l1_flush_msr = 1038 VMX_SKIP_L1D_FLUSH; 1039 } 1040 } 1041} 1042#endif /* NVMM > 0 */ 1043