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 if (checkAndLogFailure(AcpiInstallAddressSpaceHandler( 236 ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_SYSTEM_MEMORY, 237 ACPI_DEFAULT_HANDLER, NULL, NULL), 238 "Could not initialise SystemMemory handler:")) 239 goto err; 240 241 if (checkAndLogFailure(AcpiInstallAddressSpaceHandler( 242 ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_SYSTEM_IO, 243 ACPI_DEFAULT_HANDLER, NULL, NULL), 244 "Could not initialise SystemIO handler:")) 245 goto err; 246 247 if (checkAndLogFailure(AcpiInstallAddressSpaceHandler( 248 ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_PCI_CONFIG, 249 ACPI_DEFAULT_HANDLER, NULL, NULL), 250 "Could not initialise PciConfig handler:")) 251 goto err; 252 253 arg.Integer.Type = ACPI_TYPE_INTEGER; 254 arg.Integer.Value = apic_available() ? APIC_MODE : PIC_MODE; 255 256 parameter.Count = 1; 257 parameter.Pointer = &arg; 258 259 AcpiEvaluateObject(NULL, "\\_PIC", ¶meter, NULL); 260 261 if (checkAndLogFailure(AcpiEnableSubsystem( 262 ACPI_FULL_INITIALIZATION), 263 "AcpiEnableSubsystem failed")) 264 goto err; 265 266 if (checkAndLogFailure(AcpiInitializeObjects( 267 ACPI_FULL_INITIALIZATION), 268 "AcpiInitializeObjects failed")) 269 goto err; 270 271 //TODO: Walk namespace init ALL _PRW's 272 273 #ifdef ACPI_DEBUG_OUTPUT 274 checkAndLogFailure( 275 AcpiInstallGlobalEventHandler(globalGPEHandler, NULL), 276 "Failed to install global GPE-handler."); 277 278 checkAndLogFailure(AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT, 279 ACPI_ALL_NOTIFY, globalNotifyHandler, NULL), 280 "Failed to install global Notify-handler."); 281 #endif 282 checkAndLogFailure(AcpiEnableAllRuntimeGpes(), 283 "Failed to enable all runtime Gpes"); 284 285 checkAndLogFailure(AcpiUpdateAllGpes(), 286 "Failed to update all Gpes"); 287 288 TRACE("ACPI initialized\n"); 289 return B_OK; 290 291 err: 292 return B_ERROR; 293 } 294 295 case B_MODULE_UNINIT: 296 { 297 if (checkAndLogFailure(AcpiTerminate(), 298 "Could not bring system out of ACPI mode. Oh well.")); 299 300 gDPC->delete_dpc_queue(gDPCHandle); 301 gDPCHandle = NULL; 302 break; 303 } 304 305 default: 306 return B_ERROR; 307 } 308 return B_OK; 309 } 310 311 312 status_t 313 get_handle(acpi_handle parent, const char *pathname, acpi_handle *retHandle) 314 { 315 return AcpiGetHandle(parent, (ACPI_STRING)pathname, retHandle) == AE_OK 316 ? B_OK : B_ERROR; 317 } 318 319 320 status_t 321 get_name(acpi_handle handle, uint32 nameType, char* returnedName, 322 size_t bufferLength) 323 { 324 ACPI_BUFFER buffer = {bufferLength, (void*)returnedName}; 325 return AcpiGetName(handle, nameType, &buffer) == AE_OK ? B_OK : B_ERROR; 326 } 327 328 329 status_t 330 acquire_global_lock(uint16 timeout, uint32 *handle) 331 { 332 return AcpiAcquireGlobalLock(timeout, (UINT32*)handle) == AE_OK 333 ? B_OK : B_ERROR; 334 } 335 336 337 status_t 338 release_global_lock(uint32 handle) 339 { 340 return AcpiReleaseGlobalLock(handle) == AE_OK ? B_OK : B_ERROR; 341 } 342 343 344 status_t 345 install_notify_handler(acpi_handle device, uint32 handlerType, 346 acpi_notify_handler handler, void *context) 347 { 348 return AcpiInstallNotifyHandler(device, handlerType, 349 (ACPI_NOTIFY_HANDLER)handler, context) == AE_OK ? B_OK : B_ERROR; 350 } 351 352 353 status_t 354 remove_notify_handler(acpi_handle device, uint32 handlerType, 355 acpi_notify_handler handler) 356 { 357 return AcpiRemoveNotifyHandler(device, handlerType, 358 (ACPI_NOTIFY_HANDLER)handler) == AE_OK ? B_OK : B_ERROR; 359 } 360 361 362 status_t 363 update_all_gpes() 364 { 365 return AcpiUpdateAllGpes() == AE_OK ? B_OK : B_ERROR; 366 } 367 368 369 status_t 370 enable_gpe(acpi_handle handle, uint32 gpeNumber) 371 { 372 return AcpiEnableGpe(handle, gpeNumber) == AE_OK ? B_OK : B_ERROR; 373 } 374 375 376 status_t 377 disable_gpe(acpi_handle handle, uint32 gpeNumber) 378 { 379 return AcpiDisableGpe(handle, gpeNumber) == AE_OK ? B_OK : B_ERROR; 380 } 381 382 383 status_t 384 clear_gpe(acpi_handle handle, uint32 gpeNumber) 385 { 386 return AcpiClearGpe(handle, gpeNumber) == AE_OK ? B_OK : B_ERROR; 387 } 388 389 390 status_t 391 set_gpe(acpi_handle handle, uint32 gpeNumber, uint8 action) 392 { 393 return AcpiSetGpe(handle, gpeNumber, action) == AE_OK ? B_OK : B_ERROR; 394 } 395 396 397 status_t 398 finish_gpe(acpi_handle handle, uint32 gpeNumber) 399 { 400 return AcpiFinishGpe(handle, gpeNumber) == AE_OK ? B_OK : B_ERROR; 401 } 402 403 404 status_t 405 install_gpe_handler(acpi_handle handle, uint32 gpeNumber, uint32 type, 406 acpi_gpe_handler handler, void *data) 407 { 408 return AcpiInstallGpeHandler(handle, gpeNumber, type, 409 (ACPI_GPE_HANDLER)handler, data) == AE_OK ? B_OK : B_ERROR; 410 } 411 412 413 status_t 414 remove_gpe_handler(acpi_handle handle, uint32 gpeNumber, 415 acpi_gpe_handler address) 416 { 417 return AcpiRemoveGpeHandler(handle, gpeNumber, (ACPI_GPE_HANDLER)address) 418 == AE_OK ? B_OK : B_ERROR; 419 } 420 421 422 status_t 423 install_address_space_handler(acpi_handle handle, uint32 spaceId, 424 acpi_adr_space_handler handler, acpi_adr_space_setup setup, void *data) 425 { 426 return AcpiInstallAddressSpaceHandler(handle, spaceId, 427 (ACPI_ADR_SPACE_HANDLER)handler, (ACPI_ADR_SPACE_SETUP)setup, data) 428 == AE_OK ? B_OK : B_ERROR; 429 } 430 431 432 status_t 433 remove_address_space_handler(acpi_handle handle, uint32 spaceId, 434 acpi_adr_space_handler handler) 435 { 436 return AcpiRemoveAddressSpaceHandler(handle, spaceId, 437 (ACPI_ADR_SPACE_HANDLER)handler) == AE_OK ? B_OK : B_ERROR; 438 } 439 440 441 void 442 enable_fixed_event(uint32 event) 443 { 444 AcpiEnableEvent(event, 0); 445 } 446 447 448 void 449 disable_fixed_event(uint32 event) 450 { 451 AcpiDisableEvent(event, 0); 452 } 453 454 455 uint32 456 fixed_event_status(uint32 event) 457 { 458 ACPI_EVENT_STATUS status = 0; 459 AcpiGetEventStatus(event, &status); 460 return status/* & ACPI_EVENT_FLAG_SET*/; 461 } 462 463 464 void 465 reset_fixed_event(uint32 event) 466 { 467 AcpiClearEvent(event); 468 } 469 470 471 status_t 472 install_fixed_event_handler(uint32 event, acpi_event_handler handler, 473 void *data) 474 { 475 return AcpiInstallFixedEventHandler(event, (ACPI_EVENT_HANDLER)handler, data) == AE_OK 476 ? B_OK : B_ERROR; 477 } 478 479 480 status_t 481 remove_fixed_event_handler(uint32 event, acpi_event_handler handler) 482 { 483 return AcpiRemoveFixedEventHandler(event, (ACPI_EVENT_HANDLER)handler) == AE_OK 484 ? B_OK : B_ERROR; 485 } 486 487 488 status_t 489 get_next_entry(uint32 objectType, const char *base, char *result, 490 size_t length, void **counter) 491 { 492 ACPI_HANDLE parent, child, newChild; 493 ACPI_BUFFER buffer; 494 ACPI_STATUS status; 495 496 TRACE("get_next_entry %ld, %s\n", objectType, base); 497 498 if (base == NULL || !strcmp(base, "\\")) { 499 parent = ACPI_ROOT_OBJECT; 500 } else { 501 status = AcpiGetHandle(NULL, (ACPI_STRING)base, &parent); 502 if (status != AE_OK) 503 return B_ENTRY_NOT_FOUND; 504 } 505 506 child = *counter; 507 508 status = AcpiGetNextObject(objectType, parent, child, &newChild); 509 if (status != AE_OK) 510 return B_ENTRY_NOT_FOUND; 511 512 *counter = newChild; 513 buffer.Length = length; 514 buffer.Pointer = result; 515 516 status = AcpiGetName(newChild, ACPI_FULL_PATHNAME, &buffer); 517 if (status != AE_OK) 518 return B_NO_MEMORY; /* Corresponds to AE_BUFFER_OVERFLOW */ 519 520 return B_OK; 521 } 522 523 524 status_t 525 get_next_object(uint32 objectType, acpi_handle parent, 526 acpi_handle* currentChild) 527 { 528 acpi_handle child = *currentChild; 529 return AcpiGetNextObject(objectType, parent, child, currentChild) == AE_OK 530 ? B_OK : B_ERROR; 531 } 532 533 534 status_t 535 get_device(const char* hid, uint32 index, char* result, size_t resultLength) 536 { 537 ACPI_STATUS status; 538 uint32 counter[2] = {index, 0}; 539 char *buffer = NULL; 540 541 TRACE("get_device %s, index %ld\n", hid, index); 542 status = AcpiGetDevices((ACPI_STRING)hid, (ACPI_WALK_CALLBACK)&get_device_by_hid_callback, 543 counter, (void**)&buffer); 544 if (status != AE_OK || buffer == NULL) 545 return B_ENTRY_NOT_FOUND; 546 547 strlcpy(result, buffer, resultLength); 548 free(buffer); 549 return B_OK; 550 } 551 552 553 status_t 554 get_device_hid(const char *path, char *hid, size_t bufferLength) 555 { 556 ACPI_HANDLE handle; 557 ACPI_DEVICE_INFO *info; 558 559 TRACE("get_device_hid: path %s, hid %s\n", path, hid); 560 if (AcpiGetHandle(NULL, (ACPI_STRING)path, &handle) != AE_OK) 561 return B_ENTRY_NOT_FOUND; 562 563 if (bufferLength < ACPI_DEVICE_ID_LENGTH) 564 return B_BUFFER_OVERFLOW; 565 566 if (AcpiGetObjectInfo(handle, &info) != AE_OK) 567 return B_BAD_TYPE; 568 569 if ((info->Valid & ACPI_VALID_HID) != 0) 570 strlcpy(hid, info->HardwareId.String, bufferLength); 571 else 572 hid[0] = '\0'; 573 AcpiOsFree(info); 574 return B_OK; 575 } 576 577 578 uint32 579 get_object_type(const char* path) 580 { 581 ACPI_HANDLE handle; 582 ACPI_OBJECT_TYPE type; 583 584 if (AcpiGetHandle(NULL, (ACPI_STRING)path, &handle) != AE_OK) 585 return B_ENTRY_NOT_FOUND; 586 587 AcpiGetType(handle, &type); 588 return type; 589 } 590 591 592 status_t 593 get_object(const char* path, acpi_object_type** _returnValue) 594 { 595 ACPI_HANDLE handle; 596 ACPI_BUFFER buffer; 597 ACPI_STATUS status; 598 599 status = AcpiGetHandle(NULL, (ACPI_STRING)path, &handle); 600 if (status != AE_OK) 601 return B_ENTRY_NOT_FOUND; 602 603 buffer.Pointer = NULL; 604 buffer.Length = ACPI_ALLOCATE_BUFFER; 605 606 status = AcpiEvaluateObject(handle, NULL, NULL, &buffer); 607 608 *_returnValue = (acpi_object_type*)buffer.Pointer; 609 return status == AE_OK ? B_OK : B_ERROR; 610 } 611 612 613 status_t 614 get_object_typed(const char* path, acpi_object_type** _returnValue, 615 uint32 objectType) 616 { 617 ACPI_HANDLE handle; 618 ACPI_BUFFER buffer; 619 ACPI_STATUS status; 620 621 status = AcpiGetHandle(NULL, (ACPI_STRING)path, &handle); 622 if (status != AE_OK) 623 return B_ENTRY_NOT_FOUND; 624 625 buffer.Pointer = NULL; 626 buffer.Length = ACPI_ALLOCATE_BUFFER; 627 628 status = AcpiEvaluateObjectTyped(handle, NULL, NULL, &buffer, objectType); 629 630 *_returnValue = (acpi_object_type*)buffer.Pointer; 631 return status == AE_OK ? B_OK : B_ERROR; 632 } 633 634 635 status_t 636 ns_handle_to_pathname(acpi_handle targetHandle, acpi_data *buffer) 637 { 638 status_t status = AcpiNsHandleToPathname(targetHandle, 639 (ACPI_BUFFER*)buffer); 640 return status == AE_OK ? B_OK : B_ERROR; 641 } 642 643 644 status_t 645 evaluate_object(acpi_handle handle, const char* object, acpi_objects *args, 646 acpi_object_type* returnValue, size_t bufferLength) 647 { 648 ACPI_BUFFER buffer; 649 ACPI_STATUS status; 650 651 buffer.Pointer = returnValue; 652 buffer.Length = bufferLength; 653 654 status = AcpiEvaluateObject(handle, (ACPI_STRING)object, 655 (ACPI_OBJECT_LIST*)args, returnValue != NULL ? &buffer : NULL); 656 if (status == AE_BUFFER_OVERFLOW) 657 dprintf("evaluate_object: the passed buffer is too small!\n"); 658 659 return status == AE_OK ? B_OK : B_ERROR; 660 } 661 662 663 status_t 664 evaluate_method(acpi_handle handle, const char* method, 665 acpi_objects *args, acpi_data *returnValue) 666 { 667 ACPI_STATUS status; 668 669 status = AcpiEvaluateObject(handle, (ACPI_STRING)method, 670 (ACPI_OBJECT_LIST*)args, (ACPI_BUFFER*)returnValue); 671 if (status == AE_BUFFER_OVERFLOW) 672 dprintf("evaluate_method: the passed buffer is too small!\n"); 673 674 return status == AE_OK ? B_OK : B_ERROR; 675 } 676 677 678 status_t 679 get_irq_routing_table(acpi_handle busDeviceHandle, acpi_data *retBuffer) 680 { 681 ACPI_STATUS status; 682 683 status = AcpiGetIrqRoutingTable(busDeviceHandle, (ACPI_BUFFER*)retBuffer); 684 if (status == AE_BUFFER_OVERFLOW) 685 dprintf("evaluate_method: the passed buffer is too small!\n"); 686 687 return status == AE_OK ? B_OK : B_ERROR; 688 } 689 690 691 status_t 692 get_current_resources(acpi_handle busDeviceHandle, acpi_data *retBuffer) 693 { 694 return AcpiGetCurrentResources(busDeviceHandle, (ACPI_BUFFER*)retBuffer) 695 == AE_OK ? B_OK : B_ERROR; 696 } 697 698 699 status_t 700 get_possible_resources(acpi_handle busDeviceHandle, acpi_data *retBuffer) 701 { 702 return AcpiGetPossibleResources(busDeviceHandle, (ACPI_BUFFER*)retBuffer) 703 == AE_OK ? B_OK : B_ERROR; 704 } 705 706 707 status_t 708 set_current_resources(acpi_handle busDeviceHandle, acpi_data *buffer) 709 { 710 return AcpiSetCurrentResources(busDeviceHandle, (ACPI_BUFFER*)buffer) 711 == AE_OK ? B_OK : B_ERROR; 712 } 713 714 715 status_t 716 walk_resources(acpi_handle busDeviceHandle, char* method, 717 acpi_walk_resources_callback callback, void* context) 718 { 719 return AcpiWalkResources(busDeviceHandle, method, 720 (ACPI_WALK_RESOURCE_CALLBACK)callback, context); 721 } 722 723 724 status_t 725 prepare_sleep_state(uint8 state, void (*wakeFunc)(void), size_t size) 726 { 727 ACPI_STATUS acpiStatus; 728 729 TRACE("prepare_sleep_state %d, %p, %ld\n", state, wakeFunc, size); 730 731 if (state != ACPI_POWER_STATE_OFF) { 732 physical_entry wakeVector; 733 status_t status; 734 735 // Note: The supplied code must already be locked into memory. 736 status = get_memory_map((const void*)wakeFunc, size, &wakeVector, 1); 737 if (status != B_OK) 738 return status; 739 740 #if ACPI_MACHINE_WIDTH == 32 741 # if B_HAIKU_PHYSICAL_BITS > 32 742 if (wakeVector.address >= 0x100000000LL) { 743 ERROR("prepare_sleep_state(): ACPI_MACHINE_WIDTH == 32, but we " 744 "have a physical address >= 4 GB\n"); 745 } 746 # endif 747 acpiStatus = AcpiSetFirmwareWakingVector(wakeVector.address); 748 #else 749 acpiStatus = AcpiSetFirmwareWakingVector64(wakeVector.address); 750 #endif 751 if (acpiStatus != AE_OK) 752 return B_ERROR; 753 } 754 755 acpiStatus = AcpiEnterSleepStatePrep(state); 756 if (acpiStatus != AE_OK) 757 return B_ERROR; 758 759 return B_OK; 760 } 761 762 763 status_t 764 enter_sleep_state(uint8 state) 765 { 766 ACPI_STATUS status; 767 768 TRACE("enter_sleep_state %d\n", state); 769 770 cpu_status cpu = disable_interrupts(); 771 status = AcpiEnterSleepState(state); 772 restore_interrupts(cpu); 773 panic("AcpiEnterSleepState should not return."); 774 if (status != AE_OK) 775 return B_ERROR; 776 777 /*status = AcpiLeaveSleepState(state); 778 if (status != AE_OK) 779 return B_ERROR;*/ 780 781 return B_OK; 782 } 783 784 785 status_t 786 reboot(void) 787 { 788 ACPI_STATUS status; 789 790 TRACE("reboot\n"); 791 792 status = AcpiReset(); 793 if (status == AE_NOT_EXIST) 794 return B_UNSUPPORTED; 795 796 if (status != AE_OK) { 797 ERROR("Reset failed, status = %d\n", status); 798 return B_ERROR; 799 } 800 801 snooze(1000000); 802 ERROR("Reset failed, timeout\n"); 803 return B_ERROR; 804 } 805 806 807 status_t 808 get_table(const char* signature, uint32 instance, void** tableHeader) 809 { 810 return AcpiGetTable((char*)signature, instance, 811 (ACPI_TABLE_HEADER**)tableHeader) == AE_OK ? B_OK : B_ERROR; 812 } 813 814 815 status_t 816 read_bit_register(uint32 regid, uint32 *val) 817 { 818 return AcpiReadBitRegister(regid, (UINT32 *)val); 819 } 820 821 822 status_t 823 write_bit_register(uint32 regid, uint32 val) 824 { 825 return AcpiWriteBitRegister(regid, val); 826 } 827 828 829 struct acpi_module_info gACPIModule = { 830 { 831 B_ACPI_MODULE_NAME, 832 B_KEEP_LOADED, 833 acpi_std_ops 834 }, 835 836 get_handle, 837 get_name, 838 acquire_global_lock, 839 release_global_lock, 840 install_notify_handler, 841 remove_notify_handler, 842 update_all_gpes, 843 enable_gpe, 844 disable_gpe, 845 clear_gpe, 846 set_gpe, 847 finish_gpe, 848 install_gpe_handler, 849 remove_gpe_handler, 850 install_address_space_handler, 851 remove_address_space_handler, 852 enable_fixed_event, 853 disable_fixed_event, 854 fixed_event_status, 855 reset_fixed_event, 856 install_fixed_event_handler, 857 remove_fixed_event_handler, 858 get_next_entry, 859 get_next_object, 860 get_device, 861 get_device_hid, 862 get_object_type, 863 get_object, 864 get_object_typed, 865 ns_handle_to_pathname, 866 evaluate_object, 867 evaluate_method, 868 get_irq_routing_table, 869 get_current_resources, 870 get_possible_resources, 871 set_current_resources, 872 walk_resources, 873 prepare_sleep_state, 874 enter_sleep_state, 875 reboot, 876 get_table, 877 read_bit_register, 878 write_bit_register 879 }; 880