1 /****************************************************************************** 2 * 3 * Module Name: osunixxf - UNIX OSL interfaces 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2018, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 /* 45 * These interfaces are required in order to compile the ASL compiler and the 46 * various ACPICA tools under Linux or other Unix-like system. 47 */ 48 #include "acpi.h" 49 #include "accommon.h" 50 #include "amlcode.h" 51 #include "acparser.h" 52 #include "acdebug.h" 53 54 #include <stdio.h> 55 #include <stdlib.h> 56 #include <stdarg.h> 57 #include <unistd.h> 58 #include <sys/time.h> 59 #include <semaphore.h> 60 #include <pthread.h> 61 #include <errno.h> 62 63 #define _COMPONENT ACPI_OS_SERVICES 64 ACPI_MODULE_NAME ("osunixxf") 65 66 67 /* Upcalls to AcpiExec */ 68 69 void 70 AeTableOverride ( 71 ACPI_TABLE_HEADER *ExistingTable, 72 ACPI_TABLE_HEADER **NewTable); 73 74 typedef void* (*PTHREAD_CALLBACK) (void *); 75 76 /* Buffer used by AcpiOsVprintf */ 77 78 #define ACPI_VPRINTF_BUFFER_SIZE 512 79 #define _ASCII_NEWLINE '\n' 80 81 /* Terminal support for AcpiExec only */ 82 83 #ifdef ACPI_EXEC_APP 84 #include <termios.h> 85 86 struct termios OriginalTermAttributes; 87 int TermAttributesWereSet = 0; 88 89 ACPI_STATUS 90 AcpiUtReadLine ( 91 char *Buffer, 92 UINT32 BufferLength, 93 UINT32 *BytesRead); 94 95 static void 96 OsEnterLineEditMode ( 97 void); 98 99 static void 100 OsExitLineEditMode ( 101 void); 102 103 104 /****************************************************************************** 105 * 106 * FUNCTION: OsEnterLineEditMode, OsExitLineEditMode 107 * 108 * PARAMETERS: None 109 * 110 * RETURN: None 111 * 112 * DESCRIPTION: Enter/Exit the raw character input mode for the terminal. 113 * 114 * Interactive line-editing support for the AML debugger. Used with the 115 * common/acgetline module. 116 * 117 * readline() is not used because of non-portability. It is not available 118 * on all systems, and if it is, often the package must be manually installed. 119 * 120 * Therefore, we use the POSIX tcgetattr/tcsetattr and do the minimal line 121 * editing that we need in AcpiOsGetLine. 122 * 123 * If the POSIX tcgetattr/tcsetattr interfaces are unavailable, these 124 * calls will also work: 125 * For OsEnterLineEditMode: system ("stty cbreak -echo") 126 * For OsExitLineEditMode: system ("stty cooked echo") 127 * 128 *****************************************************************************/ 129 130 static void 131 OsEnterLineEditMode ( 132 void) 133 { 134 struct termios LocalTermAttributes; 135 136 137 TermAttributesWereSet = 0; 138 139 /* STDIN must be a terminal */ 140 141 if (!isatty (STDIN_FILENO)) 142 { 143 return; 144 } 145 146 /* Get and keep the original attributes */ 147 148 if (tcgetattr (STDIN_FILENO, &OriginalTermAttributes)) 149 { 150 fprintf (stderr, "Could not get terminal attributes!\n"); 151 return; 152 } 153 154 /* Set the new attributes to enable raw character input */ 155 156 memcpy (&LocalTermAttributes, &OriginalTermAttributes, 157 sizeof (struct termios)); 158 159 LocalTermAttributes.c_lflag &= ~(ICANON | ECHO); 160 LocalTermAttributes.c_cc[VMIN] = 1; 161 LocalTermAttributes.c_cc[VTIME] = 0; 162 163 if (tcsetattr (STDIN_FILENO, TCSANOW, &LocalTermAttributes)) 164 { 165 fprintf (stderr, "Could not set terminal attributes!\n"); 166 return; 167 } 168 169 TermAttributesWereSet = 1; 170 } 171 172 173 static void 174 OsExitLineEditMode ( 175 void) 176 { 177 178 if (!TermAttributesWereSet) 179 { 180 return; 181 } 182 183 /* Set terminal attributes back to the original values */ 184 185 if (tcsetattr (STDIN_FILENO, TCSANOW, &OriginalTermAttributes)) 186 { 187 fprintf (stderr, "Could not restore terminal attributes!\n"); 188 } 189 } 190 191 192 #else 193 194 /* These functions are not needed for other ACPICA utilities */ 195 196 #define OsEnterLineEditMode() 197 #define OsExitLineEditMode() 198 #endif 199 200 201 /****************************************************************************** 202 * 203 * FUNCTION: AcpiOsInitialize, AcpiOsTerminate 204 * 205 * PARAMETERS: None 206 * 207 * RETURN: Status 208 * 209 * DESCRIPTION: Initialize and terminate this module. 210 * 211 *****************************************************************************/ 212 213 ACPI_STATUS 214 AcpiOsInitialize ( 215 void) 216 { 217 ACPI_STATUS Status; 218 219 220 AcpiGbl_OutputFile = stdout; 221 222 OsEnterLineEditMode (); 223 224 Status = AcpiOsCreateLock (&AcpiGbl_PrintLock); 225 if (ACPI_FAILURE (Status)) 226 { 227 return (Status); 228 } 229 230 return (AE_OK); 231 } 232 233 ACPI_STATUS 234 AcpiOsTerminate ( 235 void) 236 { 237 238 OsExitLineEditMode (); 239 return (AE_OK); 240 } 241 242 243 #ifndef ACPI_USE_NATIVE_RSDP_POINTER 244 /****************************************************************************** 245 * 246 * FUNCTION: AcpiOsGetRootPointer 247 * 248 * PARAMETERS: None 249 * 250 * RETURN: RSDP physical address 251 * 252 * DESCRIPTION: Gets the ACPI root pointer (RSDP) 253 * 254 *****************************************************************************/ 255 256 ACPI_PHYSICAL_ADDRESS 257 AcpiOsGetRootPointer ( 258 void) 259 { 260 261 return (0); 262 } 263 #endif 264 265 266 /****************************************************************************** 267 * 268 * FUNCTION: AcpiOsPredefinedOverride 269 * 270 * PARAMETERS: InitVal - Initial value of the predefined object 271 * NewVal - The new value for the object 272 * 273 * RETURN: Status, pointer to value. Null pointer returned if not 274 * overriding. 275 * 276 * DESCRIPTION: Allow the OS to override predefined names 277 * 278 *****************************************************************************/ 279 280 ACPI_STATUS 281 AcpiOsPredefinedOverride ( 282 const ACPI_PREDEFINED_NAMES *InitVal, 283 ACPI_STRING *NewVal) 284 { 285 286 if (!InitVal || !NewVal) 287 { 288 return (AE_BAD_PARAMETER); 289 } 290 291 *NewVal = NULL; 292 return (AE_OK); 293 } 294 295 296 /****************************************************************************** 297 * 298 * FUNCTION: AcpiOsTableOverride 299 * 300 * PARAMETERS: ExistingTable - Header of current table (probably 301 * firmware) 302 * NewTable - Where an entire new table is returned. 303 * 304 * RETURN: Status, pointer to new table. Null pointer returned if no 305 * table is available to override 306 * 307 * DESCRIPTION: Return a different version of a table if one is available 308 * 309 *****************************************************************************/ 310 311 ACPI_STATUS 312 AcpiOsTableOverride ( 313 ACPI_TABLE_HEADER *ExistingTable, 314 ACPI_TABLE_HEADER **NewTable) 315 { 316 317 if (!ExistingTable || !NewTable) 318 { 319 return (AE_BAD_PARAMETER); 320 } 321 322 *NewTable = NULL; 323 324 #ifdef ACPI_EXEC_APP 325 326 AeTableOverride (ExistingTable, NewTable); 327 return (AE_OK); 328 #else 329 330 return (AE_NO_ACPI_TABLES); 331 #endif 332 } 333 334 335 /****************************************************************************** 336 * 337 * FUNCTION: AcpiOsPhysicalTableOverride 338 * 339 * PARAMETERS: ExistingTable - Header of current table (probably firmware) 340 * NewAddress - Where new table address is returned 341 * (Physical address) 342 * NewTableLength - Where new table length is returned 343 * 344 * RETURN: Status, address/length of new table. Null pointer returned 345 * if no table is available to override. 346 * 347 * DESCRIPTION: Returns AE_SUPPORT, function not used in user space. 348 * 349 *****************************************************************************/ 350 351 ACPI_STATUS 352 AcpiOsPhysicalTableOverride ( 353 ACPI_TABLE_HEADER *ExistingTable, 354 ACPI_PHYSICAL_ADDRESS *NewAddress, 355 UINT32 *NewTableLength) 356 { 357 358 return (AE_SUPPORT); 359 } 360 361 362 /****************************************************************************** 363 * 364 * FUNCTION: 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 int RetVal; 880 #ifndef ACPI_USE_ALTERNATE_TIMEOUT 881 struct timespec Time; 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 while (((RetVal = sem_wait (Sem)) == -1) && (errno == EINTR)) 912 { 913 continue; /* Restart if interrupted */ 914 } 915 if (RetVal != 0) 916 { 917 Status = (AE_TIME); 918 } 919 break; 920 921 922 /* Wait with MsecTimeout */ 923 924 default: 925 926 #ifdef ACPI_USE_ALTERNATE_TIMEOUT 927 /* 928 * Alternate timeout mechanism for environments where 929 * sem_timedwait is not available or does not work properly. 930 */ 931 while (MsecTimeout) 932 { 933 if (sem_trywait (Sem) == 0) 934 { 935 /* Got the semaphore */ 936 return (AE_OK); 937 } 938 939 if (MsecTimeout >= 10) 940 { 941 MsecTimeout -= 10; 942 usleep (10 * ACPI_USEC_PER_MSEC); /* ten milliseconds */ 943 } 944 else 945 { 946 MsecTimeout--; 947 usleep (ACPI_USEC_PER_MSEC); /* one millisecond */ 948 } 949 } 950 Status = (AE_TIME); 951 #else 952 /* 953 * The interface to sem_timedwait is an absolute time, so we need to 954 * get the current time, then add in the millisecond Timeout value. 955 */ 956 if (clock_gettime (CLOCK_REALTIME, &Time) == -1) 957 { 958 perror ("clock_gettime"); 959 return (AE_TIME); 960 } 961 962 Time.tv_sec += (MsecTimeout / ACPI_MSEC_PER_SEC); 963 Time.tv_nsec += ((MsecTimeout % ACPI_MSEC_PER_SEC) * ACPI_NSEC_PER_MSEC); 964 965 /* Handle nanosecond overflow (field must be less than one second) */ 966 967 if (Time.tv_nsec >= ACPI_NSEC_PER_SEC) 968 { 969 Time.tv_sec += (Time.tv_nsec / ACPI_NSEC_PER_SEC); 970 Time.tv_nsec = (Time.tv_nsec % ACPI_NSEC_PER_SEC); 971 } 972 973 while (((RetVal = sem_timedwait (Sem, &Time)) == -1) && (errno == EINTR)) 974 { 975 continue; /* Restart if interrupted */ 976 977 } 978 979 if (RetVal != 0) 980 { 981 if (errno != ETIMEDOUT) 982 { 983 perror ("sem_timedwait"); 984 } 985 Status = (AE_TIME); 986 } 987 #endif 988 break; 989 } 990 991 return (Status); 992 } 993 994 995 /****************************************************************************** 996 * 997 * FUNCTION: AcpiOsSignalSemaphore 998 * 999 * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore 1000 * Units - Number of units to send 1001 * 1002 * RETURN: Status 1003 * 1004 * DESCRIPTION: Send units 1005 * 1006 *****************************************************************************/ 1007 1008 ACPI_STATUS 1009 AcpiOsSignalSemaphore ( 1010 ACPI_HANDLE Handle, 1011 UINT32 Units) 1012 { 1013 sem_t *Sem = (sem_t *)Handle; 1014 1015 1016 if (!Sem) 1017 { 1018 return (AE_BAD_PARAMETER); 1019 } 1020 1021 if (sem_post (Sem) == -1) 1022 { 1023 return (AE_LIMIT); 1024 } 1025 1026 return (AE_OK); 1027 } 1028 1029 #endif /* ACPI_SINGLE_THREADED */ 1030 1031 1032 /****************************************************************************** 1033 * 1034 * FUNCTION: Spinlock interfaces 1035 * 1036 * DESCRIPTION: Map these interfaces to semaphore interfaces 1037 * 1038 *****************************************************************************/ 1039 1040 ACPI_STATUS 1041 AcpiOsCreateLock ( 1042 ACPI_SPINLOCK *OutHandle) 1043 { 1044 1045 return (AcpiOsCreateSemaphore (1, 1, OutHandle)); 1046 } 1047 1048 1049 void 1050 AcpiOsDeleteLock ( 1051 ACPI_SPINLOCK Handle) 1052 { 1053 AcpiOsDeleteSemaphore (Handle); 1054 } 1055 1056 1057 ACPI_CPU_FLAGS 1058 AcpiOsAcquireLock ( 1059 ACPI_HANDLE Handle) 1060 { 1061 AcpiOsWaitSemaphore (Handle, 1, 0xFFFF); 1062 return (0); 1063 } 1064 1065 1066 void 1067 AcpiOsReleaseLock ( 1068 ACPI_SPINLOCK Handle, 1069 ACPI_CPU_FLAGS Flags) 1070 { 1071 AcpiOsSignalSemaphore (Handle, 1); 1072 } 1073 1074 1075 /****************************************************************************** 1076 * 1077 * FUNCTION: AcpiOsInstallInterruptHandler 1078 * 1079 * PARAMETERS: InterruptNumber - Level handler should respond to. 1080 * Isr - Address of the ACPI interrupt handler 1081 * ExceptPtr - Where status is returned 1082 * 1083 * RETURN: Handle to the newly installed handler. 1084 * 1085 * DESCRIPTION: Install an interrupt handler. Used to install the ACPI 1086 * OS-independent handler. 1087 * 1088 *****************************************************************************/ 1089 1090 UINT32 1091 AcpiOsInstallInterruptHandler ( 1092 UINT32 InterruptNumber, 1093 ACPI_OSD_HANDLER ServiceRoutine, 1094 void *Context) 1095 { 1096 1097 return (AE_OK); 1098 } 1099 1100 1101 /****************************************************************************** 1102 * 1103 * FUNCTION: AcpiOsRemoveInterruptHandler 1104 * 1105 * PARAMETERS: Handle - Returned when handler was installed 1106 * 1107 * RETURN: Status 1108 * 1109 * DESCRIPTION: Uninstalls an interrupt handler. 1110 * 1111 *****************************************************************************/ 1112 1113 ACPI_STATUS 1114 AcpiOsRemoveInterruptHandler ( 1115 UINT32 InterruptNumber, 1116 ACPI_OSD_HANDLER ServiceRoutine) 1117 { 1118 1119 return (AE_OK); 1120 } 1121 1122 1123 /****************************************************************************** 1124 * 1125 * FUNCTION: AcpiOsStall 1126 * 1127 * PARAMETERS: microseconds - Time to sleep 1128 * 1129 * RETURN: Blocks until sleep is completed. 1130 * 1131 * DESCRIPTION: Sleep at microsecond granularity 1132 * 1133 *****************************************************************************/ 1134 1135 void 1136 AcpiOsStall ( 1137 UINT32 microseconds) 1138 { 1139 1140 if (microseconds) 1141 { 1142 usleep (microseconds); 1143 } 1144 } 1145 1146 1147 /****************************************************************************** 1148 * 1149 * FUNCTION: AcpiOsSleep 1150 * 1151 * PARAMETERS: milliseconds - Time to sleep 1152 * 1153 * RETURN: Blocks until sleep is completed. 1154 * 1155 * DESCRIPTION: Sleep at millisecond granularity 1156 * 1157 *****************************************************************************/ 1158 1159 void 1160 AcpiOsSleep ( 1161 UINT64 milliseconds) 1162 { 1163 1164 /* Sleep for whole seconds */ 1165 1166 sleep (milliseconds / ACPI_MSEC_PER_SEC); 1167 1168 /* 1169 * Sleep for remaining microseconds. 1170 * Arg to usleep() is in usecs and must be less than 1,000,000 (1 second). 1171 */ 1172 usleep ((milliseconds % ACPI_MSEC_PER_SEC) * ACPI_USEC_PER_MSEC); 1173 } 1174 1175 1176 /****************************************************************************** 1177 * 1178 * FUNCTION: AcpiOsGetTimer 1179 * 1180 * PARAMETERS: None 1181 * 1182 * RETURN: Current time in 100 nanosecond units 1183 * 1184 * DESCRIPTION: Get the current system time 1185 * 1186 *****************************************************************************/ 1187 1188 UINT64 1189 AcpiOsGetTimer ( 1190 void) 1191 { 1192 struct timeval time; 1193 1194 1195 /* This timer has sufficient resolution for user-space application code */ 1196 1197 gettimeofday (&time, NULL); 1198 1199 /* (Seconds * 10^7 = 100ns(10^-7)) + (Microseconds(10^-6) * 10^1 = 100ns) */ 1200 1201 return (((UINT64) time.tv_sec * ACPI_100NSEC_PER_SEC) + 1202 ((UINT64) time.tv_usec * ACPI_100NSEC_PER_USEC)); 1203 } 1204 1205 1206 /****************************************************************************** 1207 * 1208 * FUNCTION: AcpiOsReadPciConfiguration 1209 * 1210 * PARAMETERS: PciId - Seg/Bus/Dev 1211 * PciRegister - Device Register 1212 * Value - Buffer where value is placed 1213 * Width - Number of bits 1214 * 1215 * RETURN: Status 1216 * 1217 * DESCRIPTION: Read data from PCI configuration space 1218 * 1219 *****************************************************************************/ 1220 1221 ACPI_STATUS 1222 AcpiOsReadPciConfiguration ( 1223 ACPI_PCI_ID *PciId, 1224 UINT32 PciRegister, 1225 UINT64 *Value, 1226 UINT32 Width) 1227 { 1228 1229 *Value = 0; 1230 return (AE_OK); 1231 } 1232 1233 1234 /****************************************************************************** 1235 * 1236 * FUNCTION: AcpiOsWritePciConfiguration 1237 * 1238 * PARAMETERS: PciId - Seg/Bus/Dev 1239 * PciRegister - Device Register 1240 * Value - Value to be written 1241 * Width - Number of bits 1242 * 1243 * RETURN: Status. 1244 * 1245 * DESCRIPTION: Write data to PCI configuration space 1246 * 1247 *****************************************************************************/ 1248 1249 ACPI_STATUS 1250 AcpiOsWritePciConfiguration ( 1251 ACPI_PCI_ID *PciId, 1252 UINT32 PciRegister, 1253 UINT64 Value, 1254 UINT32 Width) 1255 { 1256 1257 return (AE_OK); 1258 } 1259 1260 1261 /****************************************************************************** 1262 * 1263 * FUNCTION: AcpiOsReadPort 1264 * 1265 * PARAMETERS: Address - Address of I/O port/register to read 1266 * Value - Where value is placed 1267 * Width - Number of bits 1268 * 1269 * RETURN: Value read from port 1270 * 1271 * DESCRIPTION: Read data from an I/O port or register 1272 * 1273 *****************************************************************************/ 1274 1275 ACPI_STATUS 1276 AcpiOsReadPort ( 1277 ACPI_IO_ADDRESS Address, 1278 UINT32 *Value, 1279 UINT32 Width) 1280 { 1281 1282 switch (Width) 1283 { 1284 case 8: 1285 1286 *Value = 0xFF; 1287 break; 1288 1289 case 16: 1290 1291 *Value = 0xFFFF; 1292 break; 1293 1294 case 32: 1295 1296 *Value = 0xFFFFFFFF; 1297 break; 1298 1299 default: 1300 1301 return (AE_BAD_PARAMETER); 1302 } 1303 1304 return (AE_OK); 1305 } 1306 1307 1308 /****************************************************************************** 1309 * 1310 * FUNCTION: AcpiOsWritePort 1311 * 1312 * PARAMETERS: Address - Address of I/O port/register to write 1313 * Value - Value to write 1314 * Width - Number of bits 1315 * 1316 * RETURN: None 1317 * 1318 * DESCRIPTION: Write data to an I/O port or register 1319 * 1320 *****************************************************************************/ 1321 1322 ACPI_STATUS 1323 AcpiOsWritePort ( 1324 ACPI_IO_ADDRESS Address, 1325 UINT32 Value, 1326 UINT32 Width) 1327 { 1328 1329 return (AE_OK); 1330 } 1331 1332 1333 /****************************************************************************** 1334 * 1335 * FUNCTION: AcpiOsReadMemory 1336 * 1337 * PARAMETERS: Address - Physical Memory Address to read 1338 * Value - Where value is placed 1339 * Width - Number of bits (8,16,32, or 64) 1340 * 1341 * RETURN: Value read from physical memory address. Always returned 1342 * as a 64-bit integer, regardless of the read width. 1343 * 1344 * DESCRIPTION: Read data from a physical memory address 1345 * 1346 *****************************************************************************/ 1347 1348 ACPI_STATUS 1349 AcpiOsReadMemory ( 1350 ACPI_PHYSICAL_ADDRESS Address, 1351 UINT64 *Value, 1352 UINT32 Width) 1353 { 1354 1355 switch (Width) 1356 { 1357 case 8: 1358 case 16: 1359 case 32: 1360 case 64: 1361 1362 *Value = 0; 1363 break; 1364 1365 default: 1366 1367 return (AE_BAD_PARAMETER); 1368 } 1369 return (AE_OK); 1370 } 1371 1372 1373 /****************************************************************************** 1374 * 1375 * FUNCTION: AcpiOsWriteMemory 1376 * 1377 * PARAMETERS: Address - Physical Memory Address to write 1378 * Value - Value to write 1379 * Width - Number of bits (8,16,32, or 64) 1380 * 1381 * RETURN: None 1382 * 1383 * DESCRIPTION: Write data to a physical memory address 1384 * 1385 *****************************************************************************/ 1386 1387 ACPI_STATUS 1388 AcpiOsWriteMemory ( 1389 ACPI_PHYSICAL_ADDRESS Address, 1390 UINT64 Value, 1391 UINT32 Width) 1392 { 1393 1394 return (AE_OK); 1395 } 1396 1397 1398 /****************************************************************************** 1399 * 1400 * FUNCTION: AcpiOsReadable 1401 * 1402 * PARAMETERS: Pointer - Area to be verified 1403 * Length - Size of area 1404 * 1405 * RETURN: TRUE if readable for entire length 1406 * 1407 * DESCRIPTION: Verify that a pointer is valid for reading 1408 * 1409 *****************************************************************************/ 1410 1411 BOOLEAN 1412 AcpiOsReadable ( 1413 void *Pointer, 1414 ACPI_SIZE Length) 1415 { 1416 1417 return (TRUE); 1418 } 1419 1420 1421 /****************************************************************************** 1422 * 1423 * FUNCTION: AcpiOsWritable 1424 * 1425 * PARAMETERS: Pointer - Area to be verified 1426 * Length - Size of area 1427 * 1428 * RETURN: TRUE if writable for entire length 1429 * 1430 * DESCRIPTION: Verify that a pointer is valid for writing 1431 * 1432 *****************************************************************************/ 1433 1434 BOOLEAN 1435 AcpiOsWritable ( 1436 void *Pointer, 1437 ACPI_SIZE Length) 1438 { 1439 1440 return (TRUE); 1441 } 1442 1443 1444 /****************************************************************************** 1445 * 1446 * FUNCTION: AcpiOsSignal 1447 * 1448 * PARAMETERS: Function - ACPI A signal function code 1449 * Info - Pointer to function-dependent structure 1450 * 1451 * RETURN: Status 1452 * 1453 * DESCRIPTION: Miscellaneous functions. Example implementation only. 1454 * 1455 *****************************************************************************/ 1456 1457 ACPI_STATUS 1458 AcpiOsSignal ( 1459 UINT32 Function, 1460 void *Info) 1461 { 1462 1463 switch (Function) 1464 { 1465 case ACPI_SIGNAL_FATAL: 1466 1467 break; 1468 1469 case ACPI_SIGNAL_BREAKPOINT: 1470 1471 break; 1472 1473 default: 1474 1475 break; 1476 } 1477 1478 return (AE_OK); 1479 } 1480 1481 /* Optional multi-thread support */ 1482 1483 #ifndef ACPI_SINGLE_THREADED 1484 /****************************************************************************** 1485 * 1486 * FUNCTION: AcpiOsGetThreadId 1487 * 1488 * PARAMETERS: None 1489 * 1490 * RETURN: Id of the running thread 1491 * 1492 * DESCRIPTION: Get the ID of the current (running) thread 1493 * 1494 *****************************************************************************/ 1495 1496 ACPI_THREAD_ID 1497 AcpiOsGetThreadId ( 1498 void) 1499 { 1500 pthread_t thread; 1501 1502 1503 thread = pthread_self(); 1504 return (ACPI_CAST_PTHREAD_T (thread)); 1505 } 1506 1507 1508 /****************************************************************************** 1509 * 1510 * FUNCTION: AcpiOsExecute 1511 * 1512 * PARAMETERS: Type - Type of execution 1513 * Function - Address of the function to execute 1514 * Context - Passed as a parameter to the function 1515 * 1516 * RETURN: Status. 1517 * 1518 * DESCRIPTION: Execute a new thread 1519 * 1520 *****************************************************************************/ 1521 1522 ACPI_STATUS 1523 AcpiOsExecute ( 1524 ACPI_EXECUTE_TYPE Type, 1525 ACPI_OSD_EXEC_CALLBACK Function, 1526 void *Context) 1527 { 1528 pthread_t thread; 1529 int ret; 1530 1531 1532 ret = pthread_create (&thread, NULL, (PTHREAD_CALLBACK) Function, Context); 1533 if (ret) 1534 { 1535 AcpiOsPrintf("Create thread failed"); 1536 } 1537 return (0); 1538 } 1539 1540 #else /* ACPI_SINGLE_THREADED */ 1541 ACPI_THREAD_ID 1542 AcpiOsGetThreadId ( 1543 void) 1544 { 1545 return (1); 1546 } 1547 1548 ACPI_STATUS 1549 AcpiOsExecute ( 1550 ACPI_EXECUTE_TYPE Type, 1551 ACPI_OSD_EXEC_CALLBACK Function, 1552 void *Context) 1553 { 1554 1555 Function (Context); 1556 1557 return (AE_OK); 1558 } 1559 1560 #endif /* ACPI_SINGLE_THREADED */ 1561 1562 1563 /****************************************************************************** 1564 * 1565 * FUNCTION: AcpiOsWaitEventsComplete 1566 * 1567 * PARAMETERS: None 1568 * 1569 * RETURN: None 1570 * 1571 * DESCRIPTION: Wait for all asynchronous events to complete. This 1572 * implementation does nothing. 1573 * 1574 *****************************************************************************/ 1575 1576 void 1577 AcpiOsWaitEventsComplete ( 1578 void) 1579 { 1580 return; 1581 } 1582