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