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