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