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