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