1 /* $NetBSD: acpi_cpu_md.c,v 1.36 2010/11/30 18:44:07 jruoho Exp $ */ 2 3 /*- 4 * Copyright (c) 2010 Jukka Ruohonen <jruohonen@iki.fi> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.36 2010/11/30 18:44:07 jruoho Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/bus.h> 34 #include <sys/kcore.h> 35 #include <sys/sysctl.h> 36 #include <sys/xcall.h> 37 38 #include <x86/cpu.h> 39 #include <x86/cpufunc.h> 40 #include <x86/cputypes.h> 41 #include <x86/cpuvar.h> 42 #include <x86/cpu_msr.h> 43 #include <x86/machdep.h> 44 45 #include <dev/acpi/acpica.h> 46 #include <dev/acpi/acpi_cpu.h> 47 48 #include <dev/pci/pcivar.h> 49 #include <dev/pci/pcidevs.h> 50 51 /* 52 * AMD C1E. 53 */ 54 #define MSR_CMPHALT 0xc0010055 55 56 #define MSR_CMPHALT_SMI __BIT(27) 57 #define MSR_CMPHALT_C1E __BIT(28) 58 #define MSR_CMPHALT_BMSTS __BIT(29) 59 60 /* 61 * AMD families 10h and 11h. 62 */ 63 #define MSR_10H_LIMIT 0xc0010061 64 #define MSR_10H_CONTROL 0xc0010062 65 #define MSR_10H_STATUS 0xc0010063 66 #define MSR_10H_CONFIG 0xc0010064 67 68 /* 69 * AMD family 0Fh. 70 */ 71 #define MSR_0FH_CONTROL 0xc0010041 72 #define MSR_0FH_STATUS 0xc0010042 73 74 #define MSR_0FH_STATUS_CFID __BITS( 0, 5) 75 #define MSR_0FH_STATUS_CVID __BITS(32, 36) 76 #define MSR_0FH_STATUS_PENDING __BITS(31, 31) 77 78 #define MSR_0FH_CONTROL_FID __BITS( 0, 5) 79 #define MSR_0FH_CONTROL_VID __BITS( 8, 12) 80 #define MSR_0FH_CONTROL_CHG __BITS(16, 16) 81 #define MSR_0FH_CONTROL_CNT __BITS(32, 51) 82 83 #define ACPI_0FH_STATUS_FID __BITS( 0, 5) 84 #define ACPI_0FH_STATUS_VID __BITS( 6, 10) 85 86 #define ACPI_0FH_CONTROL_FID __BITS( 0, 5) 87 #define ACPI_0FH_CONTROL_VID __BITS( 6, 10) 88 #define ACPI_0FH_CONTROL_VST __BITS(11, 17) 89 #define ACPI_0FH_CONTROL_MVS __BITS(18, 19) 90 #define ACPI_0FH_CONTROL_PLL __BITS(20, 26) 91 #define ACPI_0FH_CONTROL_RVO __BITS(28, 29) 92 #define ACPI_0FH_CONTROL_IRT __BITS(30, 31) 93 94 #define FID_TO_VCO_FID(fidd) (((fid) < 8) ? (8 + ((fid) << 1)) : (fid)) 95 96 static char native_idle_text[16]; 97 void (*native_idle)(void) = NULL; 98 99 static int acpicpu_md_quirks_piix4(struct pci_attach_args *); 100 static void acpicpu_md_pstate_status(void *, void *); 101 static int acpicpu_md_pstate_fidvid_get(struct acpicpu_softc *, 102 uint32_t *); 103 static int acpicpu_md_pstate_fidvid_set(struct acpicpu_pstate *); 104 static int acpicpu_md_pstate_fidvid_read(uint32_t *, uint32_t *); 105 static void acpicpu_md_pstate_fidvid_write(uint32_t, uint32_t, 106 uint32_t, uint32_t); 107 static void acpicpu_md_tstate_status(void *, void *); 108 static int acpicpu_md_pstate_sysctl_init(void); 109 static int acpicpu_md_pstate_sysctl_get(SYSCTLFN_PROTO); 110 static int acpicpu_md_pstate_sysctl_set(SYSCTLFN_PROTO); 111 static int acpicpu_md_pstate_sysctl_all(SYSCTLFN_PROTO); 112 113 extern uint32_t cpus_running; 114 extern struct acpicpu_softc **acpicpu_sc; 115 static bool acpicpu_pstate_status = false; 116 static struct sysctllog *acpicpu_log = NULL; 117 118 uint32_t 119 acpicpu_md_cap(void) 120 { 121 struct cpu_info *ci = curcpu(); 122 uint32_t val = 0; 123 124 if (cpu_vendor != CPUVENDOR_IDT && 125 cpu_vendor != CPUVENDOR_INTEL) 126 return val; 127 128 /* 129 * Basic SMP C-states (required for _CST). 130 */ 131 val |= ACPICPU_PDC_C_C1PT | ACPICPU_PDC_C_C2C3; 132 133 /* 134 * If MONITOR/MWAIT is available, announce 135 * support for native instructions in all C-states. 136 */ 137 if ((ci->ci_feat_val[1] & CPUID2_MONITOR) != 0) 138 val |= ACPICPU_PDC_C_C1_FFH | ACPICPU_PDC_C_C2C3_FFH; 139 140 /* 141 * Set native P- and T-states, if available. 142 */ 143 if ((ci->ci_feat_val[1] & CPUID2_EST) != 0) 144 val |= ACPICPU_PDC_P_FFH; 145 146 if ((ci->ci_feat_val[0] & CPUID_ACPI) != 0) 147 val |= ACPICPU_PDC_T_FFH; 148 149 return val; 150 } 151 152 uint32_t 153 acpicpu_md_quirks(void) 154 { 155 struct cpu_info *ci = curcpu(); 156 struct pci_attach_args pa; 157 uint32_t family, val = 0; 158 uint32_t regs[4]; 159 160 if (acpicpu_md_cpus_running() == 1) 161 val |= ACPICPU_FLAG_C_BM; 162 163 if ((ci->ci_feat_val[1] & CPUID2_MONITOR) != 0) 164 val |= ACPICPU_FLAG_C_FFH; 165 166 val |= ACPICPU_FLAG_C_APIC | ACPICPU_FLAG_C_TSC; 167 168 switch (cpu_vendor) { 169 170 case CPUVENDOR_IDT: 171 172 if ((ci->ci_feat_val[1] & CPUID2_EST) != 0) 173 val |= ACPICPU_FLAG_P_FFH; 174 175 if ((ci->ci_feat_val[0] & CPUID_ACPI) != 0) 176 val |= ACPICPU_FLAG_T_FFH; 177 178 break; 179 180 case CPUVENDOR_INTEL: 181 182 val |= ACPICPU_FLAG_C_BM | ACPICPU_FLAG_C_ARB; 183 184 if ((ci->ci_feat_val[1] & CPUID2_EST) != 0) 185 val |= ACPICPU_FLAG_P_FFH; 186 187 if ((ci->ci_feat_val[0] & CPUID_ACPI) != 0) 188 val |= ACPICPU_FLAG_T_FFH; 189 190 /* 191 * Check whether MSR_APERF, MSR_MPERF, and Turbo 192 * Boost are available. Also see if we might have 193 * an invariant local APIC timer ("ARAT"). 194 */ 195 if (cpuid_level >= 0x06) { 196 197 x86_cpuid(0x06, regs); 198 199 if ((regs[2] & CPUID_DSPM_HWF) != 0) 200 val |= ACPICPU_FLAG_P_HW; 201 202 if ((regs[0] & CPUID_DSPM_IDA) != 0) 203 val |= ACPICPU_FLAG_P_TURBO; 204 205 if ((regs[0] & CPUID_DSPM_ARAT) != 0) 206 val &= ~ACPICPU_FLAG_C_APIC; 207 } 208 209 /* 210 * Detect whether TSC is invariant. If it is not, 211 * we keep the flag to note that TSC will not run 212 * at constant rate. Depending on the CPU, this may 213 * affect P- and T-state changes, but especially 214 * relevant are C-states; with variant TSC, states 215 * larger than C1 may completely stop the counter. 216 */ 217 x86_cpuid(0x80000000, regs); 218 219 if (regs[0] >= 0x80000007) { 220 221 x86_cpuid(0x80000007, regs); 222 223 if ((regs[3] & __BIT(8)) != 0) 224 val &= ~ACPICPU_FLAG_C_TSC; 225 } 226 227 break; 228 229 case CPUVENDOR_AMD: 230 231 x86_cpuid(0x80000000, regs); 232 233 if (regs[0] < 0x80000007) 234 break; 235 236 x86_cpuid(0x80000007, regs); 237 238 family = CPUID2FAMILY(ci->ci_signature); 239 240 if (family == 0xf) 241 family += CPUID2EXTFAMILY(ci->ci_signature); 242 243 switch (family) { 244 245 case 0x0f: 246 247 if ((regs[3] & CPUID_APM_FID) == 0) 248 break; 249 250 if ((regs[3] & CPUID_APM_VID) == 0) 251 break; 252 253 val |= ACPICPU_FLAG_P_FFH | ACPICPU_FLAG_P_FIDVID; 254 break; 255 256 case 0x10: 257 case 0x11: 258 259 if ((regs[3] & CPUID_APM_TSC) != 0) 260 val &= ~ACPICPU_FLAG_C_TSC; 261 262 if ((regs[3] & CPUID_APM_HWP) != 0) 263 val |= ACPICPU_FLAG_P_FFH; 264 265 if ((regs[3] & CPUID_APM_CPB) != 0) 266 val |= ACPICPU_FLAG_P_TURBO; 267 268 val |= ACPICPU_FLAG_C_C1E; 269 break; 270 } 271 272 break; 273 } 274 275 /* 276 * There are several erratums for PIIX4. 277 */ 278 if (pci_find_device(&pa, acpicpu_md_quirks_piix4) != 0) 279 val |= ACPICPU_FLAG_PIIX4; 280 281 return val; 282 } 283 284 static int 285 acpicpu_md_quirks_piix4(struct pci_attach_args *pa) 286 { 287 288 /* 289 * XXX: The pci_find_device(9) function only 290 * deals with attached devices. Change this 291 * to use something like pci_device_foreach(). 292 */ 293 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL) 294 return 0; 295 296 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82371AB_ISA || 297 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82440MX_PMC) 298 return 1; 299 300 return 0; 301 } 302 303 void 304 acpicpu_md_quirks_c1e(void) 305 { 306 const uint64_t c1e = MSR_CMPHALT_SMI | MSR_CMPHALT_C1E; 307 uint64_t val; 308 309 val = rdmsr(MSR_CMPHALT); 310 311 if ((val & c1e) != 0) 312 wrmsr(MSR_CMPHALT, val & ~c1e); 313 } 314 315 uint32_t 316 acpicpu_md_cpus_running(void) 317 { 318 319 return popcount32(cpus_running); 320 } 321 322 int 323 acpicpu_md_idle_start(struct acpicpu_softc *sc) 324 { 325 const size_t size = sizeof(native_idle_text); 326 struct acpicpu_cstate *cs; 327 bool ipi = false; 328 int i; 329 330 x86_cpu_idle_get(&native_idle, native_idle_text, size); 331 332 for (i = 0; i < ACPI_C_STATE_COUNT; i++) { 333 334 cs = &sc->sc_cstate[i]; 335 336 if (cs->cs_method == ACPICPU_C_STATE_HALT) { 337 ipi = true; 338 break; 339 } 340 } 341 342 x86_cpu_idle_set(acpicpu_cstate_idle, "acpi", ipi); 343 344 return 0; 345 } 346 347 int 348 acpicpu_md_idle_stop(void) 349 { 350 uint64_t xc; 351 bool ipi; 352 353 ipi = (native_idle != x86_cpu_idle_halt) ? false : true; 354 x86_cpu_idle_set(native_idle, native_idle_text, ipi); 355 356 /* 357 * Run a cross-call to ensure that all CPUs are 358 * out from the ACPI idle-loop before detachment. 359 */ 360 xc = xc_broadcast(0, (xcfunc_t)nullop, NULL, NULL); 361 xc_wait(xc); 362 363 return 0; 364 } 365 366 /* 367 * Called with interrupts disabled. 368 * Caller should enable interrupts after return. 369 */ 370 void 371 acpicpu_md_idle_enter(int method, int state) 372 { 373 struct cpu_info *ci = curcpu(); 374 375 switch (method) { 376 377 case ACPICPU_C_STATE_FFH: 378 379 x86_enable_intr(); 380 x86_monitor(&ci->ci_want_resched, 0, 0); 381 382 if (__predict_false(ci->ci_want_resched != 0)) 383 return; 384 385 x86_mwait((state - 1) << 4, 0); 386 break; 387 388 case ACPICPU_C_STATE_HALT: 389 390 if (__predict_false(ci->ci_want_resched != 0)) 391 return; 392 393 x86_stihlt(); 394 break; 395 } 396 } 397 398 int 399 acpicpu_md_pstate_start(void) 400 { 401 const uint64_t est = __BIT(16); 402 uint64_t val; 403 404 switch (cpu_vendor) { 405 406 case CPUVENDOR_IDT: 407 case CPUVENDOR_INTEL: 408 409 val = rdmsr(MSR_MISC_ENABLE); 410 411 if ((val & est) == 0) { 412 413 val |= est; 414 415 wrmsr(MSR_MISC_ENABLE, val); 416 val = rdmsr(MSR_MISC_ENABLE); 417 418 if ((val & est) == 0) 419 return ENOTTY; 420 } 421 } 422 423 return acpicpu_md_pstate_sysctl_init(); 424 } 425 426 int 427 acpicpu_md_pstate_stop(void) 428 { 429 430 if (acpicpu_log != NULL) 431 sysctl_teardown(&acpicpu_log); 432 433 return 0; 434 } 435 436 int 437 acpicpu_md_pstate_pss(struct acpicpu_softc *sc) 438 { 439 struct acpicpu_pstate *ps, msr; 440 struct cpu_info *ci = curcpu(); 441 uint32_t family, i = 0; 442 443 (void)memset(&msr, 0, sizeof(struct acpicpu_pstate)); 444 445 switch (cpu_vendor) { 446 447 case CPUVENDOR_IDT: 448 case CPUVENDOR_INTEL: 449 450 /* 451 * If the so-called Turbo Boost is present, 452 * the P0-state is always the "turbo state". 453 * 454 * For discussion, see: 455 * 456 * Intel Corporation: Intel Turbo Boost Technology 457 * in Intel Core(tm) Microarchitectures (Nehalem) 458 * Based Processors. White Paper, November 2008. 459 */ 460 if ((sc->sc_flags & ACPICPU_FLAG_P_TURBO) != 0) 461 sc->sc_pstate[0].ps_flags |= ACPICPU_FLAG_P_TURBO; 462 463 msr.ps_control_addr = MSR_PERF_CTL; 464 msr.ps_control_mask = __BITS(0, 15); 465 466 msr.ps_status_addr = MSR_PERF_STATUS; 467 msr.ps_status_mask = __BITS(0, 15); 468 break; 469 470 case CPUVENDOR_AMD: 471 472 if ((sc->sc_flags & ACPICPU_FLAG_P_FIDVID) != 0) 473 msr.ps_flags |= ACPICPU_FLAG_P_FIDVID; 474 475 family = CPUID2FAMILY(ci->ci_signature); 476 477 if (family == 0xf) 478 family += CPUID2EXTFAMILY(ci->ci_signature); 479 480 switch (family) { 481 482 case 0x0f: 483 msr.ps_control_addr = MSR_0FH_CONTROL; 484 msr.ps_status_addr = MSR_0FH_STATUS; 485 break; 486 487 case 0x10: 488 case 0x11: 489 msr.ps_control_addr = MSR_10H_CONTROL; 490 msr.ps_control_mask = __BITS(0, 2); 491 492 msr.ps_status_addr = MSR_10H_STATUS; 493 msr.ps_status_mask = __BITS(0, 2); 494 break; 495 496 default: 497 498 if ((sc->sc_flags & ACPICPU_FLAG_P_XPSS) == 0) 499 return EOPNOTSUPP; 500 } 501 502 break; 503 504 default: 505 return ENODEV; 506 } 507 508 /* 509 * Fill the P-state structures with MSR addresses that are 510 * known to be correct. If we do not know the addresses, 511 * leave the values intact. If a vendor uses XPSS, we do 512 * not necessary need to do anything to support new CPUs. 513 */ 514 while (i < sc->sc_pstate_count) { 515 516 ps = &sc->sc_pstate[i]; 517 518 if (msr.ps_flags != 0) 519 ps->ps_flags |= msr.ps_flags; 520 521 if (msr.ps_status_addr != 0) 522 ps->ps_status_addr = msr.ps_status_addr; 523 524 if (msr.ps_status_mask != 0) 525 ps->ps_status_mask = msr.ps_status_mask; 526 527 if (msr.ps_control_addr != 0) 528 ps->ps_control_addr = msr.ps_control_addr; 529 530 if (msr.ps_control_mask != 0) 531 ps->ps_control_mask = msr.ps_control_mask; 532 533 i++; 534 } 535 536 return 0; 537 } 538 539 int 540 acpicpu_md_pstate_get(struct acpicpu_softc *sc, uint32_t *freq) 541 { 542 struct acpicpu_pstate *ps = NULL; 543 uint64_t val; 544 uint32_t i; 545 546 if ((sc->sc_flags & ACPICPU_FLAG_P_FIDVID) != 0) 547 return acpicpu_md_pstate_fidvid_get(sc, freq); 548 549 for (i = 0; i < sc->sc_pstate_count; i++) { 550 551 ps = &sc->sc_pstate[i]; 552 553 if (__predict_true(ps->ps_freq != 0)) 554 break; 555 } 556 557 if (__predict_false(ps == NULL)) 558 return ENODEV; 559 560 if (__predict_false(ps->ps_status_addr == 0)) 561 return EINVAL; 562 563 val = rdmsr(ps->ps_status_addr); 564 565 if (__predict_true(ps->ps_status_mask != 0)) 566 val = val & ps->ps_status_mask; 567 568 for (i = 0; i < sc->sc_pstate_count; i++) { 569 570 ps = &sc->sc_pstate[i]; 571 572 if (__predict_false(ps->ps_freq == 0)) 573 continue; 574 575 if (val == ps->ps_status) { 576 *freq = ps->ps_freq; 577 return 0; 578 } 579 } 580 581 return EIO; 582 } 583 584 int 585 acpicpu_md_pstate_set(struct acpicpu_pstate *ps) 586 { 587 struct msr_rw_info msr; 588 uint64_t xc; 589 int rv = 0; 590 591 if ((ps->ps_flags & ACPICPU_FLAG_P_FIDVID) != 0) 592 return acpicpu_md_pstate_fidvid_set(ps); 593 594 msr.msr_read = false; 595 msr.msr_type = ps->ps_control_addr; 596 msr.msr_value = ps->ps_control; 597 598 if (__predict_true(ps->ps_control_mask != 0)) { 599 msr.msr_mask = ps->ps_control_mask; 600 msr.msr_read = true; 601 } 602 603 xc = xc_broadcast(0, (xcfunc_t)x86_msr_xcall, &msr, NULL); 604 xc_wait(xc); 605 606 /* 607 * Due several problems, we bypass the 608 * relatively expensive status check. 609 */ 610 if (acpicpu_pstate_status != true) { 611 DELAY(ps->ps_latency); 612 return 0; 613 } 614 615 xc = xc_broadcast(0, (xcfunc_t)acpicpu_md_pstate_status, ps, &rv); 616 xc_wait(xc); 617 618 return rv; 619 } 620 621 static void 622 acpicpu_md_pstate_status(void *arg1, void *arg2) 623 { 624 struct acpicpu_pstate *ps = arg1; 625 uint64_t val; 626 int i; 627 628 for (i = val = 0; i < ACPICPU_P_STATE_RETRY; i++) { 629 630 val = rdmsr(ps->ps_status_addr); 631 632 if (__predict_true(ps->ps_status_mask != 0)) 633 val = val & ps->ps_status_mask; 634 635 if (val == ps->ps_status) 636 return; 637 638 DELAY(ps->ps_latency); 639 } 640 641 *(uintptr_t *)arg2 = EAGAIN; 642 } 643 644 static int 645 acpicpu_md_pstate_fidvid_get(struct acpicpu_softc *sc, uint32_t *freq) 646 { 647 struct acpicpu_pstate *ps; 648 uint32_t fid, i, vid; 649 uint32_t cfid, cvid; 650 int rv; 651 652 /* 653 * AMD family 0Fh needs special treatment. 654 * While it wants to use ACPI, it does not 655 * comply with the ACPI specifications. 656 */ 657 rv = acpicpu_md_pstate_fidvid_read(&cfid, &cvid); 658 659 if (rv != 0) 660 return rv; 661 662 for (i = 0; i < sc->sc_pstate_count; i++) { 663 664 ps = &sc->sc_pstate[i]; 665 666 if (__predict_false(ps->ps_freq == 0)) 667 continue; 668 669 fid = __SHIFTOUT(ps->ps_status, ACPI_0FH_STATUS_FID); 670 vid = __SHIFTOUT(ps->ps_status, ACPI_0FH_STATUS_VID); 671 672 if (cfid == fid && cvid == vid) { 673 *freq = ps->ps_freq; 674 return 0; 675 } 676 } 677 678 return EIO; 679 } 680 681 static int 682 acpicpu_md_pstate_fidvid_set(struct acpicpu_pstate *ps) 683 { 684 const uint64_t ctrl = ps->ps_control; 685 uint32_t cfid, cvid, fid, i, irt; 686 uint32_t pll, vco_cfid, vco_fid; 687 uint32_t val, vid, vst; 688 int rv; 689 690 rv = acpicpu_md_pstate_fidvid_read(&cfid, &cvid); 691 692 if (rv != 0) 693 return rv; 694 695 fid = __SHIFTOUT(ctrl, ACPI_0FH_CONTROL_FID); 696 vid = __SHIFTOUT(ctrl, ACPI_0FH_CONTROL_VID); 697 irt = __SHIFTOUT(ctrl, ACPI_0FH_CONTROL_IRT); 698 vst = __SHIFTOUT(ctrl, ACPI_0FH_CONTROL_VST); 699 pll = __SHIFTOUT(ctrl, ACPI_0FH_CONTROL_PLL); 700 701 vst = vst * 20; 702 pll = pll * 1000 / 5; 703 irt = 10 * __BIT(irt); 704 705 /* 706 * Phase 1. 707 */ 708 while (cvid > vid) { 709 710 val = 1 << __SHIFTOUT(ctrl, ACPI_0FH_CONTROL_MVS); 711 val = (val > cvid) ? 0 : cvid - val; 712 713 acpicpu_md_pstate_fidvid_write(cfid, val, 1, vst); 714 rv = acpicpu_md_pstate_fidvid_read(NULL, &cvid); 715 716 if (rv != 0) 717 return rv; 718 } 719 720 i = __SHIFTOUT(ctrl, ACPI_0FH_CONTROL_RVO); 721 722 for (; i > 0 && cvid > 0; --i) { 723 724 acpicpu_md_pstate_fidvid_write(cfid, cvid - 1, 1, vst); 725 rv = acpicpu_md_pstate_fidvid_read(NULL, &cvid); 726 727 if (rv != 0) 728 return rv; 729 } 730 731 /* 732 * Phase 2. 733 */ 734 if (cfid != fid) { 735 736 vco_fid = FID_TO_VCO_FID(fid); 737 vco_cfid = FID_TO_VCO_FID(cfid); 738 739 while (abs(vco_fid - vco_cfid) > 2) { 740 741 if (fid <= cfid) 742 val = cfid - 2; 743 else { 744 val = (cfid > 6) ? cfid + 2 : 745 FID_TO_VCO_FID(cfid) + 2; 746 } 747 748 acpicpu_md_pstate_fidvid_write(val, cvid, pll, irt); 749 rv = acpicpu_md_pstate_fidvid_read(&cfid, NULL); 750 751 if (rv != 0) 752 return rv; 753 754 vco_cfid = FID_TO_VCO_FID(cfid); 755 } 756 757 acpicpu_md_pstate_fidvid_write(fid, cvid, pll, irt); 758 rv = acpicpu_md_pstate_fidvid_read(&cfid, NULL); 759 760 if (rv != 0) 761 return rv; 762 } 763 764 /* 765 * Phase 3. 766 */ 767 if (cvid != vid) { 768 769 acpicpu_md_pstate_fidvid_write(cfid, vid, 1, vst); 770 rv = acpicpu_md_pstate_fidvid_read(NULL, &cvid); 771 772 if (rv != 0) 773 return rv; 774 } 775 776 if (cfid != fid || cvid != vid) 777 return EIO; 778 779 return 0; 780 } 781 782 static int 783 acpicpu_md_pstate_fidvid_read(uint32_t *cfid, uint32_t *cvid) 784 { 785 int i = ACPICPU_P_STATE_RETRY * 100; 786 uint64_t val; 787 788 do { 789 val = rdmsr(MSR_0FH_STATUS); 790 791 } while (__SHIFTOUT(val, MSR_0FH_STATUS_PENDING) != 0 && --i >= 0); 792 793 if (i == 0) 794 return EAGAIN; 795 796 if (cfid != NULL) 797 *cfid = __SHIFTOUT(val, MSR_0FH_STATUS_CFID); 798 799 if (cvid != NULL) 800 *cvid = __SHIFTOUT(val, MSR_0FH_STATUS_CVID); 801 802 return 0; 803 } 804 805 static void 806 acpicpu_md_pstate_fidvid_write(uint32_t fid, 807 uint32_t vid, uint32_t cnt, uint32_t tmo) 808 { 809 struct msr_rw_info msr; 810 uint64_t xc; 811 812 msr.msr_read = false; 813 msr.msr_type = MSR_0FH_CONTROL; 814 msr.msr_value = 0; 815 816 msr.msr_value |= __SHIFTIN(fid, MSR_0FH_CONTROL_FID); 817 msr.msr_value |= __SHIFTIN(vid, MSR_0FH_CONTROL_VID); 818 msr.msr_value |= __SHIFTIN(cnt, MSR_0FH_CONTROL_CNT); 819 msr.msr_value |= __SHIFTIN(0x1, MSR_0FH_CONTROL_CHG); 820 821 xc = xc_broadcast(0, (xcfunc_t)x86_msr_xcall, &msr, NULL); 822 xc_wait(xc); 823 824 DELAY(tmo); 825 } 826 827 int 828 acpicpu_md_tstate_get(struct acpicpu_softc *sc, uint32_t *percent) 829 { 830 struct acpicpu_tstate *ts; 831 uint64_t val; 832 uint32_t i; 833 834 val = rdmsr(MSR_THERM_CONTROL); 835 836 for (i = 0; i < sc->sc_tstate_count; i++) { 837 838 ts = &sc->sc_tstate[i]; 839 840 if (ts->ts_percent == 0) 841 continue; 842 843 if (val == ts->ts_status) { 844 *percent = ts->ts_percent; 845 return 0; 846 } 847 } 848 849 return EIO; 850 } 851 852 int 853 acpicpu_md_tstate_set(struct acpicpu_tstate *ts) 854 { 855 struct msr_rw_info msr; 856 uint64_t xc; 857 int rv = 0; 858 859 msr.msr_read = true; 860 msr.msr_type = MSR_THERM_CONTROL; 861 msr.msr_value = ts->ts_control; 862 msr.msr_mask = __BITS(1, 4); 863 864 xc = xc_broadcast(0, (xcfunc_t)x86_msr_xcall, &msr, NULL); 865 xc_wait(xc); 866 867 if (ts->ts_status == 0) { 868 DELAY(ts->ts_latency); 869 return 0; 870 } 871 872 xc = xc_broadcast(0, (xcfunc_t)acpicpu_md_tstate_status, ts, &rv); 873 xc_wait(xc); 874 875 return rv; 876 } 877 878 static void 879 acpicpu_md_tstate_status(void *arg1, void *arg2) 880 { 881 struct acpicpu_tstate *ts = arg1; 882 uint64_t val; 883 int i; 884 885 for (i = val = 0; i < ACPICPU_T_STATE_RETRY; i++) { 886 887 val = rdmsr(MSR_THERM_CONTROL); 888 889 if (val == ts->ts_status) 890 return; 891 892 DELAY(ts->ts_latency); 893 } 894 895 *(uintptr_t *)arg2 = EAGAIN; 896 } 897 898 /* 899 * A kludge for backwards compatibility. 900 */ 901 static int 902 acpicpu_md_pstate_sysctl_init(void) 903 { 904 const struct sysctlnode *fnode, *mnode, *rnode; 905 const char *str; 906 int rv; 907 908 switch (cpu_vendor) { 909 910 case CPUVENDOR_IDT: 911 case CPUVENDOR_INTEL: 912 str = "est"; 913 break; 914 915 case CPUVENDOR_AMD: 916 str = "powernow"; 917 break; 918 919 default: 920 return ENODEV; 921 } 922 923 924 rv = sysctl_createv(&acpicpu_log, 0, NULL, &rnode, 925 CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL, 926 NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL); 927 928 if (rv != 0) 929 goto fail; 930 931 rv = sysctl_createv(&acpicpu_log, 0, &rnode, &mnode, 932 0, CTLTYPE_NODE, str, NULL, 933 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); 934 935 if (rv != 0) 936 goto fail; 937 938 rv = sysctl_createv(&acpicpu_log, 0, &mnode, &fnode, 939 0, CTLTYPE_NODE, "frequency", NULL, 940 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); 941 942 if (rv != 0) 943 goto fail; 944 945 rv = sysctl_createv(&acpicpu_log, 0, &fnode, &rnode, 946 CTLFLAG_READWRITE, CTLTYPE_INT, "target", NULL, 947 acpicpu_md_pstate_sysctl_set, 0, NULL, 0, CTL_CREATE, CTL_EOL); 948 949 if (rv != 0) 950 goto fail; 951 952 rv = sysctl_createv(&acpicpu_log, 0, &fnode, &rnode, 953 CTLFLAG_READONLY, CTLTYPE_INT, "current", NULL, 954 acpicpu_md_pstate_sysctl_get, 0, NULL, 0, CTL_CREATE, CTL_EOL); 955 956 if (rv != 0) 957 goto fail; 958 959 rv = sysctl_createv(&acpicpu_log, 0, &fnode, &rnode, 960 CTLFLAG_READONLY, CTLTYPE_STRING, "available", NULL, 961 acpicpu_md_pstate_sysctl_all, 0, NULL, 0, CTL_CREATE, CTL_EOL); 962 963 if (rv != 0) 964 goto fail; 965 966 return 0; 967 968 fail: 969 if (acpicpu_log != NULL) { 970 sysctl_teardown(&acpicpu_log); 971 acpicpu_log = NULL; 972 } 973 974 return rv; 975 } 976 977 static int 978 acpicpu_md_pstate_sysctl_get(SYSCTLFN_ARGS) 979 { 980 struct cpu_info *ci = curcpu(); 981 struct acpicpu_softc *sc; 982 struct sysctlnode node; 983 uint32_t freq; 984 int err; 985 986 sc = acpicpu_sc[ci->ci_acpiid]; 987 988 if (sc == NULL) 989 return ENXIO; 990 991 err = acpicpu_pstate_get(sc, &freq); 992 993 if (err != 0) 994 return err; 995 996 node = *rnode; 997 node.sysctl_data = &freq; 998 999 err = sysctl_lookup(SYSCTLFN_CALL(&node)); 1000 1001 if (err != 0 || newp == NULL) 1002 return err; 1003 1004 return 0; 1005 } 1006 1007 static int 1008 acpicpu_md_pstate_sysctl_set(SYSCTLFN_ARGS) 1009 { 1010 struct cpu_info *ci = curcpu(); 1011 struct acpicpu_softc *sc; 1012 struct sysctlnode node; 1013 uint32_t freq; 1014 int err; 1015 1016 sc = acpicpu_sc[ci->ci_acpiid]; 1017 1018 if (sc == NULL) 1019 return ENXIO; 1020 1021 err = acpicpu_pstate_get(sc, &freq); 1022 1023 if (err != 0) 1024 return err; 1025 1026 node = *rnode; 1027 node.sysctl_data = &freq; 1028 1029 err = sysctl_lookup(SYSCTLFN_CALL(&node)); 1030 1031 if (err != 0 || newp == NULL) 1032 return err; 1033 1034 err = acpicpu_pstate_set(sc, freq); 1035 1036 if (err != 0) 1037 return err; 1038 1039 return 0; 1040 } 1041 1042 static int 1043 acpicpu_md_pstate_sysctl_all(SYSCTLFN_ARGS) 1044 { 1045 struct cpu_info *ci = curcpu(); 1046 struct acpicpu_softc *sc; 1047 struct sysctlnode node; 1048 char buf[1024]; 1049 size_t len; 1050 uint32_t i; 1051 int err; 1052 1053 sc = acpicpu_sc[ci->ci_acpiid]; 1054 1055 if (sc == NULL) 1056 return ENXIO; 1057 1058 (void)memset(&buf, 0, sizeof(buf)); 1059 1060 mutex_enter(&sc->sc_mtx); 1061 1062 for (len = 0, i = sc->sc_pstate_max; i < sc->sc_pstate_count; i++) { 1063 1064 if (sc->sc_pstate[i].ps_freq == 0) 1065 continue; 1066 1067 len += snprintf(buf + len, sizeof(buf) - len, "%u%s", 1068 sc->sc_pstate[i].ps_freq, 1069 i < (sc->sc_pstate_count - 1) ? " " : ""); 1070 } 1071 1072 mutex_exit(&sc->sc_mtx); 1073 1074 node = *rnode; 1075 node.sysctl_data = buf; 1076 1077 err = sysctl_lookup(SYSCTLFN_CALL(&node)); 1078 1079 if (err != 0 || newp == NULL) 1080 return err; 1081 1082 return 0; 1083 } 1084 1085