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