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