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