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