Home | History | Annotate | Line # | Download | only in service_layers
osunixxf.c revision 1.1.1.12
      1 /******************************************************************************
      2  *
      3  * Module Name: osunixxf - UNIX OSL interfaces
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2019, 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:    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     int                 RetVal;
    880 #ifndef ACPI_USE_ALTERNATE_TIMEOUT
    881     struct timespec     Time;
    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         while (((RetVal = sem_wait (Sem)) == -1) && (errno == EINTR))
    912         {
    913             continue;   /* Restart if interrupted */
    914         }
    915         if (RetVal != 0)
    916         {
    917             Status = (AE_TIME);
    918         }
    919         break;
    920 
    921 
    922     /* Wait with MsecTimeout */
    923 
    924     default:
    925 
    926 #ifdef ACPI_USE_ALTERNATE_TIMEOUT
    927         /*
    928          * Alternate timeout mechanism for environments where
    929          * sem_timedwait is not available or does not work properly.
    930          */
    931         while (MsecTimeout)
    932         {
    933             if (sem_trywait (Sem) == 0)
    934             {
    935                 /* Got the semaphore */
    936                 return (AE_OK);
    937             }
    938 
    939             if (MsecTimeout >= 10)
    940             {
    941                 MsecTimeout -= 10;
    942                 usleep (10 * ACPI_USEC_PER_MSEC); /* ten milliseconds */
    943             }
    944             else
    945             {
    946                 MsecTimeout--;
    947                 usleep (ACPI_USEC_PER_MSEC); /* one millisecond */
    948             }
    949         }
    950         Status = (AE_TIME);
    951 #else
    952         /*
    953          * The interface to sem_timedwait is an absolute time, so we need to
    954          * get the current time, then add in the millisecond Timeout value.
    955          */
    956         if (clock_gettime (CLOCK_REALTIME, &Time) == -1)
    957         {
    958             perror ("clock_gettime");
    959             return (AE_TIME);
    960         }
    961 
    962         Time.tv_sec += (MsecTimeout / ACPI_MSEC_PER_SEC);
    963         Time.tv_nsec += ((MsecTimeout % ACPI_MSEC_PER_SEC) * ACPI_NSEC_PER_MSEC);
    964 
    965         /* Handle nanosecond overflow (field must be less than one second) */
    966 
    967         if (Time.tv_nsec >= ACPI_NSEC_PER_SEC)
    968         {
    969             Time.tv_sec += (Time.tv_nsec / ACPI_NSEC_PER_SEC);
    970             Time.tv_nsec = (Time.tv_nsec % ACPI_NSEC_PER_SEC);
    971         }
    972 
    973         while (((RetVal = sem_timedwait (Sem, &Time)) == -1) && (errno == EINTR))
    974         {
    975             continue;   /* Restart if interrupted */
    976 
    977         }
    978 
    979         if (RetVal != 0)
    980         {
    981             if (errno != ETIMEDOUT)
    982             {
    983                 perror ("sem_timedwait");
    984             }
    985             Status = (AE_TIME);
    986         }
    987 #endif
    988         break;
    989     }
    990 
    991     return (Status);
    992 }
    993 
    994 
    995 /******************************************************************************
    996  *
    997  * FUNCTION:    AcpiOsSignalSemaphore
    998  *
    999  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
   1000  *              Units               - Number of units to send
   1001  *
   1002  * RETURN:      Status
   1003  *
   1004  * DESCRIPTION: Send units
   1005  *
   1006  *****************************************************************************/
   1007 
   1008 ACPI_STATUS
   1009 AcpiOsSignalSemaphore (
   1010     ACPI_HANDLE         Handle,
   1011     UINT32              Units)
   1012 {
   1013     sem_t               *Sem = (sem_t *)Handle;
   1014 
   1015 
   1016     if (!Sem)
   1017     {
   1018         return (AE_BAD_PARAMETER);
   1019     }
   1020 
   1021     if (sem_post (Sem) == -1)
   1022     {
   1023         return (AE_LIMIT);
   1024     }
   1025 
   1026     return (AE_OK);
   1027 }
   1028 
   1029 #endif /* ACPI_SINGLE_THREADED */
   1030 
   1031 
   1032 /******************************************************************************
   1033  *
   1034  * FUNCTION:    Spinlock interfaces
   1035  *
   1036  * DESCRIPTION: Map these interfaces to semaphore interfaces
   1037  *
   1038  *****************************************************************************/
   1039 
   1040 ACPI_STATUS
   1041 AcpiOsCreateLock (
   1042     ACPI_SPINLOCK           *OutHandle)
   1043 {
   1044 
   1045     return (AcpiOsCreateSemaphore (1, 1, OutHandle));
   1046 }
   1047 
   1048 
   1049 void
   1050 AcpiOsDeleteLock (
   1051     ACPI_SPINLOCK           Handle)
   1052 {
   1053     AcpiOsDeleteSemaphore (Handle);
   1054 }
   1055 
   1056 
   1057 ACPI_CPU_FLAGS
   1058 AcpiOsAcquireLock (
   1059     ACPI_HANDLE             Handle)
   1060 {
   1061     AcpiOsWaitSemaphore (Handle, 1, 0xFFFF);
   1062     return (0);
   1063 }
   1064 
   1065 
   1066 void
   1067 AcpiOsReleaseLock (
   1068     ACPI_SPINLOCK           Handle,
   1069     ACPI_CPU_FLAGS          Flags)
   1070 {
   1071     AcpiOsSignalSemaphore (Handle, 1);
   1072 }
   1073 
   1074 
   1075 /******************************************************************************
   1076  *
   1077  * FUNCTION:    AcpiOsInstallInterruptHandler
   1078  *
   1079  * PARAMETERS:  InterruptNumber     - Level handler should respond to.
   1080  *              Isr                 - Address of the ACPI interrupt handler
   1081  *              ExceptPtr           - Where status is returned
   1082  *
   1083  * RETURN:      Handle to the newly installed handler.
   1084  *
   1085  * DESCRIPTION: Install an interrupt handler. Used to install the ACPI
   1086  *              OS-independent handler.
   1087  *
   1088  *****************************************************************************/
   1089 
   1090 UINT32
   1091 AcpiOsInstallInterruptHandler (
   1092     UINT32                  InterruptNumber,
   1093     ACPI_OSD_HANDLER        ServiceRoutine,
   1094     void                    *Context)
   1095 {
   1096 
   1097     return (AE_OK);
   1098 }
   1099 
   1100 
   1101 /******************************************************************************
   1102  *
   1103  * FUNCTION:    AcpiOsRemoveInterruptHandler
   1104  *
   1105  * PARAMETERS:  Handle              - Returned when handler was installed
   1106  *
   1107  * RETURN:      Status
   1108  *
   1109  * DESCRIPTION: Uninstalls an interrupt handler.
   1110  *
   1111  *****************************************************************************/
   1112 
   1113 ACPI_STATUS
   1114 AcpiOsRemoveInterruptHandler (
   1115     UINT32                  InterruptNumber,
   1116     ACPI_OSD_HANDLER        ServiceRoutine)
   1117 {
   1118 
   1119     return (AE_OK);
   1120 }
   1121 
   1122 
   1123 /******************************************************************************
   1124  *
   1125  * FUNCTION:    AcpiOsStall
   1126  *
   1127  * PARAMETERS:  microseconds        - Time to sleep
   1128  *
   1129  * RETURN:      Blocks until sleep is completed.
   1130  *
   1131  * DESCRIPTION: Sleep at microsecond granularity
   1132  *
   1133  *****************************************************************************/
   1134 
   1135 void
   1136 AcpiOsStall (
   1137     UINT32                  microseconds)
   1138 {
   1139 
   1140     if (microseconds)
   1141     {
   1142         usleep (microseconds);
   1143     }
   1144 }
   1145 
   1146 
   1147 /******************************************************************************
   1148  *
   1149  * FUNCTION:    AcpiOsSleep
   1150  *
   1151  * PARAMETERS:  milliseconds        - Time to sleep
   1152  *
   1153  * RETURN:      Blocks until sleep is completed.
   1154  *
   1155  * DESCRIPTION: Sleep at millisecond granularity
   1156  *
   1157  *****************************************************************************/
   1158 
   1159 void
   1160 AcpiOsSleep (
   1161     UINT64                  milliseconds)
   1162 {
   1163 
   1164     /* Sleep for whole seconds */
   1165 
   1166     sleep (milliseconds / ACPI_MSEC_PER_SEC);
   1167 
   1168     /*
   1169      * Sleep for remaining microseconds.
   1170      * Arg to usleep() is in usecs and must be less than 1,000,000 (1 second).
   1171      */
   1172     usleep ((milliseconds % ACPI_MSEC_PER_SEC) * ACPI_USEC_PER_MSEC);
   1173 }
   1174 
   1175 
   1176 /******************************************************************************
   1177  *
   1178  * FUNCTION:    AcpiOsGetTimer
   1179  *
   1180  * PARAMETERS:  None
   1181  *
   1182  * RETURN:      Current time in 100 nanosecond units
   1183  *
   1184  * DESCRIPTION: Get the current system time
   1185  *
   1186  *****************************************************************************/
   1187 
   1188 UINT64
   1189 AcpiOsGetTimer (
   1190     void)
   1191 {
   1192     struct timeval          time;
   1193 
   1194 
   1195     /* This timer has sufficient resolution for user-space application code */
   1196 
   1197     gettimeofday (&time, NULL);
   1198 
   1199     /* (Seconds * 10^7 = 100ns(10^-7)) + (Microseconds(10^-6) * 10^1 = 100ns) */
   1200 
   1201     return (((UINT64) time.tv_sec * ACPI_100NSEC_PER_SEC) +
   1202             ((UINT64) time.tv_usec * ACPI_100NSEC_PER_USEC));
   1203 }
   1204 
   1205 
   1206 /******************************************************************************
   1207  *
   1208  * FUNCTION:    AcpiOsReadPciConfiguration
   1209  *
   1210  * PARAMETERS:  PciId               - Seg/Bus/Dev
   1211  *              PciRegister         - Device Register
   1212  *              Value               - Buffer where value is placed
   1213  *              Width               - Number of bits
   1214  *
   1215  * RETURN:      Status
   1216  *
   1217  * DESCRIPTION: Read data from PCI configuration space
   1218  *
   1219  *****************************************************************************/
   1220 
   1221 ACPI_STATUS
   1222 AcpiOsReadPciConfiguration (
   1223     ACPI_PCI_ID             *PciId,
   1224     UINT32                  PciRegister,
   1225     UINT64                  *Value,
   1226     UINT32                  Width)
   1227 {
   1228 
   1229     *Value = 0;
   1230     return (AE_OK);
   1231 }
   1232 
   1233 
   1234 /******************************************************************************
   1235  *
   1236  * FUNCTION:    AcpiOsWritePciConfiguration
   1237  *
   1238  * PARAMETERS:  PciId               - Seg/Bus/Dev
   1239  *              PciRegister         - Device Register
   1240  *              Value               - Value to be written
   1241  *              Width               - Number of bits
   1242  *
   1243  * RETURN:      Status.
   1244  *
   1245  * DESCRIPTION: Write data to PCI configuration space
   1246  *
   1247  *****************************************************************************/
   1248 
   1249 ACPI_STATUS
   1250 AcpiOsWritePciConfiguration (
   1251     ACPI_PCI_ID             *PciId,
   1252     UINT32                  PciRegister,
   1253     UINT64                  Value,
   1254     UINT32                  Width)
   1255 {
   1256 
   1257     return (AE_OK);
   1258 }
   1259 
   1260 
   1261 /******************************************************************************
   1262  *
   1263  * FUNCTION:    AcpiOsReadPort
   1264  *
   1265  * PARAMETERS:  Address             - Address of I/O port/register to read
   1266  *              Value               - Where value is placed
   1267  *              Width               - Number of bits
   1268  *
   1269  * RETURN:      Value read from port
   1270  *
   1271  * DESCRIPTION: Read data from an I/O port or register
   1272  *
   1273  *****************************************************************************/
   1274 
   1275 ACPI_STATUS
   1276 AcpiOsReadPort (
   1277     ACPI_IO_ADDRESS         Address,
   1278     UINT32                  *Value,
   1279     UINT32                  Width)
   1280 {
   1281 
   1282     switch (Width)
   1283     {
   1284     case 8:
   1285 
   1286         *Value = 0xFF;
   1287         break;
   1288 
   1289     case 16:
   1290 
   1291         *Value = 0xFFFF;
   1292         break;
   1293 
   1294     case 32:
   1295 
   1296         *Value = 0xFFFFFFFF;
   1297         break;
   1298 
   1299     default:
   1300 
   1301         return (AE_BAD_PARAMETER);
   1302     }
   1303 
   1304     return (AE_OK);
   1305 }
   1306 
   1307 
   1308 /******************************************************************************
   1309  *
   1310  * FUNCTION:    AcpiOsWritePort
   1311  *
   1312  * PARAMETERS:  Address             - Address of I/O port/register to write
   1313  *              Value               - Value to write
   1314  *              Width               - Number of bits
   1315  *
   1316  * RETURN:      None
   1317  *
   1318  * DESCRIPTION: Write data to an I/O port or register
   1319  *
   1320  *****************************************************************************/
   1321 
   1322 ACPI_STATUS
   1323 AcpiOsWritePort (
   1324     ACPI_IO_ADDRESS         Address,
   1325     UINT32                  Value,
   1326     UINT32                  Width)
   1327 {
   1328 
   1329     return (AE_OK);
   1330 }
   1331 
   1332 
   1333 /******************************************************************************
   1334  *
   1335  * FUNCTION:    AcpiOsReadMemory
   1336  *
   1337  * PARAMETERS:  Address             - Physical Memory Address to read
   1338  *              Value               - Where value is placed
   1339  *              Width               - Number of bits (8,16,32, or 64)
   1340  *
   1341  * RETURN:      Value read from physical memory address. Always returned
   1342  *              as a 64-bit integer, regardless of the read width.
   1343  *
   1344  * DESCRIPTION: Read data from a physical memory address
   1345  *
   1346  *****************************************************************************/
   1347 
   1348 ACPI_STATUS
   1349 AcpiOsReadMemory (
   1350     ACPI_PHYSICAL_ADDRESS   Address,
   1351     UINT64                  *Value,
   1352     UINT32                  Width)
   1353 {
   1354 
   1355     switch (Width)
   1356     {
   1357     case 8:
   1358     case 16:
   1359     case 32:
   1360     case 64:
   1361 
   1362         *Value = 0;
   1363         break;
   1364 
   1365     default:
   1366 
   1367         return (AE_BAD_PARAMETER);
   1368     }
   1369     return (AE_OK);
   1370 }
   1371 
   1372 
   1373 /******************************************************************************
   1374  *
   1375  * FUNCTION:    AcpiOsWriteMemory
   1376  *
   1377  * PARAMETERS:  Address             - Physical Memory Address to write
   1378  *              Value               - Value to write
   1379  *              Width               - Number of bits (8,16,32, or 64)
   1380  *
   1381  * RETURN:      None
   1382  *
   1383  * DESCRIPTION: Write data to a physical memory address
   1384  *
   1385  *****************************************************************************/
   1386 
   1387 ACPI_STATUS
   1388 AcpiOsWriteMemory (
   1389     ACPI_PHYSICAL_ADDRESS   Address,
   1390     UINT64                  Value,
   1391     UINT32                  Width)
   1392 {
   1393 
   1394     return (AE_OK);
   1395 }
   1396 
   1397 
   1398 /******************************************************************************
   1399  *
   1400  * FUNCTION:    AcpiOsReadable
   1401  *
   1402  * PARAMETERS:  Pointer             - Area to be verified
   1403  *              Length              - Size of area
   1404  *
   1405  * RETURN:      TRUE if readable for entire length
   1406  *
   1407  * DESCRIPTION: Verify that a pointer is valid for reading
   1408  *
   1409  *****************************************************************************/
   1410 
   1411 BOOLEAN
   1412 AcpiOsReadable (
   1413     void                    *Pointer,
   1414     ACPI_SIZE               Length)
   1415 {
   1416 
   1417     return (TRUE);
   1418 }
   1419 
   1420 
   1421 /******************************************************************************
   1422  *
   1423  * FUNCTION:    AcpiOsWritable
   1424  *
   1425  * PARAMETERS:  Pointer             - Area to be verified
   1426  *              Length              - Size of area
   1427  *
   1428  * RETURN:      TRUE if writable for entire length
   1429  *
   1430  * DESCRIPTION: Verify that a pointer is valid for writing
   1431  *
   1432  *****************************************************************************/
   1433 
   1434 BOOLEAN
   1435 AcpiOsWritable (
   1436     void                    *Pointer,
   1437     ACPI_SIZE               Length)
   1438 {
   1439 
   1440     return (TRUE);
   1441 }
   1442 
   1443 
   1444 /******************************************************************************
   1445  *
   1446  * FUNCTION:    AcpiOsSignal
   1447  *
   1448  * PARAMETERS:  Function            - ACPI A signal function code
   1449  *              Info                - Pointer to function-dependent structure
   1450  *
   1451  * RETURN:      Status
   1452  *
   1453  * DESCRIPTION: Miscellaneous functions. Example implementation only.
   1454  *
   1455  *****************************************************************************/
   1456 
   1457 ACPI_STATUS
   1458 AcpiOsSignal (
   1459     UINT32                  Function,
   1460     void                    *Info)
   1461 {
   1462 
   1463     switch (Function)
   1464     {
   1465     case ACPI_SIGNAL_FATAL:
   1466 
   1467         break;
   1468 
   1469     case ACPI_SIGNAL_BREAKPOINT:
   1470 
   1471         break;
   1472 
   1473     default:
   1474 
   1475         break;
   1476     }
   1477 
   1478     return (AE_OK);
   1479 }
   1480 
   1481 /* Optional multi-thread support */
   1482 
   1483 #ifndef ACPI_SINGLE_THREADED
   1484 /******************************************************************************
   1485  *
   1486  * FUNCTION:    AcpiOsGetThreadId
   1487  *
   1488  * PARAMETERS:  None
   1489  *
   1490  * RETURN:      Id of the running thread
   1491  *
   1492  * DESCRIPTION: Get the ID of the current (running) thread
   1493  *
   1494  *****************************************************************************/
   1495 
   1496 ACPI_THREAD_ID
   1497 AcpiOsGetThreadId (
   1498     void)
   1499 {
   1500     pthread_t               thread;
   1501 
   1502 
   1503     thread = pthread_self();
   1504     return (ACPI_CAST_PTHREAD_T (thread));
   1505 }
   1506 
   1507 
   1508 /******************************************************************************
   1509  *
   1510  * FUNCTION:    AcpiOsExecute
   1511  *
   1512  * PARAMETERS:  Type                - Type of execution
   1513  *              Function            - Address of the function to execute
   1514  *              Context             - Passed as a parameter to the function
   1515  *
   1516  * RETURN:      Status.
   1517  *
   1518  * DESCRIPTION: Execute a new thread
   1519  *
   1520  *****************************************************************************/
   1521 
   1522 ACPI_STATUS
   1523 AcpiOsExecute (
   1524     ACPI_EXECUTE_TYPE       Type,
   1525     ACPI_OSD_EXEC_CALLBACK  Function,
   1526     void                    *Context)
   1527 {
   1528     pthread_t               thread;
   1529     int                     ret;
   1530 
   1531 
   1532     ret = pthread_create (&thread, NULL, (PTHREAD_CALLBACK) Function, Context);
   1533     if (ret)
   1534     {
   1535         AcpiOsPrintf("Create thread failed");
   1536     }
   1537     return (0);
   1538 }
   1539 
   1540 #else /* ACPI_SINGLE_THREADED */
   1541 ACPI_THREAD_ID
   1542 AcpiOsGetThreadId (
   1543     void)
   1544 {
   1545     return (1);
   1546 }
   1547 
   1548 ACPI_STATUS
   1549 AcpiOsExecute (
   1550     ACPI_EXECUTE_TYPE       Type,
   1551     ACPI_OSD_EXEC_CALLBACK  Function,
   1552     void                    *Context)
   1553 {
   1554 
   1555     Function (Context);
   1556 
   1557     return (AE_OK);
   1558 }
   1559 
   1560 #endif /* ACPI_SINGLE_THREADED */
   1561 
   1562 
   1563 /******************************************************************************
   1564  *
   1565  * FUNCTION:    AcpiOsWaitEventsComplete
   1566  *
   1567  * PARAMETERS:  None
   1568  *
   1569  * RETURN:      None
   1570  *
   1571  * DESCRIPTION: Wait for all asynchronous events to complete. This
   1572  *              implementation does nothing.
   1573  *
   1574  *****************************************************************************/
   1575 
   1576 void
   1577 AcpiOsWaitEventsComplete (
   1578     void)
   1579 {
   1580     return;
   1581 }
   1582