1 /* 2 * Copyright 2009, Vincent Duvert, vincent.duvert@free.fr 3 * Copyright 2009, Clemens Zeidler, haiku@clemens-zeidler.de 4 * Copyright 2008-2015, Axel Dörfler, axeld@pinc-software.de. 5 * Copyright 2006, Bryan Varner. All rights reserved. 6 * Copyright 2005, Nathan Whitehorn. All rights reserved. 7 * 8 * Distributed under the terms of the MIT License. 9 */ 10 11 12 #include <stdio.h> 13 #include <stdlib.h> 14 #include <string.h> 15 16 #include <ACPI.h> 17 #include <apic.h> 18 #include <dpc.h> 19 #include <KernelExport.h> 20 #include <PCI.h> 21 22 #include <safemode.h> 23 24 extern "C" { 25 #include "acpi.h" 26 #include "accommon.h" 27 #include "acdisasm.h" 28 #include "acnamesp.h" 29 } 30 #include "ACPIPrivate.h" 31 32 //#define TRACE_ACPI_BUS 33 #ifdef TRACE_ACPI_BUS 34 #define TRACE(x...) dprintf("acpi: " x) 35 #else 36 #define TRACE(x...) 37 #endif 38 39 #define ERROR(x...) dprintf("acpi: " x) 40 41 #define PIC_MODE 0 42 #define APIC_MODE 1 43 44 #define ACPI_DEVICE_ID_LENGTH 0x08 45 46 extern pci_module_info* gPCIManager; 47 extern dpc_module_info* gDPC; 48 void* gDPCHandle = NULL; 49 50 51 static bool 52 checkAndLogFailure(const ACPI_STATUS status, const char* msg) 53 { 54 bool failure = ACPI_FAILURE(status); 55 if (failure) 56 dprintf("acpi: %s %s\n", msg, AcpiFormatException(status)); 57 58 return failure; 59 } 60 61 62 static ACPI_STATUS 63 get_device_by_hid_callback(ACPI_HANDLE object, UINT32 depth, void* context, 64 void** _returnValue) 65 { 66 uint32* counter = (uint32*)context; 67 ACPI_BUFFER buffer; 68 69 TRACE("get_device_by_hid_callback %p, %d, %p\n", object, depth, context); 70 71 *_returnValue = NULL; 72 73 if (counter[0] == counter[1]) { 74 buffer.Length = 254; 75 buffer.Pointer = malloc(255); 76 77 if (checkAndLogFailure(AcpiGetName(object, ACPI_FULL_PATHNAME, &buffer), 78 "Failed to find device")) { 79 free(buffer.Pointer); 80 return AE_CTRL_TERMINATE; 81 } 82 83 ((char*)buffer.Pointer)[buffer.Length] = '\0'; 84 *_returnValue = buffer.Pointer; 85 return AE_CTRL_TERMINATE; 86 } 87 88 counter[1]++; 89 return AE_OK; 90 } 91 92 93 #ifdef ACPI_DEBUG_OUTPUT 94 95 96 static void 97 globalGPEHandler(UINT32 eventType, ACPI_HANDLE device, UINT32 eventNumber, 98 void* context) 99 { 100 ACPI_BUFFER path; 101 char deviceName[256]; 102 path.Length = sizeof(deviceName); 103 path.Pointer = deviceName; 104 105 ACPI_STATUS status = AcpiNsHandleToPathname(device, &path); 106 if (ACPI_FAILURE(status)) 107 strcpy(deviceName, "(missing)"); 108 109 switch (eventType) { 110 case ACPI_EVENT_TYPE_GPE: 111 dprintf("acpi: GPE Event %d for %s\n", eventNumber, deviceName); 112 break; 113 114 case ACPI_EVENT_TYPE_FIXED: 115 { 116 switch (eventNumber) { 117 case ACPI_EVENT_PMTIMER: 118 dprintf("acpi: PMTIMER(%d) event for %s\n", eventNumber, 119 deviceName); 120 break; 121 122 case ACPI_EVENT_GLOBAL: 123 dprintf("acpi: Global(%d) event for %s\n", eventNumber, 124 deviceName); 125 break; 126 127 case ACPI_EVENT_POWER_BUTTON: 128 dprintf("acpi: Powerbutton(%d) event for %s\n", eventNumber, 129 deviceName); 130 break; 131 132 case ACPI_EVENT_SLEEP_BUTTON: 133 dprintf("acpi: sleepbutton(%d) event for %s\n", eventNumber, 134 deviceName); 135 break; 136 137 case ACPI_EVENT_RTC: 138 dprintf("acpi: RTC(%d) event for %s\n", eventNumber, 139 deviceName); 140 break; 141 142 default: 143 dprintf("acpi: unknown fixed(%d) event for %s\n", 144 eventNumber, deviceName); 145 } 146 break; 147 } 148 149 default: 150 dprintf("acpi: unknown event type (%d:%d) event for %s\n", 151 eventType, eventNumber, deviceName); 152 } 153 } 154 155 156 static void globalNotifyHandler(ACPI_HANDLE device, UINT32 value, void* context) 157 { 158 ACPI_BUFFER path; 159 char deviceName[256]; 160 path.Length = sizeof(deviceName); 161 path.Pointer = deviceName; 162 163 ACPI_STATUS status = AcpiNsHandleToPathname(device, &path); 164 if (ACPI_FAILURE(status)) 165 strcpy(deviceName, "(missing)"); 166 167 dprintf("acpi: Notify event %d for %s\n", value, deviceName); 168 } 169 170 171 #endif 172 173 174 // #pragma mark - ACPI bus manager API 175 176 177 static status_t 178 acpi_std_ops(int32 op,...) 179 { 180 switch (op) { 181 case B_MODULE_INIT: 182 { 183 ACPI_OBJECT arg; 184 ACPI_OBJECT_LIST parameter; 185 void *settings; 186 bool acpiDisabled = false; 187 AcpiGbl_CopyDsdtLocally = true; 188 189 settings = load_driver_settings("kernel"); 190 if (settings != NULL) { 191 acpiDisabled = !get_driver_boolean_parameter(settings, "acpi", 192 true, true); 193 unload_driver_settings(settings); 194 } 195 196 if (!acpiDisabled) { 197 // check if safemode settings disable ACPI 198 settings = load_driver_settings(B_SAFEMODE_DRIVER_SETTINGS); 199 if (settings != NULL) { 200 acpiDisabled = get_driver_boolean_parameter(settings, 201 B_SAFEMODE_DISABLE_ACPI, false, false); 202 unload_driver_settings(settings); 203 } 204 } 205 206 if (acpiDisabled) { 207 ERROR("ACPI disabled\n"); 208 return ENOSYS; 209 } 210 211 if (gDPC->new_dpc_queue(&gDPCHandle, "acpi_task", 212 B_URGENT_DISPLAY_PRIORITY + 1) != B_OK) { 213 ERROR("failed to create os execution queue\n"); 214 return B_ERROR; 215 } 216 217 #ifdef ACPI_DEBUG_OUTPUT 218 AcpiDbgLevel = ACPI_DEBUG_ALL | ACPI_LV_VERBOSE; 219 AcpiDbgLayer = ACPI_ALL_COMPONENTS; 220 #endif 221 222 if (checkAndLogFailure(AcpiInitializeSubsystem(), 223 "AcpiInitializeSubsystem failed")) 224 goto err; 225 226 if (checkAndLogFailure(AcpiInitializeTables(NULL, 0, TRUE), 227 "AcpiInitializeTables failed")) 228 goto err; 229 230 if (checkAndLogFailure(AcpiLoadTables(), 231 "AcpiLoadTables failed")) 232 goto err; 233 234 /* Install the default address space handlers. */ 235 236 arg.Integer.Type = ACPI_TYPE_INTEGER; 237 arg.Integer.Value = apic_available() ? APIC_MODE : PIC_MODE; 238 239 parameter.Count = 1; 240 parameter.Pointer = &arg; 241 242 AcpiEvaluateObject(NULL, (ACPI_STRING)"\\_PIC", ¶meter, NULL); 243 244 if (checkAndLogFailure(AcpiEnableSubsystem( 245 ACPI_FULL_INITIALIZATION), 246 "AcpiEnableSubsystem failed")) 247 goto err; 248 249 if (checkAndLogFailure(AcpiInitializeObjects( 250 ACPI_FULL_INITIALIZATION), 251 "AcpiInitializeObjects failed")) 252 goto err; 253 254 //TODO: Walk namespace init ALL _PRW's 255 256 #ifdef ACPI_DEBUG_OUTPUT 257 checkAndLogFailure( 258 AcpiInstallGlobalEventHandler(globalGPEHandler, NULL), 259 "Failed to install global GPE-handler."); 260 261 checkAndLogFailure(AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT, 262 ACPI_ALL_NOTIFY, globalNotifyHandler, NULL), 263 "Failed to install global Notify-handler."); 264 #endif 265 checkAndLogFailure(AcpiEnableAllRuntimeGpes(), 266 "Failed to enable all runtime Gpes"); 267 268 checkAndLogFailure(AcpiUpdateAllGpes(), 269 "Failed to update all Gpes"); 270 271 TRACE("ACPI initialized\n"); 272 return B_OK; 273 274 err: 275 return B_ERROR; 276 } 277 278 case B_MODULE_UNINIT: 279 { 280 if (checkAndLogFailure(AcpiTerminate(), 281 "Could not bring system out of ACPI mode. Oh well.")); 282 283 gDPC->delete_dpc_queue(gDPCHandle); 284 gDPCHandle = NULL; 285 break; 286 } 287 288 default: 289 return B_ERROR; 290 } 291 return B_OK; 292 } 293 294 295 status_t 296 get_handle(acpi_handle parent, const char *pathname, acpi_handle *retHandle) 297 { 298 return AcpiGetHandle(parent, (ACPI_STRING)pathname, retHandle) == AE_OK 299 ? B_OK : B_ERROR; 300 } 301 302 303 status_t 304 get_name(acpi_handle handle, uint32 nameType, char* returnedName, 305 size_t bufferLength) 306 { 307 ACPI_BUFFER buffer = {bufferLength, (void*)returnedName}; 308 return AcpiGetName(handle, nameType, &buffer) == AE_OK ? B_OK : B_ERROR; 309 } 310 311 312 status_t 313 acquire_global_lock(uint16 timeout, uint32 *handle) 314 { 315 return AcpiAcquireGlobalLock(timeout, (UINT32*)handle) == AE_OK 316 ? B_OK : B_ERROR; 317 } 318 319 320 status_t 321 release_global_lock(uint32 handle) 322 { 323 return AcpiReleaseGlobalLock(handle) == AE_OK ? B_OK : B_ERROR; 324 } 325 326 327 status_t 328 install_notify_handler(acpi_handle device, uint32 handlerType, 329 acpi_notify_handler handler, void *context) 330 { 331 return AcpiInstallNotifyHandler(device, handlerType, 332 (ACPI_NOTIFY_HANDLER)handler, context) == AE_OK ? B_OK : B_ERROR; 333 } 334 335 336 status_t 337 remove_notify_handler(acpi_handle device, uint32 handlerType, 338 acpi_notify_handler handler) 339 { 340 return AcpiRemoveNotifyHandler(device, handlerType, 341 (ACPI_NOTIFY_HANDLER)handler) == AE_OK ? B_OK : B_ERROR; 342 } 343 344 345 status_t 346 update_all_gpes() 347 { 348 return AcpiUpdateAllGpes() == AE_OK ? B_OK : B_ERROR; 349 } 350 351 352 status_t 353 enable_gpe(acpi_handle handle, uint32 gpeNumber) 354 { 355 return AcpiEnableGpe(handle, gpeNumber) == AE_OK ? B_OK : B_ERROR; 356 } 357 358 359 status_t 360 disable_gpe(acpi_handle handle, uint32 gpeNumber) 361 { 362 return AcpiDisableGpe(handle, gpeNumber) == AE_OK ? B_OK : B_ERROR; 363 } 364 365 366 status_t 367 clear_gpe(acpi_handle handle, uint32 gpeNumber) 368 { 369 return AcpiClearGpe(handle, gpeNumber) == AE_OK ? B_OK : B_ERROR; 370 } 371 372 373 status_t 374 set_gpe(acpi_handle handle, uint32 gpeNumber, uint8 action) 375 { 376 return AcpiSetGpe(handle, gpeNumber, action) == AE_OK ? B_OK : B_ERROR; 377 } 378 379 380 status_t 381 finish_gpe(acpi_handle handle, uint32 gpeNumber) 382 { 383 return AcpiFinishGpe(handle, gpeNumber) == AE_OK ? B_OK : B_ERROR; 384 } 385 386 387 status_t 388 install_gpe_handler(acpi_handle handle, uint32 gpeNumber, uint32 type, 389 acpi_gpe_handler handler, void *data) 390 { 391 return AcpiInstallGpeHandler(handle, gpeNumber, type, 392 (ACPI_GPE_HANDLER)handler, data) == AE_OK ? B_OK : B_ERROR; 393 } 394 395 396 status_t 397 remove_gpe_handler(acpi_handle handle, uint32 gpeNumber, 398 acpi_gpe_handler address) 399 { 400 return AcpiRemoveGpeHandler(handle, gpeNumber, (ACPI_GPE_HANDLER)address) 401 == AE_OK ? B_OK : B_ERROR; 402 } 403 404 405 status_t 406 install_address_space_handler(acpi_handle handle, uint32 spaceId, 407 acpi_adr_space_handler handler, acpi_adr_space_setup setup, void *data) 408 { 409 return AcpiInstallAddressSpaceHandler(handle, spaceId, 410 (ACPI_ADR_SPACE_HANDLER)handler, (ACPI_ADR_SPACE_SETUP)setup, data) 411 == AE_OK ? B_OK : B_ERROR; 412 } 413 414 415 status_t 416 remove_address_space_handler(acpi_handle handle, uint32 spaceId, 417 acpi_adr_space_handler handler) 418 { 419 return AcpiRemoveAddressSpaceHandler(handle, spaceId, 420 (ACPI_ADR_SPACE_HANDLER)handler) == AE_OK ? B_OK : B_ERROR; 421 } 422 423 424 void 425 enable_fixed_event(uint32 event) 426 { 427 AcpiEnableEvent(event, 0); 428 } 429 430 431 void 432 disable_fixed_event(uint32 event) 433 { 434 AcpiDisableEvent(event, 0); 435 } 436 437 438 uint32 439 fixed_event_status(uint32 event) 440 { 441 ACPI_EVENT_STATUS status = 0; 442 AcpiGetEventStatus(event, &status); 443 return status/* & ACPI_EVENT_FLAG_SET*/; 444 } 445 446 447 void 448 reset_fixed_event(uint32 event) 449 { 450 AcpiClearEvent(event); 451 } 452 453 454 status_t 455 install_fixed_event_handler(uint32 event, acpi_event_handler handler, 456 void *data) 457 { 458 return AcpiInstallFixedEventHandler(event, (ACPI_EVENT_HANDLER)handler, data) == AE_OK 459 ? B_OK : B_ERROR; 460 } 461 462 463 status_t 464 remove_fixed_event_handler(uint32 event, acpi_event_handler handler) 465 { 466 return AcpiRemoveFixedEventHandler(event, (ACPI_EVENT_HANDLER)handler) == AE_OK 467 ? B_OK : B_ERROR; 468 } 469 470 471 status_t 472 get_next_entry(uint32 objectType, const char *base, char *result, 473 size_t length, void **counter) 474 { 475 ACPI_HANDLE parent, child, newChild; 476 ACPI_BUFFER buffer; 477 ACPI_STATUS status; 478 479 TRACE("get_next_entry %ld, %s\n", objectType, base); 480 481 if (base == NULL || !strcmp(base, "\\")) { 482 parent = ACPI_ROOT_OBJECT; 483 } else { 484 status = AcpiGetHandle(NULL, (ACPI_STRING)base, &parent); 485 if (status != AE_OK) 486 return B_ENTRY_NOT_FOUND; 487 } 488 489 child = *counter; 490 491 status = AcpiGetNextObject(objectType, parent, child, &newChild); 492 if (status != AE_OK) 493 return B_ENTRY_NOT_FOUND; 494 495 *counter = newChild; 496 buffer.Length = length; 497 buffer.Pointer = result; 498 499 status = AcpiGetName(newChild, ACPI_FULL_PATHNAME, &buffer); 500 if (status != AE_OK) 501 return B_NO_MEMORY; /* Corresponds to AE_BUFFER_OVERFLOW */ 502 503 return B_OK; 504 } 505 506 507 status_t 508 get_next_object(uint32 objectType, acpi_handle parent, 509 acpi_handle* currentChild) 510 { 511 acpi_handle child = *currentChild; 512 return AcpiGetNextObject(objectType, parent, child, currentChild) == AE_OK 513 ? B_OK : B_ERROR; 514 } 515 516 517 status_t 518 get_device(const char* hid, uint32 index, char* result, size_t resultLength) 519 { 520 ACPI_STATUS status; 521 uint32 counter[2] = {index, 0}; 522 char *buffer = NULL; 523 524 TRACE("get_device %s, index %ld\n", hid, index); 525 status = AcpiGetDevices((ACPI_STRING)hid, (ACPI_WALK_CALLBACK)&get_device_by_hid_callback, 526 counter, (void**)&buffer); 527 if (status != AE_OK || buffer == NULL) 528 return B_ENTRY_NOT_FOUND; 529 530 strlcpy(result, buffer, resultLength); 531 free(buffer); 532 return B_OK; 533 } 534 535 536 status_t 537 get_device_hid(const char *path, char *hid, size_t bufferLength) 538 { 539 ACPI_HANDLE handle; 540 ACPI_DEVICE_INFO *info; 541 542 TRACE("get_device_hid: path %s, hid %s\n", path, hid); 543 if (AcpiGetHandle(NULL, (ACPI_STRING)path, &handle) != AE_OK) 544 return B_ENTRY_NOT_FOUND; 545 546 if (bufferLength < ACPI_DEVICE_ID_LENGTH) 547 return B_BUFFER_OVERFLOW; 548 549 if (AcpiGetObjectInfo(handle, &info) != AE_OK) 550 return B_BAD_TYPE; 551 552 if ((info->Valid & ACPI_VALID_HID) != 0) 553 strlcpy(hid, info->HardwareId.String, bufferLength); 554 else 555 hid[0] = '\0'; 556 AcpiOsFree(info); 557 return B_OK; 558 } 559 560 561 uint32 562 get_object_type(const char* path) 563 { 564 ACPI_HANDLE handle; 565 ACPI_OBJECT_TYPE type; 566 567 if (AcpiGetHandle(NULL, (ACPI_STRING)path, &handle) != AE_OK) 568 return B_ENTRY_NOT_FOUND; 569 570 AcpiGetType(handle, &type); 571 return type; 572 } 573 574 575 status_t 576 get_object(const char* path, acpi_object_type** _returnValue) 577 { 578 ACPI_HANDLE handle; 579 ACPI_BUFFER buffer; 580 ACPI_STATUS status; 581 582 status = AcpiGetHandle(NULL, (ACPI_STRING)path, &handle); 583 if (status != AE_OK) 584 return B_ENTRY_NOT_FOUND; 585 586 buffer.Pointer = NULL; 587 buffer.Length = ACPI_ALLOCATE_BUFFER; 588 589 status = AcpiEvaluateObject(handle, NULL, NULL, &buffer); 590 591 *_returnValue = (acpi_object_type*)buffer.Pointer; 592 return status == AE_OK ? B_OK : B_ERROR; 593 } 594 595 596 status_t 597 get_object_typed(const char* path, acpi_object_type** _returnValue, 598 uint32 objectType) 599 { 600 ACPI_HANDLE handle; 601 ACPI_BUFFER buffer; 602 ACPI_STATUS status; 603 604 status = AcpiGetHandle(NULL, (ACPI_STRING)path, &handle); 605 if (status != AE_OK) 606 return B_ENTRY_NOT_FOUND; 607 608 buffer.Pointer = NULL; 609 buffer.Length = ACPI_ALLOCATE_BUFFER; 610 611 status = AcpiEvaluateObjectTyped(handle, NULL, NULL, &buffer, objectType); 612 613 *_returnValue = (acpi_object_type*)buffer.Pointer; 614 return status == AE_OK ? B_OK : B_ERROR; 615 } 616 617 618 status_t 619 ns_handle_to_pathname(acpi_handle targetHandle, acpi_data *buffer) 620 { 621 status_t status = AcpiNsHandleToPathname(targetHandle, 622 (ACPI_BUFFER*)buffer, false); 623 return status == AE_OK ? B_OK : B_ERROR; 624 } 625 626 627 status_t 628 evaluate_object(acpi_handle handle, const char* object, acpi_objects *args, 629 acpi_object_type* returnValue, size_t bufferLength) 630 { 631 ACPI_BUFFER buffer; 632 ACPI_STATUS status; 633 634 buffer.Pointer = returnValue; 635 buffer.Length = bufferLength; 636 637 status = AcpiEvaluateObject(handle, (ACPI_STRING)object, 638 (ACPI_OBJECT_LIST*)args, returnValue != NULL ? &buffer : NULL); 639 if (status == AE_BUFFER_OVERFLOW) 640 dprintf("evaluate_object: the passed buffer is too small!\n"); 641 642 return status == AE_OK ? B_OK : B_ERROR; 643 } 644 645 646 status_t 647 evaluate_method(acpi_handle handle, const char* method, 648 acpi_objects *args, acpi_data *returnValue) 649 { 650 ACPI_STATUS status; 651 652 status = AcpiEvaluateObject(handle, (ACPI_STRING)method, 653 (ACPI_OBJECT_LIST*)args, (ACPI_BUFFER*)returnValue); 654 if (status == AE_BUFFER_OVERFLOW) 655 dprintf("evaluate_method: the passed buffer is too small!\n"); 656 657 return status == AE_OK ? B_OK : B_ERROR; 658 } 659 660 661 status_t 662 get_irq_routing_table(acpi_handle busDeviceHandle, acpi_data *retBuffer) 663 { 664 ACPI_STATUS status; 665 666 status = AcpiGetIrqRoutingTable(busDeviceHandle, (ACPI_BUFFER*)retBuffer); 667 if (status == AE_BUFFER_OVERFLOW) 668 dprintf("evaluate_method: the passed buffer is too small!\n"); 669 670 return status == AE_OK ? B_OK : B_ERROR; 671 } 672 673 674 status_t 675 get_current_resources(acpi_handle busDeviceHandle, acpi_data *retBuffer) 676 { 677 return AcpiGetCurrentResources(busDeviceHandle, (ACPI_BUFFER*)retBuffer) 678 == AE_OK ? B_OK : B_ERROR; 679 } 680 681 682 status_t 683 get_possible_resources(acpi_handle busDeviceHandle, acpi_data *retBuffer) 684 { 685 return AcpiGetPossibleResources(busDeviceHandle, (ACPI_BUFFER*)retBuffer) 686 == AE_OK ? B_OK : B_ERROR; 687 } 688 689 690 status_t 691 set_current_resources(acpi_handle busDeviceHandle, acpi_data *buffer) 692 { 693 return AcpiSetCurrentResources(busDeviceHandle, (ACPI_BUFFER*)buffer) 694 == AE_OK ? B_OK : B_ERROR; 695 } 696 697 698 status_t 699 walk_resources(acpi_handle busDeviceHandle, char* method, 700 acpi_walk_resources_callback callback, void* context) 701 { 702 return AcpiWalkResources(busDeviceHandle, method, 703 (ACPI_WALK_RESOURCE_CALLBACK)callback, context); 704 } 705 706 707 status_t 708 prepare_sleep_state(uint8 state, void (*wakeFunc)(void), size_t size) 709 { 710 ACPI_STATUS acpiStatus; 711 712 TRACE("prepare_sleep_state %d, %p, %ld\n", state, wakeFunc, size); 713 714 if (state != ACPI_POWER_STATE_OFF) { 715 physical_entry wakeVector; 716 status_t status; 717 718 // Note: The supplied code must already be locked into memory. 719 status = get_memory_map((const void*)wakeFunc, size, &wakeVector, 1); 720 if (status != B_OK) 721 return status; 722 723 # if B_HAIKU_PHYSICAL_BITS > 32 724 if (wakeVector.address >= 0x100000000LL) { 725 ERROR("prepare_sleep_state(): ACPI 2.0c says use 32 bit " 726 "vector, but we have a physical address >= 4 GB\n"); 727 } 728 # endif 729 acpiStatus = AcpiSetFirmwareWakingVector(wakeVector.address, 730 wakeVector.address); 731 if (acpiStatus != AE_OK) 732 return B_ERROR; 733 } 734 735 acpiStatus = AcpiEnterSleepStatePrep(state); 736 if (acpiStatus != AE_OK) 737 return B_ERROR; 738 739 return B_OK; 740 } 741 742 743 status_t 744 enter_sleep_state(uint8 state) 745 { 746 ACPI_STATUS status; 747 748 TRACE("enter_sleep_state %d\n", state); 749 750 cpu_status cpu = disable_interrupts(); 751 status = AcpiEnterSleepState(state); 752 restore_interrupts(cpu); 753 panic("AcpiEnterSleepState should not return."); 754 if (status != AE_OK) 755 return B_ERROR; 756 757 /*status = AcpiLeaveSleepState(state); 758 if (status != AE_OK) 759 return B_ERROR;*/ 760 761 return B_OK; 762 } 763 764 765 status_t 766 reboot(void) 767 { 768 ACPI_STATUS status; 769 770 TRACE("reboot\n"); 771 772 status = AcpiReset(); 773 if (status == AE_NOT_EXIST) 774 return B_UNSUPPORTED; 775 776 if (status != AE_OK) { 777 ERROR("Reset failed, status = %d\n", status); 778 return B_ERROR; 779 } 780 781 snooze(1000000); 782 ERROR("Reset failed, timeout\n"); 783 return B_ERROR; 784 } 785 786 787 status_t 788 get_table(const char* signature, uint32 instance, void** tableHeader) 789 { 790 return AcpiGetTable((char*)signature, instance, 791 (ACPI_TABLE_HEADER**)tableHeader) == AE_OK ? B_OK : B_ERROR; 792 } 793 794 795 status_t 796 read_bit_register(uint32 regid, uint32 *val) 797 { 798 return AcpiReadBitRegister(regid, (UINT32 *)val); 799 } 800 801 802 status_t 803 write_bit_register(uint32 regid, uint32 val) 804 { 805 return AcpiWriteBitRegister(regid, val); 806 } 807 808 809 struct acpi_module_info gACPIModule = { 810 { 811 B_ACPI_MODULE_NAME, 812 B_KEEP_LOADED, 813 acpi_std_ops 814 }, 815 816 get_handle, 817 get_name, 818 acquire_global_lock, 819 release_global_lock, 820 install_notify_handler, 821 remove_notify_handler, 822 update_all_gpes, 823 enable_gpe, 824 disable_gpe, 825 clear_gpe, 826 set_gpe, 827 finish_gpe, 828 install_gpe_handler, 829 remove_gpe_handler, 830 install_address_space_handler, 831 remove_address_space_handler, 832 enable_fixed_event, 833 disable_fixed_event, 834 fixed_event_status, 835 reset_fixed_event, 836 install_fixed_event_handler, 837 remove_fixed_event_handler, 838 get_next_entry, 839 get_next_object, 840 get_device, 841 get_device_hid, 842 get_object_type, 843 get_object, 844 get_object_typed, 845 ns_handle_to_pathname, 846 evaluate_object, 847 evaluate_method, 848 get_irq_routing_table, 849 get_current_resources, 850 get_possible_resources, 851 set_current_resources, 852 walk_resources, 853 prepare_sleep_state, 854 enter_sleep_state, 855 reboot, 856 get_table, 857 read_bit_register, 858 write_bit_register 859 }; 860