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