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