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