Home | History | Annotate | Line # | Download | only in service_layers
oswinxf.c revision 1.1.1.2.2.2
      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 store the line
    481  *
    482  * RETURN:      Actual bytes read
    483  *
    484  * DESCRIPTION: Formatted input with argument list pointer
    485  *
    486  *****************************************************************************/
    487 
    488 UINT32
    489 AcpiOsGetLine (
    490     char                    *Buffer)
    491 {
    492     char                    Temp;
    493     UINT32                  i;
    494 
    495 
    496     for (i = 0; ; i++)
    497     {
    498         scanf ("%1c", &Temp);
    499         if (!Temp || Temp == '\n')
    500         {
    501             break;
    502         }
    503 
    504         Buffer [i] = Temp;
    505     }
    506 
    507     /* Null terminate the buffer */
    508 
    509     Buffer [i] = 0;
    510 
    511     /* Return the number of bytes in the string */
    512 
    513     return (i);
    514 }
    515 
    516 
    517 /******************************************************************************
    518  *
    519  * FUNCTION:    AcpiOsMapMemory
    520  *
    521  * PARAMETERS:  Where               - Physical address of memory to be mapped
    522  *              Length              - How much memory to map
    523  *
    524  * RETURN:      Pointer to mapped memory. Null on error.
    525  *
    526  * DESCRIPTION: Map physical memory into caller's address space
    527  *
    528  *****************************************************************************/
    529 
    530 void *
    531 AcpiOsMapMemory (
    532     ACPI_PHYSICAL_ADDRESS   Where,
    533     ACPI_SIZE               Length)
    534 {
    535 
    536     return (ACPI_TO_POINTER ((ACPI_SIZE) Where));
    537 }
    538 
    539 
    540 /******************************************************************************
    541  *
    542  * FUNCTION:    AcpiOsUnmapMemory
    543  *
    544  * PARAMETERS:  Where               - Logical address of memory to be unmapped
    545  *              Length              - How much memory to unmap
    546  *
    547  * RETURN:      None.
    548  *
    549  * DESCRIPTION: Delete a previously created mapping. Where and Length must
    550  *              correspond to a previous mapping exactly.
    551  *
    552  *****************************************************************************/
    553 
    554 void
    555 AcpiOsUnmapMemory (
    556     void                    *Where,
    557     ACPI_SIZE               Length)
    558 {
    559 
    560     return;
    561 }
    562 
    563 
    564 /******************************************************************************
    565  *
    566  * FUNCTION:    AcpiOsAllocate
    567  *
    568  * PARAMETERS:  Size                - Amount to allocate, in bytes
    569  *
    570  * RETURN:      Pointer to the new allocation. Null on error.
    571  *
    572  * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS.
    573  *
    574  *****************************************************************************/
    575 
    576 void *
    577 AcpiOsAllocate (
    578     ACPI_SIZE               Size)
    579 {
    580     void                    *Mem;
    581 
    582 
    583     Mem = (void *) malloc ((size_t) Size);
    584 
    585     return (Mem);
    586 }
    587 
    588 
    589 /******************************************************************************
    590  *
    591  * FUNCTION:    AcpiOsFree
    592  *
    593  * PARAMETERS:  Mem                 - Pointer to previously allocated memory
    594  *
    595  * RETURN:      None.
    596  *
    597  * DESCRIPTION: Free memory allocated via AcpiOsAllocate
    598  *
    599  *****************************************************************************/
    600 
    601 void
    602 AcpiOsFree (
    603     void                    *Mem)
    604 {
    605 
    606     free (Mem);
    607 }
    608 
    609 
    610 #ifdef ACPI_SINGLE_THREADED
    611 /******************************************************************************
    612  *
    613  * FUNCTION:    Semaphore stub functions
    614  *
    615  * DESCRIPTION: Stub functions used for single-thread applications that do
    616  *              not require semaphore synchronization. Full implementations
    617  *              of these functions appear after the stubs.
    618  *
    619  *****************************************************************************/
    620 
    621 ACPI_STATUS
    622 AcpiOsCreateSemaphore (
    623     UINT32              MaxUnits,
    624     UINT32              InitialUnits,
    625     ACPI_HANDLE         *OutHandle)
    626 {
    627     *OutHandle = (ACPI_HANDLE) 1;
    628     return (AE_OK);
    629 }
    630 
    631 ACPI_STATUS
    632 AcpiOsDeleteSemaphore (
    633     ACPI_HANDLE         Handle)
    634 {
    635     return (AE_OK);
    636 }
    637 
    638 ACPI_STATUS
    639 AcpiOsWaitSemaphore (
    640     ACPI_HANDLE         Handle,
    641     UINT32              Units,
    642     UINT16              Timeout)
    643 {
    644     return (AE_OK);
    645 }
    646 
    647 ACPI_STATUS
    648 AcpiOsSignalSemaphore (
    649     ACPI_HANDLE         Handle,
    650     UINT32              Units)
    651 {
    652     return (AE_OK);
    653 }
    654 
    655 #else
    656 /******************************************************************************
    657  *
    658  * FUNCTION:    AcpiOsCreateSemaphore
    659  *
    660  * PARAMETERS:  MaxUnits            - Maximum units that can be sent
    661  *              InitialUnits        - Units to be assigned to the new semaphore
    662  *              OutHandle           - Where a handle will be returned
    663  *
    664  * RETURN:      Status
    665  *
    666  * DESCRIPTION: Create an OS semaphore
    667  *
    668  *****************************************************************************/
    669 
    670 ACPI_STATUS
    671 AcpiOsCreateSemaphore (
    672     UINT32              MaxUnits,
    673     UINT32              InitialUnits,
    674     ACPI_SEMAPHORE      *OutHandle)
    675 {
    676     void                *Mutex;
    677     UINT32              i;
    678 
    679     ACPI_FUNCTION_NAME (OsCreateSemaphore);
    680 
    681 
    682     if (MaxUnits == ACPI_UINT32_MAX)
    683     {
    684         MaxUnits = 255;
    685     }
    686 
    687     if (InitialUnits == ACPI_UINT32_MAX)
    688     {
    689         InitialUnits = MaxUnits;
    690     }
    691 
    692     if (InitialUnits > MaxUnits)
    693     {
    694         return (AE_BAD_PARAMETER);
    695     }
    696 
    697     /* Find an empty slot */
    698 
    699     for (i = 0; i < ACPI_OS_MAX_SEMAPHORES; i++)
    700     {
    701         if (!AcpiGbl_Semaphores[i].OsHandle)
    702         {
    703             break;
    704         }
    705     }
    706     if (i >= ACPI_OS_MAX_SEMAPHORES)
    707     {
    708         ACPI_EXCEPTION ((AE_INFO, AE_LIMIT,
    709             "Reached max semaphores (%u), could not create", ACPI_OS_MAX_SEMAPHORES));
    710         return (AE_LIMIT);
    711     }
    712 
    713     /* Create an OS semaphore */
    714 
    715     Mutex = CreateSemaphore (NULL, InitialUnits, MaxUnits, NULL);
    716     if (!Mutex)
    717     {
    718         ACPI_ERROR ((AE_INFO, "Could not create semaphore"));
    719         return (AE_NO_MEMORY);
    720     }
    721 
    722     AcpiGbl_Semaphores[i].MaxUnits = (UINT16) MaxUnits;
    723     AcpiGbl_Semaphores[i].CurrentUnits = (UINT16) InitialUnits;
    724     AcpiGbl_Semaphores[i].OsHandle = Mutex;
    725 
    726     ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Handle=%u, Max=%u, Current=%u, OsHandle=%p\n",
    727             i, MaxUnits, InitialUnits, Mutex));
    728 
    729     *OutHandle = (void *) i;
    730     return (AE_OK);
    731 }
    732 
    733 
    734 /******************************************************************************
    735  *
    736  * FUNCTION:    AcpiOsDeleteSemaphore
    737  *
    738  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
    739  *
    740  * RETURN:      Status
    741  *
    742  * DESCRIPTION: Delete an OS semaphore
    743  *
    744  *****************************************************************************/
    745 
    746 ACPI_STATUS
    747 AcpiOsDeleteSemaphore (
    748     ACPI_SEMAPHORE      Handle)
    749 {
    750     UINT32              Index = (UINT32) Handle;
    751 
    752 
    753     if ((Index >= ACPI_OS_MAX_SEMAPHORES) ||
    754         !AcpiGbl_Semaphores[Index].OsHandle)
    755     {
    756         return (AE_BAD_PARAMETER);
    757     }
    758 
    759     CloseHandle (AcpiGbl_Semaphores[Index].OsHandle);
    760     AcpiGbl_Semaphores[Index].OsHandle = NULL;
    761     return (AE_OK);
    762 }
    763 
    764 
    765 /******************************************************************************
    766  *
    767  * FUNCTION:    AcpiOsWaitSemaphore
    768  *
    769  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
    770  *              Units               - How many units to wait for
    771  *              Timeout             - How long to wait
    772  *
    773  * RETURN:      Status
    774  *
    775  * DESCRIPTION: Wait for units
    776  *
    777  *****************************************************************************/
    778 
    779 ACPI_STATUS
    780 AcpiOsWaitSemaphore (
    781     ACPI_SEMAPHORE      Handle,
    782     UINT32              Units,
    783     UINT16              Timeout)
    784 {
    785     UINT32              Index = (UINT32) Handle;
    786     UINT32              WaitStatus;
    787     UINT32              OsTimeout = Timeout;
    788 
    789 
    790     ACPI_FUNCTION_ENTRY ();
    791 
    792 
    793     if ((Index >= ACPI_OS_MAX_SEMAPHORES) ||
    794         !AcpiGbl_Semaphores[Index].OsHandle)
    795     {
    796         return (AE_BAD_PARAMETER);
    797     }
    798 
    799     if (Units > 1)
    800     {
    801         printf ("WaitSemaphore: Attempt to receive %u units\n", Units);
    802         return (AE_NOT_IMPLEMENTED);
    803     }
    804 
    805     if (Timeout == ACPI_WAIT_FOREVER)
    806     {
    807         OsTimeout = INFINITE;
    808         if (AcpiGbl_DebugTimeout)
    809         {
    810             /* The debug timeout will prevent hang conditions */
    811 
    812             OsTimeout = ACPI_OS_DEBUG_TIMEOUT;
    813         }
    814     }
    815     else
    816     {
    817         /* Add 10ms to account for clock tick granularity */
    818 
    819         OsTimeout += 10;
    820     }
    821 
    822     WaitStatus = WaitForSingleObject (AcpiGbl_Semaphores[Index].OsHandle, OsTimeout);
    823     if (WaitStatus == WAIT_TIMEOUT)
    824     {
    825         if (AcpiGbl_DebugTimeout)
    826         {
    827             ACPI_EXCEPTION ((AE_INFO, AE_TIME,
    828                 "Debug timeout on semaphore 0x%04X (%ums)\n",
    829                 Index, ACPI_OS_DEBUG_TIMEOUT));
    830         }
    831         return (AE_TIME);
    832     }
    833 
    834     if (AcpiGbl_Semaphores[Index].CurrentUnits == 0)
    835     {
    836         ACPI_ERROR ((AE_INFO, "%s - No unit received. Timeout 0x%X, OS_Status 0x%X",
    837             AcpiUtGetMutexName (Index), Timeout, WaitStatus));
    838 
    839         return (AE_OK);
    840     }
    841 
    842     AcpiGbl_Semaphores[Index].CurrentUnits--;
    843     return (AE_OK);
    844 }
    845 
    846 
    847 /******************************************************************************
    848  *
    849  * FUNCTION:    AcpiOsSignalSemaphore
    850  *
    851  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
    852  *              Units               - Number of units to send
    853  *
    854  * RETURN:      Status
    855  *
    856  * DESCRIPTION: Send units
    857  *
    858  *****************************************************************************/
    859 
    860 ACPI_STATUS
    861 AcpiOsSignalSemaphore (
    862     ACPI_SEMAPHORE      Handle,
    863     UINT32              Units)
    864 {
    865     UINT32              Index = (UINT32) Handle;
    866 
    867 
    868     ACPI_FUNCTION_ENTRY ();
    869 
    870 
    871     if (Index >= ACPI_OS_MAX_SEMAPHORES)
    872     {
    873         printf ("SignalSemaphore: Index/Handle out of range: %2.2X\n", Index);
    874         return (AE_BAD_PARAMETER);
    875     }
    876 
    877     if (!AcpiGbl_Semaphores[Index].OsHandle)
    878     {
    879         printf ("SignalSemaphore: Null OS handle, Index %2.2X\n", Index);
    880         return (AE_BAD_PARAMETER);
    881     }
    882 
    883     if (Units > 1)
    884     {
    885         printf ("SignalSemaphore: Attempt to signal %u units, Index %2.2X\n", Units, Index);
    886         return (AE_NOT_IMPLEMENTED);
    887     }
    888 
    889     if ((AcpiGbl_Semaphores[Index].CurrentUnits + 1) >
    890         AcpiGbl_Semaphores[Index].MaxUnits)
    891     {
    892         ACPI_ERROR ((AE_INFO,
    893             "Oversignalled semaphore[%u]! Current %u Max %u",
    894             Index, AcpiGbl_Semaphores[Index].CurrentUnits,
    895             AcpiGbl_Semaphores[Index].MaxUnits));
    896 
    897         return (AE_LIMIT);
    898     }
    899 
    900     AcpiGbl_Semaphores[Index].CurrentUnits++;
    901     ReleaseSemaphore (AcpiGbl_Semaphores[Index].OsHandle, Units, NULL);
    902 
    903     return (AE_OK);
    904 }
    905 
    906 #endif /* ACPI_SINGLE_THREADED */
    907 
    908 
    909 /******************************************************************************
    910  *
    911  * FUNCTION:    Spinlock interfaces
    912  *
    913  * DESCRIPTION: Map these interfaces to semaphore interfaces
    914  *
    915  *****************************************************************************/
    916 
    917 ACPI_STATUS
    918 AcpiOsCreateLock (
    919     ACPI_SPINLOCK           *OutHandle)
    920 {
    921     return (AcpiOsCreateSemaphore (1, 1, OutHandle));
    922 }
    923 
    924 void
    925 AcpiOsDeleteLock (
    926     ACPI_SPINLOCK           Handle)
    927 {
    928     AcpiOsDeleteSemaphore (Handle);
    929 }
    930 
    931 ACPI_CPU_FLAGS
    932 AcpiOsAcquireLock (
    933     ACPI_SPINLOCK           Handle)
    934 {
    935     AcpiOsWaitSemaphore (Handle, 1, 0xFFFF);
    936     return (0);
    937 }
    938 
    939 void
    940 AcpiOsReleaseLock (
    941     ACPI_SPINLOCK           Handle,
    942     ACPI_CPU_FLAGS          Flags)
    943 {
    944     AcpiOsSignalSemaphore (Handle, 1);
    945 }
    946 
    947 
    948 #if ACPI_FUTURE_IMPLEMENTATION
    949 
    950 /* Mutex interfaces, just implement with a semaphore */
    951 
    952 ACPI_STATUS
    953 AcpiOsCreateMutex (
    954     ACPI_MUTEX              *OutHandle)
    955 {
    956     return (AcpiOsCreateSemaphore (1, 1, OutHandle));
    957 }
    958 
    959 void
    960 AcpiOsDeleteMutex (
    961     ACPI_MUTEX              Handle)
    962 {
    963     AcpiOsDeleteSemaphore (Handle);
    964 }
    965 
    966 ACPI_STATUS
    967 AcpiOsAcquireMutex (
    968     ACPI_MUTEX              Handle,
    969     UINT16                  Timeout)
    970 {
    971     AcpiOsWaitSemaphore (Handle, 1, Timeout);
    972     return (0);
    973 }
    974 
    975 void
    976 AcpiOsReleaseMutex (
    977     ACPI_MUTEX              Handle)
    978 {
    979     AcpiOsSignalSemaphore (Handle, 1);
    980 }
    981 #endif
    982 
    983 
    984 /******************************************************************************
    985  *
    986  * FUNCTION:    AcpiOsInstallInterruptHandler
    987  *
    988  * PARAMETERS:  InterruptNumber     - Level handler should respond to.
    989  *              ServiceRoutine      - Address of the ACPI interrupt handler
    990  *              Context             - User context
    991  *
    992  * RETURN:      Handle to the newly installed handler.
    993  *
    994  * DESCRIPTION: Install an interrupt handler. Used to install the ACPI
    995  *              OS-independent handler.
    996  *
    997  *****************************************************************************/
    998 
    999 UINT32
   1000 AcpiOsInstallInterruptHandler (
   1001     UINT32                  InterruptNumber,
   1002     ACPI_OSD_HANDLER        ServiceRoutine,
   1003     void                    *Context)
   1004 {
   1005 
   1006     return (AE_OK);
   1007 }
   1008 
   1009 
   1010 /******************************************************************************
   1011  *
   1012  * FUNCTION:    AcpiOsRemoveInterruptHandler
   1013  *
   1014  * PARAMETERS:  Handle              - Returned when handler was installed
   1015  *
   1016  * RETURN:      Status
   1017  *
   1018  * DESCRIPTION: Uninstalls an interrupt handler.
   1019  *
   1020  *****************************************************************************/
   1021 
   1022 ACPI_STATUS
   1023 AcpiOsRemoveInterruptHandler (
   1024     UINT32                  InterruptNumber,
   1025     ACPI_OSD_HANDLER        ServiceRoutine)
   1026 {
   1027 
   1028     return (AE_OK);
   1029 }
   1030 
   1031 
   1032 /******************************************************************************
   1033  *
   1034  * FUNCTION:    AcpiOsGetThreadId
   1035  *
   1036  * PARAMETERS:  None
   1037  *
   1038  * RETURN:      Id of the running thread
   1039  *
   1040  * DESCRIPTION: Get the Id of the current (running) thread
   1041  *
   1042  *****************************************************************************/
   1043 
   1044 ACPI_THREAD_ID
   1045 AcpiOsGetThreadId (
   1046     void)
   1047 {
   1048     DWORD                   ThreadId;
   1049 
   1050     /* Ensure ID is never 0 */
   1051 
   1052     ThreadId = GetCurrentThreadId ();
   1053     return ((ACPI_THREAD_ID) (ThreadId + 1));
   1054 }
   1055 
   1056 
   1057 /******************************************************************************
   1058  *
   1059  * FUNCTION:    AcpiOsExecute
   1060  *
   1061  * PARAMETERS:  Type                - Type of execution
   1062  *              Function            - Address of the function to execute
   1063  *              Context             - Passed as a parameter to the function
   1064  *
   1065  * RETURN:      Status
   1066  *
   1067  * DESCRIPTION: Execute a new thread
   1068  *
   1069  *****************************************************************************/
   1070 
   1071 ACPI_STATUS
   1072 AcpiOsExecute (
   1073     ACPI_EXECUTE_TYPE       Type,
   1074     ACPI_OSD_EXEC_CALLBACK  Function,
   1075     void                    *Context)
   1076 {
   1077 
   1078 #ifndef ACPI_SINGLE_THREADED
   1079     _beginthread (Function, (unsigned) 0, Context);
   1080 #endif
   1081 
   1082     return (0);
   1083 }
   1084 
   1085 
   1086 /******************************************************************************
   1087  *
   1088  * FUNCTION:    AcpiOsStall
   1089  *
   1090  * PARAMETERS:  Microseconds        - Time to stall
   1091  *
   1092  * RETURN:      None. Blocks until stall is completed.
   1093  *
   1094  * DESCRIPTION: Sleep at microsecond granularity
   1095  *
   1096  *****************************************************************************/
   1097 
   1098 void
   1099 AcpiOsStall (
   1100     UINT32                  Microseconds)
   1101 {
   1102 
   1103     Sleep ((Microseconds / 1000) + 1);
   1104     return;
   1105 }
   1106 
   1107 
   1108 /******************************************************************************
   1109  *
   1110  * FUNCTION:    AcpiOsSleep
   1111  *
   1112  * PARAMETERS:  Milliseconds        - Time to sleep
   1113  *
   1114  * RETURN:      None. Blocks until sleep is completed.
   1115  *
   1116  * DESCRIPTION: Sleep at millisecond granularity
   1117  *
   1118  *****************************************************************************/
   1119 
   1120 void
   1121 AcpiOsSleep (
   1122     UINT64                  Milliseconds)
   1123 {
   1124 
   1125     /* Add 10ms to account for clock tick granularity */
   1126 
   1127     Sleep (((unsigned long) Milliseconds) + 10);
   1128     return;
   1129 }
   1130 
   1131 
   1132 /******************************************************************************
   1133  *
   1134  * FUNCTION:    AcpiOsReadPciConfiguration
   1135  *
   1136  * PARAMETERS:  PciId               - Seg/Bus/Dev
   1137  *              Register            - Device Register
   1138  *              Value               - Buffer where value is placed
   1139  *              Width               - Number of bits
   1140  *
   1141  * RETURN:      Status
   1142  *
   1143  * DESCRIPTION: Read data from PCI configuration space
   1144  *
   1145  *****************************************************************************/
   1146 
   1147 ACPI_STATUS
   1148 AcpiOsReadPciConfiguration (
   1149     ACPI_PCI_ID             *PciId,
   1150     UINT32                  Register,
   1151     UINT64                  *Value,
   1152     UINT32                  Width)
   1153 {
   1154 
   1155     return (AE_OK);
   1156 }
   1157 
   1158 
   1159 /******************************************************************************
   1160  *
   1161  * FUNCTION:    AcpiOsWritePciConfiguration
   1162  *
   1163  * PARAMETERS:  PciId               - Seg/Bus/Dev
   1164  *              Register            - Device Register
   1165  *              Value               - Value to be written
   1166  *              Width               - Number of bits
   1167  *
   1168  * RETURN:      Status
   1169  *
   1170  * DESCRIPTION: Write data to PCI configuration space
   1171  *
   1172  *****************************************************************************/
   1173 
   1174 ACPI_STATUS
   1175 AcpiOsWritePciConfiguration (
   1176     ACPI_PCI_ID             *PciId,
   1177     UINT32                  Register,
   1178     UINT64                  Value,
   1179     UINT32                  Width)
   1180 {
   1181 
   1182     return (AE_OK);
   1183 }
   1184 
   1185 
   1186 /******************************************************************************
   1187  *
   1188  * FUNCTION:    AcpiOsReadPort
   1189  *
   1190  * PARAMETERS:  Address             - Address of I/O port/register to read
   1191  *              Value               - Where value is placed
   1192  *              Width               - Number of bits
   1193  *
   1194  * RETURN:      Value read from port
   1195  *
   1196  * DESCRIPTION: Read data from an I/O port or register
   1197  *
   1198  *****************************************************************************/
   1199 
   1200 ACPI_STATUS
   1201 AcpiOsReadPort (
   1202     ACPI_IO_ADDRESS         Address,
   1203     UINT32                  *Value,
   1204     UINT32                  Width)
   1205 {
   1206 
   1207     switch (Width)
   1208     {
   1209     case 8:
   1210         *Value = 0xFF;
   1211         break;
   1212 
   1213     case 16:
   1214         *Value = 0xFFFF;
   1215         break;
   1216 
   1217     case 32:
   1218         *Value = 0xFFFFFFFF;
   1219         break;
   1220 
   1221     default:
   1222         return (AE_BAD_PARAMETER);
   1223     }
   1224 
   1225     return (AE_OK);
   1226 }
   1227 
   1228 
   1229 /******************************************************************************
   1230  *
   1231  * FUNCTION:    AcpiOsWritePort
   1232  *
   1233  * PARAMETERS:  Address             - Address of I/O port/register to write
   1234  *              Value               - Value to write
   1235  *              Width               - Number of bits
   1236  *
   1237  * RETURN:      None
   1238  *
   1239  * DESCRIPTION: Write data to an I/O port or register
   1240  *
   1241  *****************************************************************************/
   1242 
   1243 ACPI_STATUS
   1244 AcpiOsWritePort (
   1245     ACPI_IO_ADDRESS         Address,
   1246     UINT32                  Value,
   1247     UINT32                  Width)
   1248 {
   1249 
   1250     return (AE_OK);
   1251 }
   1252 
   1253 
   1254 /******************************************************************************
   1255  *
   1256  * FUNCTION:    AcpiOsReadMemory
   1257  *
   1258  * PARAMETERS:  Address             - Physical Memory Address to read
   1259  *              Value               - Where value is placed
   1260  *              Width               - Number of bits
   1261  *
   1262  * RETURN:      Value read from physical memory address. Always returned
   1263  *              as a 32-bit integer, regardless of the read width.
   1264  *
   1265  * DESCRIPTION: Read data from a physical memory address
   1266  *
   1267  *****************************************************************************/
   1268 
   1269 ACPI_STATUS
   1270 AcpiOsReadMemory (
   1271     ACPI_PHYSICAL_ADDRESS   Address,
   1272     UINT32                  *Value,
   1273     UINT32                  Width)
   1274 {
   1275 
   1276     switch (Width)
   1277     {
   1278     case 8:
   1279     case 16:
   1280     case 32:
   1281         *Value = 0;
   1282         break;
   1283 
   1284     default:
   1285         return (AE_BAD_PARAMETER);
   1286         break;
   1287     }
   1288 
   1289     return (AE_OK);
   1290 }
   1291 
   1292 
   1293 /******************************************************************************
   1294  *
   1295  * FUNCTION:    AcpiOsWriteMemory
   1296  *
   1297  * PARAMETERS:  Address             - Physical Memory Address to write
   1298  *              Value               - Value to write
   1299  *              Width               - Number of bits
   1300  *
   1301  * RETURN:      None
   1302  *
   1303  * DESCRIPTION: Write data to a physical memory address
   1304  *
   1305  *****************************************************************************/
   1306 
   1307 ACPI_STATUS
   1308 AcpiOsWriteMemory (
   1309     ACPI_PHYSICAL_ADDRESS   Address,
   1310     UINT32                  Value,
   1311     UINT32                  Width)
   1312 {
   1313 
   1314     return (AE_OK);
   1315 }
   1316 
   1317 
   1318 /******************************************************************************
   1319  *
   1320  * FUNCTION:    AcpiOsSignal
   1321  *
   1322  * PARAMETERS:  Function            - ACPI CA signal function code
   1323  *              Info                - Pointer to function-dependent structure
   1324  *
   1325  * RETURN:      Status
   1326  *
   1327  * DESCRIPTION: Miscellaneous functions. Example implementation only.
   1328  *
   1329  *****************************************************************************/
   1330 
   1331 ACPI_STATUS
   1332 AcpiOsSignal (
   1333     UINT32                  Function,
   1334     void                    *Info)
   1335 {
   1336 
   1337     switch (Function)
   1338     {
   1339     case ACPI_SIGNAL_FATAL:
   1340         break;
   1341 
   1342     case ACPI_SIGNAL_BREAKPOINT:
   1343         break;
   1344 
   1345     default:
   1346         break;
   1347     }
   1348 
   1349     return (AE_OK);
   1350 }
   1351 
   1352 
   1353 /******************************************************************************
   1354  *
   1355  * FUNCTION:    Local cache interfaces
   1356  *
   1357  * DESCRIPTION: Implements cache interfaces via malloc/free for testing
   1358  *              purposes only.
   1359  *
   1360  *****************************************************************************/
   1361 
   1362 #ifndef ACPI_USE_LOCAL_CACHE
   1363 
   1364 ACPI_STATUS
   1365 AcpiOsCreateCache (
   1366     char                    *CacheName,
   1367     UINT16                  ObjectSize,
   1368     UINT16                  MaxDepth,
   1369     ACPI_CACHE_T            **ReturnCache)
   1370 {
   1371     ACPI_MEMORY_LIST        *NewCache;
   1372 
   1373 
   1374     NewCache = malloc (sizeof (ACPI_MEMORY_LIST));
   1375     if (!NewCache)
   1376     {
   1377         return (AE_NO_MEMORY);
   1378     }
   1379 
   1380     memset (NewCache, 0, sizeof (ACPI_MEMORY_LIST));
   1381     NewCache->LinkOffset = 8;
   1382     NewCache->ListName = CacheName;
   1383     NewCache->ObjectSize = ObjectSize;
   1384     NewCache->MaxDepth = MaxDepth;
   1385 
   1386     *ReturnCache = (ACPI_CACHE_T) NewCache;
   1387     return (AE_OK);
   1388 }
   1389 
   1390 ACPI_STATUS
   1391 AcpiOsDeleteCache (
   1392     ACPI_CACHE_T            *Cache)
   1393 {
   1394     free (Cache);
   1395     return (AE_OK);
   1396 }
   1397 
   1398 ACPI_STATUS
   1399 AcpiOsPurgeCache (
   1400     ACPI_CACHE_T            *Cache)
   1401 {
   1402     return (AE_OK);
   1403 }
   1404 
   1405 void *
   1406 AcpiOsAcquireObject (
   1407     ACPI_CACHE_T            *Cache)
   1408 {
   1409     void                    *NewObject;
   1410 
   1411     NewObject = malloc (((ACPI_MEMORY_LIST *) Cache)->ObjectSize);
   1412     memset (NewObject, 0, ((ACPI_MEMORY_LIST *) Cache)->ObjectSize);
   1413 
   1414     return (NewObject);
   1415 }
   1416 
   1417 ACPI_STATUS
   1418 AcpiOsReleaseObject (
   1419     ACPI_CACHE_T            *Cache,
   1420     void                    *Object)
   1421 {
   1422     free (Object);
   1423     return (AE_OK);
   1424 }
   1425 
   1426 #endif
   1427