1 /* 2 * Copyright (c) 2009 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Sepherosa Ziehau <sepherosa@gmail.com> 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 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 3. Neither the name of The DragonFly Project nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific, prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #include "opt_acpi.h" 36 37 #include <sys/param.h> 38 #include <sys/bus.h> 39 #include <sys/cpuhelper.h> 40 #include <sys/kernel.h> 41 #include <sys/malloc.h> 42 #include <sys/queue.h> 43 #include <sys/rman.h> 44 #include <sys/sysctl.h> 45 #include <sys/msgport2.h> 46 #include <sys/cpu_topology.h> 47 48 #include "acpi.h" 49 #include "acpivar.h" 50 #include "acpi_cpu.h" 51 #include "acpi_cpu_pstate.h" 52 53 #define ACPI_NPSTATE_MAX 32 54 55 #define ACPI_PSS_PX_NENTRY 6 56 57 #define ACPI_PSD_COORD_SWALL 0xfc 58 #define ACPI_PSD_COORD_SWANY 0xfd 59 #define ACPI_PSD_COORD_HWALL 0xfe 60 #define ACPI_PSD_COORD_VALID(coord) \ 61 ((coord) == ACPI_PSD_COORD_SWALL || \ 62 (coord) == ACPI_PSD_COORD_SWANY || \ 63 (coord) == ACPI_PSD_COORD_HWALL) 64 65 struct acpi_pst_softc; 66 LIST_HEAD(acpi_pst_list, acpi_pst_softc); 67 68 struct acpi_pst_chmsg { 69 struct cpuhelper_msg ch_msg; 70 const struct acpi_pst_res *ch_ctrl; 71 const struct acpi_pst_res *ch_status; 72 }; 73 74 struct acpi_pst_domain { 75 uint32_t pd_dom; 76 uint32_t pd_coord; 77 uint32_t pd_nproc; 78 LIST_ENTRY(acpi_pst_domain) pd_link; 79 80 uint32_t pd_flags; 81 82 struct lwkt_serialize pd_serialize; 83 84 int pd_state; 85 struct acpi_pst_list pd_pstlist; 86 87 struct sysctl_ctx_list pd_sysctl_ctx; 88 struct sysctl_oid *pd_sysctl_tree; 89 }; 90 LIST_HEAD(acpi_pst_domlist, acpi_pst_domain); 91 92 #define ACPI_PSTDOM_FLAG_STUB 0x1 /* stub domain, no _PSD */ 93 #define ACPI_PSTDOM_FLAG_DEAD 0x2 /* domain can't be started */ 94 #define ACPI_PSTDOM_FLAG_INT 0x4 /* domain created from Integer _PSD */ 95 96 struct acpi_pst_softc { 97 device_t pst_dev; 98 struct acpi_cpu_softc *pst_parent; 99 struct acpi_pst_domain *pst_domain; 100 struct acpi_pst_res pst_creg; 101 struct acpi_pst_res pst_sreg; 102 103 int pst_state; 104 int pst_cpuid; 105 106 uint32_t pst_flags; 107 108 ACPI_HANDLE pst_handle; 109 110 LIST_ENTRY(acpi_pst_softc) pst_link; 111 }; 112 113 #define ACPI_PST_FLAG_PPC 0x1 114 #define ACPI_PST_FLAG_PDL 0x2 115 116 static int acpi_pst_probe(device_t dev); 117 static int acpi_pst_attach(device_t dev); 118 static void acpi_pst_notify(device_t dev); 119 120 static void acpi_pst_postattach(void *); 121 static struct acpi_pst_domain * 122 acpi_pst_domain_create_int(device_t, uint32_t); 123 static struct acpi_pst_domain * 124 acpi_pst_domain_create_pkg(device_t, ACPI_OBJECT *); 125 static struct acpi_pst_domain * 126 acpi_pst_domain_find(uint32_t); 127 static struct acpi_pst_domain * 128 acpi_pst_domain_alloc(uint32_t, uint32_t, uint32_t); 129 static void acpi_pst_domain_set_pstate_locked(struct acpi_pst_domain *, 130 int, int *); 131 static void acpi_pst_domain_set_pstate(struct acpi_pst_domain *, int, 132 int *); 133 static void acpi_pst_domain_check_nproc(device_t, struct acpi_pst_domain *); 134 static void acpi_pst_global_set_pstate(int); 135 static void acpi_pst_global_fixup_pstate(void); 136 137 static int acpi_pst_check_csr(struct acpi_pst_softc *); 138 static int acpi_pst_check_pstates(struct acpi_pst_softc *); 139 static int acpi_pst_init(struct acpi_pst_softc *); 140 static int acpi_pst_set_pstate(struct acpi_pst_softc *, 141 const struct acpi_pstate *); 142 static const struct acpi_pstate * 143 acpi_pst_get_pstate(struct acpi_pst_softc *); 144 static int acpi_pst_alloc_resource(device_t, ACPI_OBJECT *, int, 145 struct acpi_pst_res *); 146 static int acpi_pst_eval_ppc(struct acpi_pst_softc *, int *); 147 static int acpi_pst_eval_pdl(struct acpi_pst_softc *, int *); 148 149 static void acpi_pst_check_csr_handler(struct cpuhelper_msg *); 150 static void acpi_pst_check_pstates_handler(struct cpuhelper_msg *); 151 static void acpi_pst_init_handler(struct cpuhelper_msg *); 152 static void acpi_pst_set_pstate_handler(struct cpuhelper_msg *); 153 static void acpi_pst_get_pstate_handler(struct cpuhelper_msg *); 154 155 static int acpi_pst_sysctl_freqs(SYSCTL_HANDLER_ARGS); 156 static int acpi_pst_sysctl_freqs_bin(SYSCTL_HANDLER_ARGS); 157 static int acpi_pst_sysctl_power(SYSCTL_HANDLER_ARGS); 158 static int acpi_pst_sysctl_members(SYSCTL_HANDLER_ARGS); 159 static int acpi_pst_sysctl_select(SYSCTL_HANDLER_ARGS); 160 static int acpi_pst_sysctl_global(SYSCTL_HANDLER_ARGS); 161 162 static struct acpi_pst_domlist acpi_pst_domains = 163 LIST_HEAD_INITIALIZER(acpi_pst_domains); 164 static int acpi_pst_domain_id; 165 166 static int acpi_pst_global_state; 167 168 static int acpi_pstate_start = -1; 169 static int acpi_pstate_count; 170 static int acpi_npstates; 171 static struct acpi_pstate *acpi_pstates; 172 173 static const struct acpi_pst_md *acpi_pst_md; 174 175 static int acpi_pst_pdl = -1; 176 TUNABLE_INT("hw.acpi.cpu.pst.pdl", &acpi_pst_pdl); 177 178 static int acpi_pst_ht_reuse_domain = 1; 179 TUNABLE_INT("hw.acpi.cpu.pst.ht_reuse_domain", &acpi_pst_ht_reuse_domain); 180 181 static int acpi_pst_force_pkg_domain = 0; 182 TUNABLE_INT("hw.acpi.cpu.pst.force_pkg_domain", &acpi_pst_force_pkg_domain); 183 184 static int acpi_pst_handle_notify = 1; 185 TUNABLE_INT("hw.acpi.cpu.pst.handle_notify", &acpi_pst_handle_notify); 186 187 /* 188 * Force CPU package power domain for Intel CPUs. 189 * 190 * As of this write (14 July 2015), all Intel CPUs only have CPU package 191 * power domain. 192 */ 193 static int acpi_pst_intel_pkg_domain = 1; 194 TUNABLE_INT("hw.acpi.cpu.pst.intel_pkg_domain", &acpi_pst_intel_pkg_domain); 195 196 static device_method_t acpi_pst_methods[] = { 197 /* Device interface */ 198 DEVMETHOD(device_probe, acpi_pst_probe), 199 DEVMETHOD(device_attach, acpi_pst_attach), 200 DEVMETHOD(device_detach, bus_generic_detach), 201 DEVMETHOD(device_shutdown, bus_generic_shutdown), 202 DEVMETHOD(device_suspend, bus_generic_suspend), 203 DEVMETHOD(device_resume, bus_generic_resume), 204 205 /* Bus interface */ 206 DEVMETHOD(bus_add_child, bus_generic_add_child), 207 DEVMETHOD(bus_print_child, bus_generic_print_child), 208 DEVMETHOD(bus_read_ivar, bus_generic_read_ivar), 209 DEVMETHOD(bus_write_ivar, bus_generic_write_ivar), 210 DEVMETHOD(bus_get_resource_list, bus_generic_get_resource_list), 211 DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), 212 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), 213 DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), 214 DEVMETHOD(bus_release_resource, bus_generic_release_resource), 215 DEVMETHOD(bus_driver_added, bus_generic_driver_added), 216 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 217 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 218 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 219 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 220 221 DEVMETHOD_END 222 }; 223 224 static driver_t acpi_pst_driver = { 225 "cpu_pst", 226 acpi_pst_methods, 227 sizeof(struct acpi_pst_softc), 228 .gpri = KOBJ_GPRI_ACPI+2 229 }; 230 231 static devclass_t acpi_pst_devclass; 232 DRIVER_MODULE(cpu_pst, cpu, acpi_pst_driver, acpi_pst_devclass, NULL, NULL); 233 MODULE_DEPEND(cpu_pst, acpi, 1, 1, 1); 234 235 static __inline int 236 acpi_pst_freq2index(int freq) 237 { 238 int i; 239 240 for (i = 0; i < acpi_npstates; ++i) { 241 if (acpi_pstates[i].st_freq == freq) 242 return i; 243 } 244 return -1; 245 } 246 247 static int 248 acpi_pst_probe(device_t dev) 249 { 250 ACPI_BUFFER buf; 251 ACPI_HANDLE handle; 252 ACPI_STATUS status; 253 ACPI_OBJECT *obj; 254 255 if (acpi_disabled("cpu_pst") || 256 acpi_get_type(dev) != ACPI_TYPE_PROCESSOR) 257 return ENXIO; 258 259 if (acpi_pst_md == NULL) 260 acpi_pst_md = acpi_pst_md_probe(); 261 262 handle = acpi_get_handle(dev); 263 264 /* 265 * Check _PSD package 266 * 267 * NOTE: 268 * Some BIOSes do not expose _PCT for the second thread of 269 * CPU cores. In this case, _PSD should be enough to get the 270 * P-state of the second thread working, since it must have 271 * the same _PCT and _PSS as the first thread in the same 272 * core. 273 */ 274 buf.Pointer = NULL; 275 buf.Length = ACPI_ALLOCATE_BUFFER; 276 status = AcpiEvaluateObject(handle, "_PSD", NULL, &buf); 277 if (!ACPI_FAILURE(status)) { 278 AcpiOsFree((ACPI_OBJECT *)buf.Pointer); 279 goto done; 280 } 281 282 /* 283 * Check _PCT package 284 */ 285 buf.Pointer = NULL; 286 buf.Length = ACPI_ALLOCATE_BUFFER; 287 status = AcpiEvaluateObject(handle, "_PCT", NULL, &buf); 288 if (ACPI_FAILURE(status)) { 289 if (bootverbose) { 290 device_printf(dev, "Can't get _PCT package - %s\n", 291 AcpiFormatException(status)); 292 } 293 return ENXIO; 294 } 295 296 obj = (ACPI_OBJECT *)buf.Pointer; 297 if (!ACPI_PKG_VALID_EQ(obj, 2)) { 298 device_printf(dev, "Invalid _PCT package\n"); 299 AcpiOsFree(obj); 300 return ENXIO; 301 } 302 AcpiOsFree(obj); 303 304 /* 305 * Check _PSS package 306 */ 307 buf.Pointer = NULL; 308 buf.Length = ACPI_ALLOCATE_BUFFER; 309 status = AcpiEvaluateObject(handle, "_PSS", NULL, &buf); 310 if (ACPI_FAILURE(status)) { 311 device_printf(dev, "Can't get _PSS package - %s\n", 312 AcpiFormatException(status)); 313 return ENXIO; 314 } 315 316 obj = (ACPI_OBJECT *)buf.Pointer; 317 if (!ACPI_PKG_VALID(obj, 1)) { 318 device_printf(dev, "Invalid _PSS package\n"); 319 AcpiOsFree(obj); 320 return ENXIO; 321 } 322 AcpiOsFree(obj); 323 324 done: 325 device_set_desc(dev, "ACPI CPU P-State"); 326 return 0; 327 } 328 329 static int 330 acpi_pst_attach(device_t dev) 331 { 332 struct acpi_pst_softc *sc = device_get_softc(dev); 333 struct acpi_pst_domain *dom = NULL; 334 ACPI_BUFFER buf; 335 ACPI_STATUS status; 336 ACPI_OBJECT *obj; 337 struct acpi_pstate *pstate, *p; 338 int i, npstate, error, sstart, scount; 339 340 sc->pst_dev = dev; 341 sc->pst_parent = device_get_softc(device_get_parent(dev)); 342 sc->pst_handle = acpi_get_handle(dev); 343 sc->pst_cpuid = acpi_get_magic(dev); 344 345 /* 346 * If there is a _PSD, then we create procossor domain 347 * accordingly. If there is no _PSD, we just fake a 348 * default processor domain0. 349 */ 350 buf.Pointer = NULL; 351 buf.Length = ACPI_ALLOCATE_BUFFER; 352 status = AcpiEvaluateObject(sc->pst_handle, "_PSD", NULL, &buf); 353 if (!ACPI_FAILURE(status)) { 354 obj = (ACPI_OBJECT *)buf.Pointer; 355 356 if (acpi_pst_domain_id > 0) { 357 device_printf(dev, "Missing _PSD for certain CPUs\n"); 358 AcpiOsFree(obj); 359 return ENXIO; 360 } 361 acpi_pst_domain_id = -1; 362 363 if (ACPI_PKG_VALID_EQ(obj, 1)) { 364 dom = acpi_pst_domain_create_pkg(dev, 365 &obj->Package.Elements[0]); 366 if (dom == NULL) { 367 AcpiOsFree(obj); 368 return ENXIO; 369 } 370 } else { 371 if (obj->Type != ACPI_TYPE_INTEGER) { 372 device_printf(dev, 373 "Invalid _PSD package, Type 0x%x\n", 374 obj->Type); 375 AcpiOsFree(obj); 376 return ENXIO; 377 } else { 378 device_printf(dev, "Integer _PSD %ju\n", 379 (uintmax_t)obj->Integer.Value); 380 dom = acpi_pst_domain_create_int(dev, 381 obj->Integer.Value); 382 if (dom == NULL) { 383 AcpiOsFree(obj); 384 return ENXIO; 385 } 386 } 387 } 388 389 /* Free _PSD */ 390 AcpiOsFree(buf.Pointer); 391 } else { 392 if (acpi_pst_domain_id < 0) { 393 device_printf(dev, "Missing _PSD for cpu%d\n", 394 sc->pst_cpuid); 395 return ENXIO; 396 } 397 398 /* 399 * Create a stub one processor domain for each processor 400 */ 401 dom = acpi_pst_domain_alloc(acpi_pst_domain_id, 402 ACPI_PSD_COORD_SWANY, 1); 403 dom->pd_flags |= ACPI_PSTDOM_FLAG_STUB; 404 405 ++acpi_pst_domain_id; 406 } 407 408 /* Make sure that adding us will not overflow our domain */ 409 acpi_pst_domain_check_nproc(dev, dom); 410 411 /* 412 * Get control/status registers from _PCT 413 */ 414 buf.Pointer = NULL; 415 buf.Length = ACPI_ALLOCATE_BUFFER; 416 status = AcpiEvaluateObject(sc->pst_handle, "_PCT", NULL, &buf); 417 if (ACPI_FAILURE(status)) { 418 struct acpi_pst_softc *pst; 419 420 /* 421 * No _PCT. See the comment in acpi_pst_probe() near 422 * _PSD check. 423 * 424 * Use control/status registers of another CPU in the 425 * same domain, or in the same core, if the type of 426 * these registers are "Fixed Hardware", e.g. on most 427 * of the model Intel CPUs. 428 */ 429 pst = LIST_FIRST(&dom->pd_pstlist); 430 if (pst == NULL) { 431 cpumask_t mask; 432 433 mask = get_cpumask_from_level(sc->pst_cpuid, 434 CORE_LEVEL); 435 if (CPUMASK_TESTNZERO(mask)) { 436 struct acpi_pst_domain *dom1; 437 438 LIST_FOREACH(dom1, &acpi_pst_domains, pd_link) { 439 LIST_FOREACH(pst, &dom1->pd_pstlist, 440 pst_link) { 441 if (CPUMASK_TESTBIT(mask, 442 pst->pst_cpuid)) 443 break; 444 } 445 if (pst != NULL) 446 break; 447 } 448 if (pst != NULL && acpi_pst_ht_reuse_domain) { 449 /* 450 * Use the same domain for CPUs in the 451 * same core. 452 */ 453 device_printf(dev, "Destroy domain%u, " 454 "reuse domain%u\n", 455 dom->pd_dom, dom1->pd_dom); 456 LIST_REMOVE(dom, pd_link); 457 kfree(dom, M_DEVBUF); 458 dom = dom1; 459 /* 460 * Make sure that adding us will not 461 * overflow the domain containing 462 * siblings in the same core. 463 */ 464 acpi_pst_domain_check_nproc(dev, dom); 465 } 466 } 467 } 468 if (pst != NULL && 469 pst->pst_creg.pr_res == NULL && 470 pst->pst_creg.pr_rid == 0 && 471 pst->pst_creg.pr_gas.SpaceId == 472 ACPI_ADR_SPACE_FIXED_HARDWARE && 473 pst->pst_sreg.pr_res == NULL && 474 pst->pst_sreg.pr_rid == 0 && 475 pst->pst_sreg.pr_gas.SpaceId == 476 ACPI_ADR_SPACE_FIXED_HARDWARE) { 477 sc->pst_creg = pst->pst_creg; 478 sc->pst_sreg = pst->pst_sreg; 479 device_printf(dev, 480 "No _PCT; reuse %s control/status regs\n", 481 device_get_nameunit(pst->pst_dev)); 482 goto fetch_pss; 483 } 484 device_printf(dev, "Can't get _PCT package - %s\n", 485 AcpiFormatException(status)); 486 return ENXIO; 487 } 488 489 obj = (ACPI_OBJECT *)buf.Pointer; 490 if (!ACPI_PKG_VALID_EQ(obj, 2)) { 491 device_printf(dev, "Invalid _PCT package\n"); 492 AcpiOsFree(obj); 493 return ENXIO; 494 } 495 496 /* Save and try allocating control register */ 497 error = acpi_pst_alloc_resource(dev, obj, 0, &sc->pst_creg); 498 if (error) { 499 AcpiOsFree(obj); 500 return error; 501 } 502 if (bootverbose) { 503 device_printf(dev, "control reg %d %jx\n", 504 sc->pst_creg.pr_gas.SpaceId, 505 (uintmax_t)sc->pst_creg.pr_gas.Address); 506 } 507 508 /* Save and try allocating status register */ 509 error = acpi_pst_alloc_resource(dev, obj, 1, &sc->pst_sreg); 510 if (error) { 511 AcpiOsFree(obj); 512 return error; 513 } 514 if (bootverbose) { 515 device_printf(dev, "status reg %d %jx\n", 516 sc->pst_sreg.pr_gas.SpaceId, 517 (uintmax_t)sc->pst_sreg.pr_gas.Address); 518 } 519 520 /* Free _PCT */ 521 AcpiOsFree(obj); 522 523 fetch_pss: 524 /* 525 * Create P-State table according to _PSS 526 */ 527 buf.Pointer = NULL; 528 buf.Length = ACPI_ALLOCATE_BUFFER; 529 status = AcpiEvaluateObject(sc->pst_handle, "_PSS", NULL, &buf); 530 if (ACPI_FAILURE(status)) { 531 /* 532 * No _PSS. See the comment in acpi_pst_probe() near 533 * _PSD check. 534 * 535 * Assume _PSS are same across all CPUs; well, they 536 * should/have to be so. 537 */ 538 if (acpi_npstates > 0 && acpi_pstates != NULL) { 539 device_printf(dev, "No _PSS\n"); 540 goto fetch_ppc; 541 } 542 device_printf(dev, "Can't get _PSS package - %s\n", 543 AcpiFormatException(status)); 544 return ENXIO; 545 } 546 547 obj = (ACPI_OBJECT *)buf.Pointer; 548 if (!ACPI_PKG_VALID(obj, 1)) { 549 device_printf(dev, "Invalid _PSS package\n"); 550 AcpiOsFree(obj); 551 return ENXIO; 552 } 553 554 /* Don't create too many P-States */ 555 npstate = obj->Package.Count; 556 if (npstate > ACPI_NPSTATE_MAX) { 557 device_printf(dev, "Too many P-States, %d->%d\n", 558 npstate, ACPI_NPSTATE_MAX); 559 npstate = ACPI_NPSTATE_MAX; 560 } 561 562 /* 563 * If we have already created P-State table, 564 * we must make sure that number of entries 565 * is consistent. 566 */ 567 if (acpi_pstates != NULL && acpi_npstates != npstate) { 568 device_printf(dev, "Inconsistent # of P-States " 569 "cross Processor objects\n"); 570 AcpiOsFree(obj); 571 return ENXIO; 572 } 573 574 /* 575 * Create a temporary P-State table 576 */ 577 pstate = kmalloc(sizeof(*pstate) * npstate, M_TEMP, M_WAITOK); 578 for (i = 0, p = pstate; i < npstate; ++i, ++p) { 579 ACPI_OBJECT *pkg; 580 uint32_t *ptr[ACPI_PSS_PX_NENTRY] = { 581 &p->st_freq, &p->st_power, &p->st_xsit_lat, 582 &p->st_bm_lat, &p->st_cval, &p->st_sval 583 }; 584 int j; 585 586 pkg = &obj->Package.Elements[i]; 587 if (!ACPI_PKG_VALID(pkg, ACPI_PSS_PX_NENTRY)) { 588 device_printf(dev, "Invalud _PSS P%d\n", i); 589 AcpiOsFree(obj); 590 kfree(pstate, M_TEMP); 591 return ENXIO; 592 } 593 for (j = 0; j < ACPI_PSS_PX_NENTRY; ++j) { 594 if (acpi_PkgInt32(pkg, j, ptr[j]) != 0) { 595 device_printf(dev, "Can't extract " 596 "_PSS P%d %dth entry\n", i, j); 597 AcpiOsFree(obj); 598 kfree(pstate, M_TEMP); 599 return ENXIO; 600 } 601 } 602 if (p->st_freq & 0x80000000) { 603 device_printf(dev, "Invalid _PSS P%d freq: 0x%08x\n", 604 i, p->st_freq); 605 AcpiOsFree(obj); 606 kfree(pstate, M_TEMP); 607 return ENXIO; 608 } 609 } 610 611 /* Free _PSS */ 612 AcpiOsFree(obj); 613 614 if (acpi_pstates == NULL) { 615 /* 616 * If no P-State table is created yet, 617 * save the temporary one we just created. 618 */ 619 acpi_pstates = pstate; 620 acpi_npstates = npstate; 621 pstate = NULL; 622 623 if (bootverbose) { 624 for (i = 0; i < acpi_npstates; ++i) { 625 device_printf(dev, 626 "freq %u, pwr %u, xlat %u, blat %u, " 627 "cv %08x, sv %08x\n", 628 acpi_pstates[i].st_freq, 629 acpi_pstates[i].st_power, 630 acpi_pstates[i].st_xsit_lat, 631 acpi_pstates[i].st_bm_lat, 632 acpi_pstates[i].st_cval, 633 acpi_pstates[i].st_sval); 634 } 635 } 636 } else { 637 /* 638 * Make sure that P-State tables are same 639 * for all processors. 640 */ 641 if (memcmp(pstate, acpi_pstates, 642 sizeof(*pstate) * npstate) != 0) { 643 device_printf(dev, "Inconsistent _PSS " 644 "cross Processor objects\n"); 645 #if 0 646 /* 647 * Some BIOSes create different P-State tables; 648 * just trust the one from the BSP and move on. 649 */ 650 kfree(pstate, M_TEMP); 651 return ENXIO; 652 #endif 653 } 654 kfree(pstate, M_TEMP); 655 } 656 657 fetch_ppc: 658 /* By default, we start from P-State table's first entry */ 659 sstart = 0; 660 661 /* 662 * Adjust the usable first entry of P-State table, 663 * if there is _PPC object. 664 */ 665 error = acpi_pst_eval_ppc(sc, &sstart); 666 if (error && error != ENOENT) 667 return error; 668 else if (!error) 669 sc->pst_flags |= ACPI_PST_FLAG_PPC; 670 if (acpi_pstate_start < 0) { 671 acpi_pstate_start = sstart; 672 } else if (acpi_pstate_start != sstart) { 673 device_printf(dev, "_PPC mismatch, was %d, now %d\n", 674 acpi_pstate_start, sstart); 675 if (acpi_pstate_start < sstart) { 676 device_printf(dev, "_PPC %d -> %d\n", 677 acpi_pstate_start, sstart); 678 acpi_pstate_start = sstart; 679 } 680 } 681 682 /* 683 * By default, we assume number of usable P-States is same as 684 * number of P-States. 685 */ 686 scount = acpi_npstates; 687 688 /* 689 * Allow users to override or set _PDL 690 */ 691 if (acpi_pst_pdl >= 0) { 692 if (acpi_pst_pdl < acpi_npstates) { 693 if (bootverbose) { 694 device_printf(dev, "_PDL override %d\n", 695 acpi_pst_pdl); 696 } 697 scount = acpi_pst_pdl + 1; 698 goto proc_pdl; 699 } else { 700 device_printf(dev, "Invalid _PDL override %d, " 701 "must be less than %d\n", acpi_pst_pdl, 702 acpi_npstates); 703 } 704 } 705 706 /* 707 * Adjust the number of usable entries in P-State table, 708 * if there is _PDL object. 709 */ 710 error = acpi_pst_eval_pdl(sc, &scount); 711 if (error && error != ENOENT) 712 return error; 713 else if (!error) 714 sc->pst_flags |= ACPI_PST_FLAG_PDL; 715 proc_pdl: 716 if (acpi_pstate_count == 0) { 717 acpi_pstate_count = scount; 718 } else if (acpi_pstate_count != scount) { 719 device_printf(dev, "_PDL mismatch, was %d, now %d\n", 720 acpi_pstate_count, scount); 721 if (acpi_pstate_count > scount) { 722 device_printf(dev, "_PDL %d -> %d\n", 723 acpi_pstate_count, scount); 724 acpi_pstate_count = scount; 725 } 726 } 727 728 /* 729 * Some CPUs only have package P-states, but some BIOSes put each 730 * hyperthread to its own P-state domain; allow user to override. 731 */ 732 if (LIST_EMPTY(&dom->pd_pstlist) && 733 (acpi_pst_force_pkg_domain || 734 (cpu_vendor_id == CPU_VENDOR_INTEL && 735 acpi_pst_intel_pkg_domain))) { 736 cpumask_t mask; 737 738 mask = get_cpumask_from_level(sc->pst_cpuid, CHIP_LEVEL); 739 if (CPUMASK_TESTNZERO(mask)) { 740 struct acpi_pst_softc *pst = NULL; 741 struct acpi_pst_domain *dom1; 742 743 LIST_FOREACH(dom1, &acpi_pst_domains, pd_link) { 744 LIST_FOREACH(pst, &dom1->pd_pstlist, 745 pst_link) { 746 if (CPUMASK_TESTBIT(mask, 747 pst->pst_cpuid)) 748 break; 749 } 750 if (pst != NULL) 751 break; 752 } 753 if (pst != NULL && 754 memcmp(&pst->pst_creg, &sc->pst_creg, 755 sizeof(sc->pst_creg)) == 0 && 756 memcmp(&pst->pst_sreg, &sc->pst_sreg, 757 sizeof(sc->pst_sreg)) == 0) { 758 /* 759 * Use the same domain for CPUs in the 760 * same package. 761 */ 762 device_printf(dev, "Destroy domain%u, " 763 "force pkg domain%u\n", 764 dom->pd_dom, dom1->pd_dom); 765 LIST_REMOVE(dom, pd_link); 766 kfree(dom, M_DEVBUF); 767 dom = dom1; 768 /* 769 * Make sure that adding us will not 770 * overflow the domain containing 771 * siblings in the same package. 772 */ 773 acpi_pst_domain_check_nproc(dev, dom); 774 } 775 } 776 } 777 778 /* Link us with the domain */ 779 sc->pst_domain = dom; 780 LIST_INSERT_HEAD(&dom->pd_pstlist, sc, pst_link); 781 782 if (device_get_unit(dev) == 0) 783 AcpiOsExecute(OSL_NOTIFY_HANDLER, acpi_pst_postattach, NULL); 784 785 if (sc->pst_flags & (ACPI_PST_FLAG_PPC | ACPI_PST_FLAG_PDL)) 786 sc->pst_parent->cpu_pst_notify = acpi_pst_notify; 787 788 return 0; 789 } 790 791 static struct acpi_pst_domain * 792 acpi_pst_domain_create_pkg(device_t dev, ACPI_OBJECT *obj) 793 { 794 struct acpi_pst_domain *dom; 795 uint32_t val, domain, coord, nproc; 796 797 if (!ACPI_PKG_VALID_EQ(obj, 5)) { 798 device_printf(dev, "Invalid _PSD package\n"); 799 return NULL; 800 } 801 802 /* NumberOfEntries */ 803 if (acpi_PkgInt32(obj, 0, &val) != 0 || val != 5) { 804 device_printf(dev, "Invalid _PSD NumberOfEntries\n"); 805 return NULL; 806 } 807 808 /* Revision */ 809 if (acpi_PkgInt32(obj, 1, &val) != 0 || val != 0) { 810 device_printf(dev, "Invalid _PSD Revision\n"); 811 return NULL; 812 } 813 814 if (acpi_PkgInt32(obj, 2, &domain) != 0 || 815 acpi_PkgInt32(obj, 3, &coord) != 0 || 816 acpi_PkgInt32(obj, 4, &nproc) != 0) { 817 device_printf(dev, "Can't extract _PSD package\n"); 818 return NULL; 819 } 820 821 if (!ACPI_PSD_COORD_VALID(coord)) { 822 device_printf(dev, "Invalid _PSD CoordType (%#x)\n", coord); 823 return NULL; 824 } 825 826 if (nproc > MAXCPU) { 827 /* 828 * If NumProcessors is greater than MAXCPU 829 * and domain's coordination is SWALL, then 830 * we will never be able to start all CPUs 831 * within this domain, and power state 832 * transition will never be completed, so we 833 * just bail out here. 834 */ 835 if (coord == ACPI_PSD_COORD_SWALL) { 836 device_printf(dev, "Unsupported _PSD NumProcessors " 837 "(%d)\n", nproc); 838 return NULL; 839 } 840 } else if (nproc == 0) { 841 device_printf(dev, "_PSD NumProcessors are zero\n"); 842 return NULL; 843 } 844 845 dom = acpi_pst_domain_find(domain); 846 if (dom != NULL) { 847 if (dom->pd_flags & ACPI_PSTDOM_FLAG_INT) { 848 device_printf(dev, "Mixed Integer _PSD and " 849 "Package _PSD\n"); 850 return NULL; 851 } 852 if (dom->pd_coord != coord) { 853 device_printf(dev, "Inconsistent _PSD coord " 854 "information cross Processor objects\n"); 855 return NULL; 856 } 857 if (dom->pd_nproc != nproc) { 858 device_printf(dev, "Inconsistent _PSD nproc " 859 "information cross Processor objects\n"); 860 /* 861 * Some stupid BIOSes will set wrong "# of processors", 862 * e.g. 1 for CPU w/ hyperthreading; Be lenient here. 863 */ 864 } 865 return dom; 866 } 867 868 dom = acpi_pst_domain_alloc(domain, coord, nproc); 869 if (bootverbose) { 870 device_printf(dev, "create pkg domain%u, coord %#x\n", 871 dom->pd_dom, dom->pd_coord); 872 } 873 874 return dom; 875 } 876 877 static struct acpi_pst_domain * 878 acpi_pst_domain_create_int(device_t dev, uint32_t domain) 879 { 880 struct acpi_pst_domain *dom; 881 882 dom = acpi_pst_domain_find(domain); 883 if (dom != NULL) { 884 if ((dom->pd_flags & ACPI_PSTDOM_FLAG_INT) == 0) { 885 device_printf(dev, "Mixed Package _PSD and " 886 "Integer _PSD\n"); 887 return NULL; 888 } 889 KKASSERT(dom->pd_coord == ACPI_PSD_COORD_SWALL); 890 891 dom->pd_nproc++; 892 return dom; 893 } 894 895 dom = acpi_pst_domain_alloc(domain, ACPI_PSD_COORD_SWALL, 1); 896 dom->pd_flags |= ACPI_PSTDOM_FLAG_INT; 897 898 if (bootverbose) 899 device_printf(dev, "create int domain%u\n", dom->pd_dom); 900 901 return dom; 902 } 903 904 static struct acpi_pst_domain * 905 acpi_pst_domain_find(uint32_t domain) 906 { 907 struct acpi_pst_domain *dom; 908 909 LIST_FOREACH(dom, &acpi_pst_domains, pd_link) { 910 if (dom->pd_flags & ACPI_PSTDOM_FLAG_STUB) 911 continue; 912 if (dom->pd_dom == domain) 913 return dom; 914 } 915 return NULL; 916 } 917 918 static struct acpi_pst_domain * 919 acpi_pst_domain_alloc(uint32_t domain, uint32_t coord, uint32_t nproc) 920 { 921 struct acpi_pst_domain *dom; 922 923 dom = kmalloc(sizeof(*dom), M_DEVBUF, M_WAITOK | M_ZERO); 924 dom->pd_dom = domain; 925 dom->pd_coord = coord; 926 dom->pd_nproc = nproc; 927 LIST_INIT(&dom->pd_pstlist); 928 lwkt_serialize_init(&dom->pd_serialize); 929 930 LIST_INSERT_HEAD(&acpi_pst_domains, dom, pd_link); 931 932 return dom; 933 } 934 935 static void 936 acpi_pst_domain_set_pstate_locked(struct acpi_pst_domain *dom, int i, int *global) 937 { 938 const struct acpi_pstate *pstate; 939 struct acpi_pst_softc *sc; 940 int done, error; 941 942 ASSERT_SERIALIZED(&dom->pd_serialize); 943 944 KKASSERT(i >= 0 && i < acpi_npstates); 945 pstate = &acpi_pstates[i]; 946 947 done = 0; 948 LIST_FOREACH(sc, &dom->pd_pstlist, pst_link) { 949 if (!done) { 950 error = acpi_pst_set_pstate(sc, pstate); 951 if (error) { 952 device_printf(sc->pst_dev, "can't set " 953 "freq %d\n", pstate->st_freq); 954 /* XXX error cleanup? */ 955 } 956 if (dom->pd_coord == ACPI_PSD_COORD_SWANY) 957 done = 1; 958 } 959 sc->pst_state = i; 960 } 961 dom->pd_state = i; 962 963 if (global != NULL) 964 *global = i; 965 } 966 967 static void 968 acpi_pst_domain_set_pstate(struct acpi_pst_domain *dom, int i, int *global) 969 { 970 lwkt_serialize_enter(&dom->pd_serialize); 971 acpi_pst_domain_set_pstate_locked(dom, i, global); 972 lwkt_serialize_exit(&dom->pd_serialize); 973 } 974 975 static void 976 acpi_pst_global_set_pstate(int i) 977 { 978 struct acpi_pst_domain *dom; 979 int *global = &acpi_pst_global_state; 980 981 LIST_FOREACH(dom, &acpi_pst_domains, pd_link) { 982 /* Skip dead domain */ 983 if (dom->pd_flags & ACPI_PSTDOM_FLAG_DEAD) 984 continue; 985 acpi_pst_domain_set_pstate(dom, i, global); 986 global = NULL; 987 } 988 } 989 990 static void 991 acpi_pst_global_fixup_pstate(void) 992 { 993 struct acpi_pst_domain *dom; 994 int *global = &acpi_pst_global_state; 995 int sstart, scount; 996 997 sstart = acpi_pstate_start; 998 scount = acpi_pstate_count; 999 1000 LIST_FOREACH(dom, &acpi_pst_domains, pd_link) { 1001 int i = -1; 1002 1003 /* Skip dead domain */ 1004 if (dom->pd_flags & ACPI_PSTDOM_FLAG_DEAD) 1005 continue; 1006 1007 lwkt_serialize_enter(&dom->pd_serialize); 1008 1009 if (global != NULL) { 1010 if (*global < sstart) 1011 *global = sstart; 1012 else if (*global >= scount) 1013 *global = scount - 1; 1014 global = NULL; 1015 } 1016 if (dom->pd_state < sstart) 1017 i = sstart; 1018 else if (dom->pd_state >= scount) 1019 i = scount - 1; 1020 if (i >= 0) 1021 acpi_pst_domain_set_pstate_locked(dom, i, NULL); 1022 1023 lwkt_serialize_exit(&dom->pd_serialize); 1024 } 1025 } 1026 1027 static void 1028 acpi_pst_postattach(void *arg __unused) 1029 { 1030 struct acpi_pst_domain *dom; 1031 struct acpi_cpu_softc *cpu; 1032 device_t *devices; 1033 int i, ndevices, error, has_domain; 1034 1035 devices = NULL; 1036 ndevices = 0; 1037 error = devclass_get_devices(acpi_pst_devclass, &devices, &ndevices); 1038 if (error) 1039 return; 1040 1041 if (ndevices == 0) 1042 return; 1043 1044 cpu = NULL; 1045 for (i = 0; i < ndevices; ++i) { 1046 cpu = device_get_softc(device_get_parent(devices[i])); 1047 if (cpu->glob_sysctl_tree != NULL) 1048 break; 1049 } 1050 kfree(devices, M_TEMP); 1051 KKASSERT(cpu != NULL); 1052 1053 if (acpi_pst_md == NULL) 1054 kprintf("ACPI: no P-State CPU driver\n"); 1055 1056 has_domain = 0; 1057 LIST_FOREACH(dom, &acpi_pst_domains, pd_link) { 1058 struct acpi_pst_softc *sc; 1059 char buf[32]; 1060 1061 dom->pd_state = acpi_pstate_start; 1062 1063 /* 1064 * Make sure that all processors belonging to this 1065 * domain are located. 1066 */ 1067 i = 0; 1068 LIST_FOREACH(sc, &dom->pd_pstlist, pst_link) { 1069 sc->pst_state = acpi_pstate_start; 1070 ++i; 1071 } 1072 if (i != dom->pd_nproc) { 1073 KKASSERT(i < dom->pd_nproc); 1074 1075 kprintf("ACPI: domain%u misses processors, " 1076 "should be %d, got %d\n", dom->pd_dom, 1077 dom->pd_nproc, i); 1078 if (dom->pd_coord == ACPI_PSD_COORD_SWALL) { 1079 /* 1080 * If this domain's coordination is 1081 * SWALL and we don't see all of the 1082 * member CPUs of this domain, then 1083 * the P-State transition will never 1084 * be completed, so just leave this 1085 * domain out. 1086 */ 1087 dom->pd_flags |= ACPI_PSTDOM_FLAG_DEAD; 1088 continue; 1089 } 1090 dom->pd_nproc = i; 1091 } 1092 1093 /* 1094 * Validate P-State configurations for this domain 1095 */ 1096 LIST_FOREACH(sc, &dom->pd_pstlist, pst_link) { 1097 error = acpi_pst_check_csr(sc); 1098 if (error) 1099 break; 1100 1101 error = acpi_pst_check_pstates(sc); 1102 if (error) 1103 break; 1104 } 1105 if (sc != NULL) { 1106 kprintf("ACPI: domain%u P-State configuration " 1107 "check failed\n", dom->pd_dom); 1108 dom->pd_flags |= ACPI_PSTDOM_FLAG_DEAD; 1109 continue; 1110 } 1111 1112 /* 1113 * Do necssary P-State initialization 1114 */ 1115 LIST_FOREACH(sc, &dom->pd_pstlist, pst_link) { 1116 error = acpi_pst_init(sc); 1117 if (error) 1118 break; 1119 } 1120 if (sc != NULL) { 1121 kprintf("ACPI: domain%u P-State initialization " 1122 "check failed\n", dom->pd_dom); 1123 dom->pd_flags |= ACPI_PSTDOM_FLAG_DEAD; 1124 continue; 1125 } 1126 1127 has_domain = 1; 1128 1129 ksnprintf(buf, sizeof(buf), "px_dom%u", dom->pd_dom); 1130 1131 sysctl_ctx_init(&dom->pd_sysctl_ctx); 1132 dom->pd_sysctl_tree = 1133 SYSCTL_ADD_NODE(&dom->pd_sysctl_ctx, 1134 SYSCTL_CHILDREN(cpu->glob_sysctl_tree), 1135 OID_AUTO, buf, CTLFLAG_RD, 0, 1136 "P-State domain"); 1137 if (dom->pd_sysctl_tree == NULL) { 1138 kprintf("ACPI: Can't create sysctl tree for domain%u", 1139 dom->pd_dom); 1140 continue; 1141 } 1142 1143 SYSCTL_ADD_PROC(&dom->pd_sysctl_ctx, 1144 SYSCTL_CHILDREN(dom->pd_sysctl_tree), 1145 OID_AUTO, "available", 1146 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_SKIP, 1147 dom, 0, acpi_pst_sysctl_freqs, "A", 1148 "available frequencies"); 1149 1150 SYSCTL_ADD_PROC(&dom->pd_sysctl_ctx, 1151 SYSCTL_CHILDREN(dom->pd_sysctl_tree), 1152 OID_AUTO, "avail", 1153 CTLTYPE_OPAQUE | CTLFLAG_RD, 1154 dom, 0, acpi_pst_sysctl_freqs_bin, "IU", 1155 "available frequencies"); 1156 1157 SYSCTL_ADD_PROC(&dom->pd_sysctl_ctx, 1158 SYSCTL_CHILDREN(dom->pd_sysctl_tree), 1159 OID_AUTO, "power", 1160 CTLTYPE_OPAQUE | CTLFLAG_RD, 1161 dom, 0, acpi_pst_sysctl_power, "IU", 1162 "power of available frequencies"); 1163 1164 SYSCTL_ADD_PROC(&dom->pd_sysctl_ctx, 1165 SYSCTL_CHILDREN(dom->pd_sysctl_tree), 1166 OID_AUTO, "members", 1167 CTLTYPE_STRING | CTLFLAG_RD, 1168 dom, 0, acpi_pst_sysctl_members, "A", 1169 "member cpus"); 1170 1171 if (acpi_pst_md != NULL && 1172 acpi_pst_md->pmd_set_pstate != NULL) { 1173 SYSCTL_ADD_PROC(&dom->pd_sysctl_ctx, 1174 SYSCTL_CHILDREN(dom->pd_sysctl_tree), 1175 OID_AUTO, "select", 1176 CTLTYPE_UINT | CTLFLAG_RW, 1177 dom, 0, acpi_pst_sysctl_select, 1178 "IU", "select freq"); 1179 } 1180 } 1181 1182 if (has_domain && acpi_pst_md != NULL && 1183 acpi_pst_md->pmd_set_pstate != NULL) { 1184 SYSCTL_ADD_PROC(&cpu->glob_sysctl_ctx, 1185 SYSCTL_CHILDREN(cpu->glob_sysctl_tree), 1186 OID_AUTO, "px_global", 1187 CTLTYPE_UINT | CTLFLAG_RW, 1188 NULL, 0, acpi_pst_sysctl_global, 1189 "IU", "select freq for all domains"); 1190 SYSCTL_ADD_INT(&cpu->glob_sysctl_ctx, 1191 SYSCTL_CHILDREN(cpu->glob_sysctl_tree), 1192 OID_AUTO, "px_handle_notify", CTLFLAG_RW, 1193 &acpi_pst_handle_notify, 0, 1194 "handle type 0x80 notify"); 1195 1196 acpi_pst_global_set_pstate(acpi_pstate_start); 1197 } 1198 } 1199 1200 static int 1201 acpi_pst_sysctl_freqs(SYSCTL_HANDLER_ARGS) 1202 { 1203 int i, error, sstart, scount; 1204 1205 error = 0; 1206 sstart = acpi_pstate_start; 1207 scount = acpi_pstate_count; 1208 for (i = 0; i < acpi_npstates; ++i) { 1209 if (error == 0 && i) 1210 error = SYSCTL_OUT(req, " ", 1); 1211 if (error == 0) { 1212 const char *pat; 1213 char buf[32]; 1214 1215 if (i < sstart || i >= scount) 1216 pat = "(%u)"; 1217 else 1218 pat = "%u"; 1219 1220 ksnprintf(buf, sizeof(buf), pat, 1221 acpi_pstates[i].st_freq); 1222 error = SYSCTL_OUT(req, buf, strlen(buf)); 1223 } 1224 } 1225 return error; 1226 } 1227 1228 static int 1229 acpi_pst_sysctl_freqs_bin(SYSCTL_HANDLER_ARGS) 1230 { 1231 uint32_t freqs[ACPI_NPSTATE_MAX]; 1232 int cnt, i, sstart, scount; 1233 1234 sstart = acpi_pstate_start; 1235 scount = acpi_pstate_count; 1236 1237 cnt = scount - sstart; 1238 for (i = 0; i < cnt; ++i) 1239 freqs[i] = acpi_pstates[sstart + i].st_freq; 1240 1241 return sysctl_handle_opaque(oidp, freqs, cnt * sizeof(freqs[0]), req); 1242 } 1243 1244 static int 1245 acpi_pst_sysctl_power(SYSCTL_HANDLER_ARGS) 1246 { 1247 uint32_t power[ACPI_NPSTATE_MAX]; 1248 int cnt, i, sstart, scount; 1249 1250 sstart = acpi_pstate_start; 1251 scount = acpi_pstate_count; 1252 1253 cnt = scount - sstart; 1254 for (i = 0; i < cnt; ++i) 1255 power[i] = acpi_pstates[sstart + i].st_power; 1256 1257 return sysctl_handle_opaque(oidp, power, cnt * sizeof(power[0]), req); 1258 } 1259 1260 static int 1261 acpi_pst_sysctl_members(SYSCTL_HANDLER_ARGS) 1262 { 1263 struct acpi_pst_domain *dom = arg1; 1264 struct acpi_pst_softc *sc; 1265 int loop, error; 1266 1267 loop = error = 0; 1268 LIST_FOREACH(sc, &dom->pd_pstlist, pst_link) { 1269 char buf[32]; 1270 1271 if (error == 0 && loop) 1272 error = SYSCTL_OUT(req, " ", 1); 1273 if (error == 0) { 1274 ksnprintf(buf, sizeof(buf), "cpu%d", sc->pst_cpuid); 1275 error = SYSCTL_OUT(req, buf, strlen(buf)); 1276 } 1277 1278 if (error == 0 && acpi_pst_md && acpi_pst_md->pmd_get_pstate) { 1279 const struct acpi_pstate *pstate; 1280 const char *str; 1281 1282 pstate = acpi_pst_get_pstate(sc); 1283 if (pstate == NULL) { 1284 str = "(*)"; 1285 } else { 1286 ksnprintf(buf, sizeof(buf), "(%d)", 1287 pstate->st_freq); 1288 str = buf; 1289 } 1290 error = SYSCTL_OUT(req, str, strlen(str)); 1291 } 1292 ++loop; 1293 } 1294 return error; 1295 } 1296 1297 static int 1298 acpi_pst_sysctl_select(SYSCTL_HANDLER_ARGS) 1299 { 1300 struct acpi_pst_domain *dom = arg1; 1301 int error, i, freq; 1302 1303 KKASSERT(dom->pd_state >= 0 && dom->pd_state < acpi_npstates); 1304 1305 freq = acpi_pstates[dom->pd_state].st_freq; 1306 1307 error = sysctl_handle_int(oidp, &freq, 0, req); 1308 if (error || req->newptr == NULL) 1309 return error; 1310 1311 i = acpi_pst_freq2index(freq); 1312 if (i < 0) 1313 return EINVAL; 1314 1315 acpi_pst_domain_set_pstate(dom, i, NULL); 1316 return 0; 1317 } 1318 1319 static int 1320 acpi_pst_sysctl_global(SYSCTL_HANDLER_ARGS) 1321 { 1322 int error, i, freq; 1323 1324 KKASSERT(acpi_pst_global_state >= 0 && 1325 acpi_pst_global_state < acpi_npstates); 1326 1327 freq = acpi_pstates[acpi_pst_global_state].st_freq; 1328 1329 error = sysctl_handle_int(oidp, &freq, 0, req); 1330 if (error || req->newptr == NULL) 1331 return error; 1332 1333 i = acpi_pst_freq2index(freq); 1334 if (i < 0) 1335 return EINVAL; 1336 1337 acpi_pst_global_set_pstate(i); 1338 1339 return 0; 1340 } 1341 1342 static void 1343 acpi_pst_check_csr_handler(struct cpuhelper_msg *msg) 1344 { 1345 struct acpi_pst_chmsg *pmsg = (struct acpi_pst_chmsg *)msg; 1346 int error; 1347 1348 error = acpi_pst_md->pmd_check_csr(pmsg->ch_ctrl, pmsg->ch_status); 1349 cpuhelper_replymsg(msg, error); 1350 } 1351 1352 static int 1353 acpi_pst_check_csr(struct acpi_pst_softc *sc) 1354 { 1355 struct acpi_pst_chmsg msg; 1356 1357 if (acpi_pst_md == NULL) 1358 return 0; 1359 1360 cpuhelper_initmsg(&msg.ch_msg, &curthread->td_msgport, 1361 acpi_pst_check_csr_handler, NULL, MSGF_PRIORITY); 1362 msg.ch_ctrl = &sc->pst_creg; 1363 msg.ch_status = &sc->pst_sreg; 1364 1365 return (cpuhelper_domsg(&msg.ch_msg, sc->pst_cpuid)); 1366 } 1367 1368 static void 1369 acpi_pst_check_pstates_handler(struct cpuhelper_msg *msg) 1370 { 1371 int error; 1372 1373 error = acpi_pst_md->pmd_check_pstates(acpi_pstates, acpi_npstates); 1374 cpuhelper_replymsg(msg, error); 1375 } 1376 1377 static int 1378 acpi_pst_check_pstates(struct acpi_pst_softc *sc) 1379 { 1380 struct cpuhelper_msg msg; 1381 1382 if (acpi_pst_md == NULL) 1383 return 0; 1384 1385 cpuhelper_initmsg(&msg, &curthread->td_msgport, 1386 acpi_pst_check_pstates_handler, NULL, MSGF_PRIORITY); 1387 return (cpuhelper_domsg(&msg, sc->pst_cpuid)); 1388 } 1389 1390 static void 1391 acpi_pst_init_handler(struct cpuhelper_msg *msg) 1392 { 1393 struct acpi_pst_chmsg *pmsg = (struct acpi_pst_chmsg *)msg; 1394 int error; 1395 1396 error = acpi_pst_md->pmd_init(pmsg->ch_ctrl, pmsg->ch_status); 1397 cpuhelper_replymsg(msg, error); 1398 } 1399 1400 static int 1401 acpi_pst_init(struct acpi_pst_softc *sc) 1402 { 1403 struct acpi_pst_chmsg msg; 1404 1405 if (acpi_pst_md == NULL) 1406 return 0; 1407 1408 cpuhelper_initmsg(&msg.ch_msg, &curthread->td_msgport, 1409 acpi_pst_init_handler, NULL, MSGF_PRIORITY); 1410 msg.ch_ctrl = &sc->pst_creg; 1411 msg.ch_status = &sc->pst_sreg; 1412 1413 return (cpuhelper_domsg(&msg.ch_msg, sc->pst_cpuid)); 1414 } 1415 1416 static void 1417 acpi_pst_set_pstate_handler(struct cpuhelper_msg *msg) 1418 { 1419 struct acpi_pst_chmsg *pmsg = (struct acpi_pst_chmsg *)msg; 1420 int error; 1421 1422 error = acpi_pst_md->pmd_set_pstate(pmsg->ch_ctrl, pmsg->ch_status, 1423 msg->ch_cbarg); 1424 cpuhelper_replymsg(msg, error); 1425 } 1426 1427 static int 1428 acpi_pst_set_pstate(struct acpi_pst_softc *sc, const struct acpi_pstate *pstate) 1429 { 1430 struct acpi_pst_chmsg msg; 1431 1432 KKASSERT(acpi_pst_md != NULL); 1433 1434 cpuhelper_initmsg(&msg.ch_msg, &curthread->td_msgport, 1435 acpi_pst_set_pstate_handler, __DECONST(void *, pstate), 1436 MSGF_PRIORITY); 1437 msg.ch_ctrl = &sc->pst_creg; 1438 msg.ch_status = &sc->pst_sreg; 1439 1440 return (cpuhelper_domsg(&msg.ch_msg, sc->pst_cpuid)); 1441 } 1442 1443 static void 1444 acpi_pst_get_pstate_handler(struct cpuhelper_msg *msg) 1445 { 1446 struct acpi_pst_chmsg *pmsg = (struct acpi_pst_chmsg *)msg; 1447 const struct acpi_pstate *pstate; 1448 1449 pstate = acpi_pst_md->pmd_get_pstate(pmsg->ch_status, acpi_pstates, 1450 acpi_npstates); 1451 msg->ch_cbarg = __DECONST(void *, pstate); 1452 cpuhelper_replymsg(msg, 0); 1453 } 1454 1455 static const struct acpi_pstate * 1456 acpi_pst_get_pstate(struct acpi_pst_softc *sc) 1457 { 1458 struct acpi_pst_chmsg msg; 1459 1460 if (acpi_pst_md == NULL) 1461 return 0; 1462 1463 cpuhelper_initmsg(&msg.ch_msg, &curthread->td_msgport, 1464 acpi_pst_get_pstate_handler, NULL, MSGF_PRIORITY); 1465 msg.ch_status = &sc->pst_sreg; 1466 1467 cpuhelper_domsg(&msg.ch_msg, sc->pst_cpuid); 1468 return (msg.ch_msg.ch_cbarg); 1469 } 1470 1471 static int 1472 acpi_pst_alloc_resource(device_t dev, ACPI_OBJECT *obj, int idx, 1473 struct acpi_pst_res *res) 1474 { 1475 struct acpi_pst_softc *sc = device_get_softc(dev); 1476 int error, type; 1477 1478 /* Save GAS */ 1479 error = acpi_PkgRawGas(obj, idx, &res->pr_gas); 1480 if (error) 1481 return error; 1482 1483 /* Allocate resource, if possible */ 1484 res->pr_rid = sc->pst_parent->cpu_next_rid; 1485 acpi_bus_alloc_gas(dev, &type, &res->pr_rid, &res->pr_gas, &res->pr_res, 0); 1486 if (res->pr_res != NULL) { 1487 sc->pst_parent->cpu_next_rid++; 1488 res->pr_bt = rman_get_bustag(res->pr_res); 1489 res->pr_bh = rman_get_bushandle(res->pr_res); 1490 } else { 1491 res->pr_rid = 0; 1492 } 1493 return 0; 1494 } 1495 1496 static void 1497 acpi_pst_domain_check_nproc(device_t dev, struct acpi_pst_domain *dom) 1498 { 1499 struct acpi_pst_softc *pst; 1500 int i; 1501 1502 i = 0; 1503 LIST_FOREACH(pst, &dom->pd_pstlist, pst_link) 1504 ++i; 1505 if (i == dom->pd_nproc) { 1506 /* 1507 * Some stupid BIOSes will set wrong "# of processors", 1508 * e.g. 1 for CPU w/ hyperthreading; Be lenient here. 1509 */ 1510 if (bootverbose) { 1511 device_printf(dev, "domain%u already contains %d " 1512 "P-States\n", dom->pd_dom, dom->pd_nproc); 1513 } 1514 dom->pd_nproc++; 1515 } 1516 KKASSERT(i < dom->pd_nproc); 1517 } 1518 1519 static int 1520 acpi_pst_eval_ppc(struct acpi_pst_softc *sc, int *sstart) 1521 { 1522 ACPI_BUFFER buf; 1523 ACPI_STATUS status; 1524 ACPI_OBJECT *obj; 1525 1526 buf.Pointer = NULL; 1527 buf.Length = ACPI_ALLOCATE_BUFFER; 1528 status = AcpiEvaluateObject(sc->pst_handle, "_PPC", NULL, &buf); 1529 if (!ACPI_FAILURE(status)) { 1530 ACPI_OBJECT_LIST arglist; 1531 ACPI_OBJECT arg[2]; 1532 1533 obj = (ACPI_OBJECT *)buf.Pointer; 1534 if (obj->Type == ACPI_TYPE_INTEGER) { 1535 if (obj->Integer.Value >= acpi_npstates) { 1536 /* 1537 * Some broken BIOSes can set this 1538 * to any values; let's simply start 1539 * from the first P-state, which 1540 * should be the highest frequency 1541 * available. 1542 */ 1543 if (bootverbose) { 1544 device_printf(sc->pst_dev, 1545 "Invalid _PPC value %ju, " 1546 "npstates %d\n", 1547 (uintmax_t)obj->Integer.Value, 1548 acpi_npstates); 1549 } 1550 *sstart = 0; 1551 } else { 1552 *sstart = obj->Integer.Value; 1553 if (bootverbose) { 1554 device_printf(sc->pst_dev, "_PPC %d\n", 1555 *sstart); 1556 } 1557 } 1558 } else { 1559 device_printf(sc->pst_dev, "Invalid _PPC object\n"); 1560 AcpiOsFree(obj); 1561 return ENXIO; 1562 } 1563 1564 /* Free _PPC */ 1565 AcpiOsFree(obj); 1566 1567 /* _PPC has been successfully processed */ 1568 arglist.Pointer = arg; 1569 arglist.Count = 2; 1570 arg[0].Type = ACPI_TYPE_INTEGER; 1571 arg[0].Integer.Value = 0x80; 1572 arg[1].Type = ACPI_TYPE_INTEGER; 1573 arg[1].Integer.Value = 0; 1574 AcpiEvaluateObject(sc->pst_handle, "_OST", &arglist, NULL); 1575 1576 return 0; 1577 } 1578 return ENOENT; 1579 } 1580 1581 static int 1582 acpi_pst_eval_pdl(struct acpi_pst_softc *sc, int *scount) 1583 { 1584 ACPI_BUFFER buf; 1585 ACPI_STATUS status; 1586 ACPI_OBJECT *obj; 1587 1588 buf.Pointer = NULL; 1589 buf.Length = ACPI_ALLOCATE_BUFFER; 1590 status = AcpiEvaluateObject(sc->pst_handle, "_PDL", NULL, &buf); 1591 if (!ACPI_FAILURE(status)) { 1592 obj = (ACPI_OBJECT *)buf.Pointer; 1593 if (obj->Type == ACPI_TYPE_INTEGER) { 1594 if (obj->Integer.Value >= acpi_npstates) { 1595 device_printf(sc->pst_dev, 1596 "Invalid _PDL value\n"); 1597 AcpiOsFree(obj); 1598 return ENXIO; 1599 } 1600 if (obj->Integer.Value >= acpi_pstate_start) { 1601 *scount = obj->Integer.Value + 1; 1602 if (bootverbose) { 1603 device_printf(sc->pst_dev, "_PDL %d\n", 1604 *scount); 1605 } 1606 } else { 1607 /* Prefer _PPC as stated in ACPI 5.1 8.4.4.6 */ 1608 device_printf(sc->pst_dev, "conflict _PDL %ju " 1609 "and _PPC %d, ignore\n", 1610 (uintmax_t)obj->Integer.Value, 1611 acpi_pstate_start); 1612 } 1613 } else { 1614 device_printf(sc->pst_dev, "Invalid _PDL object\n"); 1615 AcpiOsFree(obj); 1616 return ENXIO; 1617 } 1618 1619 /* Free _PDL */ 1620 AcpiOsFree(obj); 1621 1622 return 0; 1623 } 1624 return ENOENT; 1625 } 1626 1627 /* 1628 * Notify is serialized by acpi task thread. 1629 */ 1630 static void 1631 acpi_pst_notify(device_t dev) 1632 { 1633 struct acpi_pst_softc *sc = device_get_softc(dev); 1634 boolean_t fixup = FALSE; 1635 1636 if (!acpi_pst_handle_notify) 1637 return; 1638 1639 /* 1640 * NOTE: 1641 * _PPC and _PDL evaluation order is critical. _PDL 1642 * evaluation depends on _PPC evaluation. 1643 */ 1644 if (sc->pst_flags & ACPI_PST_FLAG_PPC) { 1645 int sstart = acpi_pstate_start; 1646 1647 acpi_pst_eval_ppc(sc, &sstart); 1648 if (acpi_pstate_start != sstart && sc->pst_cpuid == 0) { 1649 acpi_pstate_start = sstart; 1650 fixup = TRUE; 1651 } 1652 } 1653 if (sc->pst_flags & ACPI_PST_FLAG_PDL) { 1654 int scount = acpi_pstate_count; 1655 1656 acpi_pst_eval_pdl(sc, &scount); 1657 if (acpi_pstate_count != scount && sc->pst_cpuid == 0) { 1658 acpi_pstate_count = scount; 1659 fixup = TRUE; 1660 } 1661 } 1662 1663 if (fixup && acpi_pst_md != NULL && 1664 acpi_pst_md->pmd_set_pstate != NULL) 1665 acpi_pst_global_fixup_pstate(); 1666 } 1667