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