1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2008, 2009 Rui Paulo <rpaulo@FreeBSD.org> 5 * Copyright (c) 2009 Norikatsu Shigemura <nork@FreeBSD.org> 6 * Copyright (c) 2009-2012 Jung-uk Kim <jkim@FreeBSD.org> 7 * All rights reserved. 8 * Copyright (c) 2017-2020 Conrad Meyer <cem@FreeBSD.org>. All rights reserved. 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 * 31 * $FreeBSD: head/sys/dev/amdtemp/amdtemp.c 366136 2020-09-25 04:16:28Z cem $ 32 */ 33 34 /* 35 * Driver for the AMD CPU on-die thermal sensors. 36 * Initially based on the k8temp Linux driver. 37 */ 38 39 #include <sys/param.h> 40 #include <sys/bus.h> 41 #include <sys/conf.h> 42 #include <sys/kernel.h> 43 #include <sys/module.h> 44 #include <sys/sysctl.h> 45 #include <sys/systm.h> 46 #include <sys/malloc.h> 47 #include <sys/sensors.h> 48 49 #include <machine/cpufunc.h> 50 #include <machine/md_var.h> 51 #include <machine/specialreg.h> 52 53 #include <bus/pci/pcivar.h> 54 #include <bus/pci/pci_cfgreg.h> 55 56 #include <dev/powermng/amdsmn/amdsmn.h> 57 58 typedef enum { 59 CORE0_SENSOR0, 60 CORE0_SENSOR1, 61 CORE1_SENSOR0, 62 CORE1_SENSOR1, 63 CORE0, 64 CORE1, 65 CCD1, 66 CCD_BASE = CCD1, 67 CCD2, 68 CCD3, 69 CCD4, 70 CCD5, 71 CCD6, 72 CCD7, 73 CCD8, 74 MAXSENSORS, 75 76 CCD_MAX = CCD8, 77 NUM_CCDS = CCD_MAX - CCD_BASE + 1, 78 } amdsensor_t; 79 80 struct amdtemp_softc { 81 int sc_ncores; 82 int sc_ntemps; 83 int sc_flags; 84 int sc_ccd_display; 85 #define AMDTEMP_FLAG_CS_SWAP 0x01 /* ThermSenseCoreSel is inverted. */ 86 #define AMDTEMP_FLAG_CT_10BIT 0x02 /* CurTmp is 10-bit wide. */ 87 #define AMDTEMP_FLAG_ALT_OFFSET 0x04 /* CurTmp starts at -28C. */ 88 int32_t sc_offset; 89 int32_t (*sc_gettemp)(device_t, amdsensor_t); 90 struct sysctl_oid *sc_sysctl_cpu[MAXCPU]; 91 struct intr_config_hook sc_ich; 92 device_t sc_smn; 93 uint32_t sc_probed_regmask; 94 95 /* 96 * NOTE: We put common sensors like the CCDs on cpu0. Remaining 97 * cores are only applicable if ntemps == 2 (with no CCDs). 98 * When ntemps == 1 the temp sensors are CCD-based and shared. 99 */ 100 struct sensorcpu { 101 device_t dev; 102 struct amdtemp_softc *sc; 103 struct ksensordev sensordev; 104 struct ksensor *sensors; 105 struct sensor_task *senstask; 106 uint32_t regmask; 107 } *sc_sensorcpus; 108 }; 109 110 /* 111 * N.B. The numbers in macro names below are significant and represent CPU 112 * family and model numbers. Do not make up fictitious family or model numbers 113 * when adding support for new devices. 114 */ 115 #define VENDORID_AMD 0x1022 116 #define DEVICEID_AMD_MISC0F 0x1103 117 #define DEVICEID_AMD_MISC10 0x1203 118 #define DEVICEID_AMD_MISC11 0x1303 119 #define DEVICEID_AMD_MISC14 0x1703 120 #define DEVICEID_AMD_MISC15 0x1603 121 #define DEVICEID_AMD_MISC15_M10H 0x1403 122 #define DEVICEID_AMD_MISC15_M30H 0x141d 123 #define DEVICEID_AMD_MISC15_M60H_ROOT 0x1576 124 #define DEVICEID_AMD_MISC16 0x1533 125 #define DEVICEID_AMD_MISC16_M30H 0x1583 126 #define DEVICEID_AMD_HOSTB17H_ROOT 0x1450 127 #define DEVICEID_AMD_HOSTB17H_M10H_ROOT 0x15d0 128 #define DEVICEID_AMD_HOSTB17H_M30H_ROOT 0x1480 /* Also M70h. */ 129 #define DEVICEID_AMD_HOSTB17H_M60H_ROOT 0x1630 130 131 static const struct amdtemp_product { 132 uint16_t amdtemp_vendorid; 133 uint16_t amdtemp_deviceid; 134 /* 135 * 0xFC register is only valid on the D18F3 PCI device; SMN temp 136 * drivers do not attach to that device. 137 */ 138 bool amdtemp_has_cpuid; 139 } amdtemp_products[] = { 140 { VENDORID_AMD, DEVICEID_AMD_MISC0F, true }, 141 { VENDORID_AMD, DEVICEID_AMD_MISC10, true }, 142 { VENDORID_AMD, DEVICEID_AMD_MISC11, true }, 143 { VENDORID_AMD, DEVICEID_AMD_MISC14, true }, 144 { VENDORID_AMD, DEVICEID_AMD_MISC15, true }, 145 { VENDORID_AMD, DEVICEID_AMD_MISC15_M10H, true }, 146 { VENDORID_AMD, DEVICEID_AMD_MISC15_M30H, true }, 147 { VENDORID_AMD, DEVICEID_AMD_MISC15_M60H_ROOT, false }, 148 { VENDORID_AMD, DEVICEID_AMD_MISC16, true }, 149 { VENDORID_AMD, DEVICEID_AMD_MISC16_M30H, true }, 150 { VENDORID_AMD, DEVICEID_AMD_HOSTB17H_ROOT, false }, 151 { VENDORID_AMD, DEVICEID_AMD_HOSTB17H_M10H_ROOT, false }, 152 { VENDORID_AMD, DEVICEID_AMD_HOSTB17H_M30H_ROOT, false }, 153 { VENDORID_AMD, DEVICEID_AMD_HOSTB17H_M60H_ROOT, false }, 154 }; 155 156 /* 157 * Reported Temperature Control Register, family 0Fh-15h (some models), 16h. 158 */ 159 #define AMDTEMP_REPTMP_CTRL 0xa4 160 161 #define AMDTEMP_REPTMP10H_CURTMP_MASK 0x7ff 162 #define AMDTEMP_REPTMP10H_CURTMP_SHIFT 21 163 #define AMDTEMP_REPTMP10H_TJSEL_MASK 0x3 164 #define AMDTEMP_REPTMP10H_TJSEL_SHIFT 16 165 166 /* 167 * Reported Temperature, Family 15h, M60+ 168 * 169 * Same register bit definitions as other Family 15h CPUs, but access is 170 * indirect via SMN, like Family 17h. 171 */ 172 #define AMDTEMP_15H_M60H_REPTMP_CTRL 0xd8200ca4 173 174 /* 175 * Reported Temperature, Family 17h 176 * 177 * According to AMD OSRR for 17H, section 4.2.1, bits 31-21 of this register 178 * provide the current temp. bit 19, when clear, means the temp is reported in 179 * a range 0.."225C" (probable typo for 255C), and when set changes the range 180 * to -49..206C. 181 */ 182 #define AMDTEMP_17H_CUR_TMP 0x59800 183 #define AMDTEMP_17H_CUR_TMP_RANGE_SEL (1u << 19) 184 /* 185 * The following register set was discovered experimentally by Ondrej Čerman 186 * and collaborators, but is not (yet) documented in a PPR/OSRR (other than 187 * the M70H PPR SMN memory map showing [0x59800, +0x314] as allocated to 188 * SMU::THM). It seems plausible and the Linux sensor folks have adopted it. 189 */ 190 #define AMDTEMP_17H_CCD_TMP_BASE 0x59954 191 #define AMDTEMP_17H_CCD_TMP_VALID (1u << 11) 192 193 /* 194 * AMD temperature range adjustment, in deciKelvins (i.e., 49.0 Celsius). 195 */ 196 #define AMDTEMP_CURTMP_RANGE_ADJUST 490 197 198 /* 199 * Thermaltrip Status Register (Family 0Fh only) 200 */ 201 #define AMDTEMP_THERMTP_STAT 0xe4 202 #define AMDTEMP_TTSR_SELCORE 0x04 203 #define AMDTEMP_TTSR_SELSENSOR 0x40 204 205 /* 206 * DRAM Configuration High Register 207 */ 208 #define AMDTEMP_DRAM_CONF_HIGH 0x94 /* Function 2 */ 209 #define AMDTEMP_DRAM_MODE_DDR3 0x0100 210 211 /* 212 * CPU Family/Model Register 213 */ 214 #define AMDTEMP_CPUID 0xfc 215 216 /* 217 * Device methods. 218 */ 219 static void amdtemp_identify(driver_t *driver, device_t parent); 220 static int amdtemp_probe(device_t dev); 221 static int amdtemp_attach(device_t dev); 222 static void amdtemp_intrhook(void *arg); 223 static int amdtemp_detach(device_t dev); 224 static int32_t amdtemp_gettemp0f(device_t dev, amdsensor_t sensor); 225 static int32_t amdtemp_gettemp(device_t dev, amdsensor_t sensor); 226 static int32_t amdtemp_gettemp15hm60h(device_t dev, amdsensor_t sensor); 227 static int32_t amdtemp_gettemp17to19h(device_t dev, amdsensor_t sensor); 228 static void amdtemp_probe_ccd_sensors17h(device_t dev, uint32_t model); 229 static void amdtemp_probe_ccd_sensors19h(device_t dev, uint32_t model); 230 static int amdtemp_sysctl(SYSCTL_HANDLER_ARGS); 231 static void amdtemp_sensor_task(void *); 232 233 static device_method_t amdtemp_methods[] = { 234 /* Device interface */ 235 DEVMETHOD(device_identify, amdtemp_identify), 236 DEVMETHOD(device_probe, amdtemp_probe), 237 DEVMETHOD(device_attach, amdtemp_attach), 238 DEVMETHOD(device_detach, amdtemp_detach), 239 240 DEVMETHOD_END 241 }; 242 243 static driver_t amdtemp_driver = { 244 "amdtemp", 245 amdtemp_methods, 246 sizeof(struct amdtemp_softc), 247 }; 248 249 static devclass_t amdtemp_devclass; 250 DRIVER_MODULE(amdtemp, hostb, amdtemp_driver, amdtemp_devclass, NULL, NULL); 251 MODULE_VERSION(amdtemp, 1); 252 MODULE_DEPEND(amdtemp, amdsmn, 1, 1, 1); 253 #if !defined(__DragonFly__) 254 MODULE_PNP_INFO("U16:vendor;U16:device", pci, amdtemp, amdtemp_products, 255 nitems(amdtemp_products)); 256 #endif 257 258 static bool 259 amdtemp_match(device_t dev, const struct amdtemp_product **product_out) 260 { 261 int i; 262 uint16_t vendor, devid; 263 264 vendor = pci_get_vendor(dev); 265 devid = pci_get_device(dev); 266 267 for (i = 0; i < nitems(amdtemp_products); i++) { 268 if (vendor == amdtemp_products[i].amdtemp_vendorid && 269 devid == amdtemp_products[i].amdtemp_deviceid) { 270 if (product_out != NULL) 271 *product_out = &amdtemp_products[i]; 272 return (true); 273 } 274 } 275 return (false); 276 } 277 278 static void 279 amdtemp_identify(driver_t *driver, device_t parent) 280 { 281 device_t child; 282 283 /* Make sure we're not being doubly invoked. */ 284 if (device_find_child(parent, "amdtemp", -1) != NULL) 285 return; 286 287 if (amdtemp_match(parent, NULL)) { 288 child = device_add_child(parent, "amdtemp", -1); 289 if (child == NULL) 290 device_printf(parent, "add amdtemp child failed\n"); 291 } 292 } 293 294 static int 295 amdtemp_probe(device_t dev) 296 { 297 uint32_t family, model; 298 299 if (resource_disabled("amdtemp", 0)) 300 return (ENXIO); 301 if (!amdtemp_match(device_get_parent(dev), NULL)) 302 return (ENXIO); 303 304 family = CPUID_TO_FAMILY(cpu_id); 305 model = CPUID_TO_MODEL(cpu_id); 306 307 switch (family) { 308 case 0x0f: 309 if ((model == 0x04 && (cpu_id & CPUID_STEPPING) == 0) || 310 (model == 0x05 && (cpu_id & CPUID_STEPPING) <= 1)) 311 return (ENXIO); 312 break; 313 case 0x10: 314 case 0x11: 315 case 0x12: 316 case 0x14: 317 case 0x15: 318 case 0x16: 319 case 0x17: 320 case 0x19: 321 break; 322 default: 323 return (ENXIO); 324 } 325 device_set_desc(dev, "AMD CPU On-Die Thermal Sensors"); 326 327 return (BUS_PROBE_GENERIC); 328 } 329 330 static int 331 amdtemp_attach(device_t dev) 332 { 333 char tn[32]; 334 u_int regs[4]; 335 const struct amdtemp_product *product; 336 struct amdtemp_softc *sc; 337 struct sysctl_ctx_list *sysctlctx; 338 struct sysctl_oid *sysctlnode; 339 uint32_t cpuid, family, model; 340 u_int bid; 341 int erratum319, unit; 342 bool needsmn; 343 344 sc = device_get_softc(dev); 345 erratum319 = 0; 346 needsmn = false; 347 348 if (!amdtemp_match(device_get_parent(dev), &product)) 349 return (ENXIO); 350 351 cpuid = cpu_id; 352 family = CPUID_TO_FAMILY(cpuid); 353 model = CPUID_TO_MODEL(cpuid); 354 355 /* 356 * This checks for the byzantine condition of running a heterogenous 357 * revision multi-socket system where the attach thread is potentially 358 * probing a remote socket's PCI device. 359 * 360 * Currently, such scenarios are unsupported on models using the SMN 361 * (because on those models, amdtemp(4) attaches to a different PCI 362 * device than the one that contains AMDTEMP_CPUID). 363 * 364 * The ancient 0x0F family of devices only supports this register from 365 * models 40h+. 366 */ 367 if (product->amdtemp_has_cpuid && (family > 0x0f || 368 (family == 0x0f && model >= 0x40))) { 369 cpuid = pci_read_config(device_get_parent(dev), AMDTEMP_CPUID, 370 4); 371 family = CPUID_TO_FAMILY(cpuid); 372 model = CPUID_TO_MODEL(cpuid); 373 } 374 375 switch (family) { 376 case 0x0f: 377 /* 378 * Thermaltrip Status Register 379 * 380 * - ThermSenseCoreSel 381 * 382 * Revision F & G: 0 - Core1, 1 - Core0 383 * Other: 0 - Core0, 1 - Core1 384 * 385 * - CurTmp 386 * 387 * Revision G: bits 23-14 388 * Other: bits 23-16 389 * 390 * XXX According to the BKDG, CurTmp, ThermSenseSel and 391 * ThermSenseCoreSel bits were introduced in Revision F 392 * but CurTmp seems working fine as early as Revision C. 393 * However, it is not clear whether ThermSenseSel and/or 394 * ThermSenseCoreSel work in undocumented cases as well. 395 * In fact, the Linux driver suggests it may not work but 396 * we just assume it does until we find otherwise. 397 * 398 * XXX According to Linux, CurTmp starts at -28C on 399 * Socket AM2 Revision G processors, which is not 400 * documented anywhere. 401 */ 402 if (model >= 0x40) 403 sc->sc_flags |= AMDTEMP_FLAG_CS_SWAP; 404 if (model >= 0x60 && model != 0xc1) { 405 do_cpuid(0x80000001, regs); 406 bid = (regs[1] >> 9) & 0x1f; 407 switch (model) { 408 case 0x68: /* Socket S1g1 */ 409 case 0x6c: 410 case 0x7c: 411 break; 412 case 0x6b: /* Socket AM2 and ASB1 (2 cores) */ 413 if (bid != 0x0b && bid != 0x0c) 414 sc->sc_flags |= 415 AMDTEMP_FLAG_ALT_OFFSET; 416 break; 417 case 0x6f: /* Socket AM2 and ASB1 (1 core) */ 418 case 0x7f: 419 if (bid != 0x07 && bid != 0x09 && 420 bid != 0x0c) 421 sc->sc_flags |= 422 AMDTEMP_FLAG_ALT_OFFSET; 423 break; 424 default: 425 sc->sc_flags |= AMDTEMP_FLAG_ALT_OFFSET; 426 } 427 sc->sc_flags |= AMDTEMP_FLAG_CT_10BIT; 428 } 429 430 /* 431 * There are two sensors per core. 432 */ 433 sc->sc_ntemps = 2; 434 sc->sc_ccd_display = 0; 435 436 sc->sc_gettemp = amdtemp_gettemp0f; 437 break; 438 case 0x10: 439 /* 440 * Erratum 319 Inaccurate Temperature Measurement 441 * 442 * http://support.amd.com/us/Processor_TechDocs/41322.pdf 443 */ 444 do_cpuid(0x80000001, regs); 445 switch ((regs[1] >> 28) & 0xf) { 446 case 0: /* Socket F */ 447 erratum319 = 1; 448 break; 449 case 1: /* Socket AM2+ or AM3 */ 450 if ((pci_cfgregread(pci_get_bus(dev), 451 pci_get_slot(dev), 2, AMDTEMP_DRAM_CONF_HIGH, 2) & 452 AMDTEMP_DRAM_MODE_DDR3) != 0 || model > 0x04 || 453 (model == 0x04 && (cpuid & CPUID_STEPPING) >= 3)) 454 break; 455 /* XXX 00100F42h (RB-C2) exists in both formats. */ 456 erratum319 = 1; 457 break; 458 } 459 /* FALLTHROUGH */ 460 case 0x11: 461 case 0x12: 462 case 0x14: 463 case 0x15: 464 case 0x16: 465 sc->sc_ntemps = 1; 466 sc->sc_ccd_display = 1; 467 /* 468 * Some later (60h+) models of family 15h use a similar SMN 469 * network as family 17h. (However, the register index differs 470 * from 17h and the decoding matches other 10h-15h models, 471 * which differ from 17h.) 472 */ 473 if (family == 0x15 && model >= 0x60) { 474 sc->sc_gettemp = amdtemp_gettemp15hm60h; 475 needsmn = true; 476 } else 477 sc->sc_gettemp = amdtemp_gettemp; 478 break; 479 case 0x17: 480 case 0x19: 481 sc->sc_ntemps = 1; 482 sc->sc_ccd_display = 1; 483 sc->sc_gettemp = amdtemp_gettemp17to19h; 484 needsmn = true; 485 break; 486 default: 487 device_printf(dev, "Bogus family 0x%x\n", family); 488 return (ENXIO); 489 } 490 491 if (needsmn) { 492 sc->sc_smn = device_find_child( 493 device_get_parent(dev), "amdsmn", -1); 494 if (sc->sc_smn == NULL) { 495 if (bootverbose) 496 device_printf(dev, "No SMN device found\n"); 497 return (ENXIO); 498 } 499 } 500 501 /* 502 * Find number of cores per package. XXX this does not work 503 * properly, it appears to be calculating the total number of cores. 504 */ 505 506 sc->sc_ncores = (amd_feature2 & AMDID2_CMP) != 0 ? 507 (cpu_procinfo2 & AMDID_CMP_CORES) + 1 : 1; 508 if (sc->sc_ncores > MAXCPU) 509 return (ENXIO); 510 511 if (erratum319) 512 device_printf(dev, 513 "Erratum 319: temperature measurement may be inaccurate\n"); 514 if (bootverbose) 515 device_printf(dev, "Found %d cores and %d sensors.\n", 516 sc->sc_ncores, 517 sc->sc_ntemps > 1 ? sc->sc_ntemps * sc->sc_ncores : 1); 518 519 /* 520 * dev.amdtemp.N tree. 521 */ 522 unit = device_get_unit(dev); 523 ksnprintf(tn, sizeof(tn), "dev.amdtemp.%d.sensor_offset", unit); 524 TUNABLE_INT_FETCH(tn, &sc->sc_offset); 525 526 sysctlctx = device_get_sysctl_ctx(dev); 527 SYSCTL_ADD_INT(sysctlctx, 528 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 529 "sensor_offset", CTLFLAG_RW, &sc->sc_offset, 0, 530 "Temperature sensor offset"); 531 sysctlnode = SYSCTL_ADD_NODE(sysctlctx, 532 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 533 "core0", CTLFLAG_RD, 0, "Core 0"); 534 535 SYSCTL_ADD_PROC(sysctlctx, 536 SYSCTL_CHILDREN(sysctlnode), 537 OID_AUTO, "sensor0", 538 CTLTYPE_INT | CTLFLAG_RD, 539 dev, CORE0_SENSOR0, amdtemp_sysctl, "IK", 540 "Core 0 / Sensor 0 temperature"); 541 542 sc->sc_probed_regmask |= 1U << CORE0_SENSOR0; 543 544 if (family == 0x17) 545 amdtemp_probe_ccd_sensors17h(dev, model); 546 else if (family == 0x19) 547 amdtemp_probe_ccd_sensors19h(dev, model); 548 else if (sc->sc_ntemps > 1) { 549 SYSCTL_ADD_PROC(sysctlctx, 550 SYSCTL_CHILDREN(sysctlnode), 551 OID_AUTO, "sensor1", 552 CTLTYPE_INT | CTLFLAG_RD, 553 dev, CORE0_SENSOR1, amdtemp_sysctl, "IK", 554 "Core 0 / Sensor 1 temperature"); 555 556 sc->sc_probed_regmask |= 1U << CORE0_SENSOR1; 557 558 if (sc->sc_ncores > 1) { 559 sysctlnode = SYSCTL_ADD_NODE(sysctlctx, 560 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 561 OID_AUTO, "core1", CTLFLAG_RD, 562 0, "Core 1"); 563 564 SYSCTL_ADD_PROC(sysctlctx, 565 SYSCTL_CHILDREN(sysctlnode), 566 OID_AUTO, "sensor0", 567 CTLTYPE_INT | CTLFLAG_RD, 568 dev, CORE1_SENSOR0, amdtemp_sysctl, "IK", 569 "Core 1 / Sensor 0 temperature"); 570 571 SYSCTL_ADD_PROC(sysctlctx, 572 SYSCTL_CHILDREN(sysctlnode), 573 OID_AUTO, "sensor1", 574 CTLTYPE_INT | CTLFLAG_RD, 575 dev, CORE1_SENSOR1, amdtemp_sysctl, "IK", 576 "Core 1 / Sensor 1 temperature"); 577 578 sc->sc_probed_regmask |= 1U << CORE1_SENSOR0; 579 sc->sc_probed_regmask |= 1U << CORE1_SENSOR1; 580 } 581 } 582 583 /* 584 * Try to create dev.cpu sysctl entries and setup intrhook function. 585 * This is needed because the cpu driver may be loaded late on boot, 586 * after us. 587 */ 588 amdtemp_intrhook(dev); 589 sc->sc_ich.ich_func = amdtemp_intrhook; 590 sc->sc_ich.ich_arg = dev; 591 if (config_intrhook_establish(&sc->sc_ich) != 0) { 592 device_printf(dev, "config_intrhook_establish failed!\n"); 593 return (ENXIO); 594 } 595 596 return (0); 597 } 598 599 void 600 amdtemp_intrhook(void *arg) 601 { 602 struct amdtemp_softc *sc; 603 struct sysctl_ctx_list *sysctlctx; 604 device_t dev = (device_t)arg; 605 device_t acpi, cpu, nexus; 606 amdsensor_t sensor; 607 int i; 608 int j; 609 610 sc = device_get_softc(dev); 611 if (sc->sc_ich.ich_arg == NULL) 612 return; 613 614 /* 615 * dev.cpu.N.temperature. 616 */ 617 nexus = device_find_child(root_bus, "nexus", 0); 618 acpi = device_find_child(nexus, "acpi", 0); 619 620 for (i = 0; i < sc->sc_ncores; i++) { 621 if (sc->sc_sysctl_cpu[i] != NULL) 622 continue; 623 cpu = device_find_child(acpi, "cpu", 624 device_get_unit(dev) * sc->sc_ncores + i); 625 if (cpu != NULL) { 626 sysctlctx = device_get_sysctl_ctx(cpu); 627 628 sensor = sc->sc_ntemps > 1 ? 629 (i == 0 ? CORE0 : CORE1) : CORE0_SENSOR0; 630 sc->sc_sysctl_cpu[i] = SYSCTL_ADD_PROC(sysctlctx, 631 SYSCTL_CHILDREN(device_get_sysctl_tree(cpu)), 632 OID_AUTO, "temperature", 633 CTLTYPE_INT | CTLFLAG_RD, 634 dev, sensor, amdtemp_sysctl, "IK", 635 "Current temparature"); 636 } 637 } 638 config_intrhook_disestablish(&sc->sc_ich); 639 640 /* 641 * sensor infrastructure. Use [ncpus] for globally shared sensors 642 */ 643 sc->sc_sensorcpus = kmalloc(sizeof(*sc->sc_sensorcpus) * 644 (sc->sc_ncores + 1), 645 M_DEVBUF, M_WAITOK | M_ZERO); 646 647 for (i = 0; i <= sc->sc_ncores; i++) { 648 struct sensorcpu *scpu = &sc->sc_sensorcpus[i]; 649 650 if (i == 0) 651 scpu->regmask = sc->sc_probed_regmask & 0x0003U; 652 else if (i == 1) 653 scpu->regmask = sc->sc_probed_regmask & 0x000CU; 654 else if (i != sc->sc_ncores) 655 scpu->regmask = 0; 656 else 657 scpu->regmask = sc->sc_probed_regmask & ~0xFU; 658 659 if (scpu->regmask == 0) 660 continue; 661 662 if (sc->sc_ccd_display) { 663 ksnprintf(scpu->sensordev.xname, 664 sizeof(scpu->sensordev.xname), 665 "die%d", device_get_unit(dev)); 666 } else { 667 ksnprintf(scpu->sensordev.xname, 668 sizeof(scpu->sensordev.xname), 669 "cpu%d", i); 670 } 671 672 scpu->dev = dev; 673 scpu->sc = sc; 674 scpu->sensors = kmalloc(sizeof(*scpu->sensors) * MAXSENSORS, 675 M_DEVBUF, M_WAITOK | M_ZERO); 676 for (j = 0; j < MAXSENSORS; ++j) { 677 if ((scpu->regmask & (1U << j)) == 0) 678 continue; 679 680 switch(j) { 681 case CORE0_SENSOR0: 682 case CORE0_SENSOR1: 683 case CORE1_SENSOR0: 684 case CORE1_SENSOR1: 685 if (sc->sc_ccd_display) { 686 ksnprintf(scpu->sensors[j].desc, 687 sizeof(scpu->sensors[0].desc), 688 "high temp"); 689 } else { 690 ksnprintf(scpu->sensors[j].desc, 691 sizeof(scpu->sensors[0].desc), 692 "temp%d", j & 1); 693 } 694 break; 695 case CORE0: 696 ksnprintf(scpu->sensors[j].desc, 697 sizeof(scpu->sensors[0].desc), 698 "core0 rollup temp"); 699 break; 700 case CORE1: 701 ksnprintf(scpu->sensors[j].desc, 702 sizeof(scpu->sensors[0].desc), 703 "core1 rollup temp"); 704 break; 705 case CCD_BASE ... CCD_MAX: 706 ksnprintf(scpu->sensors[j].desc, 707 sizeof(scpu->sensors[0].desc), 708 "ccd%u temp", j - CCD_BASE); 709 break; 710 } 711 scpu->sensors[j].type = SENSOR_TEMP; 712 sensor_set_unknown(&scpu->sensors[j]); 713 sensor_attach(&scpu->sensordev, &scpu->sensors[j]); 714 } 715 scpu->senstask = sensor_task_register2(scpu, 716 amdtemp_sensor_task, 717 2, 718 ((i < sc->sc_ncores) ? 719 i : -1)); 720 sensordev_install(&scpu->sensordev); 721 } 722 } 723 724 int 725 amdtemp_detach(device_t dev) 726 { 727 struct amdtemp_softc *sc = device_get_softc(dev); 728 int i; 729 int j; 730 731 for (i = 0; i < sc->sc_ncores; i++) { 732 if (sc->sc_sysctl_cpu[i] != NULL) 733 sysctl_remove_oid(sc->sc_sysctl_cpu[i], 1, 0); 734 } 735 736 if (sc->sc_sensorcpus) { 737 for (i = 0; i <= sc->sc_ncores; i++) { 738 struct sensorcpu *scpu = &sc->sc_sensorcpus[i]; 739 740 if (scpu->sensors) { 741 for (j = 0; j < MAXSENSORS; ++j) { 742 if ((scpu->regmask & (1U << j)) == 0) 743 continue; 744 sensor_detach(&scpu->sensordev, 745 &scpu->sensors[j]); 746 } 747 if (scpu->senstask) { 748 sensor_task_unregister2(scpu->senstask); 749 scpu->senstask = NULL; 750 } 751 sensordev_deinstall(&scpu->sensordev); 752 kfree(scpu->sensors, M_DEVBUF); 753 scpu->sensors = NULL; 754 } 755 } 756 kfree(sc->sc_sensorcpus, M_DEVBUF); 757 sc->sc_sensorcpus = NULL; 758 } 759 760 /* NewBus removes the dev.amdtemp.N tree by itself. */ 761 762 return (0); 763 } 764 765 static int 766 amdtemp_sysctl(SYSCTL_HANDLER_ARGS) 767 { 768 device_t dev = (device_t)arg1; 769 struct amdtemp_softc *sc = device_get_softc(dev); 770 amdsensor_t sensor = (amdsensor_t)arg2; 771 int32_t auxtemp[2], temp; 772 int error; 773 774 switch (sensor) { 775 case CORE0: 776 auxtemp[0] = sc->sc_gettemp(dev, CORE0_SENSOR0); 777 auxtemp[1] = sc->sc_gettemp(dev, CORE0_SENSOR1); 778 temp = imax(auxtemp[0], auxtemp[1]); 779 break; 780 case CORE1: 781 auxtemp[0] = sc->sc_gettemp(dev, CORE1_SENSOR0); 782 auxtemp[1] = sc->sc_gettemp(dev, CORE1_SENSOR1); 783 temp = imax(auxtemp[0], auxtemp[1]); 784 break; 785 default: 786 temp = sc->sc_gettemp(dev, sensor); 787 break; 788 } 789 error = sysctl_handle_int(oidp, &temp, 0, req); 790 791 return (error); 792 } 793 794 #define AMDTEMP_ZERO_C_TO_K 2731 795 796 static int32_t 797 amdtemp_gettemp0f(device_t dev, amdsensor_t sensor) 798 { 799 struct amdtemp_softc *sc = device_get_softc(dev); 800 uint32_t mask, offset, temp; 801 802 /* Set Sensor/Core selector. */ 803 temp = pci_read_config(dev, AMDTEMP_THERMTP_STAT, 1); 804 temp &= ~(AMDTEMP_TTSR_SELCORE | AMDTEMP_TTSR_SELSENSOR); 805 switch (sensor) { 806 case CORE0_SENSOR1: 807 temp |= AMDTEMP_TTSR_SELSENSOR; 808 /* FALLTHROUGH */ 809 case CORE0_SENSOR0: 810 case CORE0: 811 if ((sc->sc_flags & AMDTEMP_FLAG_CS_SWAP) != 0) 812 temp |= AMDTEMP_TTSR_SELCORE; 813 break; 814 case CORE1_SENSOR1: 815 temp |= AMDTEMP_TTSR_SELSENSOR; 816 /* FALLTHROUGH */ 817 case CORE1_SENSOR0: 818 case CORE1: 819 if ((sc->sc_flags & AMDTEMP_FLAG_CS_SWAP) == 0) 820 temp |= AMDTEMP_TTSR_SELCORE; 821 break; 822 default: 823 __assert_unreachable(); 824 } 825 pci_write_config(dev, AMDTEMP_THERMTP_STAT, temp, 1); 826 827 mask = (sc->sc_flags & AMDTEMP_FLAG_CT_10BIT) != 0 ? 0x3ff : 0x3fc; 828 offset = (sc->sc_flags & AMDTEMP_FLAG_ALT_OFFSET) != 0 ? 28 : 49; 829 temp = pci_read_config(dev, AMDTEMP_THERMTP_STAT, 4); 830 temp = ((temp >> 14) & mask) * 5 / 2; 831 temp += AMDTEMP_ZERO_C_TO_K + (sc->sc_offset - offset) * 10; 832 833 return (temp); 834 } 835 836 static uint32_t 837 amdtemp_decode_fam10h_to_17h(int32_t sc_offset, uint32_t val, bool minus49) 838 { 839 uint32_t temp; 840 841 /* Convert raw register subfield units (0.125C) to units of 0.1C. */ 842 temp = (val & AMDTEMP_REPTMP10H_CURTMP_MASK) * 5 / 4; 843 844 if (minus49) 845 temp -= AMDTEMP_CURTMP_RANGE_ADJUST; 846 847 temp += AMDTEMP_ZERO_C_TO_K + sc_offset * 10; 848 return (temp); 849 } 850 851 static uint32_t 852 amdtemp_decode_fam10h_to_16h(int32_t sc_offset, uint32_t val) 853 { 854 bool minus49; 855 856 /* 857 * On Family 15h and higher, if CurTmpTjSel is 11b, the range is 858 * adjusted down by 49.0 degrees Celsius. (This adjustment is not 859 * documented in BKDGs prior to family 15h model 00h.) 860 */ 861 minus49 = (CPUID_TO_FAMILY(cpu_id) >= 0x15 && 862 ((val >> AMDTEMP_REPTMP10H_TJSEL_SHIFT) & 863 AMDTEMP_REPTMP10H_TJSEL_MASK) == 0x3); 864 865 return (amdtemp_decode_fam10h_to_17h(sc_offset, 866 val >> AMDTEMP_REPTMP10H_CURTMP_SHIFT, minus49)); 867 } 868 869 static uint32_t 870 amdtemp_decode_fam17h_tctl(int32_t sc_offset, uint32_t val) 871 { 872 bool minus49; 873 874 minus49 = ((val & AMDTEMP_17H_CUR_TMP_RANGE_SEL) != 0); 875 return (amdtemp_decode_fam10h_to_17h(sc_offset, 876 val >> AMDTEMP_REPTMP10H_CURTMP_SHIFT, minus49)); 877 } 878 879 static int32_t 880 amdtemp_gettemp(device_t dev, amdsensor_t sensor) 881 { 882 struct amdtemp_softc *sc = device_get_softc(dev); 883 uint32_t temp; 884 885 temp = pci_read_config(dev, AMDTEMP_REPTMP_CTRL, 4); 886 return (amdtemp_decode_fam10h_to_16h(sc->sc_offset, temp)); 887 } 888 889 static int32_t 890 amdtemp_gettemp15hm60h(device_t dev, amdsensor_t sensor) 891 { 892 struct amdtemp_softc *sc = device_get_softc(dev); 893 uint32_t val; 894 int error; 895 896 error = amdsmn_read(sc->sc_smn, AMDTEMP_15H_M60H_REPTMP_CTRL, &val); 897 KASSERT(error == 0, ("amdsmn_read")); 898 return (amdtemp_decode_fam10h_to_16h(sc->sc_offset, val)); 899 } 900 901 static int32_t 902 amdtemp_gettemp17to19h(device_t dev, amdsensor_t sensor) 903 { 904 struct amdtemp_softc *sc = device_get_softc(dev); 905 uint32_t val; 906 int error; 907 908 switch (sensor) { 909 case CORE0_SENSOR0: 910 /* Tctl */ 911 error = amdsmn_read(sc->sc_smn, AMDTEMP_17H_CUR_TMP, &val); 912 KASSERT(error == 0, ("amdsmn_read")); 913 return (amdtemp_decode_fam17h_tctl(sc->sc_offset, val)); 914 case CCD_BASE ... CCD_MAX: 915 /* Tccd<N> */ 916 error = amdsmn_read(sc->sc_smn, AMDTEMP_17H_CCD_TMP_BASE + 917 (((int)sensor - CCD_BASE) * sizeof(val)), &val); 918 KASSERT(error == 0, ("amdsmn_read2")); 919 KASSERT((val & AMDTEMP_17H_CCD_TMP_VALID) != 0, 920 ("sensor %d: not valid", (int)sensor)); 921 return (amdtemp_decode_fam10h_to_17h(sc->sc_offset, val, true)); 922 default: 923 __assert_unreachable(); 924 } 925 } 926 927 static void 928 amdtemp_probe_ccd_sensors17h(device_t dev, uint32_t model) 929 { 930 char sensor_name[16], sensor_descr[32]; 931 struct amdtemp_softc *sc; 932 uint32_t maxreg, i, val; 933 int error; 934 935 switch (model) { 936 case 0x00 ... 0x1f: /* Zen1, Zen+ */ 937 maxreg = 4; 938 break; 939 case 0x30 ... 0x3f: /* Zen2 TR/Epyc */ 940 case 0x70 ... 0x7f: /* Zen2 Ryzen */ 941 maxreg = 8; 942 _Static_assert((int)NUM_CCDS >= 8, ""); 943 break; 944 default: 945 device_printf(dev, 946 "Unrecognized Family 17h Model: %02xh\n", model); 947 return; 948 } 949 950 sc = device_get_softc(dev); 951 for (i = 0; i < maxreg; i++) { 952 error = amdsmn_read(sc->sc_smn, AMDTEMP_17H_CCD_TMP_BASE + 953 (i * sizeof(val)), &val); 954 if (error != 0) 955 continue; 956 if ((val & AMDTEMP_17H_CCD_TMP_VALID) == 0) 957 continue; 958 959 ksnprintf(sensor_name, sizeof(sensor_name), "ccd%u", i); 960 ksnprintf(sensor_descr, sizeof(sensor_descr), 961 "CCD %u temperature (Tccd%u)", i, i); 962 963 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 964 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 965 sensor_name, CTLTYPE_INT | CTLFLAG_RD, 966 dev, CCD_BASE + i, amdtemp_sysctl, "IK", sensor_descr); 967 968 sc->sc_probed_regmask |= 1U << (CCD_BASE + i); 969 } 970 } 971 972 static void 973 amdtemp_probe_ccd_sensors19h(device_t dev, uint32_t model) 974 { 975 char sensor_name[16], sensor_descr[32]; 976 struct amdtemp_softc *sc; 977 uint32_t maxreg, i, val; 978 int error; 979 980 switch (model) { 981 case 0x00 ... 0x0f: /* Zen3 EPYC "Milan" */ 982 case 0x20 ... 0x2f: /* Zen3 Ryzen "Vermeer" */ 983 maxreg = 8; 984 _Static_assert((int)NUM_CCDS >= 8, ""); 985 break; 986 default: 987 device_printf(dev, 988 "Unrecognized Family 19h Model: %02xh\n", model); 989 return; 990 } 991 992 sc = device_get_softc(dev); 993 for (i = 0; i < maxreg; i++) { 994 error = amdsmn_read(sc->sc_smn, AMDTEMP_17H_CCD_TMP_BASE + 995 (i * sizeof(val)), &val); 996 if (error != 0) 997 continue; 998 if ((val & AMDTEMP_17H_CCD_TMP_VALID) == 0) 999 continue; 1000 1001 ksnprintf(sensor_name, sizeof(sensor_name), "ccd%u", i); 1002 ksnprintf(sensor_descr, sizeof(sensor_descr), 1003 "CCD %u temperature (Tccd%u)", i, i); 1004 1005 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 1006 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 1007 sensor_name, CTLTYPE_INT | CTLFLAG_RD, 1008 dev, CCD_BASE + i, amdtemp_sysctl, "IK", sensor_descr); 1009 1010 sc->sc_probed_regmask |= 1U << (CCD_BASE + i); 1011 } 1012 } 1013 1014 static void 1015 amdtemp_sensor_task(void *sc_arg) 1016 { 1017 struct sensorcpu *scpu = sc_arg; 1018 struct amdtemp_softc *sc; 1019 uint32_t mask; 1020 int32_t temp; 1021 int j; 1022 1023 sc = scpu->sc; 1024 if (sc->sc_ich.ich_arg == NULL) 1025 return; 1026 mask = scpu->regmask; 1027 1028 for (j = 0; mask; ++j) { 1029 if ((mask & (1U << j)) == 0) 1030 continue; 1031 temp = sc->sc_gettemp(scpu->dev, j); 1032 sensor_set(&scpu->sensors[j], temp * 100000L, 0); 1033 mask &= ~(1U << j); 1034 } 1035 } 1036