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