xref: /haiku/src/add-ons/kernel/bus_managers/acpi/ACPICAHaiku.cpp (revision fc7456e9b1ec38c941134ed6d01c438cf289381e)
1 /******************************************************************************
2  *
3  * Module Name: oshaiku - Haiku OSL interfaces
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights.  You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code.  No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision.  In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change.  Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee.  Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution.  In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government.  In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************/
115 
116 
117 #include <stdio.h>
118 #include <sys/cdefs.h>
119 #include <time.h>
120 #include <unistd.h>
121 
122 #include <OS.h>
123 
124 #ifdef _KERNEL_MODE
125 #	include <KernelExport.h>
126 
127 #	include <dpc.h>
128 #	include <PCI.h>
129 
130 #	include <boot_item.h>
131 #	include <kernel.h>
132 #	include <vm/vm.h>
133 #endif
134 
135 __BEGIN_DECLS
136 #include "acpi.h"
137 #include "accommon.h"
138 #include "amlcode.h"
139 #include "acparser.h"
140 #include "acdebug.h"
141 __END_DECLS
142 
143 #include "arch_init.h"
144 
145 
146 ACPI_MODULE_NAME("Haiku ACPI Module")
147 
148 #define _COMPONENT ACPI_OS_SERVICES
149 
150 // verbosity level 0 = off, 1 = normal, 2 = all
151 #define DEBUG_OSHAIKU 0
152 
153 #if DEBUG_OSHAIKU <= 0
154 // No debugging, do nothing
155 #	define DEBUG_FUNCTION()
156 #	define DEBUG_FUNCTION_F(x, y...)
157 #	define DEBUG_FUNCTION_V()
158 #	define DEBUG_FUNCTION_VF(x, y...)
159 #else
160 #	define DEBUG_FUNCTION() \
161 		dprintf("acpi[%" B_PRId32 "]: %s\n", find_thread(NULL), __PRETTY_FUNCTION__);
162 #	define DEBUG_FUNCTION_F(x, y...) \
163 		dprintf("acpi[%" B_PRId32 "]: %s(" x ")\n", find_thread(NULL), __PRETTY_FUNCTION__, y);
164 #	if DEBUG_OSHAIKU == 1
165 // No verbose debugging, do nothing
166 #		define DEBUG_FUNCTION_V()
167 #		define DEBUG_FUNCTION_VF(x, y...)
168 #	else
169 // Full debugging
170 #		define DEBUG_FUNCTION_V() \
171 			dprintf("acpi[%" B_PRId32 "]: %s\n", find_thread(NULL), __PRETTY_FUNCTION__);
172 #		define DEBUG_FUNCTION_VF(x, y...) \
173 			dprintf("acpi[%" B_PRId32 "]: %s(" x ")\n", find_thread(NULL), __PRETTY_FUNCTION__, y);
174 #	endif
175 #endif
176 
177 
178 #ifdef _KERNEL_MODE
179 extern pci_module_info *gPCIManager;
180 extern dpc_module_info *gDPC;
181 extern void *gDPCHandle;
182 #endif
183 
184 extern FILE *AcpiGbl_DebugFile;
185 FILE *AcpiGbl_OutputFile;
186 
187 static ACPI_PHYSICAL_ADDRESS sACPIRoot = 0;
188 static void *sInterruptHandlerData[32];
189 
190 
191 /******************************************************************************
192  *
193  * FUNCTION:    AcpiOsInitialize, AcpiOsTerminate
194  *
195  * PARAMETERS:  None
196  *
197  * RETURN:      Status
198  *
199  * DESCRIPTION: Init and terminate.  Nothing to do.
200  *
201  *****************************************************************************/
202 ACPI_STATUS
203 AcpiOsInitialize()
204 {
205 #ifndef _KERNEL_MODE
206 	AcpiGbl_OutputFile = stdout;
207 #else
208 	AcpiGbl_OutputFile = NULL;
209 #endif
210 	DEBUG_FUNCTION();
211 	return AE_OK;
212 }
213 
214 
215 ACPI_STATUS
216 AcpiOsTerminate()
217 {
218 	DEBUG_FUNCTION();
219 	return AE_OK;
220 }
221 
222 
223 /******************************************************************************
224  *
225  * FUNCTION:    AcpiOsGetRootPointer
226  *
227  * PARAMETERS:  None
228  *
229  * RETURN:      RSDP physical address
230  *
231  * DESCRIPTION: Gets the root pointer (RSDP)
232  *
233  *****************************************************************************/
234 ACPI_PHYSICAL_ADDRESS
235 AcpiOsGetRootPointer()
236 {
237 #ifdef _KERNEL_MODE
238 	DEBUG_FUNCTION();
239 	if (sACPIRoot == 0) {
240 		phys_addr_t* acpiRootPointer = (phys_addr_t*)get_boot_item("ACPI_ROOT_POINTER", NULL);
241 		if (acpiRootPointer != NULL)
242 			sACPIRoot = *acpiRootPointer;
243 
244 		if (sACPIRoot == 0)
245 			sACPIRoot = arch_init_find_root_pointer();
246 	}
247 	return sACPIRoot;
248 #else
249 	return AeLocalGetRootPointer();
250 #endif
251 }
252 
253 
254 /******************************************************************************
255  *
256  * FUNCTION:    AcpiOsPredefinedOverride
257  *
258  * PARAMETERS:  initVal     - Initial value of the predefined object
259  *              newVal      - The new value for the object
260  *
261  * RETURN:      Status, pointer to value.  Null pointer returned if not
262  *              overriding.
263  *
264  * DESCRIPTION: Allow the OS to override predefined names
265  *
266  *****************************************************************************/
267 ACPI_STATUS
268 AcpiOsPredefinedOverride(const ACPI_PREDEFINED_NAMES *initVal,
269 		ACPI_STRING *newVal)
270 {
271 	DEBUG_FUNCTION();
272 	if (!initVal || !newVal)
273 		return AE_BAD_PARAMETER;
274 
275 	*newVal = NULL;
276 	return AE_OK;
277 }
278 
279 
280 /******************************************************************************
281  *
282  * FUNCTION:    AcpiOsTableOverride
283  *
284  * PARAMETERS:  existingTable   - Header of current table (probably firmware)
285  *              newTable        - Where an entire new table is returned.
286  *
287  * RETURN:      Status, pointer to new table.  Null pointer returned if no
288  *              table is available to override
289  *
290  * DESCRIPTION: Return a different version of a table if one is available
291  *
292  *****************************************************************************/
293 ACPI_STATUS
294 AcpiOsTableOverride(ACPI_TABLE_HEADER *existingTable,
295 		ACPI_TABLE_HEADER **newTable)
296 {
297 	DEBUG_FUNCTION();
298 	if (!existingTable || !newTable)
299 		return AE_BAD_PARAMETER;
300 
301 	*newTable = NULL;
302 
303 #ifdef ACPI_EXEC_APP
304 	AeTableOverride(existingTable, newTable);
305 	return AE_OK;
306 #else
307 	return AE_NO_ACPI_TABLES;
308 #endif
309 }
310 
311 
312 /******************************************************************************
313  *
314  * FUNCTION:    AcpiOsPhysicalTableOverride
315  *
316  * PARAMETERS:  existingTable       - Header of current table (probably firmware)
317  *              newAddress          - Where new table address is returned
318  *                                    (Physical address)
319  *              newTableLength      - Where new table length is returned
320  *
321  * RETURN:      Status, address/length of new table. Null pointer returned
322  *              if no table is available to override.
323  *
324  * DESCRIPTION: Returns AE_SUPPORT, function not used in user space.
325  *
326  *****************************************************************************/
327 
328 ACPI_STATUS
329 AcpiOsPhysicalTableOverride(ACPI_TABLE_HEADER *existingTable,
330 	ACPI_PHYSICAL_ADDRESS *newAddress, UINT32 *newTableLength)
331 {
332 	DEBUG_FUNCTION();
333     return (AE_SUPPORT);
334 }
335 
336 
337 /******************************************************************************
338  *
339  * FUNCTION:    AcpiOsRedirectOutput
340  *
341  * PARAMETERS:  destination         - An open file handle/pointer
342  *
343  * RETURN:      None
344  *
345  * DESCRIPTION: Causes redirect of AcpiOsPrintf and AcpiOsVprintf
346  *
347  *****************************************************************************/
348 void
349 AcpiOsRedirectOutput(void *destination)
350 {
351 	DEBUG_FUNCTION();
352 	AcpiGbl_OutputFile = (FILE*)destination;
353 }
354 
355 
356 /******************************************************************************
357  *
358  * FUNCTION:    AcpiOsPrintf
359  *
360  * PARAMETERS:  fmt, ...            Standard printf format
361  *
362  * RETURN:      None
363  *
364  * DESCRIPTION: Formatted output
365  *
366  *****************************************************************************/
367 void ACPI_INTERNAL_VAR_XFACE
368 AcpiOsPrintf(const char *fmt, ...)
369 {
370 	va_list args;
371 
372 	DEBUG_FUNCTION();
373 	va_start(args, fmt);
374 	AcpiOsVprintf(fmt, args);
375 	va_end(args);
376 }
377 
378 
379 /******************************************************************************
380  *
381  * FUNCTION:    AcpiOsVprintf
382  *
383  * PARAMETERS:  fmt                 Standard printf format
384  *              args                Argument list
385  *
386  * RETURN:      None
387  *
388  * DESCRIPTION: Formatted output with argument list pointer
389  *
390  *****************************************************************************/
391 void
392 AcpiOsVprintf(const char *fmt, va_list args)
393 {
394 #ifndef _KERNEL_MODE
395 	UINT8 flags;
396 
397 	flags = AcpiGbl_DbOutputFlags;
398 	if (flags & ACPI_DB_REDIRECTABLE_OUTPUT) {
399 		// Output is directable to either a file (if open) or the console
400 		if (AcpiGbl_DebugFile) {
401 			// Output file is open, send the output there
402 			vfprintf(AcpiGbl_DebugFile, fmt, args);
403 		} else {
404 			// No redirection, send output to console (once only!)
405 			flags |= ACPI_DB_CONSOLE_OUTPUT;
406 		}
407 	}
408 
409 	if (flags & ACPI_DB_CONSOLE_OUTPUT) {
410 		vfprintf(AcpiGbl_OutputFile, fmt, args);
411     }
412 #else
413 	// Buffer the output until we have a complete line to send to syslog, this avoids added
414 	// "KERN:" entries in the middle of the line, and mixing up of the ACPI output with other
415 	// messages from other CPUs
416 	static char outputBuffer[1024];
417 
418 	// Append the new text to the buffer
419 	size_t len = strlen(outputBuffer);
420 	size_t printed = vsnprintf(outputBuffer + len, 1024 - len, fmt, args);
421 	if (printed >= 1024 - len) {
422 		// There was no space to fit the printed string in the outputBuffer. Remove what we added
423 		// there, fush the buffer, and print the long string directly
424 		outputBuffer[len] = '\0';
425 		dprintf("%s\n", outputBuffer);
426 		outputBuffer[0] = '\0';
427 		dvprintf(fmt, args);
428 		return;
429 	}
430 
431 	// See if we have a complete line
432 	char* eol = strchr(outputBuffer + len, '\n');
433 	while (eol != nullptr) {
434 		// Print the completed line, then remove it from the buffer
435 		*eol = 0;
436 		dprintf("%s\n", outputBuffer);
437 		memmove(outputBuffer, eol + 1, strlen(eol + 1) + 1);
438 		// See if there is another line to print still in the buffer (in case ACPICA would call
439 		// this function with a single string containing multiple newlines)
440 		eol = strchr(outputBuffer, '\n');
441 	}
442 #endif
443 }
444 
445 
446 /******************************************************************************
447  *
448  * FUNCTION:    AcpiOsGetLine
449  *
450  * PARAMETERS:  fmt                 Standard printf format
451  *              args                Argument list
452  *
453  * RETURN:      Actual bytes read
454  *
455  * DESCRIPTION: Formatted input with argument list pointer
456  *
457  *****************************************************************************/
458 UINT32
459 AcpiOsGetLine(char *buffer)
460 {
461 	uint32 i = 0;
462 
463 #ifndef _KERNEL_MODE
464 	uint8 temp;
465 
466 	for (i = 0; ; i++) {
467 		scanf("%1c", &temp);
468 		if (!temp || temp == '\n')
469 			break;
470 
471 		buffer[i] = temp;
472 	}
473 #endif
474 
475 	buffer[i] = 0;
476 	DEBUG_FUNCTION_F("buffer: \"%s\"; result: %" B_PRIu32, buffer, i);
477 	return i;
478 }
479 
480 
481 /******************************************************************************
482  *
483  * FUNCTION:    AcpiOsMapMemory
484  *
485  * PARAMETERS:  where               Physical address of memory to be mapped
486  *              length              How much memory to map
487  *
488  * RETURN:      Pointer to mapped memory.  Null on error.
489  *
490  * DESCRIPTION: Map physical memory into caller's address space
491  *
492  *****************************************************************************/
493 void *
494 AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS where, ACPI_SIZE length)
495 {
496 #ifdef _KERNEL_MODE
497 	// map_physical_memory() defaults to uncached memory if no type is specified.
498 	// But ACPICA handles flushing caches itself, so we don't need it uncached,
499 	// and on some architectures (e.g. ARM) uncached memory does not support
500 	// unaligned accesses. Hence we specify "writeback" to avoid the default.
501 	void *there;
502 	area_id area = map_physical_memory("acpi_physical_mem_area", (phys_addr_t)where, length,
503 		B_ANY_KERNEL_ADDRESS | B_WRITE_BACK_MEMORY, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
504 		&there);
505 
506 	DEBUG_FUNCTION_F("addr: 0x%08lx; length: %lu; mapped: %p; area: %" B_PRId32,
507 		(addr_t)where, (size_t)length, there, area);
508 	if (area < 0) {
509 		dprintf("ACPI: cannot map memory at 0x%" B_PRIu64 ", length %"
510 			B_PRIu64 "\n", (uint64)where, (uint64)length);
511 		return NULL;
512 	}
513 	return there;
514 #else
515 	return NULL;
516 #endif
517 
518 	// return ACPI_TO_POINTER((ACPI_SIZE) where);
519 }
520 
521 
522 /******************************************************************************
523  *
524  * FUNCTION:    AcpiOsUnmapMemory
525  *
526  * PARAMETERS:  where               Logical address of memory to be unmapped
527  *              length              How much memory to unmap
528  *
529  * RETURN:      None.
530  *
531  * DESCRIPTION: Delete a previously created mapping.  Where and Length must
532  *              correspond to a previous mapping exactly.
533  *
534  *****************************************************************************/
535 void
536 AcpiOsUnmapMemory(void *where, ACPI_SIZE length)
537 {
538 	DEBUG_FUNCTION_F("mapped: %p; length: %lu", where, (size_t)length);
539 	delete_area(area_for(where));
540 }
541 
542 
543 /******************************************************************************
544  *
545  * FUNCTION:    AcpiOsAllocate
546  *
547  * PARAMETERS:  size                Amount to allocate, in bytes
548  *
549  * RETURN:      Pointer to the new allocation.  Null on error.
550  *
551  * DESCRIPTION: Allocate memory.  Algorithm is dependent on the OS.
552  *
553  *****************************************************************************/
554 void *
555 AcpiOsAllocate(ACPI_SIZE size)
556 {
557 	void *mem = (void *) malloc(size);
558 	DEBUG_FUNCTION_VF("result: %p", mem);
559 	return mem;
560 }
561 
562 
563 /******************************************************************************
564  *
565  * FUNCTION:    AcpiOsFree
566  *
567  * PARAMETERS:  mem                 Pointer to previously allocated memory
568  *
569  * RETURN:      None.
570  *
571  * DESCRIPTION: Free memory allocated via AcpiOsAllocate
572  *
573  *****************************************************************************/
574 void
575 AcpiOsFree(void *mem)
576 {
577 	DEBUG_FUNCTION_VF("mem: %p", mem);
578 	free(mem);
579 }
580 
581 
582 /******************************************************************************
583  *
584  * FUNCTION:    AcpiOsCreateSemaphore
585  *
586  * PARAMETERS:  initialUnits        - Units to be assigned to the new semaphore
587  *              outHandle           - Where a handle will be returned
588  *
589  * RETURN:      Status
590  *
591  * DESCRIPTION: Create an OS semaphore
592  *
593  *****************************************************************************/
594 ACPI_STATUS
595 AcpiOsCreateSemaphore(UINT32 maxUnits, UINT32 initialUnits,
596 		ACPI_SEMAPHORE *outHandle)
597 {
598 	if (!outHandle)
599     	return AE_BAD_PARAMETER;
600 
601 	*outHandle = create_sem(initialUnits, "acpi_sem");
602 	DEBUG_FUNCTION_F("max: %" B_PRIu32 "; count: %" B_PRIu32 "; result: %" PRId32,
603 		(uint32)maxUnits, (uint32)initialUnits, *outHandle);
604 
605 	if (*outHandle >= B_OK)
606 		return AE_OK;
607 
608 	return *outHandle == B_BAD_VALUE ? AE_BAD_PARAMETER : AE_NO_MEMORY;
609 }
610 
611 
612 /******************************************************************************
613  *
614  * FUNCTION:    AcpiOsDeleteSemaphore
615  *
616  * PARAMETERS:  handle              - Handle returned by AcpiOsCreateSemaphore
617  *
618  * RETURN:      Status
619  *
620  * DESCRIPTION: Delete an OS semaphore
621  *
622  *****************************************************************************/
623 ACPI_STATUS
624 AcpiOsDeleteSemaphore(ACPI_SEMAPHORE handle)
625 {
626 	DEBUG_FUNCTION_F("sem: %" B_PRId32, handle);
627 	return delete_sem(handle) == B_OK ? AE_OK : AE_BAD_PARAMETER;
628 }
629 
630 
631 /******************************************************************************
632  *
633  * FUNCTION:    AcpiOsWaitSemaphore
634  *
635  * PARAMETERS:  handle              - Handle returned by AcpiOsCreateSemaphore
636  *              units               - How many units to wait for
637  *              timeout             - How long to wait
638  *
639  * RETURN:      Status
640  *
641  * DESCRIPTION: Wait for units
642  *
643  *****************************************************************************/
644 ACPI_STATUS
645 AcpiOsWaitSemaphore(ACPI_SEMAPHORE handle, UINT32 units, UINT16 timeout)
646 {
647 	ACPI_STATUS result = AE_OK;
648 	DEBUG_FUNCTION_VF("sem: %ld; count: %lu; timeout: %u",
649 		handle, (uint32)units, timeout);
650 
651 	if (timeout == ACPI_WAIT_FOREVER) {
652 		result = acquire_sem_etc(handle, units, 0, 0)
653 			== B_OK ? AE_OK : AE_BAD_PARAMETER;
654 	} else {
655 		switch (acquire_sem_etc(handle, units, B_RELATIVE_TIMEOUT,
656 			(bigtime_t)timeout * 1000)) {
657 			case B_OK:
658 				result = AE_OK;
659 				break;
660 			case B_INTERRUPTED:
661 			case B_TIMED_OUT:
662 			case B_WOULD_BLOCK:
663 				result = AE_TIME;
664 				break;
665 			case B_BAD_VALUE:
666 			default:
667 				result = AE_BAD_PARAMETER;
668 				break;
669 		}
670 	}
671 	DEBUG_FUNCTION_VF("sem: %ld; count: %lu; timeout: %u result: %lu",
672 		handle, (uint32)units, timeout, (uint32)result);
673 	return result;
674 }
675 
676 
677 /******************************************************************************
678  *
679  * FUNCTION:    AcpiOsSignalSemaphore
680  *
681  * PARAMETERS:  handle              - Handle returned by AcpiOsCreateSemaphore
682  *              units               - Number of units to send
683  *
684  * RETURN:      Status
685  *
686  * DESCRIPTION: Send units
687  *
688  *****************************************************************************/
689 ACPI_STATUS
690 AcpiOsSignalSemaphore(ACPI_SEMAPHORE handle, UINT32 units)
691 {
692 	status_t result;
693 	DEBUG_FUNCTION_VF("sem: %ld; count: %lu", handle, (uint32)units);
694 	// We can be called from interrupt handler, so don't reschedule
695 	result = release_sem_etc(handle, units, B_DO_NOT_RESCHEDULE);
696 	return result == B_OK ? AE_OK : AE_BAD_PARAMETER;
697 }
698 
699 
700 /******************************************************************************
701  *
702  * FUNCTION:    Spinlock interfaces
703  *
704  * DESCRIPTION: Map these interfaces to semaphore interfaces
705  *
706  *****************************************************************************/
707 ACPI_STATUS
708 AcpiOsCreateLock(ACPI_SPINLOCK *outHandle)
709 {
710 	*outHandle = (ACPI_SPINLOCK) malloc(sizeof(spinlock));
711 	DEBUG_FUNCTION_F("result: %p", *outHandle);
712 	if (*outHandle == NULL)
713 		return AE_NO_MEMORY;
714 
715 	B_INITIALIZE_SPINLOCK(*outHandle);
716 	return AE_OK;
717 }
718 
719 
720 void
721 AcpiOsDeleteLock(ACPI_SPINLOCK handle)
722 {
723 	DEBUG_FUNCTION();
724 	free((void*)handle);
725 }
726 
727 
728 ACPI_CPU_FLAGS
729 AcpiOsAcquireLock(ACPI_SPINLOCK handle)
730 {
731 	cpu_status cpu;
732 	DEBUG_FUNCTION_F("spinlock: %p", handle);
733 	cpu = disable_interrupts();
734 	acquire_spinlock(handle);
735 	return cpu;
736 }
737 
738 
739 void
740 AcpiOsReleaseLock(ACPI_SPINLOCK handle, ACPI_CPU_FLAGS flags)
741 {
742 	release_spinlock(handle);
743 	restore_interrupts(flags);
744 	DEBUG_FUNCTION_F("spinlock: %p", handle);
745 }
746 
747 
748 /******************************************************************************
749  *
750  * FUNCTION:    AcpiOsInstallInterruptHandler
751  *
752  * PARAMETERS:  interruptNumber     Level handler should respond to.
753  *              Isr                 Address of the ACPI interrupt handler
754  *              ExceptPtr           Where status is returned
755  *
756  * RETURN:      Handle to the newly installed handler.
757  *
758  * DESCRIPTION: Install an interrupt handler.  Used to install the ACPI
759  *              OS-independent handler.
760  *
761  *****************************************************************************/
762 UINT32
763 AcpiOsInstallInterruptHandler(UINT32 interruptNumber,
764 		ACPI_OSD_HANDLER serviceRoutine, void *context)
765 {
766 	status_t result;
767 	DEBUG_FUNCTION_F("vector: %" B_PRIu32 "; handler: %p context %p",
768 		(uint32)interruptNumber, serviceRoutine, context);
769 
770 #ifdef _KERNEL_MODE
771 	// It so happens that the Haiku and ACPI-CA interrupt handler routines
772 	// return the same values with the same meanings
773 	sInterruptHandlerData[interruptNumber] = context;
774 	result = install_io_interrupt_handler(interruptNumber,
775 		(interrupt_handler)serviceRoutine, context, 0);
776 
777 	DEBUG_FUNCTION_F("vector: %" B_PRIu32 "; handler: %p context %p returned %" B_PRId32,
778 		(uint32)interruptNumber, serviceRoutine, context, (uint32)result);
779 
780 	return result == B_OK ? AE_OK : AE_BAD_PARAMETER;
781 #else
782 	return AE_BAD_PARAMETER;
783 #endif
784 }
785 
786 
787 /******************************************************************************
788  *
789  * FUNCTION:    AcpiOsRemoveInterruptHandler
790  *
791  * PARAMETERS:  Handle              Returned when handler was installed
792  *
793  * RETURN:      Status
794  *
795  * DESCRIPTION: Uninstalls an interrupt handler.
796  *
797  *****************************************************************************/
798 ACPI_STATUS
799 AcpiOsRemoveInterruptHandler(UINT32 interruptNumber,
800 		ACPI_OSD_HANDLER serviceRoutine)
801 {
802 	DEBUG_FUNCTION_F("vector: %" B_PRIu32 "; handler: %p", (uint32)interruptNumber,
803 		serviceRoutine);
804 #ifdef _KERNEL_MODE
805 	return remove_io_interrupt_handler(interruptNumber,
806 		(interrupt_handler)serviceRoutine,
807 		sInterruptHandlerData[interruptNumber]) == B_OK ? AE_OK : AE_ERROR;
808 #else
809 	return AE_ERROR;
810 #endif
811 }
812 
813 
814 /******************************************************************************
815  *
816  * FUNCTION:    AcpiOsExecute
817  *
818  * PARAMETERS:  type            - Type of execution
819  *              function        - Address of the function to execute
820  *              context         - Passed as a parameter to the function
821  *
822  * RETURN:      Status.
823  *
824  * DESCRIPTION: Execute a new thread
825  *
826  *****************************************************************************/
827 ACPI_STATUS
828 AcpiOsExecute(ACPI_EXECUTE_TYPE type, ACPI_OSD_EXEC_CALLBACK  function,
829 		void *context)
830 {
831 	DEBUG_FUNCTION();
832 /* TODO: Prioritize urgent?
833 	switch (type) {
834 		case OSL_GLOBAL_LOCK_HANDLER:
835 		case OSL_NOTIFY_HANDLER:
836 		case OSL_GPE_HANDLER:
837 		case OSL_DEBUGGER_THREAD:
838 		case OSL_EC_POLL_HANDLER:
839 		case OSL_EC_BURST_HANDLER:
840 			break;
841 	}
842 */
843 
844 	if (gDPC->queue_dpc(gDPCHandle, function, context) != B_OK) {
845 		DEBUG_FUNCTION_F("Serious failure in AcpiOsExecute! function: %p",
846 			function);
847 		return AE_BAD_PARAMETER;
848 	}
849 	return AE_OK;
850 }
851 
852 
853 /******************************************************************************
854  *
855  * FUNCTION:    AcpiOsStall
856  *
857  * PARAMETERS:  microseconds        To sleep
858  *
859  * RETURN:      Blocks until sleep is completed.
860  *
861  * DESCRIPTION: Sleep at microsecond granularity
862  *
863  *****************************************************************************/
864 void
865 AcpiOsStall(UINT32 microseconds)
866 {
867 	DEBUG_FUNCTION_F("microseconds: %" B_PRIu32, (uint32)microseconds);
868 	if (microseconds)
869 		spin(microseconds);
870 }
871 
872 
873 /******************************************************************************
874  *
875  * FUNCTION:    AcpiOsSleep
876  *
877  * PARAMETERS:  milliseconds        To sleep
878  *
879  * RETURN:      Blocks until sleep is completed.
880  *
881  * DESCRIPTION: Sleep at millisecond granularity
882  *
883  *****************************************************************************/
884 void
885 AcpiOsSleep(ACPI_INTEGER milliseconds)
886 {
887 	DEBUG_FUNCTION_F("milliseconds: %" B_PRIu32, (uint32)milliseconds);
888 	if (gKernelStartup)
889 		spin(milliseconds * 1000);
890 	else
891 		snooze(milliseconds * 1000);
892 }
893 
894 
895 /******************************************************************************
896  *
897  * FUNCTION:    AcpiOsGetTimer
898  *
899  * PARAMETERS:  None
900  *
901  * RETURN:      Current time in 100 nanosecond units
902  *
903  * DESCRIPTION: Get the current system time
904  *
905  *****************************************************************************/
906 UINT64
907 AcpiOsGetTimer()
908 {
909 	DEBUG_FUNCTION();
910 	return system_time() * 10;
911 }
912 
913 
914 /******************************************************************************
915  *
916  * FUNCTION:    AcpiOsReadPciConfiguration
917  *
918  * PARAMETERS:  pciId               Seg/Bus/Dev
919  *              reg                 Device Register
920  *              value               Buffer where value is placed
921  *              width               Number of bits
922  *
923  * RETURN:      Status
924  *
925  * DESCRIPTION: Read data from PCI configuration space
926  *
927  *****************************************************************************/
928 ACPI_STATUS
929 AcpiOsReadPciConfiguration(ACPI_PCI_ID *pciId, UINT32 reg, UINT64 *value,
930 		UINT32 width)
931 {
932 #ifdef _KERNEL_MODE
933 	DEBUG_FUNCTION();
934 
935 	switch (width) {
936 		case 8:
937 		case 16:
938 		case 32:
939 			*value = gPCIManager->read_pci_config(
940 				pciId->Bus, pciId->Device, pciId->Function, reg, width / 8);
941 			break;
942 		default:
943 			return AE_ERROR;
944 	}
945 	return AE_OK;
946 #else
947 	return AE_ERROR;
948 #endif
949 }
950 
951 
952 /******************************************************************************
953  *
954  * FUNCTION:    AcpiOsWritePciConfiguration
955  *
956  * PARAMETERS:  pciId               Seg/Bus/Dev
957  *              reg                 Device Register
958  *              value               Value to be written
959  *              width               Number of bits
960  *
961  * RETURN:      Status.
962  *
963  * DESCRIPTION: Write data to PCI configuration space
964  *
965  *****************************************************************************/
966 ACPI_STATUS
967 AcpiOsWritePciConfiguration(ACPI_PCI_ID *pciId, UINT32 reg,
968 		ACPI_INTEGER value, UINT32 width)
969 {
970 #ifdef _KERNEL_MODE
971 	DEBUG_FUNCTION();
972 	gPCIManager->write_pci_config(
973 		pciId->Bus, pciId->Device, pciId->Function, reg, width / 8, value);
974 	return AE_OK;
975 #else
976 	return AE_ERROR;
977 #endif
978 }
979 
980 
981 /******************************************************************************
982  *
983  * FUNCTION:    AcpiOsReadPort
984  *
985  * PARAMETERS:  address             Address of I/O port/register to read
986  *              Value               Where value is placed
987  *              width               Number of bits
988  *
989  * RETURN:      Value read from port
990  *
991  * DESCRIPTION: Read data from an I/O port or register
992  *
993  *****************************************************************************/
994 ACPI_STATUS
995 AcpiOsReadPort(ACPI_IO_ADDRESS address, UINT32 *value, UINT32 width)
996 {
997 #ifdef _KERNEL_MODE
998 	DEBUG_FUNCTION_F("addr: 0x%08lx; width: %" B_PRIu32, (addr_t)address, (uint32)width);
999 	switch (width) {
1000 		case 8:
1001 			*value = gPCIManager->read_io_8(address);
1002 			break;
1003 
1004 		case 16:
1005 			*value = gPCIManager->read_io_16(address);
1006 			break;
1007 
1008 		case 32:
1009 			*value = gPCIManager->read_io_32(address);
1010 			break;
1011 
1012 		default:
1013 			return AE_ERROR;
1014 	}
1015 
1016 	return AE_OK;
1017 #else
1018 	return AE_ERROR;
1019 #endif
1020 }
1021 
1022 
1023 /******************************************************************************
1024  *
1025  * FUNCTION:    AcpiOsWritePort
1026  *
1027  * PARAMETERS:  address             Address of I/O port/register to write
1028  *              value               Value to write
1029  *              width               Number of bits
1030  *
1031  * RETURN:      None
1032  *
1033  * DESCRIPTION: Write data to an I/O port or register
1034  *
1035  *****************************************************************************/
1036 ACPI_STATUS
1037 AcpiOsWritePort(ACPI_IO_ADDRESS address, UINT32 value, UINT32 width)
1038 {
1039 #ifdef _KERNEL_MODE
1040 	DEBUG_FUNCTION_F("addr: 0x%08lx; value: %" B_PRIu32 "; width: %" B_PRIu32,
1041 		(addr_t)address, (uint32)value, (uint32)width);
1042 	switch (width) {
1043 		case 8:
1044 			gPCIManager->write_io_8(address, value);
1045 			break;
1046 
1047 		case 16:
1048 			gPCIManager->write_io_16(address,value);
1049 			break;
1050 
1051 		case 32:
1052 			gPCIManager->write_io_32(address,value);
1053 			break;
1054 
1055 		default:
1056 			return AE_ERROR;
1057 	}
1058 
1059 	return AE_OK;
1060 #else
1061 	return AE_ERROR;
1062 #endif
1063 }
1064 
1065 
1066 /******************************************************************************
1067  *
1068  * FUNCTION:    AcpiOsReadMemory
1069  *
1070  * PARAMETERS:  address             Physical Memory Address to read
1071  *              value               Where value is placed
1072  *              width               Number of bits
1073  *
1074  * RETURN:      Value read from physical memory address
1075  *
1076  * DESCRIPTION: Read data from a physical memory address
1077  *
1078  *****************************************************************************/
1079 ACPI_STATUS
1080 AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS address, UINT64 *value, UINT32 width)
1081 {
1082 #ifdef _KERNEL_MODE
1083 	if (vm_memcpy_from_physical(value, (phys_addr_t)address, width / 8, false)
1084 		!= B_OK) {
1085 		return AE_ERROR;
1086 	}
1087 	return AE_OK;
1088 #else
1089 	return AE_ERROR;
1090 #endif
1091 }
1092 
1093 
1094 /******************************************************************************
1095  *
1096  * FUNCTION:    AcpiOsWriteMemory
1097  *
1098  * PARAMETERS:  address             Physical Memory Address to write
1099  *              value               Value to write
1100  *              width               Number of bits
1101  *
1102  * RETURN:      None
1103  *
1104  * DESCRIPTION: Write data to a physical memory address
1105  *
1106  *****************************************************************************/
1107 ACPI_STATUS
1108 AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS address, UINT64 value, UINT32 width)
1109 {
1110 #ifdef _KERNEL_MODE
1111 	if (vm_memcpy_to_physical((phys_addr_t)address, &value, width / 8, false)
1112 			!= B_OK) {
1113 		return AE_ERROR;
1114 	}
1115 	return AE_OK;
1116 #else
1117 	return AE_ERROR;
1118 #endif
1119 }
1120 
1121 
1122 /******************************************************************************
1123  *
1124  * FUNCTION:    AcpiOsReadable
1125  *
1126  * PARAMETERS:  pointer             - Area to be verified
1127  *              length              - Size of area
1128  *
1129  * RETURN:      TRUE if readable for entire length
1130  *
1131  * DESCRIPTION: Verify that a pointer is valid for reading
1132  *
1133  *****************************************************************************/
1134 BOOLEAN
1135 AcpiOsReadable(void *pointer, ACPI_SIZE length)
1136 {
1137 #ifdef _KERNEL_MODE
1138 	return true;
1139 #else
1140 	area_id id;
1141 	area_info info;
1142 
1143 	DEBUG_FUNCTION_F("addr: %p; length: %lu", pointer, (size_t)length);
1144 
1145 	id = area_for(pointer);
1146 	if (id == B_ERROR) return false;
1147 	if (get_area_info(id, &info) != B_OK) return false;
1148 	return (info.protection & B_READ_AREA) != 0 &&
1149 			((char *)pointer) + length <= info.address + info.ram_size;
1150 #endif
1151 }
1152 
1153 
1154 /******************************************************************************
1155  *
1156  * FUNCTION:    AcpiOsWritable
1157  *
1158  * PARAMETERS:  pointer             - Area to be verified
1159  *              length              - Size of area
1160  *
1161  * RETURN:      TRUE if writable for entire length
1162  *
1163  * DESCRIPTION: Verify that a pointer is valid for writing
1164  *
1165  *****************************************************************************/
1166 BOOLEAN
1167 AcpiOsWritable(void *pointer, ACPI_SIZE length)
1168 {
1169 #ifdef _KERNEL_MODE
1170 	return true;
1171 #else
1172 	area_id id;
1173 	area_info info;
1174 
1175 	DEBUG_FUNCTION_F("addr: %p; length: %lu", pointer, (size_t)length);
1176 
1177 	id = area_for(pointer);
1178 	if (id == B_ERROR) return false;
1179 	if (get_area_info(id, &info) != B_OK) return false;
1180 	return (info.protection & B_READ_AREA) != 0 &&
1181 			(info.protection & B_WRITE_AREA) != 0 &&
1182 			((char *)pointer) + length <= info.address + info.ram_size;
1183 #endif
1184 }
1185 
1186 
1187 /******************************************************************************
1188  *
1189  * FUNCTION:    AcpiOsGetThreadId
1190  *
1191  * PARAMETERS:  None
1192  *
1193  * RETURN:      Id of the running thread
1194  *
1195  * DESCRIPTION: Get the Id of the current (running) thread
1196  *
1197  * NOTE:        The environment header should contain this line:
1198  *                  #define ACPI_THREAD_ID pthread_t
1199  *
1200  *****************************************************************************/
1201 ACPI_THREAD_ID
1202 AcpiOsGetThreadId()
1203 {
1204 	thread_id thread = find_thread(NULL);
1205 	// TODO: We arn't allowed threads with id 0, handle this case.
1206 	// ACPI treats a 0 return as an error,
1207 	// but we are thread 0 in early boot
1208 	return thread;
1209 }
1210 
1211 
1212 /******************************************************************************
1213  *
1214  * FUNCTION:    AcpiOsSignal
1215  *
1216  * PARAMETERS:  function            ACPI CA signal function code
1217  *              info                Pointer to function-dependent structure
1218  *
1219  * RETURN:      Status
1220  *
1221  * DESCRIPTION: Miscellaneous functions. Example implementation only.
1222  *
1223  *****************************************************************************/
1224 ACPI_STATUS
1225 AcpiOsSignal(UINT32 function, void *info)
1226 {
1227 	DEBUG_FUNCTION();
1228 
1229 	switch (function) {
1230 		case ACPI_SIGNAL_FATAL:
1231 #ifdef _KERNEL_MODE
1232 			panic("%s", info == NULL ? "AcpiOsSignal: fatal" : (const char*)info);
1233 			break;
1234 #endif
1235 		case ACPI_SIGNAL_BREAKPOINT:
1236 			if (info != NULL)
1237 				AcpiOsPrintf("AcpiOsBreakpoint: %s ****\n", (const char*)info);
1238 			else
1239 				AcpiOsPrintf("At AcpiOsBreakpoint ****\n");
1240 			break;
1241 	}
1242 
1243 	return AE_OK;
1244 }
1245 
1246 
1247 /*
1248  * Adapted from FreeBSD since the documentation of its intended impl
1249  * is lacking.
1250  *  Section 5.2.10.1: global lock acquire/release functions */
1251 
1252 /*
1253  * Adapted from FreeBSD since the documentation of its intended impl
1254  * is lacking.
1255  * Acquire the global lock.  If busy, set the pending bit.  The caller
1256  * will wait for notification from the BIOS that the lock is available
1257  * and then attempt to acquire it again.
1258  */
1259 int
1260 AcpiOsAcquireGlobalLock(volatile uint32_t *lock)
1261 {
1262 	uint32_t newValue;
1263 	uint32_t oldValue;
1264 
1265 	do {
1266 		oldValue = *lock;
1267 		newValue = ((oldValue & ~ACPI_GLOCK_PENDING) | ACPI_GLOCK_OWNED);
1268 		if ((oldValue & ACPI_GLOCK_OWNED) != 0)
1269 			newValue |= ACPI_GLOCK_PENDING;
1270 	} while (atomic_test_and_set((int32*)lock, newValue, oldValue) != (int32)oldValue);
1271 
1272 	return (newValue & ACPI_GLOCK_PENDING) == 0;
1273 }
1274 
1275 
1276 /*
1277  * Adapted from FreeBSD since the documentation of its intended impl
1278  * is lacking.
1279  * Release the global lock, returning whether there is a waiter pending.
1280  * If the BIOS set the pending bit, OSPM must notify the BIOS when it
1281  * releases the lock.
1282  */
1283 int
1284 AcpiOsReleaseGlobalLock(volatile uint32_t *lock)
1285 {
1286 	uint32 newValue;
1287 	uint32 oldValue;
1288 
1289 	do {
1290 		oldValue = *lock;
1291 		newValue = oldValue & ~(ACPI_GLOCK_PENDING | ACPI_GLOCK_OWNED);
1292 	} while (atomic_test_and_set((int32*)lock, newValue, oldValue) != (int32)oldValue);
1293 
1294 	return (oldValue & ACPI_GLOCK_PENDING) != 0;
1295 }
1296 
1297 
1298 ACPI_STATUS
1299 AcpiOsCreateMutex(ACPI_MUTEX* outHandle)
1300 {
1301 	*outHandle = (ACPI_MUTEX) malloc(sizeof(mutex));
1302 	DEBUG_FUNCTION_F("result: %p", *outHandle);
1303 	if (*outHandle == NULL)
1304 		return AE_NO_MEMORY;
1305 
1306 	mutex_init(*outHandle, "acpi mutex");
1307 	return AE_OK;
1308 }
1309 
1310 
1311 void
1312 AcpiOsDeleteMutex(ACPI_MUTEX handle)
1313 {
1314 	DEBUG_FUNCTION_F("mutex: %ld", (addr_t)handle);
1315 	mutex_destroy(handle);
1316 	free((void*)handle);
1317 }
1318 
1319 
1320 ACPI_STATUS
1321 AcpiOsAcquireMutex(ACPI_MUTEX handle, UINT16 timeout)
1322 {
1323 	ACPI_STATUS result = AE_OK;
1324 	DEBUG_FUNCTION_VF("mutex: %p; timeout: %u", handle, timeout);
1325 
1326 	if (timeout == ACPI_WAIT_FOREVER) {
1327 		result = (mutex_lock(handle) == B_OK) ? AE_OK : AE_BAD_PARAMETER;
1328 	} else if (timeout == ACPI_DO_NOT_WAIT) {
1329 		result = (mutex_trylock(handle) == B_OK) ? AE_OK : AE_TIME;
1330 	} else {
1331 		switch (mutex_lock_with_timeout(handle, B_RELATIVE_TIMEOUT,
1332 			(bigtime_t)timeout * 1000)) {
1333 			case B_OK:
1334 				result = AE_OK;
1335 				break;
1336 			case B_INTERRUPTED:
1337 			case B_TIMED_OUT:
1338 			case B_WOULD_BLOCK:
1339 				result = AE_TIME;
1340 				break;
1341 			case B_BAD_VALUE:
1342 			default:
1343 				result = AE_BAD_PARAMETER;
1344 				break;
1345 		}
1346 	}
1347 	DEBUG_FUNCTION_VF("mutex: %p; timeout: %u result: %lu",
1348 		handle, timeout, (uint32)result);
1349 	return result;
1350 }
1351 
1352 
1353 void
1354 AcpiOsReleaseMutex(ACPI_MUTEX handle)
1355 {
1356 	DEBUG_FUNCTION_F("mutex: %p", handle);
1357 	mutex_unlock(handle);
1358 }
1359 
1360 
1361 /******************************************************************************
1362  *
1363  * FUNCTION:    AcpiOsWaitEventsComplete
1364  *
1365  * PARAMETERS:  None
1366  *
1367  * RETURN:      None
1368  *
1369  * DESCRIPTION: Wait for all asynchronous events to complete. This
1370  *              implementation does nothing.
1371  *
1372  *****************************************************************************/
1373 void
1374 AcpiOsWaitEventsComplete()
1375 {
1376     //TODO: FreeBSD See description.
1377     return;
1378 }
1379 
1380 
1381 /******************************************************************************
1382  *
1383  * FUNCTION:    AcpiOsEnterSleep
1384  *
1385  * PARAMETERS:  SleepState          - Which sleep state to enter
1386  *              RegaValue           - Register A value
1387  *              RegbValue           - Register B value
1388  *
1389  * RETURN:      Status
1390  *
1391  * DESCRIPTION: A hook before writing sleep registers to enter the sleep
1392  *              state. Return AE_CTRL_TERMINATE to skip further sleep register
1393  *              writes.
1394  *
1395  *****************************************************************************/
1396 
1397 ACPI_STATUS
1398 AcpiOsEnterSleep (
1399 	UINT8                   SleepState,
1400 	UINT32                  RegaValue,
1401 	UINT32                  RegbValue)
1402 {
1403 	return (AE_OK);
1404 }
1405