1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 24 * Copyright 2016, Joyent, Inc. 25 */ 26 /* 27 * Copyright (c) 2009, Intel Corporation. 28 * All rights reserved. 29 */ 30 /* 31 * Solaris x86 ACPI CA services 32 */ 33 34 #include <sys/file.h> 35 #include <sys/errno.h> 36 #include <sys/conf.h> 37 #include <sys/modctl.h> 38 #include <sys/open.h> 39 #include <sys/stat.h> 40 #include <sys/spl.h> 41 #include <sys/ddi.h> 42 #include <sys/sunddi.h> 43 #include <sys/esunddi.h> 44 #include <sys/kstat.h> 45 #include <sys/x86_archext.h> 46 47 #include <sys/acpi/acpi.h> 48 #include <sys/acpica.h> 49 #include <sys/archsystm.h> 50 51 /* 52 * 53 */ 54 static struct modlmisc modlmisc = { 55 &mod_miscops, 56 "ACPI interpreter", 57 }; 58 59 static struct modlinkage modlinkage = { 60 MODREV_1, /* MODREV_1 manual */ 61 (void *)&modlmisc, /* module linkage */ 62 NULL, /* list terminator */ 63 }; 64 65 /* 66 * Local prototypes 67 */ 68 69 struct parsed_prw { 70 ACPI_HANDLE prw_gpeobj; 71 int prw_gpebit; 72 int prw_level; 73 }; 74 75 static void acpica_init_kstats(void); 76 static ACPI_STATUS acpica_init_PRW( 77 ACPI_HANDLE hdl, 78 UINT32 lvl, 79 void *ctxp, 80 void **rvpp); 81 82 static ACPI_STATUS acpica_parse_PRW( 83 ACPI_BUFFER *prw_buf, 84 struct parsed_prw *prw); 85 86 /* 87 * Local data 88 */ 89 90 static kmutex_t acpica_module_lock; 91 static kstat_t *acpica_ksp; 92 93 /* 94 * State of acpica subsystem 95 * After successful initialization, will be ACPICA_INITIALIZED 96 */ 97 int acpica_init_state = ACPICA_NOT_INITIALIZED; 98 99 void *AcpiGbl_DbBuffer; 100 uint32_t AcpiGbl_DbConsoleDebugLevel; 101 102 /* 103 * Following are set by acpica_process_user_options() 104 * 105 * acpica_enable = FALSE prevents initialization of ACPI CA 106 * completely 107 * 108 * acpi_init_level determines level of ACPI CA functionality 109 * enabled in acpica_init() 110 */ 111 int acpica_enable; 112 UINT32 acpi_init_level; 113 114 /* 115 * Non-zero enables lax behavior with respect to some 116 * common ACPI BIOS issues; see ACPI CA documentation 117 * Setting this to zero causes ACPI CA to enforce strict 118 * compliance with ACPI specification 119 */ 120 int acpica_enable_interpreter_slack = 1; 121 122 /* 123 * For non-DEBUG builds, set the ACPI CA debug level to 0 124 * to quiet chatty BIOS output into /var/adm/messages 125 * Field-patchable for diagnostic use. 126 */ 127 #ifdef DEBUG 128 int acpica_muzzle_debug_output = 0; 129 #else 130 int acpica_muzzle_debug_output = 1; 131 #endif 132 133 /* 134 * ACPI DDI hooks 135 */ 136 static int acpica_ddi_setwake(dev_info_t *dip, int level); 137 138 int 139 _init(void) 140 { 141 int error = EBUSY; 142 int status; 143 extern int (*acpi_fp_setwake)(); 144 extern kmutex_t cpu_map_lock; 145 146 mutex_init(&acpica_module_lock, NULL, MUTEX_DRIVER, NULL); 147 mutex_init(&cpu_map_lock, NULL, MUTEX_SPIN, 148 (ddi_iblock_cookie_t)ipltospl(DISP_LEVEL)); 149 150 if ((error = mod_install(&modlinkage)) != 0) { 151 mutex_destroy(&acpica_module_lock); 152 goto load_error; 153 } 154 155 AcpiGbl_EnableInterpreterSlack = (acpica_enable_interpreter_slack != 0); 156 157 /* global ACPI CA initialization */ 158 if (ACPI_FAILURE(status = AcpiInitializeSubsystem())) 159 cmn_err(CE_WARN, "!AcpiInitializeSubsystem failed: %d", status); 160 161 /* initialize table manager */ 162 if (ACPI_FAILURE(status = AcpiInitializeTables(NULL, 0, 0))) 163 cmn_err(CE_WARN, "!AcpiInitializeTables failed: %d", status); 164 165 acpi_fp_setwake = acpica_ddi_setwake; 166 167 load_error: 168 return (error); 169 } 170 171 int 172 _info(struct modinfo *modinfop) 173 { 174 return (mod_info(&modlinkage, modinfop)); 175 } 176 177 int 178 _fini(void) 179 { 180 /* 181 * acpica module is never unloaded at run-time; there's always 182 * a PSM depending on it, at the very least 183 */ 184 return (EBUSY); 185 } 186 187 /* 188 * Install acpica-provided (default) address-space handlers 189 * that may be needed before AcpiEnableSubsystem() runs. 190 * See the comment in AcpiInstallAddressSpaceHandler(). 191 * Default handlers for remaining address spaces are 192 * installed later, in AcpiEnableSubsystem. 193 */ 194 static int 195 acpica_install_handlers() 196 { 197 ACPI_STATUS rv = AE_OK; 198 ACPI_STATUS res; 199 200 /* 201 * Install ACPI CA default handlers 202 */ 203 if ((res = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT, 204 ACPI_ADR_SPACE_SYSTEM_MEMORY, 205 ACPI_DEFAULT_HANDLER, NULL, NULL)) != AE_OK && 206 res != AE_SAME_HANDLER) { 207 cmn_err(CE_WARN, "!acpica: no default handler for" 208 " system memory"); 209 rv = AE_ERROR; 210 } 211 212 if ((res = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT, 213 ACPI_ADR_SPACE_SYSTEM_IO, 214 ACPI_DEFAULT_HANDLER, NULL, NULL)) != AE_OK && 215 res != AE_SAME_HANDLER) { 216 cmn_err(CE_WARN, "!acpica: no default handler for" 217 " system I/O"); 218 rv = AE_ERROR; 219 } 220 221 if ((res = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT, 222 ACPI_ADR_SPACE_PCI_CONFIG, 223 ACPI_DEFAULT_HANDLER, NULL, NULL)) != AE_OK && 224 res != AE_SAME_HANDLER) { 225 cmn_err(CE_WARN, "!acpica: no default handler for" 226 " PCI Config"); 227 rv = AE_ERROR; 228 } 229 230 if ((res = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT, 231 ACPI_ADR_SPACE_DATA_TABLE, 232 ACPI_DEFAULT_HANDLER, NULL, NULL)) != AE_OK && 233 res != AE_SAME_HANDLER) { 234 cmn_err(CE_WARN, "!acpica: no default handler for" 235 " Data Table"); 236 rv = AE_ERROR; 237 } 238 239 return (rv); 240 } 241 242 /* 243 * Find the BIOS date, and return TRUE if supplied 244 * date is same or later than the BIOS date, or FALSE 245 * if the BIOS date can't be fetched for any reason 246 */ 247 static int 248 acpica_check_bios_date(int yy, int mm, int dd) 249 { 250 251 char *datep; 252 int bios_year, bios_month, bios_day; 253 254 /* If firmware has no bios, skip the check */ 255 if (ddi_prop_exists(DDI_DEV_T_ANY, ddi_root_node(), DDI_PROP_DONTPASS, 256 "efi-systab")) 257 return (TRUE); 258 259 /* 260 * PC BIOSes contain a string in the form of 261 * "mm/dd/yy" at absolute address 0xffff5, 262 * where mm, dd and yy are all ASCII digits. 263 * We map the string, pluck out the values, 264 * and accept all BIOSes from 1 Jan 1999 on 265 * as valid. 266 */ 267 268 if ((datep = (char *)AcpiOsMapMemory(0xffff5, 8)) == NULL) 269 return (FALSE); 270 271 /* year */ 272 bios_year = ((int)(*(datep + 6) - '0') * 10) + (*(datep + 7) - '0'); 273 /* month */ 274 bios_month = ((int)(*datep - '0') * 10) + (*(datep + 1) - '0'); 275 /* day */ 276 bios_day = ((int)(*(datep + 3) - '0') * 10) + (*(datep + 4) - '0'); 277 278 AcpiOsUnmapMemory((void *) datep, 8); 279 280 if (bios_year < 0 || bios_year > 99 || bios_month < 0 || 281 bios_month > 99 || bios_day < 0 || bios_day > 99) { 282 /* non-digit chars in BIOS date */ 283 return (FALSE); 284 } 285 286 /* 287 * Adjust for 2-digit year; note to grand-children: 288 * need a new scheme before 2080 rolls around 289 */ 290 bios_year += (bios_year >= 80 && bios_year <= 99) ? 291 1900 : 2000; 292 293 if (bios_year < yy) 294 return (FALSE); 295 else if (bios_year > yy) 296 return (TRUE); 297 298 if (bios_month < mm) 299 return (FALSE); 300 else if (bios_month > mm) 301 return (TRUE); 302 303 if (bios_day < dd) 304 return (FALSE); 305 306 return (TRUE); 307 } 308 309 /* 310 * Check for Metropolis systems with BIOSes older than 10/12/04 311 * return TRUE if BIOS requires legacy mode, FALSE otherwise 312 */ 313 static int 314 acpica_metro_old_bios() 315 { 316 ACPI_TABLE_HEADER *fadt; 317 318 /* get the FADT */ 319 if (AcpiGetTable(ACPI_SIG_FADT, 1, (ACPI_TABLE_HEADER **)&fadt) != 320 AE_OK) 321 return (FALSE); 322 323 /* compare OEM Table ID to "SUNmetro" - no match, return false */ 324 if (strncmp("SUNmetro", fadt->OemTableId, 8)) 325 return (FALSE); 326 327 /* On a Metro - return FALSE if later than 10/12/04 */ 328 return (!acpica_check_bios_date(2004, 10, 12)); 329 } 330 331 332 /* 333 * Process acpi-user-options property if present 334 */ 335 static void 336 acpica_process_user_options() 337 { 338 static int processed = 0; 339 int acpi_user_options; 340 char *acpi_prop; 341 342 /* 343 * return if acpi-user-options has already been processed 344 */ 345 if (processed) 346 return; 347 else 348 processed = 1; 349 350 /* converts acpi-user-options from type string to int, if any */ 351 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(), 352 DDI_PROP_DONTPASS, "acpi-user-options", &acpi_prop) == 353 DDI_PROP_SUCCESS) { 354 long data; 355 int ret; 356 ret = ddi_strtol(acpi_prop, NULL, 0, &data); 357 if (ret == 0) { 358 e_ddi_prop_remove(DDI_DEV_T_NONE, ddi_root_node(), 359 "acpi-user-options"); 360 e_ddi_prop_update_int(DDI_DEV_T_NONE, ddi_root_node(), 361 "acpi-user-options", data); 362 } 363 ddi_prop_free(acpi_prop); 364 } 365 366 /* 367 * fetch the optional options property 368 */ 369 acpi_user_options = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_root_node(), 370 DDI_PROP_DONTPASS, "acpi-user-options", 0); 371 372 /* 373 * Note that 'off' has precedence over 'on' 374 * Also note - all cases of ACPI_OUSER_MASK 375 * provided here, no default: case is present 376 */ 377 switch (acpi_user_options & ACPI_OUSER_MASK) { 378 case ACPI_OUSER_DFLT: 379 acpica_enable = acpica_check_bios_date(1999, 1, 1); 380 break; 381 case ACPI_OUSER_ON: 382 acpica_enable = TRUE; 383 break; 384 case ACPI_OUSER_OFF: 385 case ACPI_OUSER_OFF | ACPI_OUSER_ON: 386 acpica_enable = FALSE; 387 break; 388 } 389 390 acpi_init_level = ACPI_FULL_INITIALIZATION; 391 392 /* 393 * special test here; may be generalized in the 394 * future - test for a machines that are known to 395 * work only in legacy mode, and set OUSER_LEGACY if 396 * we're on one 397 */ 398 if (acpica_metro_old_bios()) 399 acpi_user_options |= ACPI_OUSER_LEGACY; 400 401 /* 402 * If legacy mode is specified, set initialization 403 * options to avoid entering ACPI mode and hooking SCI 404 * - basically try to act like legacy acpi_intp 405 */ 406 if ((acpi_user_options & ACPI_OUSER_LEGACY) != 0) 407 acpi_init_level |= (ACPI_NO_ACPI_ENABLE | ACPI_NO_HANDLER_INIT); 408 409 /* 410 * modify default ACPI CA debug output level for non-DEBUG builds 411 * (to avoid BIOS debug chatter in /var/adm/messages) 412 */ 413 if (acpica_muzzle_debug_output) 414 AcpiDbgLevel = 0; 415 } 416 417 /* 418 * Initialize the CA subsystem if it hasn't been done already 419 */ 420 int 421 acpica_init() 422 { 423 extern void acpica_find_ioapics(void); 424 ACPI_STATUS status; 425 426 /* 427 * Make sure user options are processed, 428 * then fail to initialize if ACPI CA has been 429 * disabled 430 */ 431 acpica_process_user_options(); 432 if (!acpica_enable) 433 return (AE_ERROR); 434 435 mutex_enter(&acpica_module_lock); 436 if (acpica_init_state == ACPICA_INITIALIZED) { 437 mutex_exit(&acpica_module_lock); 438 return (AE_OK); 439 } 440 441 if (ACPI_FAILURE(status = AcpiLoadTables())) 442 goto error; 443 444 if (ACPI_FAILURE(status = acpica_install_handlers())) 445 goto error; 446 447 /* 448 * Create ACPI-to-devinfo mapping now so _INI and _STA 449 * methods can access PCI config space when needed 450 */ 451 scan_d2a_map(); 452 453 if (ACPI_FAILURE(status = AcpiEnableSubsystem(acpi_init_level))) 454 goto error; 455 456 /* do after AcpiEnableSubsystem() so GPEs are initialized */ 457 acpica_ec_init(); /* initialize EC if present */ 458 459 /* This runs all device _STA and _INI methods. */ 460 if (ACPI_FAILURE(status = AcpiInitializeObjects(0))) 461 goto error; 462 463 acpica_init_state = ACPICA_INITIALIZED; 464 465 /* 466 * [ACPI, sec. 4.4.1.1] 467 * As of ACPICA version 20101217 (December 2010), the _PRW methods 468 * (Power Resources for Wake) are no longer automatically executed 469 * as part of the ACPICA initialization. The OS must do this. 470 */ 471 (void) AcpiWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 472 UINT32_MAX, acpica_init_PRW, NULL, NULL, NULL); 473 (void) AcpiUpdateAllGpes(); 474 475 /* 476 * If we are running on the Xen hypervisor as dom0 we need to 477 * find the ioapics so we can prevent ACPI from trying to 478 * access them. 479 */ 480 if (get_hwenv() == HW_XEN_PV && is_controldom()) 481 acpica_find_ioapics(); 482 acpica_init_kstats(); 483 error: 484 if (acpica_init_state != ACPICA_INITIALIZED) { 485 cmn_err(CE_NOTE, "!failed to initialize ACPI services"); 486 } 487 488 /* 489 * Set acpi-status to 13 if acpica has been initialized successfully. 490 * This indicates that acpica is up and running. This variable name 491 * and value were chosen in order to remain compatible with acpi_intp. 492 */ 493 e_ddi_prop_update_int(DDI_DEV_T_NONE, ddi_root_node(), "acpi-status", 494 (ACPI_SUCCESS(status)) ? (ACPI_BOOT_INIT | ACPI_BOOT_ENABLE | 495 ACPI_BOOT_BOOTCONF) : 0); 496 497 /* Mark acpica subsystem as fully initialized. */ 498 if (ACPI_SUCCESS(status) && 499 acpi_init_level == ACPI_FULL_INITIALIZATION) { 500 acpica_set_core_feature(ACPI_FEATURE_FULL_INIT); 501 } 502 503 mutex_exit(&acpica_module_lock); 504 return (status); 505 } 506 507 /* 508 * SCI handling 509 */ 510 511 ACPI_STATUS 512 acpica_get_sci(int *sci_irq, iflag_t *sci_flags) 513 { 514 ACPI_SUBTABLE_HEADER *ap; 515 ACPI_TABLE_MADT *mat; 516 ACPI_MADT_INTERRUPT_OVERRIDE *mio; 517 ACPI_TABLE_FADT *fadt; 518 int madt_seen, madt_size; 519 520 521 /* 522 * Make sure user options are processed, 523 * then return error if ACPI CA has been 524 * disabled or system is not running in ACPI 525 * and won't need/understand SCI 526 */ 527 acpica_process_user_options(); 528 if ((!acpica_enable) || (acpi_init_level & ACPI_NO_ACPI_ENABLE)) 529 return (AE_ERROR); 530 531 /* 532 * according to Intel ACPI developers, SCI 533 * conforms to PCI bus conventions; level/low 534 * unless otherwise directed by overrides. 535 */ 536 sci_flags->intr_el = INTR_EL_LEVEL; 537 sci_flags->intr_po = INTR_PO_ACTIVE_LOW; 538 sci_flags->bustype = BUS_PCI; /* we *do* conform to PCI */ 539 540 /* get the SCI from the FADT */ 541 if (AcpiGetTable(ACPI_SIG_FADT, 1, (ACPI_TABLE_HEADER **)&fadt) != 542 AE_OK) 543 return (AE_ERROR); 544 545 *sci_irq = fadt->SciInterrupt; 546 547 /* search for ISOs that modify it */ 548 /* if we don't find a MADT, that's OK; no ISOs then */ 549 if (AcpiGetTable(ACPI_SIG_MADT, 1, (ACPI_TABLE_HEADER **) &mat) != 550 AE_OK) 551 return (AE_OK); 552 553 ap = (ACPI_SUBTABLE_HEADER *) (mat + 1); 554 madt_size = mat->Header.Length; 555 madt_seen = sizeof (*mat); 556 557 while (madt_seen < madt_size) { 558 switch (ap->Type) { 559 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: 560 mio = (ACPI_MADT_INTERRUPT_OVERRIDE *) ap; 561 if (mio->SourceIrq == *sci_irq) { 562 *sci_irq = mio->GlobalIrq; 563 sci_flags->intr_el = (mio->IntiFlags & 564 ACPI_MADT_TRIGGER_MASK) >> 2; 565 sci_flags->intr_po = mio->IntiFlags & 566 ACPI_MADT_POLARITY_MASK; 567 } 568 break; 569 } 570 571 /* advance to next entry */ 572 madt_seen += ap->Length; 573 ap = (ACPI_SUBTABLE_HEADER *)(((char *)ap) + ap->Length); 574 } 575 576 /* 577 * One more check; if ISO said "conform", revert to default 578 */ 579 if (sci_flags->intr_el == INTR_EL_CONFORM) 580 sci_flags->intr_el = INTR_EL_LEVEL; 581 if (sci_flags->intr_po == INTR_PO_CONFORM) 582 sci_flags->intr_po = INTR_PO_ACTIVE_LOW; 583 584 return (AE_OK); 585 } 586 587 /* 588 * Call-back function used for _PRW initialization. For every 589 * device node that has a _PRW method, evaluate, parse, and do 590 * AcpiSetupGpeForWake(). 591 */ 592 static ACPI_STATUS 593 acpica_init_PRW( 594 ACPI_HANDLE devhdl, 595 UINT32 depth, 596 void *ctxp, 597 void **rvpp) 598 { 599 ACPI_STATUS status; 600 ACPI_BUFFER prw_buf; 601 struct parsed_prw prw; 602 603 prw_buf.Pointer = NULL; 604 prw_buf.Length = ACPI_ALLOCATE_BUFFER; 605 606 /* 607 * Attempt to evaluate _PRW object. 608 * If no valid object is found, return quietly, since not all 609 * devices have _PRW objects. 610 */ 611 status = AcpiEvaluateObject(devhdl, "_PRW", NULL, &prw_buf); 612 if (ACPI_FAILURE(status)) 613 goto done; 614 status = acpica_parse_PRW(&prw_buf, &prw); 615 if (ACPI_FAILURE(status)) 616 goto done; 617 618 (void) AcpiSetupGpeForWake(devhdl, 619 prw.prw_gpeobj, prw.prw_gpebit); 620 621 done: 622 if (prw_buf.Pointer != NULL) 623 AcpiOsFree(prw_buf.Pointer); 624 625 return (AE_OK); 626 } 627 628 /* 629 * Sets ACPI wake state for device referenced by dip. 630 * If level is S0 (0), disables wake event; otherwise, 631 * enables wake event which will wake system from level. 632 */ 633 static int 634 acpica_ddi_setwake(dev_info_t *dip, int level) 635 { 636 ACPI_STATUS status; 637 ACPI_HANDLE devobj; 638 ACPI_BUFFER prw_buf; 639 ACPI_OBJECT_LIST arglist; 640 ACPI_OBJECT args[3]; 641 struct parsed_prw prw; 642 int rv; 643 644 /* 645 * initialize these early so we can use a common 646 * exit point below 647 */ 648 prw_buf.Pointer = NULL; 649 prw_buf.Length = ACPI_ALLOCATE_BUFFER; 650 rv = 0; 651 652 /* 653 * Attempt to get a handle to a corresponding ACPI object. 654 * If no object is found, return quietly, since not all 655 * devices have corresponding ACPI objects. 656 */ 657 status = acpica_get_handle(dip, &devobj); 658 if (ACPI_FAILURE(status)) { 659 char pathbuf[MAXPATHLEN]; 660 ddi_pathname(dip, pathbuf); 661 #ifdef DEBUG 662 cmn_err(CE_NOTE, "!acpica_ddi_setwake: could not get" 663 " handle for %s, %s:%d", pathbuf, ddi_driver_name(dip), 664 ddi_get_instance(dip)); 665 #endif 666 goto done; 667 } 668 669 /* 670 * ACPI3.0 7.2.1: only use the _PSW method if OSPM does not support 671 * _DSW or if the _DSW method is not present. 672 * 673 * _DSW arguments: 674 * args[0] - Enable/Disable 675 * args[1] - Target system state 676 * args[2] - Target device state 677 */ 678 679 arglist.Count = 3; 680 arglist.Pointer = args; 681 args[0].Type = ACPI_TYPE_INTEGER; 682 args[0].Integer.Value = level ? 1 : 0; 683 args[1].Type = ACPI_TYPE_INTEGER; 684 args[1].Integer.Value = level; 685 args[2].Type = ACPI_TYPE_INTEGER; 686 args[2].Integer.Value = level; 687 if (ACPI_FAILURE(status = AcpiEvaluateObject(devobj, "_DSW", 688 &arglist, NULL))) { 689 690 if (status == AE_NOT_FOUND) { 691 arglist.Count = 1; 692 args[0].Type = ACPI_TYPE_INTEGER; 693 args[0].Integer.Value = level ? 1 : 0; 694 695 if (ACPI_FAILURE(status = AcpiEvaluateObject(devobj, 696 "_PSW", &arglist, NULL))) { 697 698 if (status != AE_NOT_FOUND) { 699 cmn_err(CE_NOTE, 700 "!_PSW failure %d for device %s", 701 status, ddi_driver_name(dip)); 702 } 703 } 704 705 } else { 706 cmn_err(CE_NOTE, "!_DSW failure %d for device %s", 707 status, ddi_driver_name(dip)); 708 } 709 } 710 711 /* 712 * Attempt to evaluate _PRW object. 713 * If no valid object is found, return quietly, since not all 714 * devices have _PRW objects. 715 */ 716 status = AcpiEvaluateObject(devobj, "_PRW", NULL, &prw_buf); 717 if (ACPI_FAILURE(status)) 718 goto done; 719 status = acpica_parse_PRW(&prw_buf, &prw); 720 if (ACPI_FAILURE(status)) 721 goto done; 722 723 rv = -1; 724 if (level == 0) { 725 status = AcpiDisableGpe(prw.prw_gpeobj, prw.prw_gpebit); 726 if (ACPI_FAILURE(status)) 727 goto done; 728 } else if (prw.prw_level >= level) { 729 status = AcpiSetGpeWakeMask(prw.prw_gpeobj, prw.prw_gpebit, 730 ACPI_GPE_ENABLE); 731 if (ACPI_SUCCESS(status)) { 732 status = AcpiEnableGpe(prw.prw_gpeobj, prw.prw_gpebit); 733 if (ACPI_FAILURE(status)) 734 goto done; 735 } 736 } 737 rv = 0; 738 done: 739 if (prw_buf.Pointer != NULL) 740 AcpiOsFree(prw_buf.Pointer); 741 return (rv); 742 } 743 744 static ACPI_STATUS 745 acpica_parse_PRW( 746 ACPI_BUFFER *prw_buf, 747 struct parsed_prw *p_prw) 748 { 749 ACPI_HANDLE gpeobj; 750 ACPI_OBJECT *prw, *gpe; 751 int gpebit, prw_level; 752 753 if (prw_buf->Length == 0 || prw_buf->Pointer == NULL) 754 return (AE_NULL_OBJECT); 755 756 prw = prw_buf->Pointer; 757 if (prw->Type != ACPI_TYPE_PACKAGE || prw->Package.Count < 2 || 758 prw->Package.Elements[1].Type != ACPI_TYPE_INTEGER) 759 return (AE_TYPE); 760 761 /* fetch the lowest wake level from the _PRW */ 762 prw_level = prw->Package.Elements[1].Integer.Value; 763 764 /* 765 * process the GPE description 766 */ 767 switch (prw->Package.Elements[0].Type) { 768 case ACPI_TYPE_INTEGER: 769 gpeobj = NULL; 770 gpebit = prw->Package.Elements[0].Integer.Value; 771 break; 772 case ACPI_TYPE_PACKAGE: 773 gpe = &prw->Package.Elements[0]; 774 if (gpe->Package.Count != 2 || 775 gpe->Package.Elements[1].Type != ACPI_TYPE_INTEGER) 776 return (AE_TYPE); 777 gpeobj = gpe->Package.Elements[0].Reference.Handle; 778 gpebit = gpe->Package.Elements[1].Integer.Value; 779 if (gpeobj == NULL) 780 return (AE_NULL_OBJECT); 781 break; 782 default: 783 return (AE_TYPE); 784 } 785 786 p_prw->prw_gpeobj = gpeobj; 787 p_prw->prw_gpebit = gpebit; 788 p_prw->prw_level = prw_level; 789 790 return (AE_OK); 791 } 792 793 /* 794 * kstat access to a limited set of ACPI propertis 795 */ 796 static void 797 acpica_init_kstats() 798 { 799 ACPI_HANDLE s3handle; 800 ACPI_STATUS status; 801 ACPI_TABLE_FADT *fadt; 802 kstat_named_t *knp; 803 804 /* 805 * Create a small set of named kstats; just return in the rare 806 * case of a failure, * in which case, the kstats won't be present. 807 */ 808 if ((acpica_ksp = kstat_create("acpi", 0, "acpi", "misc", 809 KSTAT_TYPE_NAMED, 2, 0)) == NULL) 810 return; 811 812 /* 813 * initialize kstat 'S3' to reflect the presence of \_S3 in 814 * the ACPI namespace (1 = present, 0 = not present) 815 */ 816 knp = acpica_ksp->ks_data; 817 knp->value.l = (AcpiGetHandle(NULL, "\\_S3", &s3handle) == AE_OK); 818 kstat_named_init(knp, "S3", KSTAT_DATA_LONG); 819 knp++; /* advance to next named kstat */ 820 821 /* 822 * initialize kstat 'preferred_pm_profile' to the value 823 * contained in the (always present) FADT 824 */ 825 status = AcpiGetTable(ACPI_SIG_FADT, 1, (ACPI_TABLE_HEADER **)&fadt); 826 knp->value.l = (status == AE_OK) ? fadt->PreferredProfile : -1; 827 kstat_named_init(knp, "preferred_pm_profile", KSTAT_DATA_LONG); 828 829 /* 830 * install the named kstats 831 */ 832 kstat_install(acpica_ksp); 833 } 834 835 /* 836 * Attempt to save the current ACPI settings (_CRS) for the device 837 * which corresponds to the supplied devinfo node. The settings are 838 * saved as a property on the dip. If no ACPI object is found to be 839 * associated with the devinfo node, no action is taken and no error 840 * is reported. 841 */ 842 void 843 acpica_ddi_save_resources(dev_info_t *dip) 844 { 845 ACPI_HANDLE devobj; 846 ACPI_BUFFER resbuf; 847 int ret; 848 849 resbuf.Length = ACPI_ALLOCATE_BUFFER; 850 if (ACPI_FAILURE(acpica_get_handle(dip, &devobj)) || 851 ACPI_FAILURE(AcpiGetCurrentResources(devobj, &resbuf))) 852 return; 853 854 ret = ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP, 855 "acpi-crs", resbuf.Pointer, resbuf.Length); 856 857 ASSERT(ret == DDI_PROP_SUCCESS); 858 859 AcpiOsFree(resbuf.Pointer); 860 } 861 862 /* 863 * If the supplied devinfo node has an ACPI settings property attached, 864 * restore them to the associated ACPI device using _SRS. The property 865 * is deleted from the devinfo node afterward. 866 */ 867 void 868 acpica_ddi_restore_resources(dev_info_t *dip) 869 { 870 ACPI_HANDLE devobj; 871 ACPI_BUFFER resbuf; 872 uchar_t *propdata; 873 uint_t proplen; 874 875 if (ACPI_FAILURE(acpica_get_handle(dip, &devobj))) 876 return; 877 878 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 879 "acpi-crs", &propdata, &proplen) != DDI_PROP_SUCCESS) 880 return; 881 882 resbuf.Pointer = propdata; 883 resbuf.Length = proplen; 884 (void) AcpiSetCurrentResources(devobj, &resbuf); 885 ddi_prop_free(propdata); 886 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "acpi-crs"); 887 } 888 889 void 890 acpi_reset_system(void) 891 { 892 ACPI_STATUS status; 893 int ten; 894 895 status = AcpiReset(); 896 if (status == AE_OK) { 897 /* 898 * Wait up to 500 milliseconds for AcpiReset() to make its 899 * way. 900 */ 901 ten = 50000; 902 while (ten-- > 0) 903 tenmicrosec(); 904 } 905 } 906