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