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