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