xref: /freebsd/sys/contrib/dev/acpica/os_specific/service_layers/osunixxf.c (revision 8ddb146abcdf061be9f2c0db7e391697dafad85c)
1 /******************************************************************************
2  *
3  * Module Name: osunixxf - UNIX OSL interfaces
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2022, 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  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 /*
153  * These interfaces are required in order to compile the ASL compiler and the
154  * various ACPICA tools under Linux or other Unix-like system.
155  */
156 #include <contrib/dev/acpica/include/acpi.h>
157 #include <contrib/dev/acpica/include/accommon.h>
158 #include <contrib/dev/acpica/include/amlcode.h>
159 #include <contrib/dev/acpica/include/acparser.h>
160 #include <contrib/dev/acpica/include/acdebug.h>
161 
162 #include <stdio.h>
163 #include <stdlib.h>
164 #include <stdarg.h>
165 #include <unistd.h>
166 #include <sys/time.h>
167 #include <semaphore.h>
168 #include <pthread.h>
169 #include <errno.h>
170 
171 #define _COMPONENT          ACPI_OS_SERVICES
172         ACPI_MODULE_NAME    ("osunixxf")
173 
174 
175 /* Upcalls to AcpiExec */
176 
177 void
178 AeTableOverride (
179     ACPI_TABLE_HEADER       *ExistingTable,
180     ACPI_TABLE_HEADER       **NewTable);
181 
182 typedef void* (*PTHREAD_CALLBACK) (void *);
183 
184 /* Buffer used by AcpiOsVprintf */
185 
186 #define ACPI_VPRINTF_BUFFER_SIZE    512
187 #define _ASCII_NEWLINE              '\n'
188 
189 /* Terminal support for AcpiExec only */
190 
191 #ifdef ACPI_EXEC_APP
192 #include <termios.h>
193 
194 struct termios              OriginalTermAttributes;
195 int                         TermAttributesWereSet = 0;
196 
197 ACPI_STATUS
198 AcpiUtReadLine (
199     char                    *Buffer,
200     UINT32                  BufferLength,
201     UINT32                  *BytesRead);
202 
203 static void
204 OsEnterLineEditMode (
205     void);
206 
207 static void
208 OsExitLineEditMode (
209     void);
210 
211 
212 /******************************************************************************
213  *
214  * FUNCTION:    OsEnterLineEditMode, OsExitLineEditMode
215  *
216  * PARAMETERS:  None
217  *
218  * RETURN:      None
219  *
220  * DESCRIPTION: Enter/Exit the raw character input mode for the terminal.
221  *
222  * Interactive line-editing support for the AML debugger. Used with the
223  * common/acgetline module.
224  *
225  * readline() is not used because of non-portability. It is not available
226  * on all systems, and if it is, often the package must be manually installed.
227  *
228  * Therefore, we use the POSIX tcgetattr/tcsetattr and do the minimal line
229  * editing that we need in AcpiOsGetLine.
230  *
231  * If the POSIX tcgetattr/tcsetattr interfaces are unavailable, these
232  * calls will also work:
233  *     For OsEnterLineEditMode: system ("stty cbreak -echo")
234  *     For OsExitLineEditMode:  system ("stty cooked echo")
235  *
236  *****************************************************************************/
237 
238 static void
239 OsEnterLineEditMode (
240     void)
241 {
242     struct termios          LocalTermAttributes;
243 
244 
245     TermAttributesWereSet = 0;
246 
247     /* STDIN must be a terminal */
248 
249     if (!isatty (STDIN_FILENO))
250     {
251         return;
252     }
253 
254     /* Get and keep the original attributes */
255 
256     if (tcgetattr (STDIN_FILENO, &OriginalTermAttributes))
257     {
258         fprintf (stderr, "Could not get terminal attributes!\n");
259         return;
260     }
261 
262     /* Set the new attributes to enable raw character input */
263 
264     memcpy (&LocalTermAttributes, &OriginalTermAttributes,
265         sizeof (struct termios));
266 
267     LocalTermAttributes.c_lflag &= ~(ICANON | ECHO);
268     LocalTermAttributes.c_cc[VMIN] = 1;
269     LocalTermAttributes.c_cc[VTIME] = 0;
270 
271     if (tcsetattr (STDIN_FILENO, TCSANOW, &LocalTermAttributes))
272     {
273         fprintf (stderr, "Could not set terminal attributes!\n");
274         return;
275     }
276 
277     TermAttributesWereSet = 1;
278 }
279 
280 
281 static void
282 OsExitLineEditMode (
283     void)
284 {
285 
286     if (!TermAttributesWereSet)
287     {
288         return;
289     }
290 
291     /* Set terminal attributes back to the original values */
292 
293     if (tcsetattr (STDIN_FILENO, TCSANOW, &OriginalTermAttributes))
294     {
295         fprintf (stderr, "Could not restore terminal attributes!\n");
296     }
297 }
298 
299 
300 #else
301 
302 /* These functions are not needed for other ACPICA utilities */
303 
304 #define OsEnterLineEditMode()
305 #define OsExitLineEditMode()
306 #endif
307 
308 
309 /******************************************************************************
310  *
311  * FUNCTION:    AcpiOsInitialize, AcpiOsTerminate
312  *
313  * PARAMETERS:  None
314  *
315  * RETURN:      Status
316  *
317  * DESCRIPTION: Initialize and terminate this module.
318  *
319  *****************************************************************************/
320 
321 ACPI_STATUS
322 AcpiOsInitialize (
323     void)
324 {
325     ACPI_STATUS            Status;
326 
327 
328     AcpiGbl_OutputFile = stdout;
329 
330     OsEnterLineEditMode ();
331 
332     Status = AcpiOsCreateLock (&AcpiGbl_PrintLock);
333     if (ACPI_FAILURE (Status))
334     {
335         return (Status);
336     }
337 
338     return (AE_OK);
339 }
340 
341 ACPI_STATUS
342 AcpiOsTerminate (
343     void)
344 {
345 
346     OsExitLineEditMode ();
347     return (AE_OK);
348 }
349 
350 
351 #ifndef ACPI_USE_NATIVE_RSDP_POINTER
352 /******************************************************************************
353  *
354  * FUNCTION:    AcpiOsGetRootPointer
355  *
356  * PARAMETERS:  None
357  *
358  * RETURN:      RSDP physical address
359  *
360  * DESCRIPTION: Gets the ACPI root pointer (RSDP)
361  *
362  *****************************************************************************/
363 
364 ACPI_PHYSICAL_ADDRESS
365 AcpiOsGetRootPointer (
366     void)
367 {
368 
369     return (0);
370 }
371 #endif
372 
373 
374 /******************************************************************************
375  *
376  * FUNCTION:    AcpiOsPredefinedOverride
377  *
378  * PARAMETERS:  InitVal             - Initial value of the predefined object
379  *              NewVal              - The new value for the object
380  *
381  * RETURN:      Status, pointer to value. Null pointer returned if not
382  *              overriding.
383  *
384  * DESCRIPTION: Allow the OS to override predefined names
385  *
386  *****************************************************************************/
387 
388 ACPI_STATUS
389 AcpiOsPredefinedOverride (
390     const ACPI_PREDEFINED_NAMES *InitVal,
391     ACPI_STRING                 *NewVal)
392 {
393 
394     if (!InitVal || !NewVal)
395     {
396         return (AE_BAD_PARAMETER);
397     }
398 
399     *NewVal = NULL;
400     return (AE_OK);
401 }
402 
403 
404 /******************************************************************************
405  *
406  * FUNCTION:    AcpiOsTableOverride
407  *
408  * PARAMETERS:  ExistingTable       - Header of current table (probably
409  *                                    firmware)
410  *              NewTable            - Where an entire new table is returned.
411  *
412  * RETURN:      Status, pointer to new table. Null pointer returned if no
413  *              table is available to override
414  *
415  * DESCRIPTION: Return a different version of a table if one is available
416  *
417  *****************************************************************************/
418 
419 ACPI_STATUS
420 AcpiOsTableOverride (
421     ACPI_TABLE_HEADER       *ExistingTable,
422     ACPI_TABLE_HEADER       **NewTable)
423 {
424 
425     if (!ExistingTable || !NewTable)
426     {
427         return (AE_BAD_PARAMETER);
428     }
429 
430     *NewTable = NULL;
431 
432 #ifdef ACPI_EXEC_APP
433 
434     AeTableOverride (ExistingTable, NewTable);
435     return (AE_OK);
436 #else
437 
438     return (AE_NO_ACPI_TABLES);
439 #endif
440 }
441 
442 
443 /******************************************************************************
444  *
445  * FUNCTION:    AcpiOsPhysicalTableOverride
446  *
447  * PARAMETERS:  ExistingTable       - Header of current table (probably firmware)
448  *              NewAddress          - Where new table address is returned
449  *                                    (Physical address)
450  *              NewTableLength      - Where new table length is returned
451  *
452  * RETURN:      Status, address/length of new table. Null pointer returned
453  *              if no table is available to override.
454  *
455  * DESCRIPTION: Returns AE_SUPPORT, function not used in user space.
456  *
457  *****************************************************************************/
458 
459 ACPI_STATUS
460 AcpiOsPhysicalTableOverride (
461     ACPI_TABLE_HEADER       *ExistingTable,
462     ACPI_PHYSICAL_ADDRESS   *NewAddress,
463     UINT32                  *NewTableLength)
464 {
465 
466     return (AE_SUPPORT);
467 }
468 
469 
470 /******************************************************************************
471  *
472  * FUNCTION:    AcpiOsEnterSleep
473  *
474  * PARAMETERS:  SleepState          - Which sleep state to enter
475  *              RegaValue           - Register A value
476  *              RegbValue           - Register B value
477  *
478  * RETURN:      Status
479  *
480  * DESCRIPTION: A hook before writing sleep registers to enter the sleep
481  *              state. Return AE_CTRL_TERMINATE to skip further sleep register
482  *              writes.
483  *
484  *****************************************************************************/
485 
486 ACPI_STATUS
487 AcpiOsEnterSleep (
488     UINT8                   SleepState,
489     UINT32                  RegaValue,
490     UINT32                  RegbValue)
491 {
492 
493     return (AE_OK);
494 }
495 
496 
497 /******************************************************************************
498  *
499  * FUNCTION:    AcpiOsRedirectOutput
500  *
501  * PARAMETERS:  Destination         - An open file handle/pointer
502  *
503  * RETURN:      None
504  *
505  * DESCRIPTION: Causes redirect of AcpiOsPrintf and AcpiOsVprintf
506  *
507  *****************************************************************************/
508 
509 void
510 AcpiOsRedirectOutput (
511     void                    *Destination)
512 {
513 
514     AcpiGbl_OutputFile = Destination;
515 }
516 
517 
518 /******************************************************************************
519  *
520  * FUNCTION:    AcpiOsPrintf
521  *
522  * PARAMETERS:  fmt, ...            - Standard printf format
523  *
524  * RETURN:      None
525  *
526  * DESCRIPTION: Formatted output. Note: very similar to AcpiOsVprintf
527  *              (performance), changes should be tracked in both functions.
528  *
529  *****************************************************************************/
530 
531 void ACPI_INTERNAL_VAR_XFACE
532 AcpiOsPrintf (
533     const char              *Fmt,
534     ...)
535 {
536     va_list                 Args;
537     UINT8                   Flags;
538 
539 
540     Flags = AcpiGbl_DbOutputFlags;
541     if (Flags & ACPI_DB_REDIRECTABLE_OUTPUT)
542     {
543         /* Output is directable to either a file (if open) or the console */
544 
545         if (AcpiGbl_DebugFile)
546         {
547             /* Output file is open, send the output there */
548 
549             va_start (Args, Fmt);
550             vfprintf (AcpiGbl_DebugFile, Fmt, Args);
551             va_end (Args);
552         }
553         else
554         {
555             /* No redirection, send output to console (once only!) */
556 
557             Flags |= ACPI_DB_CONSOLE_OUTPUT;
558         }
559     }
560 
561     if (Flags & ACPI_DB_CONSOLE_OUTPUT)
562     {
563         va_start (Args, Fmt);
564         vfprintf (AcpiGbl_OutputFile, Fmt, Args);
565         va_end (Args);
566     }
567 }
568 
569 
570 /******************************************************************************
571  *
572  * FUNCTION:    AcpiOsVprintf
573  *
574  * PARAMETERS:  fmt                 - Standard printf format
575  *              args                - Argument list
576  *
577  * RETURN:      None
578  *
579  * DESCRIPTION: Formatted output with argument list pointer. Note: very
580  *              similar to AcpiOsPrintf, changes should be tracked in both
581  *              functions.
582  *
583  *****************************************************************************/
584 
585 void
586 AcpiOsVprintf (
587     const char              *Fmt,
588     va_list                 Args)
589 {
590     UINT8                   Flags;
591     char                    Buffer[ACPI_VPRINTF_BUFFER_SIZE];
592 
593 
594     /*
595      * We build the output string in a local buffer because we may be
596      * outputting the buffer twice. Using vfprintf is problematic because
597      * some implementations modify the args pointer/structure during
598      * execution. Thus, we use the local buffer for portability.
599      *
600      * Note: Since this module is intended for use by the various ACPICA
601      * utilities/applications, we can safely declare the buffer on the stack.
602      * Also, This function is used for relatively small error messages only.
603      */
604     vsnprintf (Buffer, ACPI_VPRINTF_BUFFER_SIZE, Fmt, Args);
605 
606     Flags = AcpiGbl_DbOutputFlags;
607     if (Flags & ACPI_DB_REDIRECTABLE_OUTPUT)
608     {
609         /* Output is directable to either a file (if open) or the console */
610 
611         if (AcpiGbl_DebugFile)
612         {
613             /* Output file is open, send the output there */
614 
615             fputs (Buffer, AcpiGbl_DebugFile);
616         }
617         else
618         {
619             /* No redirection, send output to console (once only!) */
620 
621             Flags |= ACPI_DB_CONSOLE_OUTPUT;
622         }
623     }
624 
625     if (Flags & ACPI_DB_CONSOLE_OUTPUT)
626     {
627         fputs (Buffer, AcpiGbl_OutputFile);
628     }
629 }
630 
631 
632 #ifndef ACPI_EXEC_APP
633 /******************************************************************************
634  *
635  * FUNCTION:    AcpiOsGetLine
636  *
637  * PARAMETERS:  Buffer              - Where to return the command line
638  *              BufferLength        - Maximum length of Buffer
639  *              BytesRead           - Where the actual byte count is returned
640  *
641  * RETURN:      Status and actual bytes read
642  *
643  * DESCRIPTION: Get the next input line from the terminal. NOTE: For the
644  *              AcpiExec utility, we use the acgetline module instead to
645  *              provide line-editing and history support.
646  *
647  *****************************************************************************/
648 
649 ACPI_STATUS
650 AcpiOsGetLine (
651     char                    *Buffer,
652     UINT32                  BufferLength,
653     UINT32                  *BytesRead)
654 {
655     int                     InputChar;
656     UINT32                  EndOfLine;
657 
658 
659     /* Standard AcpiOsGetLine for all utilities except AcpiExec */
660 
661     for (EndOfLine = 0; ; EndOfLine++)
662     {
663         if (EndOfLine >= BufferLength)
664         {
665             return (AE_BUFFER_OVERFLOW);
666         }
667 
668         if ((InputChar = getchar ()) == EOF)
669         {
670             return (AE_ERROR);
671         }
672 
673         if (!InputChar || InputChar == _ASCII_NEWLINE)
674         {
675             break;
676         }
677 
678         Buffer[EndOfLine] = (char) InputChar;
679     }
680 
681     /* Null terminate the buffer */
682 
683     Buffer[EndOfLine] = 0;
684 
685     /* Return the number of bytes in the string */
686 
687     if (BytesRead)
688     {
689         *BytesRead = EndOfLine;
690     }
691 
692     return (AE_OK);
693 }
694 #endif
695 
696 
697 #ifndef ACPI_USE_NATIVE_MEMORY_MAPPING
698 /******************************************************************************
699  *
700  * FUNCTION:    AcpiOsMapMemory
701  *
702  * PARAMETERS:  where               - Physical address of memory to be mapped
703  *              length              - How much memory to map
704  *
705  * RETURN:      Pointer to mapped memory. Null on error.
706  *
707  * DESCRIPTION: Map physical memory into caller's address space
708  *
709  *****************************************************************************/
710 
711 void *
712 AcpiOsMapMemory (
713     ACPI_PHYSICAL_ADDRESS   where,
714     ACPI_SIZE               length)
715 {
716 
717     return (ACPI_TO_POINTER ((ACPI_SIZE) where));
718 }
719 
720 
721 /******************************************************************************
722  *
723  * FUNCTION:    AcpiOsUnmapMemory
724  *
725  * PARAMETERS:  where               - Logical address of memory to be unmapped
726  *              length              - How much memory to unmap
727  *
728  * RETURN:      None.
729  *
730  * DESCRIPTION: Delete a previously created mapping. Where and Length must
731  *              correspond to a previous mapping exactly.
732  *
733  *****************************************************************************/
734 
735 void
736 AcpiOsUnmapMemory (
737     void                    *where,
738     ACPI_SIZE               length)
739 {
740 
741     return;
742 }
743 #endif
744 
745 
746 /******************************************************************************
747  *
748  * FUNCTION:    AcpiOsAllocate
749  *
750  * PARAMETERS:  Size                - Amount to allocate, in bytes
751  *
752  * RETURN:      Pointer to the new allocation. Null on error.
753  *
754  * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS.
755  *
756  *****************************************************************************/
757 
758 void *
759 AcpiOsAllocate (
760     ACPI_SIZE               size)
761 {
762     void                    *Mem;
763 
764 
765     Mem = (void *) malloc ((size_t) size);
766     return (Mem);
767 }
768 
769 
770 #ifdef USE_NATIVE_ALLOCATE_ZEROED
771 /******************************************************************************
772  *
773  * FUNCTION:    AcpiOsAllocateZeroed
774  *
775  * PARAMETERS:  Size                - Amount to allocate, in bytes
776  *
777  * RETURN:      Pointer to the new allocation. Null on error.
778  *
779  * DESCRIPTION: Allocate and zero memory. Algorithm is dependent on the OS.
780  *
781  *****************************************************************************/
782 
783 void *
784 AcpiOsAllocateZeroed (
785     ACPI_SIZE               size)
786 {
787     void                    *Mem;
788 
789 
790     Mem = (void *) calloc (1, (size_t) size);
791     return (Mem);
792 }
793 #endif
794 
795 
796 /******************************************************************************
797  *
798  * FUNCTION:    AcpiOsFree
799  *
800  * PARAMETERS:  mem                 - Pointer to previously allocated memory
801  *
802  * RETURN:      None.
803  *
804  * DESCRIPTION: Free memory allocated via AcpiOsAllocate
805  *
806  *****************************************************************************/
807 
808 void
809 AcpiOsFree (
810     void                    *mem)
811 {
812 
813     free (mem);
814 }
815 
816 
817 #ifdef ACPI_SINGLE_THREADED
818 /******************************************************************************
819  *
820  * FUNCTION:    Semaphore stub functions
821  *
822  * DESCRIPTION: Stub functions used for single-thread applications that do
823  *              not require semaphore synchronization. Full implementations
824  *              of these functions appear after the stubs.
825  *
826  *****************************************************************************/
827 
828 ACPI_STATUS
829 AcpiOsCreateSemaphore (
830     UINT32              MaxUnits,
831     UINT32              InitialUnits,
832     ACPI_HANDLE         *OutHandle)
833 {
834     *OutHandle = (ACPI_HANDLE) 1;
835     return (AE_OK);
836 }
837 
838 ACPI_STATUS
839 AcpiOsDeleteSemaphore (
840     ACPI_HANDLE         Handle)
841 {
842     return (AE_OK);
843 }
844 
845 ACPI_STATUS
846 AcpiOsWaitSemaphore (
847     ACPI_HANDLE         Handle,
848     UINT32              Units,
849     UINT16              Timeout)
850 {
851     return (AE_OK);
852 }
853 
854 ACPI_STATUS
855 AcpiOsSignalSemaphore (
856     ACPI_HANDLE         Handle,
857     UINT32              Units)
858 {
859     return (AE_OK);
860 }
861 
862 #else
863 /******************************************************************************
864  *
865  * FUNCTION:    AcpiOsCreateSemaphore
866  *
867  * PARAMETERS:  InitialUnits        - Units to be assigned to the new semaphore
868  *              OutHandle           - Where a handle will be returned
869  *
870  * RETURN:      Status
871  *
872  * DESCRIPTION: Create an OS semaphore
873  *
874  *****************************************************************************/
875 
876 ACPI_STATUS
877 AcpiOsCreateSemaphore (
878     UINT32              MaxUnits,
879     UINT32              InitialUnits,
880     ACPI_HANDLE         *OutHandle)
881 {
882     sem_t               *Sem;
883 
884 
885     if (!OutHandle)
886     {
887         return (AE_BAD_PARAMETER);
888     }
889 
890 #ifdef __APPLE__
891     {
892         static int      SemaphoreCount = 0;
893         char            SemaphoreName[32];
894 
895         snprintf (SemaphoreName, sizeof (SemaphoreName), "acpi_sem_%d",
896             SemaphoreCount++);
897         printf ("%s\n", SemaphoreName);
898         Sem = sem_open (SemaphoreName, O_EXCL|O_CREAT, 0755, InitialUnits);
899         if (!Sem)
900         {
901             return (AE_NO_MEMORY);
902         }
903         sem_unlink (SemaphoreName); /* This just deletes the name */
904     }
905 
906 #else
907     Sem = AcpiOsAllocate (sizeof (sem_t));
908     if (!Sem)
909     {
910         return (AE_NO_MEMORY);
911     }
912 
913     if (sem_init (Sem, 0, InitialUnits) == -1)
914     {
915         AcpiOsFree (Sem);
916         return (AE_BAD_PARAMETER);
917     }
918 #endif
919 
920     *OutHandle = (ACPI_HANDLE) Sem;
921     return (AE_OK);
922 }
923 
924 
925 /******************************************************************************
926  *
927  * FUNCTION:    AcpiOsDeleteSemaphore
928  *
929  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
930  *
931  * RETURN:      Status
932  *
933  * DESCRIPTION: Delete an OS semaphore
934  *
935  *****************************************************************************/
936 
937 ACPI_STATUS
938 AcpiOsDeleteSemaphore (
939     ACPI_HANDLE         Handle)
940 {
941     sem_t               *Sem = (sem_t *) Handle;
942 
943 
944     if (!Sem)
945     {
946         return (AE_BAD_PARAMETER);
947     }
948 
949 #ifdef __APPLE__
950     if (sem_close (Sem) == -1)
951     {
952         return (AE_BAD_PARAMETER);
953     }
954 #else
955     if (sem_destroy (Sem) == -1)
956     {
957         return (AE_BAD_PARAMETER);
958     }
959 #endif
960 
961     return (AE_OK);
962 }
963 
964 
965 /******************************************************************************
966  *
967  * FUNCTION:    AcpiOsWaitSemaphore
968  *
969  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
970  *              Units               - How many units to wait for
971  *              MsecTimeout         - How long to wait (milliseconds)
972  *
973  * RETURN:      Status
974  *
975  * DESCRIPTION: Wait for units
976  *
977  *****************************************************************************/
978 
979 ACPI_STATUS
980 AcpiOsWaitSemaphore (
981     ACPI_HANDLE         Handle,
982     UINT32              Units,
983     UINT16              MsecTimeout)
984 {
985     ACPI_STATUS         Status = AE_OK;
986     sem_t               *Sem = (sem_t *) Handle;
987     int                 RetVal;
988 #ifndef ACPI_USE_ALTERNATE_TIMEOUT
989     struct timespec     Time;
990 #endif
991 
992 
993     if (!Sem)
994     {
995         return (AE_BAD_PARAMETER);
996     }
997 
998     switch (MsecTimeout)
999     {
1000     /*
1001      * No Wait:
1002      * --------
1003      * A zero timeout value indicates that we shouldn't wait - just
1004      * acquire the semaphore if available otherwise return AE_TIME
1005      * (a.k.a. 'would block').
1006      */
1007     case 0:
1008 
1009         if (sem_trywait(Sem) == -1)
1010         {
1011             Status = (AE_TIME);
1012         }
1013         break;
1014 
1015     /* Wait Indefinitely */
1016 
1017     case ACPI_WAIT_FOREVER:
1018 
1019         while (((RetVal = sem_wait (Sem)) == -1) && (errno == EINTR))
1020         {
1021             continue;   /* Restart if interrupted */
1022         }
1023         if (RetVal != 0)
1024         {
1025             Status = (AE_TIME);
1026         }
1027         break;
1028 
1029 
1030     /* Wait with MsecTimeout */
1031 
1032     default:
1033 
1034 #ifdef ACPI_USE_ALTERNATE_TIMEOUT
1035         /*
1036          * Alternate timeout mechanism for environments where
1037          * sem_timedwait is not available or does not work properly.
1038          */
1039         while (MsecTimeout)
1040         {
1041             if (sem_trywait (Sem) == 0)
1042             {
1043                 /* Got the semaphore */
1044                 return (AE_OK);
1045             }
1046 
1047             if (MsecTimeout >= 10)
1048             {
1049                 MsecTimeout -= 10;
1050                 usleep (10 * ACPI_USEC_PER_MSEC); /* ten milliseconds */
1051             }
1052             else
1053             {
1054                 MsecTimeout--;
1055                 usleep (ACPI_USEC_PER_MSEC); /* one millisecond */
1056             }
1057         }
1058         Status = (AE_TIME);
1059 #else
1060         /*
1061          * The interface to sem_timedwait is an absolute time, so we need to
1062          * get the current time, then add in the millisecond Timeout value.
1063          */
1064         if (clock_gettime (CLOCK_REALTIME, &Time) == -1)
1065         {
1066             perror ("clock_gettime");
1067             return (AE_TIME);
1068         }
1069 
1070         Time.tv_sec += (MsecTimeout / ACPI_MSEC_PER_SEC);
1071         Time.tv_nsec += ((MsecTimeout % ACPI_MSEC_PER_SEC) * ACPI_NSEC_PER_MSEC);
1072 
1073         /* Handle nanosecond overflow (field must be less than one second) */
1074 
1075         if (Time.tv_nsec >= ACPI_NSEC_PER_SEC)
1076         {
1077             Time.tv_sec += (Time.tv_nsec / ACPI_NSEC_PER_SEC);
1078             Time.tv_nsec = (Time.tv_nsec % ACPI_NSEC_PER_SEC);
1079         }
1080 
1081         while (((RetVal = sem_timedwait (Sem, &Time)) == -1) && (errno == EINTR))
1082         {
1083             continue;   /* Restart if interrupted */
1084 
1085         }
1086 
1087         if (RetVal != 0)
1088         {
1089             if (errno != ETIMEDOUT)
1090             {
1091                 perror ("sem_timedwait");
1092             }
1093             Status = (AE_TIME);
1094         }
1095 #endif
1096         break;
1097     }
1098 
1099     return (Status);
1100 }
1101 
1102 
1103 /******************************************************************************
1104  *
1105  * FUNCTION:    AcpiOsSignalSemaphore
1106  *
1107  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
1108  *              Units               - Number of units to send
1109  *
1110  * RETURN:      Status
1111  *
1112  * DESCRIPTION: Send units
1113  *
1114  *****************************************************************************/
1115 
1116 ACPI_STATUS
1117 AcpiOsSignalSemaphore (
1118     ACPI_HANDLE         Handle,
1119     UINT32              Units)
1120 {
1121     sem_t               *Sem = (sem_t *)Handle;
1122 
1123 
1124     if (!Sem)
1125     {
1126         return (AE_BAD_PARAMETER);
1127     }
1128 
1129     if (sem_post (Sem) == -1)
1130     {
1131         return (AE_LIMIT);
1132     }
1133 
1134     return (AE_OK);
1135 }
1136 
1137 #endif /* ACPI_SINGLE_THREADED */
1138 
1139 
1140 /******************************************************************************
1141  *
1142  * FUNCTION:    Spinlock interfaces
1143  *
1144  * DESCRIPTION: Map these interfaces to semaphore interfaces
1145  *
1146  *****************************************************************************/
1147 
1148 ACPI_STATUS
1149 AcpiOsCreateLock (
1150     ACPI_SPINLOCK           *OutHandle)
1151 {
1152 
1153     return (AcpiOsCreateSemaphore (1, 1, OutHandle));
1154 }
1155 
1156 
1157 void
1158 AcpiOsDeleteLock (
1159     ACPI_SPINLOCK           Handle)
1160 {
1161     AcpiOsDeleteSemaphore (Handle);
1162 }
1163 
1164 
1165 ACPI_CPU_FLAGS
1166 AcpiOsAcquireLock (
1167     ACPI_HANDLE             Handle)
1168 {
1169     AcpiOsWaitSemaphore (Handle, 1, 0xFFFF);
1170     return (0);
1171 }
1172 
1173 
1174 void
1175 AcpiOsReleaseLock (
1176     ACPI_SPINLOCK           Handle,
1177     ACPI_CPU_FLAGS          Flags)
1178 {
1179     AcpiOsSignalSemaphore (Handle, 1);
1180 }
1181 
1182 
1183 /******************************************************************************
1184  *
1185  * FUNCTION:    AcpiOsInstallInterruptHandler
1186  *
1187  * PARAMETERS:  InterruptNumber     - Level handler should respond to.
1188  *              Isr                 - Address of the ACPI interrupt handler
1189  *              ExceptPtr           - Where status is returned
1190  *
1191  * RETURN:      Handle to the newly installed handler.
1192  *
1193  * DESCRIPTION: Install an interrupt handler. Used to install the ACPI
1194  *              OS-independent handler.
1195  *
1196  *****************************************************************************/
1197 
1198 UINT32
1199 AcpiOsInstallInterruptHandler (
1200     UINT32                  InterruptNumber,
1201     ACPI_OSD_HANDLER        ServiceRoutine,
1202     void                    *Context)
1203 {
1204 
1205     return (AE_OK);
1206 }
1207 
1208 
1209 /******************************************************************************
1210  *
1211  * FUNCTION:    AcpiOsRemoveInterruptHandler
1212  *
1213  * PARAMETERS:  Handle              - Returned when handler was installed
1214  *
1215  * RETURN:      Status
1216  *
1217  * DESCRIPTION: Uninstalls an interrupt handler.
1218  *
1219  *****************************************************************************/
1220 
1221 ACPI_STATUS
1222 AcpiOsRemoveInterruptHandler (
1223     UINT32                  InterruptNumber,
1224     ACPI_OSD_HANDLER        ServiceRoutine)
1225 {
1226 
1227     return (AE_OK);
1228 }
1229 
1230 
1231 /******************************************************************************
1232  *
1233  * FUNCTION:    AcpiOsStall
1234  *
1235  * PARAMETERS:  microseconds        - Time to sleep
1236  *
1237  * RETURN:      Blocks until sleep is completed.
1238  *
1239  * DESCRIPTION: Sleep at microsecond granularity
1240  *
1241  *****************************************************************************/
1242 
1243 void
1244 AcpiOsStall (
1245     UINT32                  microseconds)
1246 {
1247 
1248     if (microseconds)
1249     {
1250         usleep (microseconds);
1251     }
1252 }
1253 
1254 
1255 /******************************************************************************
1256  *
1257  * FUNCTION:    AcpiOsSleep
1258  *
1259  * PARAMETERS:  milliseconds        - Time to sleep
1260  *
1261  * RETURN:      Blocks until sleep is completed.
1262  *
1263  * DESCRIPTION: Sleep at millisecond granularity
1264  *
1265  *****************************************************************************/
1266 
1267 void
1268 AcpiOsSleep (
1269     UINT64                  milliseconds)
1270 {
1271 
1272     /* Sleep for whole seconds */
1273 
1274     sleep (milliseconds / ACPI_MSEC_PER_SEC);
1275 
1276     /*
1277      * Sleep for remaining microseconds.
1278      * Arg to usleep() is in usecs and must be less than 1,000,000 (1 second).
1279      */
1280     usleep ((milliseconds % ACPI_MSEC_PER_SEC) * ACPI_USEC_PER_MSEC);
1281 }
1282 
1283 
1284 /******************************************************************************
1285  *
1286  * FUNCTION:    AcpiOsGetTimer
1287  *
1288  * PARAMETERS:  None
1289  *
1290  * RETURN:      Current time in 100 nanosecond units
1291  *
1292  * DESCRIPTION: Get the current system time
1293  *
1294  *****************************************************************************/
1295 
1296 UINT64
1297 AcpiOsGetTimer (
1298     void)
1299 {
1300     struct timeval          time;
1301 
1302 
1303     /* This timer has sufficient resolution for user-space application code */
1304 
1305     gettimeofday (&time, NULL);
1306 
1307     /* (Seconds * 10^7 = 100ns(10^-7)) + (Microseconds(10^-6) * 10^1 = 100ns) */
1308 
1309     return (((UINT64) time.tv_sec * ACPI_100NSEC_PER_SEC) +
1310             ((UINT64) time.tv_usec * ACPI_100NSEC_PER_USEC));
1311 }
1312 
1313 
1314 /******************************************************************************
1315  *
1316  * FUNCTION:    AcpiOsReadPciConfiguration
1317  *
1318  * PARAMETERS:  PciId               - Seg/Bus/Dev
1319  *              PciRegister         - Device Register
1320  *              Value               - Buffer where value is placed
1321  *              Width               - Number of bits
1322  *
1323  * RETURN:      Status
1324  *
1325  * DESCRIPTION: Read data from PCI configuration space
1326  *
1327  *****************************************************************************/
1328 
1329 ACPI_STATUS
1330 AcpiOsReadPciConfiguration (
1331     ACPI_PCI_ID             *PciId,
1332     UINT32                  PciRegister,
1333     UINT64                  *Value,
1334     UINT32                  Width)
1335 {
1336 
1337     *Value = 0;
1338     return (AE_OK);
1339 }
1340 
1341 
1342 /******************************************************************************
1343  *
1344  * FUNCTION:    AcpiOsWritePciConfiguration
1345  *
1346  * PARAMETERS:  PciId               - Seg/Bus/Dev
1347  *              PciRegister         - Device Register
1348  *              Value               - Value to be written
1349  *              Width               - Number of bits
1350  *
1351  * RETURN:      Status.
1352  *
1353  * DESCRIPTION: Write data to PCI configuration space
1354  *
1355  *****************************************************************************/
1356 
1357 ACPI_STATUS
1358 AcpiOsWritePciConfiguration (
1359     ACPI_PCI_ID             *PciId,
1360     UINT32                  PciRegister,
1361     UINT64                  Value,
1362     UINT32                  Width)
1363 {
1364 
1365     return (AE_OK);
1366 }
1367 
1368 
1369 /******************************************************************************
1370  *
1371  * FUNCTION:    AcpiOsReadPort
1372  *
1373  * PARAMETERS:  Address             - Address of I/O port/register to read
1374  *              Value               - Where value is placed
1375  *              Width               - Number of bits
1376  *
1377  * RETURN:      Value read from port
1378  *
1379  * DESCRIPTION: Read data from an I/O port or register
1380  *
1381  *****************************************************************************/
1382 
1383 ACPI_STATUS
1384 AcpiOsReadPort (
1385     ACPI_IO_ADDRESS         Address,
1386     UINT32                  *Value,
1387     UINT32                  Width)
1388 {
1389 
1390     switch (Width)
1391     {
1392     case 8:
1393 
1394         *Value = 0xFF;
1395         break;
1396 
1397     case 16:
1398 
1399         *Value = 0xFFFF;
1400         break;
1401 
1402     case 32:
1403 
1404         *Value = 0xFFFFFFFF;
1405         break;
1406 
1407     default:
1408 
1409         return (AE_BAD_PARAMETER);
1410     }
1411 
1412     return (AE_OK);
1413 }
1414 
1415 
1416 /******************************************************************************
1417  *
1418  * FUNCTION:    AcpiOsWritePort
1419  *
1420  * PARAMETERS:  Address             - Address of I/O port/register to write
1421  *              Value               - Value to write
1422  *              Width               - Number of bits
1423  *
1424  * RETURN:      None
1425  *
1426  * DESCRIPTION: Write data to an I/O port or register
1427  *
1428  *****************************************************************************/
1429 
1430 ACPI_STATUS
1431 AcpiOsWritePort (
1432     ACPI_IO_ADDRESS         Address,
1433     UINT32                  Value,
1434     UINT32                  Width)
1435 {
1436 
1437     return (AE_OK);
1438 }
1439 
1440 
1441 /******************************************************************************
1442  *
1443  * FUNCTION:    AcpiOsReadMemory
1444  *
1445  * PARAMETERS:  Address             - Physical Memory Address to read
1446  *              Value               - Where value is placed
1447  *              Width               - Number of bits (8,16,32, or 64)
1448  *
1449  * RETURN:      Value read from physical memory address. Always returned
1450  *              as a 64-bit integer, regardless of the read width.
1451  *
1452  * DESCRIPTION: Read data from a physical memory address
1453  *
1454  *****************************************************************************/
1455 
1456 ACPI_STATUS
1457 AcpiOsReadMemory (
1458     ACPI_PHYSICAL_ADDRESS   Address,
1459     UINT64                  *Value,
1460     UINT32                  Width)
1461 {
1462 
1463     switch (Width)
1464     {
1465     case 8:
1466     case 16:
1467     case 32:
1468     case 64:
1469 
1470         *Value = 0;
1471         break;
1472 
1473     default:
1474 
1475         return (AE_BAD_PARAMETER);
1476     }
1477     return (AE_OK);
1478 }
1479 
1480 
1481 /******************************************************************************
1482  *
1483  * FUNCTION:    AcpiOsWriteMemory
1484  *
1485  * PARAMETERS:  Address             - Physical Memory Address to write
1486  *              Value               - Value to write
1487  *              Width               - Number of bits (8,16,32, or 64)
1488  *
1489  * RETURN:      None
1490  *
1491  * DESCRIPTION: Write data to a physical memory address
1492  *
1493  *****************************************************************************/
1494 
1495 ACPI_STATUS
1496 AcpiOsWriteMemory (
1497     ACPI_PHYSICAL_ADDRESS   Address,
1498     UINT64                  Value,
1499     UINT32                  Width)
1500 {
1501 
1502     return (AE_OK);
1503 }
1504 
1505 
1506 /******************************************************************************
1507  *
1508  * FUNCTION:    AcpiOsReadable
1509  *
1510  * PARAMETERS:  Pointer             - Area to be verified
1511  *              Length              - Size of area
1512  *
1513  * RETURN:      TRUE if readable for entire length
1514  *
1515  * DESCRIPTION: Verify that a pointer is valid for reading
1516  *
1517  *****************************************************************************/
1518 
1519 BOOLEAN
1520 AcpiOsReadable (
1521     void                    *Pointer,
1522     ACPI_SIZE               Length)
1523 {
1524 
1525     return (TRUE);
1526 }
1527 
1528 
1529 /******************************************************************************
1530  *
1531  * FUNCTION:    AcpiOsWritable
1532  *
1533  * PARAMETERS:  Pointer             - Area to be verified
1534  *              Length              - Size of area
1535  *
1536  * RETURN:      TRUE if writable for entire length
1537  *
1538  * DESCRIPTION: Verify that a pointer is valid for writing
1539  *
1540  *****************************************************************************/
1541 
1542 BOOLEAN
1543 AcpiOsWritable (
1544     void                    *Pointer,
1545     ACPI_SIZE               Length)
1546 {
1547 
1548     return (TRUE);
1549 }
1550 
1551 
1552 /******************************************************************************
1553  *
1554  * FUNCTION:    AcpiOsSignal
1555  *
1556  * PARAMETERS:  Function            - ACPI A signal function code
1557  *              Info                - Pointer to function-dependent structure
1558  *
1559  * RETURN:      Status
1560  *
1561  * DESCRIPTION: Miscellaneous functions. Example implementation only.
1562  *
1563  *****************************************************************************/
1564 
1565 ACPI_STATUS
1566 AcpiOsSignal (
1567     UINT32                  Function,
1568     void                    *Info)
1569 {
1570 
1571     switch (Function)
1572     {
1573     case ACPI_SIGNAL_FATAL:
1574 
1575         break;
1576 
1577     case ACPI_SIGNAL_BREAKPOINT:
1578 
1579         break;
1580 
1581     default:
1582 
1583         break;
1584     }
1585 
1586     return (AE_OK);
1587 }
1588 
1589 /* Optional multi-thread support */
1590 
1591 #ifndef ACPI_SINGLE_THREADED
1592 /******************************************************************************
1593  *
1594  * FUNCTION:    AcpiOsGetThreadId
1595  *
1596  * PARAMETERS:  None
1597  *
1598  * RETURN:      Id of the running thread
1599  *
1600  * DESCRIPTION: Get the ID of the current (running) thread
1601  *
1602  *****************************************************************************/
1603 
1604 ACPI_THREAD_ID
1605 AcpiOsGetThreadId (
1606     void)
1607 {
1608     pthread_t               thread;
1609 
1610 
1611     thread = pthread_self();
1612     return (ACPI_CAST_PTHREAD_T (thread));
1613 }
1614 
1615 
1616 /******************************************************************************
1617  *
1618  * FUNCTION:    AcpiOsExecute
1619  *
1620  * PARAMETERS:  Type                - Type of execution
1621  *              Function            - Address of the function to execute
1622  *              Context             - Passed as a parameter to the function
1623  *
1624  * RETURN:      Status.
1625  *
1626  * DESCRIPTION: Execute a new thread
1627  *
1628  *****************************************************************************/
1629 
1630 ACPI_STATUS
1631 AcpiOsExecute (
1632     ACPI_EXECUTE_TYPE       Type,
1633     ACPI_OSD_EXEC_CALLBACK  Function,
1634     void                    *Context)
1635 {
1636     pthread_t               thread;
1637     int                     ret;
1638 
1639 
1640     ret = pthread_create (&thread, NULL, (PTHREAD_CALLBACK) Function, Context);
1641     if (ret)
1642     {
1643         AcpiOsPrintf("Create thread failed");
1644     }
1645     return (0);
1646 }
1647 
1648 #else /* ACPI_SINGLE_THREADED */
1649 ACPI_THREAD_ID
1650 AcpiOsGetThreadId (
1651     void)
1652 {
1653     return (1);
1654 }
1655 
1656 ACPI_STATUS
1657 AcpiOsExecute (
1658     ACPI_EXECUTE_TYPE       Type,
1659     ACPI_OSD_EXEC_CALLBACK  Function,
1660     void                    *Context)
1661 {
1662 
1663     Function (Context);
1664 
1665     return (AE_OK);
1666 }
1667 
1668 #endif /* ACPI_SINGLE_THREADED */
1669 
1670 
1671 /******************************************************************************
1672  *
1673  * FUNCTION:    AcpiOsWaitEventsComplete
1674  *
1675  * PARAMETERS:  None
1676  *
1677  * RETURN:      None
1678  *
1679  * DESCRIPTION: Wait for all asynchronous events to complete. This
1680  *              implementation does nothing.
1681  *
1682  *****************************************************************************/
1683 
1684 void
1685 AcpiOsWaitEventsComplete (
1686     void)
1687 {
1688     return;
1689 }
1690