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         char            *SemaphoreName = tmpnam (NULL);
758 
759         Sem = sem_open (SemaphoreName, O_EXCL|O_CREAT, 0755, InitialUnits);
760         if (!Sem)
761         {
762             return (AE_NO_MEMORY);
763         }
764         sem_unlink (SemaphoreName); /* This just deletes the name */
765     }
766 
767 #else
768     Sem = AcpiOsAllocate (sizeof (sem_t));
769     if (!Sem)
770     {
771         return (AE_NO_MEMORY);
772     }
773 
774     if (sem_init (Sem, 0, InitialUnits) == -1)
775     {
776         AcpiOsFree (Sem);
777         return (AE_BAD_PARAMETER);
778     }
779 #endif
780 
781     *OutHandle = (ACPI_HANDLE) Sem;
782     return (AE_OK);
783 }
784 
785 
786 /******************************************************************************
787  *
788  * FUNCTION:    AcpiOsDeleteSemaphore
789  *
790  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
791  *
792  * RETURN:      Status
793  *
794  * DESCRIPTION: Delete an OS semaphore
795  *
796  *****************************************************************************/
797 
798 ACPI_STATUS
799 AcpiOsDeleteSemaphore (
800     ACPI_HANDLE         Handle)
801 {
802     sem_t               *Sem = (sem_t *) Handle;
803 
804 
805     if (!Sem)
806     {
807         return (AE_BAD_PARAMETER);
808     }
809 
810     if (sem_destroy (Sem) == -1)
811     {
812         return (AE_BAD_PARAMETER);
813     }
814 
815     return (AE_OK);
816 }
817 
818 
819 /******************************************************************************
820  *
821  * FUNCTION:    AcpiOsWaitSemaphore
822  *
823  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
824  *              Units               - How many units to wait for
825  *              MsecTimeout         - How long to wait (milliseconds)
826  *
827  * RETURN:      Status
828  *
829  * DESCRIPTION: Wait for units
830  *
831  *****************************************************************************/
832 
833 ACPI_STATUS
834 AcpiOsWaitSemaphore (
835     ACPI_HANDLE         Handle,
836     UINT32              Units,
837     UINT16              MsecTimeout)
838 {
839     ACPI_STATUS         Status = AE_OK;
840     sem_t               *Sem = (sem_t *) Handle;
841 #ifndef ACPI_USE_ALTERNATE_TIMEOUT
842     struct timespec     Time;
843     int                 RetVal;
844 #endif
845 
846 
847     if (!Sem)
848     {
849         return (AE_BAD_PARAMETER);
850     }
851 
852     switch (MsecTimeout)
853     {
854     /*
855      * No Wait:
856      * --------
857      * A zero timeout value indicates that we shouldn't wait - just
858      * acquire the semaphore if available otherwise return AE_TIME
859      * (a.k.a. 'would block').
860      */
861     case 0:
862 
863         if (sem_trywait(Sem) == -1)
864         {
865             Status = (AE_TIME);
866         }
867         break;
868 
869     /* Wait Indefinitely */
870 
871     case ACPI_WAIT_FOREVER:
872 
873         if (sem_wait (Sem))
874         {
875             Status = (AE_TIME);
876         }
877         break;
878 
879     /* Wait with MsecTimeout */
880 
881     default:
882 
883 #ifdef ACPI_USE_ALTERNATE_TIMEOUT
884         /*
885          * Alternate timeout mechanism for environments where
886          * sem_timedwait is not available or does not work properly.
887          */
888         while (MsecTimeout)
889         {
890             if (sem_trywait (Sem) == 0)
891             {
892                 /* Got the semaphore */
893                 return (AE_OK);
894             }
895 
896             if (MsecTimeout >= 10)
897             {
898                 MsecTimeout -= 10;
899                 usleep (10 * ACPI_USEC_PER_MSEC); /* ten milliseconds */
900             }
901             else
902             {
903                 MsecTimeout--;
904                 usleep (ACPI_USEC_PER_MSEC); /* one millisecond */
905             }
906         }
907         Status = (AE_TIME);
908 #else
909         /*
910          * The interface to sem_timedwait is an absolute time, so we need to
911          * get the current time, then add in the millisecond Timeout value.
912          */
913         if (clock_gettime (CLOCK_REALTIME, &Time) == -1)
914         {
915             perror ("clock_gettime");
916             return (AE_TIME);
917         }
918 
919         Time.tv_sec += (MsecTimeout / ACPI_MSEC_PER_SEC);
920         Time.tv_nsec += ((MsecTimeout % ACPI_MSEC_PER_SEC) * ACPI_NSEC_PER_MSEC);
921 
922         /* Handle nanosecond overflow (field must be less than one second) */
923 
924         if (Time.tv_nsec >= ACPI_NSEC_PER_SEC)
925         {
926             Time.tv_sec += (Time.tv_nsec / ACPI_NSEC_PER_SEC);
927             Time.tv_nsec = (Time.tv_nsec % ACPI_NSEC_PER_SEC);
928         }
929 
930         while (((RetVal = sem_timedwait (Sem, &Time)) == -1) && (errno == EINTR))
931         {
932             continue;
933         }
934 
935         if (RetVal != 0)
936         {
937             if (errno != ETIMEDOUT)
938             {
939                 perror ("sem_timedwait");
940             }
941             Status = (AE_TIME);
942         }
943 #endif
944         break;
945     }
946 
947     return (Status);
948 }
949 
950 
951 /******************************************************************************
952  *
953  * FUNCTION:    AcpiOsSignalSemaphore
954  *
955  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
956  *              Units               - Number of units to send
957  *
958  * RETURN:      Status
959  *
960  * DESCRIPTION: Send units
961  *
962  *****************************************************************************/
963 
964 ACPI_STATUS
965 AcpiOsSignalSemaphore (
966     ACPI_HANDLE         Handle,
967     UINT32              Units)
968 {
969     sem_t               *Sem = (sem_t *)Handle;
970 
971 
972     if (!Sem)
973     {
974         return (AE_BAD_PARAMETER);
975     }
976 
977     if (sem_post (Sem) == -1)
978     {
979         return (AE_LIMIT);
980     }
981 
982     return (AE_OK);
983 }
984 
985 #endif /* ACPI_SINGLE_THREADED */
986 
987 
988 /******************************************************************************
989  *
990  * FUNCTION:    Spinlock interfaces
991  *
992  * DESCRIPTION: Map these interfaces to semaphore interfaces
993  *
994  *****************************************************************************/
995 
996 ACPI_STATUS
997 AcpiOsCreateLock (
998     ACPI_SPINLOCK           *OutHandle)
999 {
1000 
1001     return (AcpiOsCreateSemaphore (1, 1, OutHandle));
1002 }
1003 
1004 
1005 void
1006 AcpiOsDeleteLock (
1007     ACPI_SPINLOCK           Handle)
1008 {
1009     AcpiOsDeleteSemaphore (Handle);
1010 }
1011 
1012 
1013 ACPI_CPU_FLAGS
1014 AcpiOsAcquireLock (
1015     ACPI_HANDLE             Handle)
1016 {
1017     AcpiOsWaitSemaphore (Handle, 1, 0xFFFF);
1018     return (0);
1019 }
1020 
1021 
1022 void
1023 AcpiOsReleaseLock (
1024     ACPI_SPINLOCK           Handle,
1025     ACPI_CPU_FLAGS          Flags)
1026 {
1027     AcpiOsSignalSemaphore (Handle, 1);
1028 }
1029 
1030 
1031 /******************************************************************************
1032  *
1033  * FUNCTION:    AcpiOsInstallInterruptHandler
1034  *
1035  * PARAMETERS:  InterruptNumber     - Level handler should respond to.
1036  *              Isr                 - Address of the ACPI interrupt handler
1037  *              ExceptPtr           - Where status is returned
1038  *
1039  * RETURN:      Handle to the newly installed handler.
1040  *
1041  * DESCRIPTION: Install an interrupt handler. Used to install the ACPI
1042  *              OS-independent handler.
1043  *
1044  *****************************************************************************/
1045 
1046 UINT32
1047 AcpiOsInstallInterruptHandler (
1048     UINT32                  InterruptNumber,
1049     ACPI_OSD_HANDLER        ServiceRoutine,
1050     void                    *Context)
1051 {
1052 
1053     return (AE_OK);
1054 }
1055 
1056 
1057 /******************************************************************************
1058  *
1059  * FUNCTION:    AcpiOsRemoveInterruptHandler
1060  *
1061  * PARAMETERS:  Handle              - Returned when handler was installed
1062  *
1063  * RETURN:      Status
1064  *
1065  * DESCRIPTION: Uninstalls an interrupt handler.
1066  *
1067  *****************************************************************************/
1068 
1069 ACPI_STATUS
1070 AcpiOsRemoveInterruptHandler (
1071     UINT32                  InterruptNumber,
1072     ACPI_OSD_HANDLER        ServiceRoutine)
1073 {
1074 
1075     return (AE_OK);
1076 }
1077 
1078 
1079 /******************************************************************************
1080  *
1081  * FUNCTION:    AcpiOsStall
1082  *
1083  * PARAMETERS:  microseconds        - Time to sleep
1084  *
1085  * RETURN:      Blocks until sleep is completed.
1086  *
1087  * DESCRIPTION: Sleep at microsecond granularity
1088  *
1089  *****************************************************************************/
1090 
1091 void
1092 AcpiOsStall (
1093     UINT32                  microseconds)
1094 {
1095 
1096     if (microseconds)
1097     {
1098         usleep (microseconds);
1099     }
1100 }
1101 
1102 
1103 /******************************************************************************
1104  *
1105  * FUNCTION:    AcpiOsSleep
1106  *
1107  * PARAMETERS:  milliseconds        - Time to sleep
1108  *
1109  * RETURN:      Blocks until sleep is completed.
1110  *
1111  * DESCRIPTION: Sleep at millisecond granularity
1112  *
1113  *****************************************************************************/
1114 
1115 void
1116 AcpiOsSleep (
1117     UINT64                  milliseconds)
1118 {
1119 
1120     /* Sleep for whole seconds */
1121 
1122     sleep (milliseconds / ACPI_MSEC_PER_SEC);
1123 
1124     /*
1125      * Sleep for remaining microseconds.
1126      * Arg to usleep() is in usecs and must be less than 1,000,000 (1 second).
1127      */
1128     usleep ((milliseconds % ACPI_MSEC_PER_SEC) * ACPI_USEC_PER_MSEC);
1129 }
1130 
1131 
1132 /******************************************************************************
1133  *
1134  * FUNCTION:    AcpiOsGetTimer
1135  *
1136  * PARAMETERS:  None
1137  *
1138  * RETURN:      Current time in 100 nanosecond units
1139  *
1140  * DESCRIPTION: Get the current system time
1141  *
1142  *****************************************************************************/
1143 
1144 UINT64
1145 AcpiOsGetTimer (
1146     void)
1147 {
1148     struct timeval          time;
1149 
1150 
1151     /* This timer has sufficient resolution for user-space application code */
1152 
1153     gettimeofday (&time, NULL);
1154 
1155     /* (Seconds * 10^7 = 100ns(10^-7)) + (Microseconds(10^-6) * 10^1 = 100ns) */
1156 
1157     return (((UINT64) time.tv_sec * ACPI_100NSEC_PER_SEC) +
1158             ((UINT64) time.tv_usec * ACPI_100NSEC_PER_USEC));
1159 }
1160 
1161 
1162 /******************************************************************************
1163  *
1164  * FUNCTION:    AcpiOsReadPciConfiguration
1165  *
1166  * PARAMETERS:  PciId               - Seg/Bus/Dev
1167  *              PciRegister         - Device Register
1168  *              Value               - Buffer where value is placed
1169  *              Width               - Number of bits
1170  *
1171  * RETURN:      Status
1172  *
1173  * DESCRIPTION: Read data from PCI configuration space
1174  *
1175  *****************************************************************************/
1176 
1177 ACPI_STATUS
1178 AcpiOsReadPciConfiguration (
1179     ACPI_PCI_ID             *PciId,
1180     UINT32                  PciRegister,
1181     UINT64                  *Value,
1182     UINT32                  Width)
1183 {
1184 
1185     *Value = 0;
1186     return (AE_OK);
1187 }
1188 
1189 
1190 /******************************************************************************
1191  *
1192  * FUNCTION:    AcpiOsWritePciConfiguration
1193  *
1194  * PARAMETERS:  PciId               - Seg/Bus/Dev
1195  *              PciRegister         - Device Register
1196  *              Value               - Value to be written
1197  *              Width               - Number of bits
1198  *
1199  * RETURN:      Status.
1200  *
1201  * DESCRIPTION: Write data to PCI configuration space
1202  *
1203  *****************************************************************************/
1204 
1205 ACPI_STATUS
1206 AcpiOsWritePciConfiguration (
1207     ACPI_PCI_ID             *PciId,
1208     UINT32                  PciRegister,
1209     UINT64                  Value,
1210     UINT32                  Width)
1211 {
1212 
1213     return (AE_OK);
1214 }
1215 
1216 
1217 /******************************************************************************
1218  *
1219  * FUNCTION:    AcpiOsReadPort
1220  *
1221  * PARAMETERS:  Address             - Address of I/O port/register to read
1222  *              Value               - Where value is placed
1223  *              Width               - Number of bits
1224  *
1225  * RETURN:      Value read from port
1226  *
1227  * DESCRIPTION: Read data from an I/O port or register
1228  *
1229  *****************************************************************************/
1230 
1231 ACPI_STATUS
1232 AcpiOsReadPort (
1233     ACPI_IO_ADDRESS         Address,
1234     UINT32                  *Value,
1235     UINT32                  Width)
1236 {
1237 
1238     switch (Width)
1239     {
1240     case 8:
1241 
1242         *Value = 0xFF;
1243         break;
1244 
1245     case 16:
1246 
1247         *Value = 0xFFFF;
1248         break;
1249 
1250     case 32:
1251 
1252         *Value = 0xFFFFFFFF;
1253         break;
1254 
1255     default:
1256 
1257         return (AE_BAD_PARAMETER);
1258     }
1259 
1260     return (AE_OK);
1261 }
1262 
1263 
1264 /******************************************************************************
1265  *
1266  * FUNCTION:    AcpiOsWritePort
1267  *
1268  * PARAMETERS:  Address             - Address of I/O port/register to write
1269  *              Value               - Value to write
1270  *              Width               - Number of bits
1271  *
1272  * RETURN:      None
1273  *
1274  * DESCRIPTION: Write data to an I/O port or register
1275  *
1276  *****************************************************************************/
1277 
1278 ACPI_STATUS
1279 AcpiOsWritePort (
1280     ACPI_IO_ADDRESS         Address,
1281     UINT32                  Value,
1282     UINT32                  Width)
1283 {
1284 
1285     return (AE_OK);
1286 }
1287 
1288 
1289 /******************************************************************************
1290  *
1291  * FUNCTION:    AcpiOsReadMemory
1292  *
1293  * PARAMETERS:  Address             - Physical Memory Address to read
1294  *              Value               - Where value is placed
1295  *              Width               - Number of bits (8,16,32, or 64)
1296  *
1297  * RETURN:      Value read from physical memory address. Always returned
1298  *              as a 64-bit integer, regardless of the read width.
1299  *
1300  * DESCRIPTION: Read data from a physical memory address
1301  *
1302  *****************************************************************************/
1303 
1304 ACPI_STATUS
1305 AcpiOsReadMemory (
1306     ACPI_PHYSICAL_ADDRESS   Address,
1307     UINT64                  *Value,
1308     UINT32                  Width)
1309 {
1310 
1311     switch (Width)
1312     {
1313     case 8:
1314     case 16:
1315     case 32:
1316     case 64:
1317 
1318         *Value = 0;
1319         break;
1320 
1321     default:
1322 
1323         return (AE_BAD_PARAMETER);
1324     }
1325     return (AE_OK);
1326 }
1327 
1328 
1329 /******************************************************************************
1330  *
1331  * FUNCTION:    AcpiOsWriteMemory
1332  *
1333  * PARAMETERS:  Address             - Physical Memory Address to write
1334  *              Value               - Value to write
1335  *              Width               - Number of bits (8,16,32, or 64)
1336  *
1337  * RETURN:      None
1338  *
1339  * DESCRIPTION: Write data to a physical memory address
1340  *
1341  *****************************************************************************/
1342 
1343 ACPI_STATUS
1344 AcpiOsWriteMemory (
1345     ACPI_PHYSICAL_ADDRESS   Address,
1346     UINT64                  Value,
1347     UINT32                  Width)
1348 {
1349 
1350     return (AE_OK);
1351 }
1352 
1353 
1354 /******************************************************************************
1355  *
1356  * FUNCTION:    AcpiOsReadable
1357  *
1358  * PARAMETERS:  Pointer             - Area to be verified
1359  *              Length              - Size of area
1360  *
1361  * RETURN:      TRUE if readable for entire length
1362  *
1363  * DESCRIPTION: Verify that a pointer is valid for reading
1364  *
1365  *****************************************************************************/
1366 
1367 BOOLEAN
1368 AcpiOsReadable (
1369     void                    *Pointer,
1370     ACPI_SIZE               Length)
1371 {
1372 
1373     return (TRUE);
1374 }
1375 
1376 
1377 /******************************************************************************
1378  *
1379  * FUNCTION:    AcpiOsWritable
1380  *
1381  * PARAMETERS:  Pointer             - Area to be verified
1382  *              Length              - Size of area
1383  *
1384  * RETURN:      TRUE if writable for entire length
1385  *
1386  * DESCRIPTION: Verify that a pointer is valid for writing
1387  *
1388  *****************************************************************************/
1389 
1390 BOOLEAN
1391 AcpiOsWritable (
1392     void                    *Pointer,
1393     ACPI_SIZE               Length)
1394 {
1395 
1396     return (TRUE);
1397 }
1398 
1399 
1400 /******************************************************************************
1401  *
1402  * FUNCTION:    AcpiOsSignal
1403  *
1404  * PARAMETERS:  Function            - ACPI A signal function code
1405  *              Info                - Pointer to function-dependent structure
1406  *
1407  * RETURN:      Status
1408  *
1409  * DESCRIPTION: Miscellaneous functions. Example implementation only.
1410  *
1411  *****************************************************************************/
1412 
1413 ACPI_STATUS
1414 AcpiOsSignal (
1415     UINT32                  Function,
1416     void                    *Info)
1417 {
1418 
1419     switch (Function)
1420     {
1421     case ACPI_SIGNAL_FATAL:
1422 
1423         break;
1424 
1425     case ACPI_SIGNAL_BREAKPOINT:
1426 
1427         break;
1428 
1429     default:
1430 
1431         break;
1432     }
1433 
1434     return (AE_OK);
1435 }
1436 
1437 /* Optional multi-thread support */
1438 
1439 #ifndef ACPI_SINGLE_THREADED
1440 /******************************************************************************
1441  *
1442  * FUNCTION:    AcpiOsGetThreadId
1443  *
1444  * PARAMETERS:  None
1445  *
1446  * RETURN:      Id of the running thread
1447  *
1448  * DESCRIPTION: Get the ID of the current (running) thread
1449  *
1450  *****************************************************************************/
1451 
1452 ACPI_THREAD_ID
1453 AcpiOsGetThreadId (
1454     void)
1455 {
1456     pthread_t               thread;
1457 
1458 
1459     thread = pthread_self();
1460     return (ACPI_CAST_PTHREAD_T (thread));
1461 }
1462 
1463 
1464 /******************************************************************************
1465  *
1466  * FUNCTION:    AcpiOsExecute
1467  *
1468  * PARAMETERS:  Type                - Type of execution
1469  *              Function            - Address of the function to execute
1470  *              Context             - Passed as a parameter to the function
1471  *
1472  * RETURN:      Status.
1473  *
1474  * DESCRIPTION: Execute a new thread
1475  *
1476  *****************************************************************************/
1477 
1478 ACPI_STATUS
1479 AcpiOsExecute (
1480     ACPI_EXECUTE_TYPE       Type,
1481     ACPI_OSD_EXEC_CALLBACK  Function,
1482     void                    *Context)
1483 {
1484     pthread_t               thread;
1485     int                     ret;
1486 
1487 
1488     ret = pthread_create (&thread, NULL, (PTHREAD_CALLBACK) Function, Context);
1489     if (ret)
1490     {
1491         AcpiOsPrintf("Create thread failed");
1492     }
1493     return (0);
1494 }
1495 
1496 #else /* ACPI_SINGLE_THREADED */
1497 ACPI_THREAD_ID
1498 AcpiOsGetThreadId (
1499     void)
1500 {
1501     return (1);
1502 }
1503 
1504 ACPI_STATUS
1505 AcpiOsExecute (
1506     ACPI_EXECUTE_TYPE       Type,
1507     ACPI_OSD_EXEC_CALLBACK  Function,
1508     void                    *Context)
1509 {
1510 
1511     Function (Context);
1512 
1513     return (AE_OK);
1514 }
1515 
1516 #endif /* ACPI_SINGLE_THREADED */
1517 
1518 
1519 /******************************************************************************
1520  *
1521  * FUNCTION:    AcpiOsWaitEventsComplete
1522  *
1523  * PARAMETERS:  None
1524  *
1525  * RETURN:      None
1526  *
1527  * DESCRIPTION: Wait for all asynchronous events to complete. This
1528  *              implementation does nothing.
1529  *
1530  *****************************************************************************/
1531 
1532 void
1533 AcpiOsWaitEventsComplete (
1534     void)
1535 {
1536     return;
1537 }
1538