1 /* $NetBSD: acpi.c,v 1.205 2010/07/02 05:18:38 jruoho Exp $ */ 2 3 /*- 4 * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Charles M. Hannum of By Noon Software, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright 2001, 2003 Wasabi Systems, Inc. 34 * All rights reserved. 35 * 36 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 1. Redistributions of source code must retain the above copyright 42 * notice, this list of conditions and the following disclaimer. 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 3. All advertising materials mentioning features or use of this software 47 * must display the following acknowledgement: 48 * This product includes software developed for the NetBSD Project by 49 * Wasabi Systems, Inc. 50 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 51 * or promote products derived from this software without specific prior 52 * written permission. 53 * 54 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 56 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 57 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 58 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 59 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 60 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 61 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 62 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 63 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 64 * POSSIBILITY OF SUCH DAMAGE. 65 */ 66 67 #include <sys/cdefs.h> 68 __KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.205 2010/07/02 05:18:38 jruoho Exp $"); 69 70 #include "opt_acpi.h" 71 #include "opt_pcifixup.h" 72 73 #include <sys/param.h> 74 #include <sys/device.h> 75 #include <sys/kernel.h> 76 #include <sys/malloc.h> 77 #include <sys/module.h> 78 #include <sys/mutex.h> 79 #include <sys/sysctl.h> 80 #include <sys/systm.h> 81 82 #include <dev/acpi/acpireg.h> 83 #include <dev/acpi/acpivar.h> 84 #include <dev/acpi/acpi_osd.h> 85 #include <dev/acpi/acpi_pci.h> 86 #include <dev/acpi/acpi_power.h> 87 #include <dev/acpi/acpi_timer.h> 88 #include <dev/acpi/acpi_wakedev.h> 89 90 #define _COMPONENT ACPI_BUS_COMPONENT 91 ACPI_MODULE_NAME ("acpi") 92 93 #if defined(ACPI_PCI_FIXUP) 94 #error The option ACPI_PCI_FIXUP has been obsoleted by PCI_INTR_FIXUP_DISABLED. Please adjust your kernel configuration file. 95 #endif 96 97 #ifdef PCI_INTR_FIXUP_DISABLED 98 #include <dev/pci/pcidevs.h> 99 #endif 100 101 MALLOC_DECLARE(M_ACPI); 102 103 #include <machine/acpi_machdep.h> 104 105 #ifdef ACPI_DEBUGGER 106 #define ACPI_DBGR_INIT 0x01 107 #define ACPI_DBGR_TABLES 0x02 108 #define ACPI_DBGR_ENABLE 0x04 109 #define ACPI_DBGR_PROBE 0x08 110 #define ACPI_DBGR_RUNNING 0x10 111 112 static int acpi_dbgr = 0x00; 113 #endif 114 115 /* 116 * This is a flag we set when the ACPI subsystem is active. Machine 117 * dependent code may wish to skip other steps (such as attaching 118 * subsystems that ACPI supercedes) when ACPI is active. 119 */ 120 int acpi_active; 121 int acpi_force_load; 122 int acpi_suspended = 0; 123 124 struct acpi_softc *acpi_softc; 125 static uint64_t acpi_root_pointer; 126 extern kmutex_t acpi_interrupt_list_mtx; 127 static ACPI_HANDLE acpi_scopes[4]; 128 129 /* 130 * This structure provides a context for the ACPI 131 * namespace walk performed in acpi_build_tree(). 132 */ 133 struct acpi_walkcontext { 134 struct acpi_softc *aw_sc; 135 struct acpi_devnode *aw_parent; 136 }; 137 138 /* 139 * Ignored HIDs. 140 */ 141 static const char * const acpi_ignored_ids[] = { 142 #if defined(i386) || defined(x86_64) 143 "PNP0000", /* AT interrupt controller is handled internally */ 144 "PNP0200", /* AT DMA controller is handled internally */ 145 "PNP0A??", /* PCI Busses are handled internally */ 146 "PNP0B00", /* AT RTC is handled internally */ 147 "PNP0C0B", /* No need for "ACPI fan" driver */ 148 "PNP0C0F", /* ACPI PCI link devices are handled internally */ 149 "IFX0102", /* No driver for Infineon TPM */ 150 "INT0800", /* No driver for Intel Firmware Hub device */ 151 #endif 152 #if defined(x86_64) 153 "PNP0C04", /* FPU is handled internally */ 154 #endif 155 NULL 156 }; 157 158 static int acpi_match(device_t, cfdata_t, void *); 159 static int acpi_submatch(device_t, cfdata_t, const int *, void *); 160 static void acpi_attach(device_t, device_t, void *); 161 static int acpi_detach(device_t, int); 162 static void acpi_childdet(device_t, device_t); 163 static bool acpi_suspend(device_t, const pmf_qual_t *); 164 static bool acpi_resume(device_t, const pmf_qual_t *); 165 166 static void acpi_build_tree(struct acpi_softc *); 167 static ACPI_STATUS acpi_make_devnode(ACPI_HANDLE, uint32_t, 168 void *, void **); 169 static ACPI_STATUS acpi_make_devnode_post(ACPI_HANDLE, uint32_t, 170 void *, void **); 171 172 #ifdef ACPI_ACTIVATE_DEV 173 static void acpi_activate_device(ACPI_HANDLE, ACPI_DEVICE_INFO **); 174 static ACPI_STATUS acpi_allocate_resources(ACPI_HANDLE); 175 #endif 176 177 static int acpi_rescan(device_t, const char *, const int *); 178 static void acpi_rescan_nodes(struct acpi_softc *); 179 static void acpi_rescan_capabilities(struct acpi_softc *); 180 static int acpi_print(void *aux, const char *); 181 182 static void acpi_notify_handler(ACPI_HANDLE, uint32_t, void *); 183 184 static void acpi_register_fixed_button(struct acpi_softc *, int); 185 static void acpi_deregister_fixed_button(struct acpi_softc *, int); 186 static uint32_t acpi_fixed_button_handler(void *); 187 static void acpi_fixed_button_pressed(void *); 188 189 static void acpi_sleep_init(struct acpi_softc *); 190 191 static int sysctl_hw_acpi_fixedstats(SYSCTLFN_ARGS); 192 static int sysctl_hw_acpi_sleepstate(SYSCTLFN_ARGS); 193 static int sysctl_hw_acpi_sleepstates(SYSCTLFN_ARGS); 194 195 static bool acpi_is_scope(struct acpi_devnode *); 196 static ACPI_TABLE_HEADER *acpi_map_rsdt(void); 197 static void acpi_unmap_rsdt(ACPI_TABLE_HEADER *); 198 199 extern struct cfdriver acpi_cd; 200 201 /* Handle routine vectors and loading for acpiverbose module */ 202 void acpi_null(void); 203 204 void acpi_print_devnodes_stub(struct acpi_softc *); 205 void acpi_print_tree_stub(struct acpi_devnode *, uint32_t); 206 void acpi_print_dev_stub(const char *); 207 void acpi_wmidump_stub(void *); 208 209 void (*acpi_print_devnodes)(struct acpi_softc *) = acpi_print_devnodes_stub; 210 void (*acpi_print_tree)(struct acpi_devnode *, uint32_t) = acpi_print_tree_stub; 211 void (*acpi_print_dev)(const char *) = acpi_print_dev_stub; 212 void (*acpi_wmidump)(void *) = acpi_wmidump_stub; 213 214 int acpi_verbose_loaded = 0; 215 216 /* 217 * Support for ACPIVERBOSE. 218 */ 219 void 220 acpi_null(void) 221 { 222 /* Nothing to do. */ 223 } 224 225 void 226 acpi_load_verbose(void) 227 { 228 if (acpi_verbose_loaded) 229 return; 230 231 mutex_enter(&module_lock); 232 if (module_autoload("acpiverbose", MODULE_CLASS_MISC) == 0) 233 acpi_verbose_loaded++; 234 mutex_exit(&module_lock); 235 } 236 237 void 238 acpi_print_devnodes_stub(struct acpi_softc *sc) 239 { 240 acpi_load_verbose(); 241 if (acpi_verbose_loaded) 242 acpi_print_devnodes(sc); 243 } 244 245 void 246 acpi_print_tree_stub(struct acpi_devnode *ad, uint32_t level) 247 { 248 acpi_load_verbose(); 249 if (acpi_verbose_loaded) 250 acpi_print_tree(ad, level); 251 } 252 253 void 254 acpi_print_dev_stub(const char *pnpstr) 255 { 256 acpi_load_verbose(); 257 if (acpi_verbose_loaded) 258 acpi_print_dev(pnpstr); 259 } 260 261 void 262 acpi_wmidump_stub(void *arg) 263 { 264 acpi_load_verbose(); 265 if (acpi_verbose_loaded) 266 acpi_wmidump(arg); 267 } 268 269 CFATTACH_DECL2_NEW(acpi, sizeof(struct acpi_softc), 270 acpi_match, acpi_attach, acpi_detach, NULL, acpi_rescan, acpi_childdet); 271 272 /* 273 * Probe for ACPI support. 274 * 275 * This is called by the machine-dependent ACPI front-end. 276 * Note: this is not an autoconfiguration interface function. 277 */ 278 int 279 acpi_probe(void) 280 { 281 ACPI_TABLE_HEADER *rsdt; 282 const char *func; 283 static int once; 284 bool initialized; 285 ACPI_STATUS rv; 286 287 if (once != 0) 288 panic("%s: already probed", __func__); 289 290 once = 1; 291 func = NULL; 292 initialized = false; 293 294 mutex_init(&acpi_interrupt_list_mtx, MUTEX_DEFAULT, IPL_NONE); 295 296 /* 297 * Start up ACPICA. 298 */ 299 #ifdef ACPI_DEBUGGER 300 if (acpi_dbgr & ACPI_DBGR_INIT) 301 acpi_osd_debugger(); 302 #endif 303 304 CTASSERT(TRUE == true); 305 CTASSERT(FALSE == false); 306 307 AcpiGbl_AllMethodsSerialized = false; 308 AcpiGbl_EnableInterpreterSlack = true; 309 310 rv = AcpiInitializeSubsystem(); 311 312 if (ACPI_SUCCESS(rv)) 313 initialized = true; 314 else { 315 func = "AcpiInitializeSubsystem()"; 316 goto fail; 317 } 318 319 /* 320 * Allocate space for RSDT/XSDT and DSDT, 321 * but allow resizing if more tables exist. 322 */ 323 rv = AcpiInitializeTables(NULL, 2, true); 324 325 if (ACPI_FAILURE(rv)) { 326 func = "AcpiInitializeTables()"; 327 goto fail; 328 } 329 330 #ifdef ACPI_DEBUGGER 331 if (acpi_dbgr & ACPI_DBGR_TABLES) 332 acpi_osd_debugger(); 333 #endif 334 335 rv = AcpiLoadTables(); 336 337 if (ACPI_FAILURE(rv)) { 338 func = "AcpiLoadTables()"; 339 goto fail; 340 } 341 342 rsdt = acpi_map_rsdt(); 343 344 if (rsdt == NULL) { 345 func = "acpi_map_rsdt()"; 346 rv = AE_ERROR; 347 goto fail; 348 } 349 350 if (acpi_force_load == 0 && (acpi_find_quirks() & ACPI_QUIRK_BROKEN)) { 351 aprint_normal("ACPI: BIOS is listed as broken:\n"); 352 aprint_normal("ACPI: X/RSDT: OemId <%6.6s,%8.8s,%08x>, " 353 "AslId <%4.4s,%08x>\n", 354 rsdt->OemId, rsdt->OemTableId, 355 rsdt->OemRevision, 356 rsdt->AslCompilerId, 357 rsdt->AslCompilerRevision); 358 aprint_normal("ACPI: Not used. Set acpi_force_load to use.\n"); 359 acpi_unmap_rsdt(rsdt); 360 AcpiTerminate(); 361 return 0; 362 } 363 364 acpi_unmap_rsdt(rsdt); 365 366 rv = AcpiEnableSubsystem(~(ACPI_NO_HARDWARE_INIT|ACPI_NO_ACPI_ENABLE)); 367 368 if (ACPI_FAILURE(rv)) { 369 func = "AcpiEnableSubsystem()"; 370 goto fail; 371 } 372 373 /* 374 * Looks like we have ACPI! 375 */ 376 return 1; 377 378 fail: 379 KASSERT(rv != AE_OK); 380 KASSERT(func != NULL); 381 382 aprint_error("%s: failed to probe ACPI: %s\n", 383 func, AcpiFormatException(rv)); 384 385 if (initialized != false) 386 (void)AcpiTerminate(); 387 388 return 0; 389 } 390 391 int 392 acpi_check(device_t parent, const char *ifattr) 393 { 394 return (config_search_ia(acpi_submatch, parent, ifattr, NULL) != NULL); 395 } 396 397 /* 398 * Autoconfiguration. 399 */ 400 static int 401 acpi_match(device_t parent, cfdata_t match, void *aux) 402 { 403 /* 404 * XXX: Nada; MD code has called acpi_probe(). 405 */ 406 return 1; 407 } 408 409 static int 410 acpi_submatch(device_t parent, cfdata_t cf, const int *locs, void *aux) 411 { 412 struct cfattach *ca; 413 414 ca = config_cfattach_lookup(cf->cf_name, cf->cf_atname); 415 416 return (ca == &acpi_ca); 417 } 418 419 static void 420 acpi_attach(device_t parent, device_t self, void *aux) 421 { 422 struct acpi_softc *sc = device_private(self); 423 struct acpibus_attach_args *aa = aux; 424 ACPI_TABLE_HEADER *rsdt; 425 ACPI_STATUS rv; 426 427 aprint_naive("\n"); 428 aprint_normal(": Intel ACPICA %08x\n", ACPI_CA_VERSION); 429 430 if (acpi_softc != NULL) 431 panic("%s: already attached", __func__); 432 433 rsdt = acpi_map_rsdt(); 434 435 if (rsdt == NULL) 436 aprint_error_dev(self, "X/RSDT: Not found\n"); 437 else { 438 aprint_verbose_dev(self, 439 "X/RSDT: OemId <%6.6s,%8.8s,%08x>, AslId <%4.4s,%08x>\n", 440 rsdt->OemId, rsdt->OemTableId, 441 rsdt->OemRevision, 442 rsdt->AslCompilerId, rsdt->AslCompilerRevision); 443 } 444 445 acpi_unmap_rsdt(rsdt); 446 447 sc->sc_dev = self; 448 sc->sc_root = NULL; 449 450 sc->sc_sleepstate = ACPI_STATE_S0; 451 sc->sc_quirks = acpi_find_quirks(); 452 453 sysmon_power_settype("acpi"); 454 455 sc->sc_iot = aa->aa_iot; 456 sc->sc_memt = aa->aa_memt; 457 sc->sc_pc = aa->aa_pc; 458 sc->sc_pciflags = aa->aa_pciflags; 459 sc->sc_ic = aa->aa_ic; 460 461 SIMPLEQ_INIT(&sc->ad_head); 462 463 acpi_softc = sc; 464 465 if (pmf_device_register(self, acpi_suspend, acpi_resume) != true) 466 aprint_error_dev(self, "couldn't establish power handler\n"); 467 468 /* 469 * Bring ACPI on-line. 470 */ 471 #ifdef ACPI_DEBUGGER 472 if (acpi_dbgr & ACPI_DBGR_ENABLE) 473 acpi_osd_debugger(); 474 #endif 475 476 #define ACPI_ENABLE_PHASE1 \ 477 (ACPI_NO_HANDLER_INIT | ACPI_NO_EVENT_INIT) 478 #define ACPI_ENABLE_PHASE2 \ 479 (ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE | \ 480 ACPI_NO_ADDRESS_SPACE_INIT) 481 482 rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE1); 483 484 if (ACPI_FAILURE(rv)) 485 goto fail; 486 487 acpi_md_callback(); 488 489 rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE2); 490 491 if (ACPI_FAILURE(rv)) 492 goto fail; 493 494 /* 495 * Early EC handler initialization if ECDT table is available. 496 */ 497 config_found_ia(self, "acpiecdtbus", aa, NULL); 498 499 rv = AcpiInitializeObjects(ACPI_FULL_INITIALIZATION); 500 501 if (ACPI_FAILURE(rv)) 502 goto fail; 503 504 /* 505 * Install global notify handlers. 506 */ 507 rv = AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT, 508 ACPI_SYSTEM_NOTIFY, acpi_notify_handler, NULL); 509 510 if (ACPI_FAILURE(rv)) 511 goto fail; 512 513 rv = AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT, 514 ACPI_DEVICE_NOTIFY, acpi_notify_handler, NULL); 515 516 if (ACPI_FAILURE(rv)) 517 goto fail; 518 519 acpi_active = 1; 520 521 /* Show SCI interrupt. */ 522 aprint_verbose_dev(self, "SCI interrupting at int %u\n", 523 AcpiGbl_FADT.SciInterrupt); 524 525 /* 526 * Install fixed-event handlers. 527 */ 528 acpi_register_fixed_button(sc, ACPI_EVENT_POWER_BUTTON); 529 acpi_register_fixed_button(sc, ACPI_EVENT_SLEEP_BUTTON); 530 531 acpitimer_init(); 532 533 #ifdef ACPI_DEBUGGER 534 if (acpi_dbgr & ACPI_DBGR_PROBE) 535 acpi_osd_debugger(); 536 #endif 537 538 /* 539 * Scan the namespace and build our device tree. 540 */ 541 acpi_build_tree(sc); 542 acpi_sleep_init(sc); 543 544 #ifdef ACPI_DEBUGGER 545 if (acpi_dbgr & ACPI_DBGR_RUNNING) 546 acpi_osd_debugger(); 547 #endif 548 549 #ifdef ACPI_DEBUG 550 acpi_debug_init(); 551 #endif 552 553 return; 554 555 fail: 556 KASSERT(rv != AE_OK); 557 558 aprint_error("%s: failed to initialize ACPI: %s\n", 559 __func__, AcpiFormatException(rv)); 560 } 561 562 /* 563 * XXX: This is incomplete. 564 */ 565 static int 566 acpi_detach(device_t self, int flags) 567 { 568 struct acpi_softc *sc = device_private(self); 569 ACPI_STATUS rv; 570 int rc; 571 572 rv = AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT, 573 ACPI_SYSTEM_NOTIFY, acpi_notify_handler); 574 575 if (ACPI_FAILURE(rv)) 576 return EBUSY; 577 578 rv = AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT, 579 ACPI_DEVICE_NOTIFY, acpi_notify_handler); 580 581 if (ACPI_FAILURE(rv)) 582 return EBUSY; 583 584 if ((rc = config_detach_children(self, flags)) != 0) 585 return rc; 586 587 if ((rc = acpitimer_detach()) != 0) 588 return rc; 589 590 acpi_deregister_fixed_button(sc, ACPI_EVENT_POWER_BUTTON); 591 acpi_deregister_fixed_button(sc, ACPI_EVENT_SLEEP_BUTTON); 592 593 pmf_device_deregister(self); 594 595 acpi_softc = NULL; 596 597 return 0; 598 } 599 600 /* 601 * XXX: Need to reclaim any resources? Yes. 602 */ 603 static void 604 acpi_childdet(device_t self, device_t child) 605 { 606 struct acpi_softc *sc = device_private(self); 607 struct acpi_devnode *ad; 608 609 if (sc->sc_apmbus == child) 610 sc->sc_apmbus = NULL; 611 612 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) { 613 614 if (ad->ad_device == child) 615 ad->ad_device = NULL; 616 } 617 } 618 619 static bool 620 acpi_suspend(device_t dv, const pmf_qual_t *qual) 621 { 622 623 acpi_suspended = 1; 624 625 return true; 626 } 627 628 static bool 629 acpi_resume(device_t dv, const pmf_qual_t *qual) 630 { 631 632 acpi_suspended = 0; 633 634 return true; 635 } 636 637 /* 638 * Namespace scan. 639 */ 640 static void 641 acpi_build_tree(struct acpi_softc *sc) 642 { 643 struct acpi_walkcontext awc; 644 645 /* 646 * Get the root scope handles. 647 */ 648 KASSERT(__arraycount(acpi_scopes) == 4); 649 650 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_PR_", &acpi_scopes[0]); 651 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SB_", &acpi_scopes[1]); 652 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SI_", &acpi_scopes[2]); 653 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_TZ_", &acpi_scopes[3]); 654 655 /* 656 * Make the root node. 657 */ 658 awc.aw_sc = sc; 659 awc.aw_parent = NULL; 660 661 (void)acpi_make_devnode(ACPI_ROOT_OBJECT, 0, &awc, NULL); 662 663 KASSERT(sc->sc_root == NULL); 664 KASSERT(awc.aw_parent != NULL); 665 666 sc->sc_root = awc.aw_parent; 667 668 /* 669 * Build the internal namespace. 670 */ 671 (void)AcpiWalkNamespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, UINT32_MAX, 672 acpi_make_devnode, acpi_make_devnode_post, &awc, NULL); 673 674 /* 675 * Scan the internal namespace. 676 */ 677 (void)acpi_rescan(sc->sc_dev, NULL, NULL); 678 679 acpi_rescan_capabilities(sc); 680 681 (void)acpi_pcidev_scan(sc->sc_root); 682 683 acpi_print_devnodes(sc); 684 acpi_print_tree(sc->sc_root, 0); 685 } 686 687 static ACPI_STATUS 688 acpi_make_devnode(ACPI_HANDLE handle, uint32_t level, 689 void *context, void **status) 690 { 691 struct acpi_walkcontext *awc = context; 692 struct acpi_softc *sc = awc->aw_sc; 693 struct acpi_devnode *ad; 694 ACPI_DEVICE_INFO *devinfo; 695 ACPI_OBJECT_TYPE type; 696 ACPI_NAME_UNION *anu; 697 ACPI_STATUS rv; 698 int clear, i; 699 700 rv = AcpiGetObjectInfo(handle, &devinfo); 701 702 if (ACPI_FAILURE(rv)) 703 return AE_OK; /* Do not terminate the walk. */ 704 705 type = devinfo->Type; 706 707 switch (type) { 708 709 case ACPI_TYPE_DEVICE: 710 711 #ifdef ACPI_ACTIVATE_DEV 712 acpi_activate_device(handle, &devinfo); 713 #endif 714 715 case ACPI_TYPE_PROCESSOR: 716 case ACPI_TYPE_THERMAL: 717 case ACPI_TYPE_POWER: 718 719 ad = malloc(sizeof(*ad), M_ACPI, M_NOWAIT | M_ZERO); 720 721 if (ad == NULL) 722 return AE_NO_MEMORY; 723 724 ad->ad_device = NULL; 725 ad->ad_notify = NULL; 726 ad->ad_pciinfo = NULL; 727 728 ad->ad_type = type; 729 ad->ad_handle = handle; 730 ad->ad_devinfo = devinfo; 731 732 ad->ad_root = sc->sc_dev; 733 ad->ad_parent = awc->aw_parent; 734 735 anu = (ACPI_NAME_UNION *)&devinfo->Name; 736 ad->ad_name[4] = '\0'; 737 738 for (i = 3, clear = 0; i >= 0; i--) { 739 740 if (clear == 0 && anu->Ascii[i] == '_') 741 ad->ad_name[i] = '\0'; 742 else { 743 ad->ad_name[i] = anu->Ascii[i]; 744 clear = 1; 745 } 746 } 747 748 if (ad->ad_name[0] == '\0') 749 ad->ad_name[0] = '_'; 750 751 SIMPLEQ_INIT(&ad->ad_child_head); 752 SIMPLEQ_INSERT_TAIL(&sc->ad_head, ad, ad_list); 753 754 acpi_set_node(ad); 755 756 if (ad->ad_parent != NULL) { 757 758 SIMPLEQ_INSERT_TAIL(&ad->ad_parent->ad_child_head, 759 ad, ad_child_list); 760 } 761 762 awc->aw_parent = ad; 763 } 764 765 return AE_OK; 766 } 767 768 static ACPI_STATUS 769 acpi_make_devnode_post(ACPI_HANDLE handle, uint32_t level, 770 void *context, void **status) 771 { 772 struct acpi_walkcontext *awc = context; 773 774 KASSERT(awc != NULL); 775 KASSERT(awc->aw_parent != NULL); 776 777 if (handle == awc->aw_parent->ad_handle) 778 awc->aw_parent = awc->aw_parent->ad_parent; 779 780 return AE_OK; 781 } 782 783 #ifdef ACPI_ACTIVATE_DEV 784 static void 785 acpi_activate_device(ACPI_HANDLE handle, ACPI_DEVICE_INFO **di) 786 { 787 static const int valid = ACPI_VALID_STA | ACPI_VALID_HID; 788 ACPI_DEVICE_INFO *newdi; 789 ACPI_STATUS rv; 790 uint32_t old; 791 792 /* 793 * If the device is valid and present, 794 * but not enabled, try to activate it. 795 */ 796 if (((*di)->Valid & valid) != valid) 797 return; 798 799 old = (*di)->CurrentStatus; 800 801 if ((old & (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED)) != 802 ACPI_STA_DEVICE_PRESENT) 803 return; 804 805 rv = acpi_allocate_resources(handle); 806 807 if (ACPI_FAILURE(rv)) 808 goto fail; 809 810 rv = AcpiGetObjectInfo(handle, &newdi); 811 812 if (ACPI_FAILURE(rv)) 813 goto fail; 814 815 ACPI_FREE(*di); 816 *di = newdi; 817 818 aprint_verbose_dev(acpi_softc->sc_dev, 819 "%s activated, STA 0x%08X -> STA 0x%08X\n", 820 (*di)->HardwareId.String, old, (*di)->CurrentStatus); 821 822 return; 823 824 fail: 825 aprint_error_dev(acpi_softc->sc_dev, "failed to " 826 "activate %s\n", (*di)->HardwareId.String); 827 } 828 829 /* 830 * XXX: This very incomplete. 831 */ 832 ACPI_STATUS 833 acpi_allocate_resources(ACPI_HANDLE handle) 834 { 835 ACPI_BUFFER bufp, bufc, bufn; 836 ACPI_RESOURCE *resp, *resc, *resn; 837 ACPI_RESOURCE_IRQ *irq; 838 ACPI_RESOURCE_EXTENDED_IRQ *xirq; 839 ACPI_STATUS rv; 840 uint delta; 841 842 rv = acpi_get(handle, &bufp, AcpiGetPossibleResources); 843 if (ACPI_FAILURE(rv)) 844 goto out; 845 rv = acpi_get(handle, &bufc, AcpiGetCurrentResources); 846 if (ACPI_FAILURE(rv)) { 847 goto out1; 848 } 849 850 bufn.Length = 1000; 851 bufn.Pointer = resn = malloc(bufn.Length, M_ACPI, M_WAITOK); 852 resp = bufp.Pointer; 853 resc = bufc.Pointer; 854 while (resc->Type != ACPI_RESOURCE_TYPE_END_TAG && 855 resp->Type != ACPI_RESOURCE_TYPE_END_TAG) { 856 while (resc->Type != resp->Type && resp->Type != ACPI_RESOURCE_TYPE_END_TAG) 857 resp = ACPI_NEXT_RESOURCE(resp); 858 if (resp->Type == ACPI_RESOURCE_TYPE_END_TAG) 859 break; 860 /* Found identical Id */ 861 resn->Type = resc->Type; 862 switch (resc->Type) { 863 case ACPI_RESOURCE_TYPE_IRQ: 864 memcpy(&resn->Data, &resp->Data, 865 sizeof(ACPI_RESOURCE_IRQ)); 866 irq = (ACPI_RESOURCE_IRQ *)&resn->Data; 867 irq->Interrupts[0] = 868 ((ACPI_RESOURCE_IRQ *)&resp->Data)-> 869 Interrupts[irq->InterruptCount-1]; 870 irq->InterruptCount = 1; 871 resn->Length = ACPI_RS_SIZE(ACPI_RESOURCE_IRQ); 872 break; 873 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 874 memcpy(&resn->Data, &resp->Data, 875 sizeof(ACPI_RESOURCE_EXTENDED_IRQ)); 876 xirq = (ACPI_RESOURCE_EXTENDED_IRQ *)&resn->Data; 877 #if 0 878 /* 879 * XXX: Not duplicating the interrupt logic above 880 * because its not clear what it accomplishes. 881 */ 882 xirq->Interrupts[0] = 883 ((ACPI_RESOURCE_EXT_IRQ *)&resp->Data)-> 884 Interrupts[irq->NumberOfInterrupts-1]; 885 xirq->NumberOfInterrupts = 1; 886 #endif 887 resn->Length = ACPI_RS_SIZE(ACPI_RESOURCE_EXTENDED_IRQ); 888 break; 889 case ACPI_RESOURCE_TYPE_IO: 890 memcpy(&resn->Data, &resp->Data, 891 sizeof(ACPI_RESOURCE_IO)); 892 resn->Length = resp->Length; 893 break; 894 default: 895 aprint_error_dev(acpi_softc->sc_dev, 896 "%s: invalid type %u\n", __func__, resc->Type); 897 rv = AE_BAD_DATA; 898 goto out2; 899 } 900 resc = ACPI_NEXT_RESOURCE(resc); 901 resn = ACPI_NEXT_RESOURCE(resn); 902 resp = ACPI_NEXT_RESOURCE(resp); 903 delta = (uint8_t *)resn - (uint8_t *)bufn.Pointer; 904 if (delta >= 905 bufn.Length-ACPI_RS_SIZE(ACPI_RESOURCE_DATA)) { 906 bufn.Length *= 2; 907 bufn.Pointer = realloc(bufn.Pointer, bufn.Length, 908 M_ACPI, M_WAITOK); 909 resn = (ACPI_RESOURCE *)((uint8_t *)bufn.Pointer + 910 delta); 911 } 912 } 913 914 if (resc->Type != ACPI_RESOURCE_TYPE_END_TAG) { 915 aprint_error_dev(acpi_softc->sc_dev, 916 "%s: resc not exhausted\n", __func__); 917 rv = AE_BAD_DATA; 918 goto out3; 919 } 920 921 resn->Type = ACPI_RESOURCE_TYPE_END_TAG; 922 rv = AcpiSetCurrentResources(handle, &bufn); 923 924 if (ACPI_FAILURE(rv)) 925 aprint_error_dev(acpi_softc->sc_dev, "%s: failed to set " 926 "resources: %s\n", __func__, AcpiFormatException(rv)); 927 928 out3: 929 free(bufn.Pointer, M_ACPI); 930 out2: 931 ACPI_FREE(bufc.Pointer); 932 out1: 933 ACPI_FREE(bufp.Pointer); 934 out: 935 return rv; 936 } 937 #endif /* ACPI_ACTIVATE_DEV */ 938 939 /* 940 * Device attachment. 941 */ 942 static int 943 acpi_rescan(device_t self, const char *ifattr, const int *locators) 944 { 945 struct acpi_softc *sc = device_private(self); 946 947 if (ifattr_match(ifattr, "acpinodebus")) 948 acpi_rescan_nodes(sc); 949 950 if (ifattr_match(ifattr, "acpiapmbus") && sc->sc_apmbus == NULL) 951 sc->sc_apmbus = config_found_ia(sc->sc_dev, 952 "acpiapmbus", NULL, NULL); 953 954 return 0; 955 } 956 957 static void 958 acpi_rescan_nodes(struct acpi_softc *sc) 959 { 960 struct acpi_attach_args aa; 961 struct acpi_devnode *ad; 962 ACPI_DEVICE_INFO *di; 963 964 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) { 965 966 if (ad->ad_device != NULL) 967 continue; 968 969 /* 970 * There is a bug in ACPICA: it defines the type 971 * of the scopes incorrectly for its own reasons. 972 */ 973 if (acpi_is_scope(ad) != false) 974 continue; 975 976 di = ad->ad_devinfo; 977 978 /* 979 * We only attach devices which are present, enabled, and 980 * functioning properly. However, if a device is enabled, 981 * it is decoding resources and we should claim these, 982 * if possible. This requires changes to bus_space(9). 983 */ 984 if (di->Type == ACPI_TYPE_DEVICE) { 985 986 if ((di->Valid & ACPI_VALID_STA) != 0 && 987 (di->CurrentStatus & ACPI_STA_OK) != ACPI_STA_OK) 988 continue; 989 } 990 991 /* 992 * The same problem as above. As for example 993 * thermal zones and power resources do not 994 * have a valid HID, only evaluate devices. 995 */ 996 if (di->Type == ACPI_TYPE_DEVICE && 997 (di->Valid & ACPI_VALID_HID) == 0) 998 continue; 999 1000 /* 1001 * Handled internally. 1002 */ 1003 if (di->Type == ACPI_TYPE_POWER || 1004 di->Type == ACPI_TYPE_PROCESSOR) 1005 continue; 1006 1007 /* 1008 * Skip ignored HIDs. 1009 */ 1010 if (acpi_match_hid(di, acpi_ignored_ids)) 1011 continue; 1012 1013 aa.aa_node = ad; 1014 aa.aa_iot = sc->sc_iot; 1015 aa.aa_memt = sc->sc_memt; 1016 aa.aa_pc = sc->sc_pc; 1017 aa.aa_pciflags = sc->sc_pciflags; 1018 aa.aa_ic = sc->sc_ic; 1019 1020 ad->ad_device = config_found_ia(sc->sc_dev, 1021 "acpinodebus", &aa, acpi_print); 1022 } 1023 } 1024 1025 static void 1026 acpi_rescan_capabilities(struct acpi_softc *sc) 1027 { 1028 struct acpi_devnode *ad; 1029 ACPI_HANDLE tmp; 1030 ACPI_STATUS rv; 1031 1032 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) { 1033 1034 if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE) 1035 continue; 1036 1037 /* 1038 * Scan power resource capabilities. 1039 * 1040 * If any power states are supported, 1041 * at least _PR0 and _PR3 must be present. 1042 */ 1043 rv = AcpiGetHandle(ad->ad_handle, "_PR0", &tmp); 1044 1045 if (ACPI_SUCCESS(rv)) { 1046 ad->ad_flags |= ACPI_DEVICE_POWER; 1047 acpi_power_add(ad); 1048 } 1049 1050 /* 1051 * Scan wake-up capabilities. 1052 */ 1053 rv = AcpiGetHandle(ad->ad_handle, "_PRW", &tmp); 1054 1055 if (ACPI_SUCCESS(rv)) { 1056 ad->ad_flags |= ACPI_DEVICE_WAKEUP; 1057 acpi_wakedev_add(ad); 1058 } 1059 } 1060 } 1061 1062 static int 1063 acpi_print(void *aux, const char *pnp) 1064 { 1065 struct acpi_attach_args *aa = aux; 1066 ACPI_STATUS rv; 1067 1068 if (pnp) { 1069 if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_HID) { 1070 char *pnpstr = 1071 aa->aa_node->ad_devinfo->HardwareId.String; 1072 ACPI_BUFFER buf; 1073 1074 aprint_normal("%s (%s) ", aa->aa_node->ad_name, 1075 pnpstr); 1076 1077 rv = acpi_eval_struct(aa->aa_node->ad_handle, 1078 "_STR", &buf); 1079 if (ACPI_SUCCESS(rv)) { 1080 ACPI_OBJECT *obj = buf.Pointer; 1081 switch (obj->Type) { 1082 case ACPI_TYPE_STRING: 1083 aprint_normal("[%s] ", obj->String.Pointer); 1084 break; 1085 case ACPI_TYPE_BUFFER: 1086 aprint_normal("buffer %p ", obj->Buffer.Pointer); 1087 break; 1088 default: 1089 aprint_normal("type %u ",obj->Type); 1090 break; 1091 } 1092 ACPI_FREE(buf.Pointer); 1093 } 1094 else 1095 acpi_print_dev(pnpstr); 1096 1097 aprint_normal("at %s", pnp); 1098 } else if (aa->aa_node->ad_devinfo->Type != ACPI_TYPE_DEVICE) { 1099 aprint_normal("%s (ACPI Object Type '%s' " 1100 "[0x%02x]) ", aa->aa_node->ad_name, 1101 AcpiUtGetTypeName(aa->aa_node->ad_devinfo->Type), 1102 aa->aa_node->ad_devinfo->Type); 1103 aprint_normal("at %s", pnp); 1104 } else 1105 return 0; 1106 } else { 1107 aprint_normal(" (%s", aa->aa_node->ad_name); 1108 if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_HID) { 1109 aprint_normal(", %s", aa->aa_node->ad_devinfo->HardwareId.String); 1110 if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_UID) { 1111 const char *uid; 1112 1113 uid = aa->aa_node->ad_devinfo->UniqueId.String; 1114 if (uid[0] == '\0') 1115 uid = "<null>"; 1116 aprint_normal("-%s", uid); 1117 } 1118 } 1119 aprint_normal(")"); 1120 } 1121 1122 return UNCONF; 1123 } 1124 1125 /* 1126 * Notify. 1127 */ 1128 static void 1129 acpi_notify_handler(ACPI_HANDLE handle, uint32_t event, void *aux) 1130 { 1131 struct acpi_softc *sc = acpi_softc; 1132 struct acpi_devnode *ad; 1133 1134 KASSERT(sc != NULL); 1135 KASSERT(aux == NULL); 1136 KASSERT(acpi_active != 0); 1137 1138 if (acpi_suspended != 0) 1139 return; 1140 1141 /* 1142 * System: 0x00 - 0x7F. 1143 * Device: 0x80 - 0xFF. 1144 */ 1145 switch (event) { 1146 1147 case ACPI_NOTIFY_BUS_CHECK: 1148 case ACPI_NOTIFY_DEVICE_CHECK: 1149 case ACPI_NOTIFY_DEVICE_WAKE: 1150 case ACPI_NOTIFY_EJECT_REQUEST: 1151 case ACPI_NOTIFY_DEVICE_CHECK_LIGHT: 1152 case ACPI_NOTIFY_FREQUENCY_MISMATCH: 1153 case ACPI_NOTIFY_BUS_MODE_MISMATCH: 1154 case ACPI_NOTIFY_POWER_FAULT: 1155 case ACPI_NOTIFY_CAPABILITIES_CHECK: 1156 case ACPI_NOTIFY_DEVICE_PLD_CHECK: 1157 case ACPI_NOTIFY_RESERVED: 1158 case ACPI_NOTIFY_LOCALITY_UPDATE: 1159 break; 1160 } 1161 1162 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "notification 0x%02X for " 1163 "%s (%p)\n", event, acpi_name(handle), handle)); 1164 1165 /* 1166 * We deliver notifications only to drivers 1167 * that have been succesfully attached and 1168 * that have registered a handler with us. 1169 * The opaque pointer is always the device_t. 1170 */ 1171 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) { 1172 1173 if (ad->ad_device == NULL) 1174 continue; 1175 1176 if (ad->ad_notify == NULL) 1177 continue; 1178 1179 if (ad->ad_handle != handle) 1180 continue; 1181 1182 (*ad->ad_notify)(ad->ad_handle, event, ad->ad_device); 1183 1184 return; 1185 } 1186 1187 aprint_debug_dev(sc->sc_dev, "unhandled notify 0x%02X " 1188 "for %s (%p)\n", event, acpi_name(handle), handle); 1189 } 1190 1191 bool 1192 acpi_register_notify(struct acpi_devnode *ad, ACPI_NOTIFY_HANDLER notify) 1193 { 1194 struct acpi_softc *sc = acpi_softc; 1195 1196 KASSERT(sc != NULL); 1197 KASSERT(acpi_active != 0); 1198 1199 if (acpi_suspended != 0) 1200 goto fail; 1201 1202 if (ad == NULL || notify == NULL) 1203 goto fail; 1204 1205 ad->ad_notify = notify; 1206 1207 return true; 1208 1209 fail: 1210 aprint_error_dev(sc->sc_dev, "failed to register notify " 1211 "handler for %s (%p)\n", ad->ad_name, ad->ad_handle); 1212 1213 return false; 1214 } 1215 1216 void 1217 acpi_deregister_notify(struct acpi_devnode *ad) 1218 { 1219 1220 ad->ad_notify = NULL; 1221 } 1222 1223 /* 1224 * Fixed buttons. 1225 */ 1226 static void 1227 acpi_register_fixed_button(struct acpi_softc *sc, int event) 1228 { 1229 struct sysmon_pswitch *smpsw; 1230 ACPI_STATUS rv; 1231 int type; 1232 1233 switch (event) { 1234 1235 case ACPI_EVENT_POWER_BUTTON: 1236 1237 if ((AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON) != 0) 1238 return; 1239 1240 type = PSWITCH_TYPE_POWER; 1241 smpsw = &sc->sc_smpsw_power; 1242 break; 1243 1244 case ACPI_EVENT_SLEEP_BUTTON: 1245 1246 if ((AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON) != 0) 1247 return; 1248 1249 type = PSWITCH_TYPE_SLEEP; 1250 smpsw = &sc->sc_smpsw_sleep; 1251 break; 1252 1253 default: 1254 rv = AE_TYPE; 1255 goto fail; 1256 } 1257 1258 smpsw->smpsw_type = type; 1259 smpsw->smpsw_name = device_xname(sc->sc_dev); 1260 1261 if (sysmon_pswitch_register(smpsw) != 0) { 1262 rv = AE_ERROR; 1263 goto fail; 1264 } 1265 1266 rv = AcpiInstallFixedEventHandler(event, 1267 acpi_fixed_button_handler, smpsw); 1268 1269 if (ACPI_FAILURE(rv)) { 1270 sysmon_pswitch_unregister(smpsw); 1271 goto fail; 1272 } 1273 1274 aprint_debug_dev(sc->sc_dev, "fixed %s button present\n", 1275 (type != ACPI_EVENT_SLEEP_BUTTON) ? "power" : "sleep"); 1276 1277 return; 1278 1279 fail: 1280 aprint_error_dev(sc->sc_dev, "failed to register " 1281 "fixed event: %s\n", AcpiFormatException(rv)); 1282 } 1283 1284 static void 1285 acpi_deregister_fixed_button(struct acpi_softc *sc, int event) 1286 { 1287 struct sysmon_pswitch *smpsw; 1288 ACPI_STATUS rv; 1289 1290 switch (event) { 1291 1292 case ACPI_EVENT_POWER_BUTTON: 1293 smpsw = &sc->sc_smpsw_power; 1294 1295 if ((AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON) != 0) { 1296 KASSERT(smpsw->smpsw_type != PSWITCH_TYPE_POWER); 1297 return; 1298 } 1299 1300 break; 1301 1302 case ACPI_EVENT_SLEEP_BUTTON: 1303 smpsw = &sc->sc_smpsw_sleep; 1304 1305 if ((AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON) != 0) { 1306 KASSERT(smpsw->smpsw_type != PSWITCH_TYPE_SLEEP); 1307 return; 1308 } 1309 1310 break; 1311 1312 default: 1313 rv = AE_TYPE; 1314 goto fail; 1315 } 1316 1317 rv = AcpiRemoveFixedEventHandler(event, acpi_fixed_button_handler); 1318 1319 if (ACPI_SUCCESS(rv)) { 1320 sysmon_pswitch_unregister(smpsw); 1321 return; 1322 } 1323 1324 fail: 1325 aprint_error_dev(sc->sc_dev, "failed to deregister " 1326 "fixed event: %s\n", AcpiFormatException(rv)); 1327 } 1328 1329 static uint32_t 1330 acpi_fixed_button_handler(void *context) 1331 { 1332 static const int handler = OSL_NOTIFY_HANDLER; 1333 struct sysmon_pswitch *smpsw = context; 1334 1335 (void)AcpiOsExecute(handler, acpi_fixed_button_pressed, smpsw); 1336 1337 return ACPI_INTERRUPT_HANDLED; 1338 } 1339 1340 static void 1341 acpi_fixed_button_pressed(void *context) 1342 { 1343 struct sysmon_pswitch *smpsw = context; 1344 1345 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s fixed button pressed\n", 1346 (smpsw->smpsw_type != ACPI_EVENT_SLEEP_BUTTON) ? 1347 "power" : "sleep")); 1348 1349 sysmon_pswitch_event(smpsw, PSWITCH_EVENT_PRESSED); 1350 } 1351 1352 /* 1353 * Sleep. 1354 */ 1355 static void 1356 acpi_sleep_init(struct acpi_softc *sc) 1357 { 1358 uint8_t a, b, i; 1359 ACPI_STATUS rv; 1360 1361 CTASSERT(ACPI_STATE_S0 == 0 && ACPI_STATE_S1 == 1); 1362 CTASSERT(ACPI_STATE_S2 == 2 && ACPI_STATE_S3 == 3); 1363 CTASSERT(ACPI_STATE_S4 == 4 && ACPI_STATE_S5 == 5); 1364 1365 /* 1366 * Evaluate supported sleep states. 1367 */ 1368 for (i = ACPI_STATE_S0; i <= ACPI_STATE_S5; i++) { 1369 1370 rv = AcpiGetSleepTypeData(i, &a, &b); 1371 1372 if (ACPI_SUCCESS(rv)) 1373 sc->sc_sleepstates |= __BIT(i); 1374 } 1375 } 1376 1377 void 1378 acpi_enter_sleep_state(struct acpi_softc *sc, int state) 1379 { 1380 ACPI_STATUS rv; 1381 int err; 1382 1383 if (state == sc->sc_sleepstate) 1384 return; 1385 1386 aprint_normal_dev(sc->sc_dev, "entering state S%d\n", state); 1387 1388 switch (state) { 1389 1390 case ACPI_STATE_S0: 1391 sc->sc_sleepstate = ACPI_STATE_S0; 1392 return; 1393 1394 case ACPI_STATE_S1: 1395 case ACPI_STATE_S2: 1396 case ACPI_STATE_S3: 1397 case ACPI_STATE_S4: 1398 1399 if ((sc->sc_sleepstates & __BIT(state)) == 0) { 1400 aprint_error_dev(sc->sc_dev, "sleep state " 1401 "S%d is not available\n", state); 1402 return; 1403 } 1404 1405 /* 1406 * Evaluate the _TTS method. This should be done before 1407 * pmf_system_suspend(9) and the evaluation of _PTS. 1408 * We should also re-evaluate this once we return to 1409 * S0 or if we abort the sleep state transition in the 1410 * middle (see ACPI 3.0, section 7.3.6). In reality, 1411 * however, the _TTS method is seldom seen in the field. 1412 */ 1413 rv = acpi_eval_set_integer(NULL, "\\_TTS", state); 1414 1415 if (ACPI_SUCCESS(rv)) 1416 aprint_debug_dev(sc->sc_dev, "evaluated _TTS\n"); 1417 1418 if (state != ACPI_STATE_S1 && 1419 pmf_system_suspend(PMF_Q_NONE) != true) { 1420 aprint_error_dev(sc->sc_dev, "aborting suspend\n"); 1421 break; 1422 } 1423 1424 /* 1425 * This will evaluate the _PTS and _SST methods, 1426 * but unlike the documentation claims, not _GTS, 1427 * which is evaluated in AcpiEnterSleepState(). 1428 * This must be called with interrupts enabled. 1429 */ 1430 rv = AcpiEnterSleepStatePrep(state); 1431 1432 if (ACPI_FAILURE(rv)) { 1433 aprint_error_dev(sc->sc_dev, "failed to prepare " 1434 "S%d: %s\n", state, AcpiFormatException(rv)); 1435 break; 1436 } 1437 1438 /* 1439 * After the _PTS method has been evaluated, we can 1440 * enable wake and evaluate _PSW (ACPI 4.0, p. 284). 1441 */ 1442 acpi_wakedev_commit(sc, state); 1443 1444 sc->sc_sleepstate = state; 1445 1446 if (state == ACPI_STATE_S1) { 1447 1448 /* Just enter the state. */ 1449 acpi_md_OsDisableInterrupt(); 1450 rv = AcpiEnterSleepState(state); 1451 1452 if (ACPI_FAILURE(rv)) 1453 aprint_error_dev(sc->sc_dev, "failed to " 1454 "enter S1: %s\n", AcpiFormatException(rv)); 1455 1456 (void)AcpiLeaveSleepState(state); 1457 1458 } else { 1459 1460 err = acpi_md_sleep(state); 1461 1462 if (state == ACPI_STATE_S4) 1463 AcpiEnable(); 1464 1465 pmf_system_bus_resume(PMF_Q_NONE); 1466 (void)AcpiLeaveSleepState(state); 1467 pmf_system_resume(PMF_Q_NONE); 1468 } 1469 1470 break; 1471 1472 case ACPI_STATE_S5: 1473 1474 (void)acpi_eval_set_integer(NULL, "\\_TTS", ACPI_STATE_S5); 1475 1476 rv = AcpiEnterSleepStatePrep(ACPI_STATE_S5); 1477 1478 if (ACPI_FAILURE(rv)) { 1479 aprint_error_dev(sc->sc_dev, "failed to prepare " 1480 "S%d: %s\n", state, AcpiFormatException(rv)); 1481 break; 1482 } 1483 1484 DELAY(1000000); 1485 1486 sc->sc_sleepstate = state; 1487 acpi_md_OsDisableInterrupt(); 1488 1489 (void)AcpiEnterSleepState(ACPI_STATE_S5); 1490 1491 aprint_error_dev(sc->sc_dev, "WARNING: powerdown failed!\n"); 1492 1493 break; 1494 } 1495 1496 sc->sc_sleepstate = ACPI_STATE_S0; 1497 1498 (void)acpi_eval_set_integer(NULL, "\\_TTS", ACPI_STATE_S0); 1499 } 1500 1501 /* 1502 * Sysctl. 1503 */ 1504 SYSCTL_SETUP(sysctl_acpi_setup, "sysctl hw.acpi subtree setup") 1505 { 1506 const struct sysctlnode *mnode, *rnode; 1507 int err; 1508 1509 err = sysctl_createv(clog, 0, NULL, &rnode, 1510 CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", 1511 NULL, NULL, 0, NULL, 0, 1512 CTL_HW, CTL_EOL); 1513 1514 if (err != 0) 1515 return; 1516 1517 err = sysctl_createv(clog, 0, &rnode, &rnode, 1518 CTLFLAG_PERMANENT, CTLTYPE_NODE, 1519 "acpi", SYSCTL_DESCR("ACPI subsystem parameters"), 1520 NULL, 0, NULL, 0, 1521 CTL_CREATE, CTL_EOL); 1522 1523 if (err != 0) 1524 return; 1525 1526 (void)sysctl_createv(NULL, 0, &rnode, NULL, 1527 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD, 1528 "root", SYSCTL_DESCR("ACPI root pointer"), 1529 NULL, 0, &acpi_root_pointer, sizeof(acpi_root_pointer), 1530 CTL_CREATE, CTL_EOL); 1531 1532 (void)sysctl_createv(NULL, 0, &rnode, NULL, 1533 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_STRING, 1534 "supported_states", SYSCTL_DESCR("Supported system states"), 1535 sysctl_hw_acpi_sleepstates, 0, NULL, 0, 1536 CTL_CREATE, CTL_EOL); 1537 1538 err = sysctl_createv(NULL, 0, NULL, &mnode, 1539 CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", 1540 NULL, NULL, 0, NULL, 0, 1541 CTL_MACHDEP, CTL_EOL); 1542 1543 if (err == 0) { 1544 1545 (void)sysctl_createv(NULL, 0, &mnode, NULL, 1546 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, 1547 "sleep_state", SYSCTL_DESCR("System sleep state"), 1548 sysctl_hw_acpi_sleepstate, 0, NULL, 0, 1549 CTL_CREATE, CTL_EOL); 1550 } 1551 1552 err = sysctl_createv(clog, 0, &rnode, &rnode, 1553 CTLFLAG_PERMANENT, CTLTYPE_NODE, 1554 "stat", SYSCTL_DESCR("ACPI statistics"), 1555 NULL, 0, NULL, 0, 1556 CTL_CREATE, CTL_EOL); 1557 1558 if (err != 0) 1559 return; 1560 1561 (void)sysctl_createv(clog, 0, &rnode, NULL, 1562 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD, 1563 "gpe", SYSCTL_DESCR("Number of dispatched GPEs"), 1564 NULL, 0, &AcpiGpeCount, sizeof(AcpiGpeCount), 1565 CTL_CREATE, CTL_EOL); 1566 1567 (void)sysctl_createv(clog, 0, &rnode, NULL, 1568 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD, 1569 "sci", SYSCTL_DESCR("Number of SCI interrupts"), 1570 NULL, 0, &AcpiSciCount, sizeof(AcpiSciCount), 1571 CTL_CREATE, CTL_EOL); 1572 1573 (void)sysctl_createv(clog, 0, &rnode, NULL, 1574 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD, 1575 "fixed", SYSCTL_DESCR("Number of fixed events"), 1576 sysctl_hw_acpi_fixedstats, 0, NULL, 0, 1577 CTL_CREATE, CTL_EOL); 1578 1579 (void)sysctl_createv(clog, 0, &rnode, NULL, 1580 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD, 1581 "method", SYSCTL_DESCR("Number of methods executed"), 1582 NULL, 0, &AcpiMethodCount, sizeof(AcpiMethodCount), 1583 CTL_CREATE, CTL_EOL); 1584 1585 CTASSERT(sizeof(AcpiGpeCount) == sizeof(uint64_t)); 1586 CTASSERT(sizeof(AcpiSciCount) == sizeof(uint64_t)); 1587 } 1588 1589 static int 1590 sysctl_hw_acpi_fixedstats(SYSCTLFN_ARGS) 1591 { 1592 struct sysctlnode node; 1593 uint64_t t; 1594 int err, i; 1595 1596 for (i = t = 0; i < __arraycount(AcpiFixedEventCount); i++) 1597 t += AcpiFixedEventCount[i]; 1598 1599 node = *rnode; 1600 node.sysctl_data = &t; 1601 1602 err = sysctl_lookup(SYSCTLFN_CALL(&node)); 1603 1604 if (err || newp == NULL) 1605 return err; 1606 1607 return 0; 1608 } 1609 1610 static int 1611 sysctl_hw_acpi_sleepstate(SYSCTLFN_ARGS) 1612 { 1613 struct acpi_softc *sc = acpi_softc; 1614 struct sysctlnode node; 1615 int err, t; 1616 1617 if (acpi_softc == NULL) 1618 return ENOSYS; 1619 1620 node = *rnode; 1621 t = sc->sc_sleepstate; 1622 node.sysctl_data = &t; 1623 1624 err = sysctl_lookup(SYSCTLFN_CALL(&node)); 1625 1626 if (err || newp == NULL) 1627 return err; 1628 1629 if (t < ACPI_STATE_S0 || t > ACPI_STATE_S5) 1630 return EINVAL; 1631 1632 acpi_enter_sleep_state(sc, t); 1633 1634 return 0; 1635 } 1636 1637 static int 1638 sysctl_hw_acpi_sleepstates(SYSCTLFN_ARGS) 1639 { 1640 struct acpi_softc *sc = acpi_softc; 1641 struct sysctlnode node; 1642 char t[3 * 6 + 1]; 1643 int err; 1644 1645 if (acpi_softc == NULL) 1646 return ENOSYS; 1647 1648 (void)memset(t, '\0', sizeof(t)); 1649 1650 (void)snprintf(t, sizeof(t), "%s%s%s%s%s%s", 1651 ((sc->sc_sleepstates & __BIT(0)) != 0) ? "S0 " : "", 1652 ((sc->sc_sleepstates & __BIT(1)) != 0) ? "S1 " : "", 1653 ((sc->sc_sleepstates & __BIT(2)) != 0) ? "S2 " : "", 1654 ((sc->sc_sleepstates & __BIT(3)) != 0) ? "S3 " : "", 1655 ((sc->sc_sleepstates & __BIT(4)) != 0) ? "S4 " : "", 1656 ((sc->sc_sleepstates & __BIT(5)) != 0) ? "S5 " : ""); 1657 1658 node = *rnode; 1659 node.sysctl_data = &t; 1660 1661 err = sysctl_lookup(SYSCTLFN_CALL(&node)); 1662 1663 if (err || newp == NULL) 1664 return err; 1665 1666 return 0; 1667 } 1668 1669 /* 1670 * Miscellaneous. 1671 */ 1672 static bool 1673 acpi_is_scope(struct acpi_devnode *ad) 1674 { 1675 int i; 1676 1677 /* 1678 * Return true if the node is a root scope. 1679 */ 1680 if (ad->ad_parent == NULL) 1681 return false; 1682 1683 if (ad->ad_parent->ad_handle != ACPI_ROOT_OBJECT) 1684 return false; 1685 1686 for (i = 0; i < __arraycount(acpi_scopes); i++) { 1687 1688 if (acpi_scopes[i] == NULL) 1689 continue; 1690 1691 if (ad->ad_handle == acpi_scopes[i]) 1692 return true; 1693 } 1694 1695 return false; 1696 } 1697 1698 ACPI_PHYSICAL_ADDRESS 1699 acpi_OsGetRootPointer(void) 1700 { 1701 ACPI_PHYSICAL_ADDRESS PhysicalAddress; 1702 1703 /* 1704 * We let MD code handle this since there are multiple ways to do it: 1705 * 1706 * IA-32: Use AcpiFindRootPointer() to locate the RSDP. 1707 * 1708 * IA-64: Use the EFI. 1709 */ 1710 PhysicalAddress = acpi_md_OsGetRootPointer(); 1711 1712 if (acpi_root_pointer == 0) 1713 acpi_root_pointer = PhysicalAddress; 1714 1715 return PhysicalAddress; 1716 } 1717 1718 static ACPI_TABLE_HEADER * 1719 acpi_map_rsdt(void) 1720 { 1721 ACPI_PHYSICAL_ADDRESS paddr; 1722 ACPI_TABLE_RSDP *rsdp; 1723 1724 paddr = AcpiOsGetRootPointer(); 1725 1726 if (paddr == 0) 1727 return NULL; 1728 1729 rsdp = AcpiOsMapMemory(paddr, sizeof(ACPI_TABLE_RSDP)); 1730 1731 if (rsdp == NULL) 1732 return NULL; 1733 1734 if (rsdp->Revision > 1 && rsdp->XsdtPhysicalAddress) 1735 paddr = rsdp->XsdtPhysicalAddress; 1736 else 1737 paddr = rsdp->RsdtPhysicalAddress; 1738 1739 AcpiOsUnmapMemory(rsdp, sizeof(ACPI_TABLE_RSDP)); 1740 1741 return AcpiOsMapMemory(paddr, sizeof(ACPI_TABLE_HEADER)); 1742 } 1743 1744 static void 1745 acpi_unmap_rsdt(ACPI_TABLE_HEADER *rsdt) 1746 { 1747 1748 if (rsdt == NULL) 1749 return; 1750 1751 AcpiOsUnmapMemory(rsdt, sizeof(ACPI_TABLE_HEADER)); 1752 } 1753