Home | History | Annotate | Line # | Download | only in service_layers
oswinxf.c revision 1.1.1.3
      1 /******************************************************************************
      2  *
      3  * Module Name: oswinxf - Windows OSL
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2011, 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 #include "acpi.h"
     45 #include "accommon.h"
     46 
     47 #ifdef WIN32
     48 #pragma warning(disable:4115)   /* warning C4115: named type definition in parentheses (caused by rpcasync.h> */
     49 
     50 #include <windows.h>
     51 #include <winbase.h>
     52 
     53 #elif WIN64
     54 #include <windowsx.h>
     55 #endif
     56 
     57 #include <stdio.h>
     58 #include <stdlib.h>
     59 #include <stdarg.h>
     60 #include <process.h>
     61 #include <time.h>
     62 
     63 #define _COMPONENT          ACPI_OS_SERVICES
     64         ACPI_MODULE_NAME    ("oswinxf")
     65 
     66 
     67 extern FILE                 *AcpiGbl_DebugFile;
     68 extern BOOLEAN              AcpiGbl_DebugTimeout;
     69 
     70 FILE                        *AcpiGbl_OutputFile;
     71 UINT64                      TimerFrequency;
     72 char                        TableName[ACPI_NAME_SIZE + 1];
     73 
     74 #define ACPI_OS_DEBUG_TIMEOUT   30000 /* 30 seconds */
     75 
     76 
     77 /* Upcalls to application */
     78 
     79 ACPI_PHYSICAL_ADDRESS
     80 AeLocalGetRootPointer (
     81     void);
     82 
     83 void
     84 AeTableOverride (
     85     ACPI_TABLE_HEADER       *ExistingTable,
     86     ACPI_TABLE_HEADER       **NewTable);
     87 
     88 ACPI_TABLE_HEADER *
     89 OsGetTable (
     90     char                    *Signature);
     91 
     92 
     93 /*
     94  * Real semaphores are only used for a multi-threaded application
     95  */
     96 #ifndef ACPI_SINGLE_THREADED
     97 
     98 /* Semaphore information structure */
     99 
    100 typedef struct acpi_os_semaphore_info
    101 {
    102     UINT16                  MaxUnits;
    103     UINT16                  CurrentUnits;
    104     void                    *OsHandle;
    105 
    106 } ACPI_OS_SEMAPHORE_INFO;
    107 
    108 /* Need enough semaphores to run the large aslts suite */
    109 
    110 #define ACPI_OS_MAX_SEMAPHORES  256
    111 
    112 ACPI_OS_SEMAPHORE_INFO          AcpiGbl_Semaphores[ACPI_OS_MAX_SEMAPHORES];
    113 
    114 #endif /* ACPI_SINGLE_THREADED */
    115 
    116 
    117 /******************************************************************************
    118  *
    119  * FUNCTION:    AcpiOsTerminate
    120  *
    121  * PARAMETERS:  None
    122  *
    123  * RETURN:      Status
    124  *
    125  * DESCRIPTION: Nothing to do for windows
    126  *
    127  *****************************************************************************/
    128 
    129 ACPI_STATUS
    130 AcpiOsTerminate (
    131     void)
    132 {
    133     return (AE_OK);
    134 }
    135 
    136 
    137 /******************************************************************************
    138  *
    139  * FUNCTION:    AcpiOsInitialize
    140  *
    141  * PARAMETERS:  None
    142  *
    143  * RETURN:      Status
    144  *
    145  * DESCRIPTION: Init this OSL
    146  *
    147  *****************************************************************************/
    148 
    149 ACPI_STATUS
    150 AcpiOsInitialize (
    151     void)
    152 {
    153     LARGE_INTEGER           LocalTimerFrequency;
    154 
    155 
    156 #ifndef ACPI_SINGLE_THREADED
    157     /* Clear the semaphore info array */
    158 
    159     memset (AcpiGbl_Semaphores, 0x00, sizeof (AcpiGbl_Semaphores));
    160 #endif
    161 
    162     AcpiGbl_OutputFile = stdout;
    163 
    164     /* Get the timer frequency for use in AcpiOsGetTimer */
    165 
    166     TimerFrequency = 0;
    167     if (QueryPerformanceFrequency (&LocalTimerFrequency))
    168     {
    169         /* Frequency is in ticks per second */
    170 
    171         TimerFrequency = LocalTimerFrequency.QuadPart;
    172     }
    173 
    174     return (AE_OK);
    175 }
    176 
    177 
    178 /******************************************************************************
    179  *
    180  * FUNCTION:    AcpiOsGetRootPointer
    181  *
    182  * PARAMETERS:  None
    183  *
    184  * RETURN:      RSDP physical address
    185  *
    186  * DESCRIPTION: Gets the root pointer (RSDP)
    187  *
    188  *****************************************************************************/
    189 
    190 ACPI_PHYSICAL_ADDRESS
    191 AcpiOsGetRootPointer (
    192     void)
    193 {
    194 
    195     return (AeLocalGetRootPointer ());
    196 }
    197 
    198 
    199 /******************************************************************************
    200  *
    201  * FUNCTION:    AcpiOsPredefinedOverride
    202  *
    203  * PARAMETERS:  InitVal             - Initial value of the predefined object
    204  *              NewVal              - The new value for the object
    205  *
    206  * RETURN:      Status, pointer to value. Null pointer returned if not
    207  *              overriding.
    208  *
    209  * DESCRIPTION: Allow the OS to override predefined names
    210  *
    211  *****************************************************************************/
    212 
    213 ACPI_STATUS
    214 AcpiOsPredefinedOverride (
    215     const ACPI_PREDEFINED_NAMES *InitVal,
    216     ACPI_STRING                 *NewVal)
    217 {
    218 
    219     if (!InitVal || !NewVal)
    220     {
    221         return (AE_BAD_PARAMETER);
    222     }
    223 
    224     *NewVal = NULL;
    225     return (AE_OK);
    226 }
    227 
    228 
    229 /******************************************************************************
    230  *
    231  * FUNCTION:    AcpiOsTableOverride
    232  *
    233  * PARAMETERS:  ExistingTable       - Header of current table (probably firmware)
    234  *              NewTable            - Where an entire new table is returned.
    235  *
    236  * RETURN:      Status, pointer to new table. Null pointer returned if no
    237  *              table is available to override
    238  *
    239  * DESCRIPTION: Return a different version of a table if one is available
    240  *
    241  *****************************************************************************/
    242 
    243 ACPI_STATUS
    244 AcpiOsTableOverride (
    245     ACPI_TABLE_HEADER       *ExistingTable,
    246     ACPI_TABLE_HEADER       **NewTable)
    247 {
    248 
    249     if (!ExistingTable || !NewTable)
    250     {
    251         return (AE_BAD_PARAMETER);
    252     }
    253 
    254     *NewTable = NULL;
    255 
    256 
    257 #ifdef ACPI_EXEC_APP
    258 
    259     /* Call back up to AcpiExec */
    260 
    261     AeTableOverride (ExistingTable, NewTable);
    262 #endif
    263 
    264 
    265 #ifdef ACPI_ASL_COMPILER
    266 
    267     /* Attempt to get the table from the registry */
    268 
    269     /* Construct a null-terminated string from table signature */
    270 
    271     TableName[ACPI_NAME_SIZE] = 0;
    272     ACPI_STRNCPY (TableName, ExistingTable->Signature, ACPI_NAME_SIZE);
    273 
    274     *NewTable = OsGetTable (TableName);
    275     if (*NewTable)
    276     {
    277         AcpiOsPrintf ("Table [%s] obtained from registry, %u bytes\n",
    278             TableName, (*NewTable)->Length);
    279     }
    280     else
    281     {
    282         AcpiOsPrintf ("Could not read table %s from registry\n", TableName);
    283     }
    284 #endif
    285 
    286     return (AE_OK);
    287 }
    288 
    289 
    290 /******************************************************************************
    291  *
    292  * FUNCTION:    AcpiOsGetTimer
    293  *
    294  * PARAMETERS:  None
    295  *
    296  * RETURN:      Current ticks in 100-nanosecond units
    297  *
    298  * DESCRIPTION: Get the value of a system timer
    299  *
    300  ******************************************************************************/
    301 
    302 UINT64
    303 AcpiOsGetTimer (
    304     void)
    305 {
    306     LARGE_INTEGER           Timer;
    307 
    308 
    309     /* Attempt to use hi-granularity timer first */
    310 
    311     if (TimerFrequency &&
    312         QueryPerformanceCounter (&Timer))
    313     {
    314         /* Convert to 100 nanosecond ticks */
    315 
    316         return ((UINT64) ((Timer.QuadPart * (UINT64) 10000000) / TimerFrequency));
    317     }
    318 
    319     /* Fall back to the lo-granularity timer */
    320 
    321     else
    322     {
    323         /* Convert milliseconds to 100 nanosecond ticks */
    324 
    325         return ((UINT64) GetTickCount() * 10000);
    326     }
    327 }
    328 
    329 
    330 /******************************************************************************
    331  *
    332  * FUNCTION:    AcpiOsReadable
    333  *
    334  * PARAMETERS:  Pointer             - Area to be verified
    335  *              Length              - Size of area
    336  *
    337  * RETURN:      TRUE if readable for entire length
    338  *
    339  * DESCRIPTION: Verify that a pointer is valid for reading
    340  *
    341  *****************************************************************************/
    342 
    343 BOOLEAN
    344 AcpiOsReadable (
    345     void                    *Pointer,
    346     ACPI_SIZE               Length)
    347 {
    348 
    349     return ((BOOLEAN) !IsBadReadPtr (Pointer, Length));
    350 }
    351 
    352 
    353 /******************************************************************************
    354  *
    355  * FUNCTION:    AcpiOsWritable
    356  *
    357  * PARAMETERS:  Pointer             - Area to be verified
    358  *              Length              - Size of area
    359  *
    360  * RETURN:      TRUE if writable for entire length
    361  *
    362  * DESCRIPTION: Verify that a pointer is valid for writing
    363  *
    364  *****************************************************************************/
    365 
    366 BOOLEAN
    367 AcpiOsWritable (
    368     void                    *Pointer,
    369     ACPI_SIZE               Length)
    370 {
    371 
    372     return ((BOOLEAN) !IsBadWritePtr (Pointer, Length));
    373 }
    374 
    375 
    376 /******************************************************************************
    377  *
    378  * FUNCTION:    AcpiOsRedirectOutput
    379  *
    380  * PARAMETERS:  Destination         - An open file handle/pointer
    381  *
    382  * RETURN:      None
    383  *
    384  * DESCRIPTION: Causes redirect of AcpiOsPrintf and AcpiOsVprintf
    385  *
    386  *****************************************************************************/
    387 
    388 void
    389 AcpiOsRedirectOutput (
    390     void                    *Destination)
    391 {
    392 
    393     AcpiGbl_OutputFile = Destination;
    394 }
    395 
    396 
    397 /******************************************************************************
    398  *
    399  * FUNCTION:    AcpiOsPrintf
    400  *
    401  * PARAMETERS:  Fmt, ...            - Standard printf format
    402  *
    403  * RETURN:      None
    404  *
    405  * DESCRIPTION: Formatted output
    406  *
    407  *****************************************************************************/
    408 
    409 void ACPI_INTERNAL_VAR_XFACE
    410 AcpiOsPrintf (
    411     const char              *Fmt,
    412     ...)
    413 {
    414     va_list                 Args;
    415 
    416 
    417     va_start (Args, Fmt);
    418 
    419     AcpiOsVprintf (Fmt, Args);
    420 
    421     va_end (Args);
    422     return;
    423 }
    424 
    425 
    426 /******************************************************************************
    427  *
    428  * FUNCTION:    AcpiOsVprintf
    429  *
    430  * PARAMETERS:  Fmt                 - Standard printf format
    431  *              Args                - Argument list
    432  *
    433  * RETURN:      None
    434  *
    435  * DESCRIPTION: Formatted output with argument list pointer
    436  *
    437  *****************************************************************************/
    438 
    439 void
    440 AcpiOsVprintf (
    441     const char              *Fmt,
    442     va_list                 Args)
    443 {
    444     INT32                   Count = 0;
    445     UINT8                   Flags;
    446 
    447 
    448     Flags = AcpiGbl_DbOutputFlags;
    449     if (Flags & ACPI_DB_REDIRECTABLE_OUTPUT)
    450     {
    451         /* Output is directable to either a file (if open) or the console */
    452 
    453         if (AcpiGbl_DebugFile)
    454         {
    455             /* Output file is open, send the output there */
    456 
    457             Count = vfprintf (AcpiGbl_DebugFile, Fmt, Args);
    458         }
    459         else
    460         {
    461             /* No redirection, send output to console (once only!) */
    462 
    463             Flags |= ACPI_DB_CONSOLE_OUTPUT;
    464         }
    465     }
    466 
    467     if (Flags & ACPI_DB_CONSOLE_OUTPUT)
    468     {
    469         Count = vfprintf (AcpiGbl_OutputFile, Fmt, Args);
    470     }
    471 
    472     return;
    473 }
    474 
    475 
    476 /******************************************************************************
    477  *
    478  * FUNCTION:    AcpiOsGetLine
    479  *
    480  * PARAMETERS:  Buffer              - Where to return the command line
    481  *              BufferLength        - Maximum length of Buffer
    482  *              BytesRead           - Where the actual byte count is returned
    483  *
    484  * RETURN:      Status and actual bytes read
    485  *
    486  * DESCRIPTION: Formatted input with argument list pointer
    487  *
    488  *****************************************************************************/
    489 
    490 ACPI_STATUS
    491 AcpiOsGetLine (
    492     char                    *Buffer,
    493     UINT32                  BufferLength,
    494     UINT32                  *BytesRead)
    495 {
    496     char                    Temp;
    497     UINT32                  i;
    498 
    499 
    500     for (i = 0; ; i++)
    501     {
    502         if (i >= BufferLength)
    503         {
    504             return (AE_BUFFER_OVERFLOW);
    505         }
    506 
    507         scanf ("%1c", &Temp);
    508         if (!Temp || Temp == '\n')
    509         {
    510             break;
    511         }
    512 
    513         Buffer [i] = Temp;
    514     }
    515 
    516     /* Null terminate the buffer */
    517 
    518     Buffer [i] = 0;
    519 
    520     /* Return the number of bytes in the string */
    521 
    522     if (BytesRead)
    523     {
    524         *BytesRead = i;
    525     }
    526     return (AE_OK);
    527 }
    528 
    529 
    530 /******************************************************************************
    531  *
    532  * FUNCTION:    AcpiOsMapMemory
    533  *
    534  * PARAMETERS:  Where               - Physical address of memory to be mapped
    535  *              Length              - How much memory to map
    536  *
    537  * RETURN:      Pointer to mapped memory. Null on error.
    538  *
    539  * DESCRIPTION: Map physical memory into caller's address space
    540  *
    541  *****************************************************************************/
    542 
    543 void *
    544 AcpiOsMapMemory (
    545     ACPI_PHYSICAL_ADDRESS   Where,
    546     ACPI_SIZE               Length)
    547 {
    548 
    549     return (ACPI_TO_POINTER ((ACPI_SIZE) Where));
    550 }
    551 
    552 
    553 /******************************************************************************
    554  *
    555  * FUNCTION:    AcpiOsUnmapMemory
    556  *
    557  * PARAMETERS:  Where               - Logical address of memory to be unmapped
    558  *              Length              - How much memory to unmap
    559  *
    560  * RETURN:      None.
    561  *
    562  * DESCRIPTION: Delete a previously created mapping. Where and Length must
    563  *              correspond to a previous mapping exactly.
    564  *
    565  *****************************************************************************/
    566 
    567 void
    568 AcpiOsUnmapMemory (
    569     void                    *Where,
    570     ACPI_SIZE               Length)
    571 {
    572 
    573     return;
    574 }
    575 
    576 
    577 /******************************************************************************
    578  *
    579  * FUNCTION:    AcpiOsAllocate
    580  *
    581  * PARAMETERS:  Size                - Amount to allocate, in bytes
    582  *
    583  * RETURN:      Pointer to the new allocation. Null on error.
    584  *
    585  * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS.
    586  *
    587  *****************************************************************************/
    588 
    589 void *
    590 AcpiOsAllocate (
    591     ACPI_SIZE               Size)
    592 {
    593     void                    *Mem;
    594 
    595 
    596     Mem = (void *) malloc ((size_t) Size);
    597 
    598     return (Mem);
    599 }
    600 
    601 
    602 /******************************************************************************
    603  *
    604  * FUNCTION:    AcpiOsFree
    605  *
    606  * PARAMETERS:  Mem                 - Pointer to previously allocated memory
    607  *
    608  * RETURN:      None.
    609  *
    610  * DESCRIPTION: Free memory allocated via AcpiOsAllocate
    611  *
    612  *****************************************************************************/
    613 
    614 void
    615 AcpiOsFree (
    616     void                    *Mem)
    617 {
    618 
    619     free (Mem);
    620 }
    621 
    622 
    623 #ifdef ACPI_SINGLE_THREADED
    624 /******************************************************************************
    625  *
    626  * FUNCTION:    Semaphore stub functions
    627  *
    628  * DESCRIPTION: Stub functions used for single-thread applications that do
    629  *              not require semaphore synchronization. Full implementations
    630  *              of these functions appear after the stubs.
    631  *
    632  *****************************************************************************/
    633 
    634 ACPI_STATUS
    635 AcpiOsCreateSemaphore (
    636     UINT32              MaxUnits,
    637     UINT32              InitialUnits,
    638     ACPI_HANDLE         *OutHandle)
    639 {
    640     *OutHandle = (ACPI_HANDLE) 1;
    641     return (AE_OK);
    642 }
    643 
    644 ACPI_STATUS
    645 AcpiOsDeleteSemaphore (
    646     ACPI_HANDLE         Handle)
    647 {
    648     return (AE_OK);
    649 }
    650 
    651 ACPI_STATUS
    652 AcpiOsWaitSemaphore (
    653     ACPI_HANDLE         Handle,
    654     UINT32              Units,
    655     UINT16              Timeout)
    656 {
    657     return (AE_OK);
    658 }
    659 
    660 ACPI_STATUS
    661 AcpiOsSignalSemaphore (
    662     ACPI_HANDLE         Handle,
    663     UINT32              Units)
    664 {
    665     return (AE_OK);
    666 }
    667 
    668 #else
    669 /******************************************************************************
    670  *
    671  * FUNCTION:    AcpiOsCreateSemaphore
    672  *
    673  * PARAMETERS:  MaxUnits            - Maximum units that can be sent
    674  *              InitialUnits        - Units to be assigned to the new semaphore
    675  *              OutHandle           - Where a handle will be returned
    676  *
    677  * RETURN:      Status
    678  *
    679  * DESCRIPTION: Create an OS semaphore
    680  *
    681  *****************************************************************************/
    682 
    683 ACPI_STATUS
    684 AcpiOsCreateSemaphore (
    685     UINT32              MaxUnits,
    686     UINT32              InitialUnits,
    687     ACPI_SEMAPHORE      *OutHandle)
    688 {
    689     void                *Mutex;
    690     UINT32              i;
    691 
    692     ACPI_FUNCTION_NAME (OsCreateSemaphore);
    693 
    694 
    695     if (MaxUnits == ACPI_UINT32_MAX)
    696     {
    697         MaxUnits = 255;
    698     }
    699 
    700     if (InitialUnits == ACPI_UINT32_MAX)
    701     {
    702         InitialUnits = MaxUnits;
    703     }
    704 
    705     if (InitialUnits > MaxUnits)
    706     {
    707         return (AE_BAD_PARAMETER);
    708     }
    709 
    710     /* Find an empty slot */
    711 
    712     for (i = 0; i < ACPI_OS_MAX_SEMAPHORES; i++)
    713     {
    714         if (!AcpiGbl_Semaphores[i].OsHandle)
    715         {
    716             break;
    717         }
    718     }
    719     if (i >= ACPI_OS_MAX_SEMAPHORES)
    720     {
    721         ACPI_EXCEPTION ((AE_INFO, AE_LIMIT,
    722             "Reached max semaphores (%u), could not create", ACPI_OS_MAX_SEMAPHORES));
    723         return (AE_LIMIT);
    724     }
    725 
    726     /* Create an OS semaphore */
    727 
    728     Mutex = CreateSemaphore (NULL, InitialUnits, MaxUnits, NULL);
    729     if (!Mutex)
    730     {
    731         ACPI_ERROR ((AE_INFO, "Could not create semaphore"));
    732         return (AE_NO_MEMORY);
    733     }
    734 
    735     AcpiGbl_Semaphores[i].MaxUnits = (UINT16) MaxUnits;
    736     AcpiGbl_Semaphores[i].CurrentUnits = (UINT16) InitialUnits;
    737     AcpiGbl_Semaphores[i].OsHandle = Mutex;
    738 
    739     ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Handle=%u, Max=%u, Current=%u, OsHandle=%p\n",
    740             i, MaxUnits, InitialUnits, Mutex));
    741 
    742     *OutHandle = (void *) i;
    743     return (AE_OK);
    744 }
    745 
    746 
    747 /******************************************************************************
    748  *
    749  * FUNCTION:    AcpiOsDeleteSemaphore
    750  *
    751  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
    752  *
    753  * RETURN:      Status
    754  *
    755  * DESCRIPTION: Delete an OS semaphore
    756  *
    757  *****************************************************************************/
    758 
    759 ACPI_STATUS
    760 AcpiOsDeleteSemaphore (
    761     ACPI_SEMAPHORE      Handle)
    762 {
    763     UINT32              Index = (UINT32) Handle;
    764 
    765 
    766     if ((Index >= ACPI_OS_MAX_SEMAPHORES) ||
    767         !AcpiGbl_Semaphores[Index].OsHandle)
    768     {
    769         return (AE_BAD_PARAMETER);
    770     }
    771 
    772     CloseHandle (AcpiGbl_Semaphores[Index].OsHandle);
    773     AcpiGbl_Semaphores[Index].OsHandle = NULL;
    774     return (AE_OK);
    775 }
    776 
    777 
    778 /******************************************************************************
    779  *
    780  * FUNCTION:    AcpiOsWaitSemaphore
    781  *
    782  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
    783  *              Units               - How many units to wait for
    784  *              Timeout             - How long to wait
    785  *
    786  * RETURN:      Status
    787  *
    788  * DESCRIPTION: Wait for units
    789  *
    790  *****************************************************************************/
    791 
    792 ACPI_STATUS
    793 AcpiOsWaitSemaphore (
    794     ACPI_SEMAPHORE      Handle,
    795     UINT32              Units,
    796     UINT16              Timeout)
    797 {
    798     UINT32              Index = (UINT32) Handle;
    799     UINT32              WaitStatus;
    800     UINT32              OsTimeout = Timeout;
    801 
    802 
    803     ACPI_FUNCTION_ENTRY ();
    804 
    805 
    806     if ((Index >= ACPI_OS_MAX_SEMAPHORES) ||
    807         !AcpiGbl_Semaphores[Index].OsHandle)
    808     {
    809         return (AE_BAD_PARAMETER);
    810     }
    811 
    812     if (Units > 1)
    813     {
    814         printf ("WaitSemaphore: Attempt to receive %u units\n", Units);
    815         return (AE_NOT_IMPLEMENTED);
    816     }
    817 
    818     if (Timeout == ACPI_WAIT_FOREVER)
    819     {
    820         OsTimeout = INFINITE;
    821         if (AcpiGbl_DebugTimeout)
    822         {
    823             /* The debug timeout will prevent hang conditions */
    824 
    825             OsTimeout = ACPI_OS_DEBUG_TIMEOUT;
    826         }
    827     }
    828     else
    829     {
    830         /* Add 10ms to account for clock tick granularity */
    831 
    832         OsTimeout += 10;
    833     }
    834 
    835     WaitStatus = WaitForSingleObject (AcpiGbl_Semaphores[Index].OsHandle, OsTimeout);
    836     if (WaitStatus == WAIT_TIMEOUT)
    837     {
    838         if (AcpiGbl_DebugTimeout)
    839         {
    840             ACPI_EXCEPTION ((AE_INFO, AE_TIME,
    841                 "Debug timeout on semaphore 0x%04X (%ums)\n",
    842                 Index, ACPI_OS_DEBUG_TIMEOUT));
    843         }
    844         return (AE_TIME);
    845     }
    846 
    847     if (AcpiGbl_Semaphores[Index].CurrentUnits == 0)
    848     {
    849         ACPI_ERROR ((AE_INFO, "%s - No unit received. Timeout 0x%X, OS_Status 0x%X",
    850             AcpiUtGetMutexName (Index), Timeout, WaitStatus));
    851 
    852         return (AE_OK);
    853     }
    854 
    855     AcpiGbl_Semaphores[Index].CurrentUnits--;
    856     return (AE_OK);
    857 }
    858 
    859 
    860 /******************************************************************************
    861  *
    862  * FUNCTION:    AcpiOsSignalSemaphore
    863  *
    864  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
    865  *              Units               - Number of units to send
    866  *
    867  * RETURN:      Status
    868  *
    869  * DESCRIPTION: Send units
    870  *
    871  *****************************************************************************/
    872 
    873 ACPI_STATUS
    874 AcpiOsSignalSemaphore (
    875     ACPI_SEMAPHORE      Handle,
    876     UINT32              Units)
    877 {
    878     UINT32              Index = (UINT32) Handle;
    879 
    880 
    881     ACPI_FUNCTION_ENTRY ();
    882 
    883 
    884     if (Index >= ACPI_OS_MAX_SEMAPHORES)
    885     {
    886         printf ("SignalSemaphore: Index/Handle out of range: %2.2X\n", Index);
    887         return (AE_BAD_PARAMETER);
    888     }
    889 
    890     if (!AcpiGbl_Semaphores[Index].OsHandle)
    891     {
    892         printf ("SignalSemaphore: Null OS handle, Index %2.2X\n", Index);
    893         return (AE_BAD_PARAMETER);
    894     }
    895 
    896     if (Units > 1)
    897     {
    898         printf ("SignalSemaphore: Attempt to signal %u units, Index %2.2X\n", Units, Index);
    899         return (AE_NOT_IMPLEMENTED);
    900     }
    901 
    902     if ((AcpiGbl_Semaphores[Index].CurrentUnits + 1) >
    903         AcpiGbl_Semaphores[Index].MaxUnits)
    904     {
    905         ACPI_ERROR ((AE_INFO,
    906             "Oversignalled semaphore[%u]! Current %u Max %u",
    907             Index, AcpiGbl_Semaphores[Index].CurrentUnits,
    908             AcpiGbl_Semaphores[Index].MaxUnits));
    909 
    910         return (AE_LIMIT);
    911     }
    912 
    913     AcpiGbl_Semaphores[Index].CurrentUnits++;
    914     ReleaseSemaphore (AcpiGbl_Semaphores[Index].OsHandle, Units, NULL);
    915 
    916     return (AE_OK);
    917 }
    918 
    919 #endif /* ACPI_SINGLE_THREADED */
    920 
    921 
    922 /******************************************************************************
    923  *
    924  * FUNCTION:    Spinlock interfaces
    925  *
    926  * DESCRIPTION: Map these interfaces to semaphore interfaces
    927  *
    928  *****************************************************************************/
    929 
    930 ACPI_STATUS
    931 AcpiOsCreateLock (
    932     ACPI_SPINLOCK           *OutHandle)
    933 {
    934     return (AcpiOsCreateSemaphore (1, 1, OutHandle));
    935 }
    936 
    937 void
    938 AcpiOsDeleteLock (
    939     ACPI_SPINLOCK           Handle)
    940 {
    941     AcpiOsDeleteSemaphore (Handle);
    942 }
    943 
    944 ACPI_CPU_FLAGS
    945 AcpiOsAcquireLock (
    946     ACPI_SPINLOCK           Handle)
    947 {
    948     AcpiOsWaitSemaphore (Handle, 1, 0xFFFF);
    949     return (0);
    950 }
    951 
    952 void
    953 AcpiOsReleaseLock (
    954     ACPI_SPINLOCK           Handle,
    955     ACPI_CPU_FLAGS          Flags)
    956 {
    957     AcpiOsSignalSemaphore (Handle, 1);
    958 }
    959 
    960 
    961 #if ACPI_FUTURE_IMPLEMENTATION
    962 
    963 /* Mutex interfaces, just implement with a semaphore */
    964 
    965 ACPI_STATUS
    966 AcpiOsCreateMutex (
    967     ACPI_MUTEX              *OutHandle)
    968 {
    969     return (AcpiOsCreateSemaphore (1, 1, OutHandle));
    970 }
    971 
    972 void
    973 AcpiOsDeleteMutex (
    974     ACPI_MUTEX              Handle)
    975 {
    976     AcpiOsDeleteSemaphore (Handle);
    977 }
    978 
    979 ACPI_STATUS
    980 AcpiOsAcquireMutex (
    981     ACPI_MUTEX              Handle,
    982     UINT16                  Timeout)
    983 {
    984     AcpiOsWaitSemaphore (Handle, 1, Timeout);
    985     return (0);
    986 }
    987 
    988 void
    989 AcpiOsReleaseMutex (
    990     ACPI_MUTEX              Handle)
    991 {
    992     AcpiOsSignalSemaphore (Handle, 1);
    993 }
    994 #endif
    995 
    996 
    997 /******************************************************************************
    998  *
    999  * FUNCTION:    AcpiOsInstallInterruptHandler
   1000  *
   1001  * PARAMETERS:  InterruptNumber     - Level handler should respond to.
   1002  *              ServiceRoutine      - Address of the ACPI interrupt handler
   1003  *              Context             - User context
   1004  *
   1005  * RETURN:      Handle to the newly installed handler.
   1006  *
   1007  * DESCRIPTION: Install an interrupt handler. Used to install the ACPI
   1008  *              OS-independent handler.
   1009  *
   1010  *****************************************************************************/
   1011 
   1012 UINT32
   1013 AcpiOsInstallInterruptHandler (
   1014     UINT32                  InterruptNumber,
   1015     ACPI_OSD_HANDLER        ServiceRoutine,
   1016     void                    *Context)
   1017 {
   1018 
   1019     return (AE_OK);
   1020 }
   1021 
   1022 
   1023 /******************************************************************************
   1024  *
   1025  * FUNCTION:    AcpiOsRemoveInterruptHandler
   1026  *
   1027  * PARAMETERS:  Handle              - Returned when handler was installed
   1028  *
   1029  * RETURN:      Status
   1030  *
   1031  * DESCRIPTION: Uninstalls an interrupt handler.
   1032  *
   1033  *****************************************************************************/
   1034 
   1035 ACPI_STATUS
   1036 AcpiOsRemoveInterruptHandler (
   1037     UINT32                  InterruptNumber,
   1038     ACPI_OSD_HANDLER        ServiceRoutine)
   1039 {
   1040 
   1041     return (AE_OK);
   1042 }
   1043 
   1044 
   1045 /******************************************************************************
   1046  *
   1047  * FUNCTION:    AcpiOsStall
   1048  *
   1049  * PARAMETERS:  Microseconds        - Time to stall
   1050  *
   1051  * RETURN:      None. Blocks until stall is completed.
   1052  *
   1053  * DESCRIPTION: Sleep at microsecond granularity
   1054  *
   1055  *****************************************************************************/
   1056 
   1057 void
   1058 AcpiOsStall (
   1059     UINT32                  Microseconds)
   1060 {
   1061 
   1062     Sleep ((Microseconds / 1000) + 1);
   1063     return;
   1064 }
   1065 
   1066 
   1067 /******************************************************************************
   1068  *
   1069  * FUNCTION:    AcpiOsSleep
   1070  *
   1071  * PARAMETERS:  Milliseconds        - Time to sleep
   1072  *
   1073  * RETURN:      None. Blocks until sleep is completed.
   1074  *
   1075  * DESCRIPTION: Sleep at millisecond granularity
   1076  *
   1077  *****************************************************************************/
   1078 
   1079 void
   1080 AcpiOsSleep (
   1081     UINT64                  Milliseconds)
   1082 {
   1083 
   1084     /* Add 10ms to account for clock tick granularity */
   1085 
   1086     Sleep (((unsigned long) Milliseconds) + 10);
   1087     return;
   1088 }
   1089 
   1090 
   1091 /******************************************************************************
   1092  *
   1093  * FUNCTION:    AcpiOsReadPciConfiguration
   1094  *
   1095  * PARAMETERS:  PciId               - Seg/Bus/Dev
   1096  *              Register            - Device Register
   1097  *              Value               - Buffer where value is placed
   1098  *              Width               - Number of bits
   1099  *
   1100  * RETURN:      Status
   1101  *
   1102  * DESCRIPTION: Read data from PCI configuration space
   1103  *
   1104  *****************************************************************************/
   1105 
   1106 ACPI_STATUS
   1107 AcpiOsReadPciConfiguration (
   1108     ACPI_PCI_ID             *PciId,
   1109     UINT32                  Register,
   1110     UINT64                  *Value,
   1111     UINT32                  Width)
   1112 {
   1113 
   1114     return (AE_OK);
   1115 }
   1116 
   1117 
   1118 /******************************************************************************
   1119  *
   1120  * FUNCTION:    AcpiOsWritePciConfiguration
   1121  *
   1122  * PARAMETERS:  PciId               - Seg/Bus/Dev
   1123  *              Register            - Device Register
   1124  *              Value               - Value to be written
   1125  *              Width               - Number of bits
   1126  *
   1127  * RETURN:      Status
   1128  *
   1129  * DESCRIPTION: Write data to PCI configuration space
   1130  *
   1131  *****************************************************************************/
   1132 
   1133 ACPI_STATUS
   1134 AcpiOsWritePciConfiguration (
   1135     ACPI_PCI_ID             *PciId,
   1136     UINT32                  Register,
   1137     UINT64                  Value,
   1138     UINT32                  Width)
   1139 {
   1140 
   1141     return (AE_OK);
   1142 }
   1143 
   1144 
   1145 /******************************************************************************
   1146  *
   1147  * FUNCTION:    AcpiOsReadPort
   1148  *
   1149  * PARAMETERS:  Address             - Address of I/O port/register to read
   1150  *              Value               - Where value is placed
   1151  *              Width               - Number of bits
   1152  *
   1153  * RETURN:      Value read from port
   1154  *
   1155  * DESCRIPTION: Read data from an I/O port or register
   1156  *
   1157  *****************************************************************************/
   1158 
   1159 ACPI_STATUS
   1160 AcpiOsReadPort (
   1161     ACPI_IO_ADDRESS         Address,
   1162     UINT32                  *Value,
   1163     UINT32                  Width)
   1164 {
   1165 
   1166     switch (Width)
   1167     {
   1168     case 8:
   1169         *Value = 0xFF;
   1170         break;
   1171 
   1172     case 16:
   1173         *Value = 0xFFFF;
   1174         break;
   1175 
   1176     case 32:
   1177         *Value = 0xFFFFFFFF;
   1178         break;
   1179 
   1180     default:
   1181         return (AE_BAD_PARAMETER);
   1182     }
   1183 
   1184     return (AE_OK);
   1185 }
   1186 
   1187 
   1188 /******************************************************************************
   1189  *
   1190  * FUNCTION:    AcpiOsWritePort
   1191  *
   1192  * PARAMETERS:  Address             - Address of I/O port/register to write
   1193  *              Value               - Value to write
   1194  *              Width               - Number of bits
   1195  *
   1196  * RETURN:      None
   1197  *
   1198  * DESCRIPTION: Write data to an I/O port or register
   1199  *
   1200  *****************************************************************************/
   1201 
   1202 ACPI_STATUS
   1203 AcpiOsWritePort (
   1204     ACPI_IO_ADDRESS         Address,
   1205     UINT32                  Value,
   1206     UINT32                  Width)
   1207 {
   1208 
   1209     return (AE_OK);
   1210 }
   1211 
   1212 
   1213 /******************************************************************************
   1214  *
   1215  * FUNCTION:    AcpiOsReadMemory
   1216  *
   1217  * PARAMETERS:  Address             - Physical Memory Address to read
   1218  *              Value               - Where value is placed
   1219  *              Width               - Number of bits
   1220  *
   1221  * RETURN:      Value read from physical memory address. Always returned
   1222  *              as a 32-bit integer, regardless of the read width.
   1223  *
   1224  * DESCRIPTION: Read data from a physical memory address
   1225  *
   1226  *****************************************************************************/
   1227 
   1228 ACPI_STATUS
   1229 AcpiOsReadMemory (
   1230     ACPI_PHYSICAL_ADDRESS   Address,
   1231     UINT32                  *Value,
   1232     UINT32                  Width)
   1233 {
   1234 
   1235     switch (Width)
   1236     {
   1237     case 8:
   1238     case 16:
   1239     case 32:
   1240         *Value = 0;
   1241         break;
   1242 
   1243     default:
   1244         return (AE_BAD_PARAMETER);
   1245         break;
   1246     }
   1247 
   1248     return (AE_OK);
   1249 }
   1250 
   1251 
   1252 /******************************************************************************
   1253  *
   1254  * FUNCTION:    AcpiOsWriteMemory
   1255  *
   1256  * PARAMETERS:  Address             - Physical Memory Address to write
   1257  *              Value               - Value to write
   1258  *              Width               - Number of bits
   1259  *
   1260  * RETURN:      None
   1261  *
   1262  * DESCRIPTION: Write data to a physical memory address
   1263  *
   1264  *****************************************************************************/
   1265 
   1266 ACPI_STATUS
   1267 AcpiOsWriteMemory (
   1268     ACPI_PHYSICAL_ADDRESS   Address,
   1269     UINT32                  Value,
   1270     UINT32                  Width)
   1271 {
   1272 
   1273     return (AE_OK);
   1274 }
   1275 
   1276 
   1277 /******************************************************************************
   1278  *
   1279  * FUNCTION:    AcpiOsSignal
   1280  *
   1281  * PARAMETERS:  Function            - ACPI CA signal function code
   1282  *              Info                - Pointer to function-dependent structure
   1283  *
   1284  * RETURN:      Status
   1285  *
   1286  * DESCRIPTION: Miscellaneous functions. Example implementation only.
   1287  *
   1288  *****************************************************************************/
   1289 
   1290 ACPI_STATUS
   1291 AcpiOsSignal (
   1292     UINT32                  Function,
   1293     void                    *Info)
   1294 {
   1295 
   1296     switch (Function)
   1297     {
   1298     case ACPI_SIGNAL_FATAL:
   1299         break;
   1300 
   1301     case ACPI_SIGNAL_BREAKPOINT:
   1302         break;
   1303 
   1304     default:
   1305         break;
   1306     }
   1307 
   1308     return (AE_OK);
   1309 }
   1310 
   1311 
   1312 /******************************************************************************
   1313  *
   1314  * FUNCTION:    Local cache interfaces
   1315  *
   1316  * DESCRIPTION: Implements cache interfaces via malloc/free for testing
   1317  *              purposes only.
   1318  *
   1319  *****************************************************************************/
   1320 
   1321 #ifndef ACPI_USE_LOCAL_CACHE
   1322 
   1323 ACPI_STATUS
   1324 AcpiOsCreateCache (
   1325     char                    *CacheName,
   1326     UINT16                  ObjectSize,
   1327     UINT16                  MaxDepth,
   1328     ACPI_CACHE_T            **ReturnCache)
   1329 {
   1330     ACPI_MEMORY_LIST        *NewCache;
   1331 
   1332 
   1333     NewCache = malloc (sizeof (ACPI_MEMORY_LIST));
   1334     if (!NewCache)
   1335     {
   1336         return (AE_NO_MEMORY);
   1337     }
   1338 
   1339     memset (NewCache, 0, sizeof (ACPI_MEMORY_LIST));
   1340     NewCache->LinkOffset = 8;
   1341     NewCache->ListName = CacheName;
   1342     NewCache->ObjectSize = ObjectSize;
   1343     NewCache->MaxDepth = MaxDepth;
   1344 
   1345     *ReturnCache = (ACPI_CACHE_T) NewCache;
   1346     return (AE_OK);
   1347 }
   1348 
   1349 ACPI_STATUS
   1350 AcpiOsDeleteCache (
   1351     ACPI_CACHE_T            *Cache)
   1352 {
   1353     free (Cache);
   1354     return (AE_OK);
   1355 }
   1356 
   1357 ACPI_STATUS
   1358 AcpiOsPurgeCache (
   1359     ACPI_CACHE_T            *Cache)
   1360 {
   1361     return (AE_OK);
   1362 }
   1363 
   1364 void *
   1365 AcpiOsAcquireObject (
   1366     ACPI_CACHE_T            *Cache)
   1367 {
   1368     void                    *NewObject;
   1369 
   1370     NewObject = malloc (((ACPI_MEMORY_LIST *) Cache)->ObjectSize);
   1371     memset (NewObject, 0, ((ACPI_MEMORY_LIST *) Cache)->ObjectSize);
   1372 
   1373     return (NewObject);
   1374 }
   1375 
   1376 ACPI_STATUS
   1377 AcpiOsReleaseObject (
   1378     ACPI_CACHE_T            *Cache,
   1379     void                    *Object)
   1380 {
   1381     free (Object);
   1382     return (AE_OK);
   1383 }
   1384 
   1385 #endif /* ACPI_USE_LOCAL_CACHE */
   1386 
   1387 
   1388 /* Optional multi-thread support */
   1389 
   1390 #ifndef ACPI_SINGLE_THREADED
   1391 /******************************************************************************
   1392  *
   1393  * FUNCTION:    AcpiOsGetThreadId
   1394  *
   1395  * PARAMETERS:  None
   1396  *
   1397  * RETURN:      Id of the running thread
   1398  *
   1399  * DESCRIPTION: Get the Id of the current (running) thread
   1400  *
   1401  *****************************************************************************/
   1402 
   1403 ACPI_THREAD_ID
   1404 AcpiOsGetThreadId (
   1405     void)
   1406 {
   1407     DWORD                   ThreadId;
   1408 
   1409     /* Ensure ID is never 0 */
   1410 
   1411     ThreadId = GetCurrentThreadId ();
   1412     return ((ACPI_THREAD_ID) (ThreadId + 1));
   1413 }
   1414 
   1415 
   1416 /******************************************************************************
   1417  *
   1418  * FUNCTION:    AcpiOsExecute
   1419  *
   1420  * PARAMETERS:  Type                - Type of execution
   1421  *              Function            - Address of the function to execute
   1422  *              Context             - Passed as a parameter to the function
   1423  *
   1424  * RETURN:      Status
   1425  *
   1426  * DESCRIPTION: Execute a new thread
   1427  *
   1428  *****************************************************************************/
   1429 
   1430 ACPI_STATUS
   1431 AcpiOsExecute (
   1432     ACPI_EXECUTE_TYPE       Type,
   1433     ACPI_OSD_EXEC_CALLBACK  Function,
   1434     void                    *Context)
   1435 {
   1436 
   1437     _beginthread (Function, (unsigned) 0, Context);
   1438     return (0);
   1439 }
   1440 
   1441 #endif /* ACPI_SINGLE_THREADED */
   1442 
   1443