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