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