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