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
AcpiOsInitialize()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
AcpiOsTerminate()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
AcpiOsGetRootPointer()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
AcpiOsPredefinedOverride(const ACPI_PREDEFINED_NAMES * initVal,ACPI_STRING * newVal)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
AcpiOsTableOverride(ACPI_TABLE_HEADER * existingTable,ACPI_TABLE_HEADER ** newTable)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
AcpiOsPhysicalTableOverride(ACPI_TABLE_HEADER * existingTable,ACPI_PHYSICAL_ADDRESS * newAddress,UINT32 * newTableLength)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
AcpiOsRedirectOutput(void * destination)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
AcpiOsPrintf(const char * fmt,...)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
AcpiOsVprintf(const char * fmt,va_list args)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
AcpiOsGetLine(char * buffer)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 *
AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS where,ACPI_SIZE length)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
AcpiOsUnmapMemory(void * where,ACPI_SIZE length)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 *
AcpiOsAllocate(ACPI_SIZE size)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
AcpiOsFree(void * mem)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
AcpiOsCreateSemaphore(UINT32 maxUnits,UINT32 initialUnits,ACPI_SEMAPHORE * outHandle)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
AcpiOsDeleteSemaphore(ACPI_SEMAPHORE handle)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
AcpiOsWaitSemaphore(ACPI_SEMAPHORE handle,UINT32 units,UINT16 timeout)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
AcpiOsSignalSemaphore(ACPI_SEMAPHORE handle,UINT32 units)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
AcpiOsCreateLock(ACPI_SPINLOCK * outHandle)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
AcpiOsDeleteLock(ACPI_SPINLOCK handle)721 AcpiOsDeleteLock(ACPI_SPINLOCK handle)
722 {
723 DEBUG_FUNCTION();
724 free((void*)handle);
725 }
726
727
728 ACPI_CPU_FLAGS
AcpiOsAcquireLock(ACPI_SPINLOCK handle)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
AcpiOsReleaseLock(ACPI_SPINLOCK handle,ACPI_CPU_FLAGS flags)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
AcpiOsInstallInterruptHandler(UINT32 interruptNumber,ACPI_OSD_HANDLER serviceRoutine,void * context)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
AcpiOsRemoveInterruptHandler(UINT32 interruptNumber,ACPI_OSD_HANDLER serviceRoutine)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
AcpiOsExecute(ACPI_EXECUTE_TYPE type,ACPI_OSD_EXEC_CALLBACK function,void * context)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
AcpiOsStall(UINT32 microseconds)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
AcpiOsSleep(ACPI_INTEGER milliseconds)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
AcpiOsGetTimer()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
AcpiOsReadPciConfiguration(ACPI_PCI_ID * pciId,UINT32 reg,UINT64 * value,UINT32 width)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
AcpiOsWritePciConfiguration(ACPI_PCI_ID * pciId,UINT32 reg,ACPI_INTEGER value,UINT32 width)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
AcpiOsReadPort(ACPI_IO_ADDRESS address,UINT32 * value,UINT32 width)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
AcpiOsWritePort(ACPI_IO_ADDRESS address,UINT32 value,UINT32 width)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
AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS address,UINT64 * value,UINT32 width)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
AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS address,UINT64 value,UINT32 width)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
AcpiOsReadable(void * pointer,ACPI_SIZE length)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
AcpiOsWritable(void * pointer,ACPI_SIZE length)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
AcpiOsGetThreadId()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
AcpiOsSignal(UINT32 function,void * info)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
AcpiOsAcquireGlobalLock(volatile uint32_t * lock)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
AcpiOsReleaseGlobalLock(volatile uint32_t * lock)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
AcpiOsCreateMutex(ACPI_MUTEX * outHandle)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
AcpiOsDeleteMutex(ACPI_MUTEX handle)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
AcpiOsAcquireMutex(ACPI_MUTEX handle,UINT16 timeout)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
AcpiOsReleaseMutex(ACPI_MUTEX handle)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
AcpiOsWaitEventsComplete()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
AcpiOsEnterSleep(UINT8 SleepState,UINT32 RegaValue,UINT32 RegbValue)1398 AcpiOsEnterSleep (
1399 UINT8 SleepState,
1400 UINT32 RegaValue,
1401 UINT32 RegbValue)
1402 {
1403 return (AE_OK);
1404 }
1405