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