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