1 /****************************************************************************** 2 * 3 * Module Name: oswinxf - Windows OSL 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, 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 #include "acpi.h" 45 #include "accommon.h" 46 47 #ifdef WIN32 48 #pragma warning(disable:4115) /* warning C4115: named type definition in parentheses (caused by rpcasync.h> */ 49 50 #include <windows.h> 51 #include <winbase.h> 52 53 #elif WIN64 54 #include <windowsx.h> 55 #endif 56 57 #include <stdio.h> 58 #include <stdlib.h> 59 #include <stdarg.h> 60 #include <process.h> 61 #include <time.h> 62 63 #define _COMPONENT ACPI_OS_SERVICES 64 ACPI_MODULE_NAME ("oswinxf") 65 66 67 UINT64 TimerFrequency; 68 char TableName[ACPI_NAME_SIZE + 1]; 69 70 #define ACPI_OS_DEBUG_TIMEOUT 30000 /* 30 seconds */ 71 72 73 /* Upcalls to AcpiExec application */ 74 75 void 76 AeTableOverride ( 77 ACPI_TABLE_HEADER *ExistingTable, 78 ACPI_TABLE_HEADER **NewTable); 79 80 /* 81 * Real semaphores are only used for a multi-threaded application 82 */ 83 #ifndef ACPI_SINGLE_THREADED 84 85 /* Semaphore information structure */ 86 87 typedef struct acpi_os_semaphore_info 88 { 89 UINT16 MaxUnits; 90 UINT16 CurrentUnits; 91 void *OsHandle; 92 93 } ACPI_OS_SEMAPHORE_INFO; 94 95 /* Need enough semaphores to run the large aslts suite */ 96 97 #define ACPI_OS_MAX_SEMAPHORES 256 98 99 ACPI_OS_SEMAPHORE_INFO AcpiGbl_Semaphores[ACPI_OS_MAX_SEMAPHORES]; 100 101 #endif /* ACPI_SINGLE_THREADED */ 102 103 BOOLEAN AcpiGbl_DebugTimeout = FALSE; 104 105 106 /****************************************************************************** 107 * 108 * FUNCTION: AcpiOsTerminate 109 * 110 * PARAMETERS: None 111 * 112 * RETURN: Status 113 * 114 * DESCRIPTION: Nothing to do for windows 115 * 116 *****************************************************************************/ 117 118 ACPI_STATUS 119 AcpiOsTerminate ( 120 void) 121 { 122 return (AE_OK); 123 } 124 125 126 /****************************************************************************** 127 * 128 * FUNCTION: AcpiOsInitialize 129 * 130 * PARAMETERS: None 131 * 132 * RETURN: Status 133 * 134 * DESCRIPTION: Init this OSL 135 * 136 *****************************************************************************/ 137 138 ACPI_STATUS 139 AcpiOsInitialize ( 140 void) 141 { 142 ACPI_STATUS Status; 143 LARGE_INTEGER LocalTimerFrequency; 144 145 146 #ifndef ACPI_SINGLE_THREADED 147 /* Clear the semaphore info array */ 148 149 memset (AcpiGbl_Semaphores, 0x00, sizeof (AcpiGbl_Semaphores)); 150 #endif 151 152 AcpiGbl_OutputFile = stdout; 153 154 /* Get the timer frequency for use in AcpiOsGetTimer */ 155 156 TimerFrequency = 0; 157 if (QueryPerformanceFrequency (&LocalTimerFrequency)) 158 { 159 /* Frequency is in ticks per second */ 160 161 TimerFrequency = LocalTimerFrequency.QuadPart; 162 } 163 164 Status = AcpiOsCreateLock (&AcpiGbl_PrintLock); 165 if (ACPI_FAILURE (Status)) 166 { 167 return (Status); 168 } 169 170 return (AE_OK); 171 } 172 173 174 #ifndef ACPI_USE_NATIVE_RSDP_POINTER 175 /****************************************************************************** 176 * 177 * FUNCTION: AcpiOsGetRootPointer 178 * 179 * PARAMETERS: None 180 * 181 * RETURN: RSDP physical address 182 * 183 * DESCRIPTION: Gets the root pointer (RSDP) 184 * 185 *****************************************************************************/ 186 187 ACPI_PHYSICAL_ADDRESS 188 AcpiOsGetRootPointer ( 189 void) 190 { 191 192 return (0); 193 } 194 #endif 195 196 197 /****************************************************************************** 198 * 199 * FUNCTION: AcpiOsPredefinedOverride 200 * 201 * PARAMETERS: InitVal - Initial value of the predefined object 202 * NewVal - The new value for the object 203 * 204 * RETURN: Status, pointer to value. Null pointer returned if not 205 * overriding. 206 * 207 * DESCRIPTION: Allow the OS to override predefined names 208 * 209 *****************************************************************************/ 210 211 ACPI_STATUS 212 AcpiOsPredefinedOverride ( 213 const ACPI_PREDEFINED_NAMES *InitVal, 214 ACPI_STRING *NewVal) 215 { 216 217 if (!InitVal || !NewVal) 218 { 219 return (AE_BAD_PARAMETER); 220 } 221 222 *NewVal = NULL; 223 return (AE_OK); 224 } 225 226 227 /****************************************************************************** 228 * 229 * FUNCTION: AcpiOsTableOverride 230 * 231 * PARAMETERS: ExistingTable - Header of current table (probably firmware) 232 * NewTable - Where an entire new table is returned. 233 * 234 * RETURN: Status, pointer to new table. Null pointer returned if no 235 * table is available to override 236 * 237 * DESCRIPTION: Return a different version of a table if one is available 238 * 239 *****************************************************************************/ 240 241 ACPI_STATUS 242 AcpiOsTableOverride ( 243 ACPI_TABLE_HEADER *ExistingTable, 244 ACPI_TABLE_HEADER **NewTable) 245 { 246 247 if (!ExistingTable || !NewTable) 248 { 249 return (AE_BAD_PARAMETER); 250 } 251 252 *NewTable = NULL; 253 254 255 #ifdef ACPI_EXEC_APP 256 257 /* Call back up to AcpiExec */ 258 259 AeTableOverride (ExistingTable, NewTable); 260 #endif 261 262 return (AE_OK); 263 } 264 265 266 /****************************************************************************** 267 * 268 * FUNCTION: AcpiOsPhysicalTableOverride 269 * 270 * PARAMETERS: ExistingTable - Header of current table (probably firmware) 271 * NewAddress - Where new table address is returned 272 * (Physical address) 273 * NewTableLength - Where new table length is returned 274 * 275 * RETURN: Status, address/length of new table. Null pointer returned 276 * if no table is available to override. 277 * 278 * DESCRIPTION: Returns AE_SUPPORT, function not used in user space. 279 * 280 *****************************************************************************/ 281 282 ACPI_STATUS 283 AcpiOsPhysicalTableOverride ( 284 ACPI_TABLE_HEADER *ExistingTable, 285 ACPI_PHYSICAL_ADDRESS *NewAddress, 286 UINT32 *NewTableLength) 287 { 288 289 return (AE_SUPPORT); 290 } 291 292 293 /****************************************************************************** 294 * 295 * FUNCTION: AcpiOsGetTimer 296 * 297 * PARAMETERS: None 298 * 299 * RETURN: Current ticks in 100-nanosecond units 300 * 301 * DESCRIPTION: Get the value of a system timer 302 * 303 ******************************************************************************/ 304 305 UINT64 306 AcpiOsGetTimer ( 307 void) 308 { 309 LARGE_INTEGER Timer; 310 311 312 /* Attempt to use hi-granularity timer first */ 313 314 if (TimerFrequency && 315 QueryPerformanceCounter (&Timer)) 316 { 317 /* Convert to 100 nanosecond ticks */ 318 319 return ((UINT64) ((Timer.QuadPart * (UINT64) ACPI_100NSEC_PER_SEC) / 320 TimerFrequency)); 321 } 322 323 /* Fall back to the lo-granularity timer */ 324 325 else 326 { 327 /* Convert milliseconds to 100 nanosecond ticks */ 328 329 return ((UINT64) GetTickCount() * ACPI_100NSEC_PER_MSEC); 330 } 331 } 332 333 334 /****************************************************************************** 335 * 336 * FUNCTION: AcpiOsReadable 337 * 338 * PARAMETERS: Pointer - Area to be verified 339 * Length - Size of area 340 * 341 * RETURN: TRUE if readable for entire length 342 * 343 * DESCRIPTION: Verify that a pointer is valid for reading 344 * 345 *****************************************************************************/ 346 347 BOOLEAN 348 AcpiOsReadable ( 349 void *Pointer, 350 ACPI_SIZE Length) 351 { 352 353 return ((BOOLEAN) !IsBadReadPtr (Pointer, Length)); 354 } 355 356 357 /****************************************************************************** 358 * 359 * FUNCTION: AcpiOsWritable 360 * 361 * PARAMETERS: Pointer - Area to be verified 362 * Length - Size of area 363 * 364 * RETURN: TRUE if writable for entire length 365 * 366 * DESCRIPTION: Verify that a pointer is valid for writing 367 * 368 *****************************************************************************/ 369 370 BOOLEAN 371 AcpiOsWritable ( 372 void *Pointer, 373 ACPI_SIZE Length) 374 { 375 376 return ((BOOLEAN) !IsBadWritePtr (Pointer, Length)); 377 } 378 379 380 /****************************************************************************** 381 * 382 * FUNCTION: AcpiOsRedirectOutput 383 * 384 * PARAMETERS: Destination - An open file handle/pointer 385 * 386 * RETURN: None 387 * 388 * DESCRIPTION: Causes redirect of AcpiOsPrintf and AcpiOsVprintf 389 * 390 *****************************************************************************/ 391 392 void 393 AcpiOsRedirectOutput ( 394 void *Destination) 395 { 396 397 AcpiGbl_OutputFile = Destination; 398 } 399 400 401 /****************************************************************************** 402 * 403 * FUNCTION: AcpiOsPrintf 404 * 405 * PARAMETERS: Fmt, ... - Standard printf format 406 * 407 * RETURN: None 408 * 409 * DESCRIPTION: Formatted output 410 * 411 *****************************************************************************/ 412 413 void ACPI_INTERNAL_VAR_XFACE 414 AcpiOsPrintf ( 415 const char *Fmt, 416 ...) 417 { 418 va_list Args; 419 UINT8 Flags; 420 421 422 Flags = AcpiGbl_DbOutputFlags; 423 if (Flags & ACPI_DB_REDIRECTABLE_OUTPUT) 424 { 425 /* Output is directable to either a file (if open) or the console */ 426 427 if (AcpiGbl_DebugFile) 428 { 429 /* Output file is open, send the output there */ 430 431 va_start (Args, Fmt); 432 vfprintf (AcpiGbl_DebugFile, Fmt, Args); 433 va_end (Args); 434 } 435 else 436 { 437 /* No redirection, send output to console (once only!) */ 438 439 Flags |= ACPI_DB_CONSOLE_OUTPUT; 440 } 441 } 442 443 if (Flags & ACPI_DB_CONSOLE_OUTPUT) 444 { 445 va_start (Args, Fmt); 446 vfprintf (AcpiGbl_OutputFile, Fmt, Args); 447 va_end (Args); 448 } 449 450 return; 451 } 452 453 454 /****************************************************************************** 455 * 456 * FUNCTION: AcpiOsVprintf 457 * 458 * PARAMETERS: Fmt - Standard printf format 459 * Args - Argument list 460 * 461 * RETURN: None 462 * 463 * DESCRIPTION: Formatted output with argument list pointer 464 * 465 *****************************************************************************/ 466 467 void 468 AcpiOsVprintf ( 469 const char *Fmt, 470 va_list Args) 471 { 472 INT32 Count = 0; 473 UINT8 Flags; 474 475 476 Flags = AcpiGbl_DbOutputFlags; 477 if (Flags & ACPI_DB_REDIRECTABLE_OUTPUT) 478 { 479 /* Output is directable to either a file (if open) or the console */ 480 481 if (AcpiGbl_DebugFile) 482 { 483 /* Output file is open, send the output there */ 484 485 Count = vfprintf (AcpiGbl_DebugFile, Fmt, Args); 486 } 487 else 488 { 489 /* No redirection, send output to console (once only!) */ 490 491 Flags |= ACPI_DB_CONSOLE_OUTPUT; 492 } 493 } 494 495 if (Flags & ACPI_DB_CONSOLE_OUTPUT) 496 { 497 Count = vfprintf (AcpiGbl_OutputFile, Fmt, Args); 498 } 499 500 return; 501 } 502 503 504 /****************************************************************************** 505 * 506 * FUNCTION: AcpiOsGetLine 507 * 508 * PARAMETERS: Buffer - Where to return the command line 509 * BufferLength - Maximum length of Buffer 510 * BytesRead - Where the actual byte count is returned 511 * 512 * RETURN: Status and actual bytes read 513 * 514 * DESCRIPTION: Formatted input with argument list pointer 515 * 516 *****************************************************************************/ 517 518 ACPI_STATUS 519 AcpiOsGetLine ( 520 char *Buffer, 521 UINT32 BufferLength, 522 UINT32 *BytesRead) 523 { 524 int Temp; 525 UINT32 i; 526 527 528 for (i = 0; ; i++) 529 { 530 if (i >= BufferLength) 531 { 532 return (AE_BUFFER_OVERFLOW); 533 } 534 535 if ((Temp = getchar ()) == EOF) 536 { 537 return (AE_ERROR); 538 } 539 540 if (!Temp || Temp == '\n') 541 { 542 break; 543 } 544 545 Buffer [i] = (char) Temp; 546 } 547 548 /* Null terminate the buffer */ 549 550 Buffer [i] = 0; 551 552 /* Return the number of bytes in the string */ 553 554 if (BytesRead) 555 { 556 *BytesRead = i; 557 } 558 559 return (AE_OK); 560 } 561 562 563 #ifndef ACPI_USE_NATIVE_MEMORY_MAPPING 564 /****************************************************************************** 565 * 566 * FUNCTION: AcpiOsMapMemory 567 * 568 * PARAMETERS: Where - Physical address of memory to be mapped 569 * Length - How much memory to map 570 * 571 * RETURN: Pointer to mapped memory. Null on error. 572 * 573 * DESCRIPTION: Map physical memory into caller's address space 574 * 575 *****************************************************************************/ 576 577 void * 578 AcpiOsMapMemory ( 579 ACPI_PHYSICAL_ADDRESS Where, 580 ACPI_SIZE Length) 581 { 582 583 return (ACPI_TO_POINTER ((ACPI_SIZE) Where)); 584 } 585 586 587 /****************************************************************************** 588 * 589 * FUNCTION: AcpiOsUnmapMemory 590 * 591 * PARAMETERS: Where - Logical address of memory to be unmapped 592 * Length - How much memory to unmap 593 * 594 * RETURN: None. 595 * 596 * DESCRIPTION: Delete a previously created mapping. Where and Length must 597 * correspond to a previous mapping exactly. 598 * 599 *****************************************************************************/ 600 601 void 602 AcpiOsUnmapMemory ( 603 void *Where, 604 ACPI_SIZE Length) 605 { 606 607 return; 608 } 609 #endif 610 611 612 /****************************************************************************** 613 * 614 * FUNCTION: AcpiOsAllocate 615 * 616 * PARAMETERS: Size - Amount to allocate, in bytes 617 * 618 * RETURN: Pointer to the new allocation. Null on error. 619 * 620 * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS. 621 * 622 *****************************************************************************/ 623 624 void * 625 AcpiOsAllocate ( 626 ACPI_SIZE Size) 627 { 628 void *Mem; 629 630 631 Mem = (void *) malloc ((size_t) Size); 632 return (Mem); 633 } 634 635 636 #ifdef USE_NATIVE_ALLOCATE_ZEROED 637 /****************************************************************************** 638 * 639 * FUNCTION: AcpiOsAllocateZeroed 640 * 641 * PARAMETERS: Size - Amount to allocate, in bytes 642 * 643 * RETURN: Pointer to the new allocation. Null on error. 644 * 645 * DESCRIPTION: Allocate and zero memory. Algorithm is dependent on the OS. 646 * 647 *****************************************************************************/ 648 649 void * 650 AcpiOsAllocateZeroed ( 651 ACPI_SIZE Size) 652 { 653 void *Mem; 654 655 656 Mem = (void *) calloc (1, (size_t) Size); 657 return (Mem); 658 } 659 #endif 660 661 662 /****************************************************************************** 663 * 664 * FUNCTION: AcpiOsFree 665 * 666 * PARAMETERS: Mem - Pointer to previously allocated memory 667 * 668 * RETURN: None. 669 * 670 * DESCRIPTION: Free memory allocated via AcpiOsAllocate 671 * 672 *****************************************************************************/ 673 674 void 675 AcpiOsFree ( 676 void *Mem) 677 { 678 679 free (Mem); 680 } 681 682 683 #ifdef ACPI_SINGLE_THREADED 684 /****************************************************************************** 685 * 686 * FUNCTION: Semaphore stub functions 687 * 688 * DESCRIPTION: Stub functions used for single-thread applications that do 689 * not require semaphore synchronization. Full implementations 690 * of these functions appear after the stubs. 691 * 692 *****************************************************************************/ 693 694 ACPI_STATUS 695 AcpiOsCreateSemaphore ( 696 UINT32 MaxUnits, 697 UINT32 InitialUnits, 698 ACPI_HANDLE *OutHandle) 699 { 700 *OutHandle = (ACPI_HANDLE) 1; 701 return (AE_OK); 702 } 703 704 ACPI_STATUS 705 AcpiOsDeleteSemaphore ( 706 ACPI_HANDLE Handle) 707 { 708 return (AE_OK); 709 } 710 711 ACPI_STATUS 712 AcpiOsWaitSemaphore ( 713 ACPI_HANDLE Handle, 714 UINT32 Units, 715 UINT16 Timeout) 716 { 717 return (AE_OK); 718 } 719 720 ACPI_STATUS 721 AcpiOsSignalSemaphore ( 722 ACPI_HANDLE Handle, 723 UINT32 Units) 724 { 725 return (AE_OK); 726 } 727 728 #else 729 /****************************************************************************** 730 * 731 * FUNCTION: AcpiOsCreateSemaphore 732 * 733 * PARAMETERS: MaxUnits - Maximum units that can be sent 734 * InitialUnits - Units to be assigned to the new semaphore 735 * OutHandle - Where a handle will be returned 736 * 737 * RETURN: Status 738 * 739 * DESCRIPTION: Create an OS semaphore 740 * 741 *****************************************************************************/ 742 743 ACPI_STATUS 744 AcpiOsCreateSemaphore ( 745 UINT32 MaxUnits, 746 UINT32 InitialUnits, 747 ACPI_SEMAPHORE *OutHandle) 748 { 749 void *Mutex; 750 UINT32 i; 751 752 ACPI_FUNCTION_NAME (OsCreateSemaphore); 753 754 755 if (MaxUnits == ACPI_UINT32_MAX) 756 { 757 MaxUnits = 255; 758 } 759 760 if (InitialUnits == ACPI_UINT32_MAX) 761 { 762 InitialUnits = MaxUnits; 763 } 764 765 if (InitialUnits > MaxUnits) 766 { 767 return (AE_BAD_PARAMETER); 768 } 769 770 /* Find an empty slot */ 771 772 for (i = 0; i < ACPI_OS_MAX_SEMAPHORES; i++) 773 { 774 if (!AcpiGbl_Semaphores[i].OsHandle) 775 { 776 break; 777 } 778 } 779 if (i >= ACPI_OS_MAX_SEMAPHORES) 780 { 781 ACPI_EXCEPTION ((AE_INFO, AE_LIMIT, 782 "Reached max semaphores (%u), could not create", 783 ACPI_OS_MAX_SEMAPHORES)); 784 return (AE_LIMIT); 785 } 786 787 /* Create an OS semaphore */ 788 789 Mutex = CreateSemaphore (NULL, InitialUnits, MaxUnits, NULL); 790 if (!Mutex) 791 { 792 ACPI_ERROR ((AE_INFO, "Could not create semaphore")); 793 return (AE_NO_MEMORY); 794 } 795 796 AcpiGbl_Semaphores[i].MaxUnits = (UINT16) MaxUnits; 797 AcpiGbl_Semaphores[i].CurrentUnits = (UINT16) InitialUnits; 798 AcpiGbl_Semaphores[i].OsHandle = Mutex; 799 800 ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, 801 "Handle=%u, Max=%u, Current=%u, OsHandle=%p\n", 802 i, MaxUnits, InitialUnits, Mutex)); 803 804 *OutHandle = (void *) i; 805 return (AE_OK); 806 } 807 808 809 /****************************************************************************** 810 * 811 * FUNCTION: AcpiOsDeleteSemaphore 812 * 813 * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore 814 * 815 * RETURN: Status 816 * 817 * DESCRIPTION: Delete an OS semaphore 818 * 819 *****************************************************************************/ 820 821 ACPI_STATUS 822 AcpiOsDeleteSemaphore ( 823 ACPI_SEMAPHORE Handle) 824 { 825 UINT32 Index = (UINT32) Handle; 826 827 828 if ((Index >= ACPI_OS_MAX_SEMAPHORES) || 829 !AcpiGbl_Semaphores[Index].OsHandle) 830 { 831 return (AE_BAD_PARAMETER); 832 } 833 834 CloseHandle (AcpiGbl_Semaphores[Index].OsHandle); 835 AcpiGbl_Semaphores[Index].OsHandle = NULL; 836 return (AE_OK); 837 } 838 839 840 /****************************************************************************** 841 * 842 * FUNCTION: AcpiOsWaitSemaphore 843 * 844 * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore 845 * Units - How many units to wait for 846 * Timeout - How long to wait 847 * 848 * RETURN: Status 849 * 850 * DESCRIPTION: Wait for units 851 * 852 *****************************************************************************/ 853 854 ACPI_STATUS 855 AcpiOsWaitSemaphore ( 856 ACPI_SEMAPHORE Handle, 857 UINT32 Units, 858 UINT16 Timeout) 859 { 860 UINT32 Index = (UINT32) Handle; 861 UINT32 WaitStatus; 862 UINT32 OsTimeout = Timeout; 863 864 865 ACPI_FUNCTION_ENTRY (); 866 867 868 if ((Index >= ACPI_OS_MAX_SEMAPHORES) || 869 !AcpiGbl_Semaphores[Index].OsHandle) 870 { 871 return (AE_BAD_PARAMETER); 872 } 873 874 if (Units > 1) 875 { 876 printf ("WaitSemaphore: Attempt to receive %u units\n", Units); 877 return (AE_NOT_IMPLEMENTED); 878 } 879 880 if (Timeout == ACPI_WAIT_FOREVER) 881 { 882 OsTimeout = INFINITE; 883 if (AcpiGbl_DebugTimeout) 884 { 885 /* The debug timeout will prevent hang conditions */ 886 887 OsTimeout = ACPI_OS_DEBUG_TIMEOUT; 888 } 889 } 890 else 891 { 892 /* Add 10ms to account for clock tick granularity */ 893 894 OsTimeout += 10; 895 } 896 897 WaitStatus = WaitForSingleObject ( 898 AcpiGbl_Semaphores[Index].OsHandle, OsTimeout); 899 if (WaitStatus == WAIT_TIMEOUT) 900 { 901 if (AcpiGbl_DebugTimeout) 902 { 903 ACPI_EXCEPTION ((AE_INFO, AE_TIME, 904 "Debug timeout on semaphore 0x%04X (%ums)\n", 905 Index, ACPI_OS_DEBUG_TIMEOUT)); 906 } 907 908 return (AE_TIME); 909 } 910 911 if (AcpiGbl_Semaphores[Index].CurrentUnits == 0) 912 { 913 ACPI_ERROR ((AE_INFO, 914 "%s - No unit received. Timeout 0x%X, OS_Status 0x%X", 915 AcpiUtGetMutexName (Index), Timeout, WaitStatus)); 916 917 return (AE_OK); 918 } 919 920 AcpiGbl_Semaphores[Index].CurrentUnits--; 921 return (AE_OK); 922 } 923 924 925 /****************************************************************************** 926 * 927 * FUNCTION: AcpiOsSignalSemaphore 928 * 929 * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore 930 * Units - Number of units to send 931 * 932 * RETURN: Status 933 * 934 * DESCRIPTION: Send units 935 * 936 *****************************************************************************/ 937 938 ACPI_STATUS 939 AcpiOsSignalSemaphore ( 940 ACPI_SEMAPHORE Handle, 941 UINT32 Units) 942 { 943 UINT32 Index = (UINT32) Handle; 944 945 946 ACPI_FUNCTION_ENTRY (); 947 948 949 if (Index >= ACPI_OS_MAX_SEMAPHORES) 950 { 951 printf ("SignalSemaphore: Index/Handle out of range: %2.2X\n", Index); 952 return (AE_BAD_PARAMETER); 953 } 954 955 if (!AcpiGbl_Semaphores[Index].OsHandle) 956 { 957 printf ("SignalSemaphore: Null OS handle, Index %2.2X\n", Index); 958 return (AE_BAD_PARAMETER); 959 } 960 961 if (Units > 1) 962 { 963 printf ("SignalSemaphore: Attempt to signal %u units, Index %2.2X\n", Units, Index); 964 return (AE_NOT_IMPLEMENTED); 965 } 966 967 if ((AcpiGbl_Semaphores[Index].CurrentUnits + 1) > 968 AcpiGbl_Semaphores[Index].MaxUnits) 969 { 970 ACPI_ERROR ((AE_INFO, 971 "Oversignalled semaphore[%u]! Current %u Max %u", 972 Index, AcpiGbl_Semaphores[Index].CurrentUnits, 973 AcpiGbl_Semaphores[Index].MaxUnits)); 974 975 return (AE_LIMIT); 976 } 977 978 AcpiGbl_Semaphores[Index].CurrentUnits++; 979 ReleaseSemaphore (AcpiGbl_Semaphores[Index].OsHandle, Units, NULL); 980 981 return (AE_OK); 982 } 983 984 #endif /* ACPI_SINGLE_THREADED */ 985 986 987 /****************************************************************************** 988 * 989 * FUNCTION: Spinlock interfaces 990 * 991 * DESCRIPTION: Map these interfaces to semaphore interfaces 992 * 993 *****************************************************************************/ 994 995 ACPI_STATUS 996 AcpiOsCreateLock ( 997 ACPI_SPINLOCK *OutHandle) 998 { 999 return (AcpiOsCreateSemaphore (1, 1, OutHandle)); 1000 } 1001 1002 void 1003 AcpiOsDeleteLock ( 1004 ACPI_SPINLOCK Handle) 1005 { 1006 AcpiOsDeleteSemaphore (Handle); 1007 } 1008 1009 ACPI_CPU_FLAGS 1010 AcpiOsAcquireLock ( 1011 ACPI_SPINLOCK Handle) 1012 { 1013 AcpiOsWaitSemaphore (Handle, 1, 0xFFFF); 1014 return (0); 1015 } 1016 1017 void 1018 AcpiOsReleaseLock ( 1019 ACPI_SPINLOCK Handle, 1020 ACPI_CPU_FLAGS Flags) 1021 { 1022 AcpiOsSignalSemaphore (Handle, 1); 1023 } 1024 1025 1026 #if ACPI_FUTURE_IMPLEMENTATION 1027 1028 /* Mutex interfaces, just implement with a semaphore */ 1029 1030 ACPI_STATUS 1031 AcpiOsCreateMutex ( 1032 ACPI_MUTEX *OutHandle) 1033 { 1034 return (AcpiOsCreateSemaphore (1, 1, OutHandle)); 1035 } 1036 1037 void 1038 AcpiOsDeleteMutex ( 1039 ACPI_MUTEX Handle) 1040 { 1041 AcpiOsDeleteSemaphore (Handle); 1042 } 1043 1044 ACPI_STATUS 1045 AcpiOsAcquireMutex ( 1046 ACPI_MUTEX Handle, 1047 UINT16 Timeout) 1048 { 1049 AcpiOsWaitSemaphore (Handle, 1, Timeout); 1050 return (0); 1051 } 1052 1053 void 1054 AcpiOsReleaseMutex ( 1055 ACPI_MUTEX Handle) 1056 { 1057 AcpiOsSignalSemaphore (Handle, 1); 1058 } 1059 #endif 1060 1061 1062 /****************************************************************************** 1063 * 1064 * FUNCTION: AcpiOsInstallInterruptHandler 1065 * 1066 * PARAMETERS: InterruptNumber - Level handler should respond to. 1067 * ServiceRoutine - Address of the ACPI interrupt handler 1068 * Context - User context 1069 * 1070 * RETURN: Handle to the newly installed handler. 1071 * 1072 * DESCRIPTION: Install an interrupt handler. Used to install the ACPI 1073 * OS-independent handler. 1074 * 1075 *****************************************************************************/ 1076 1077 UINT32 1078 AcpiOsInstallInterruptHandler ( 1079 UINT32 InterruptNumber, 1080 ACPI_OSD_HANDLER ServiceRoutine, 1081 void *Context) 1082 { 1083 1084 return (AE_OK); 1085 } 1086 1087 1088 /****************************************************************************** 1089 * 1090 * FUNCTION: AcpiOsRemoveInterruptHandler 1091 * 1092 * PARAMETERS: Handle - Returned when handler was installed 1093 * 1094 * RETURN: Status 1095 * 1096 * DESCRIPTION: Uninstalls an interrupt handler. 1097 * 1098 *****************************************************************************/ 1099 1100 ACPI_STATUS 1101 AcpiOsRemoveInterruptHandler ( 1102 UINT32 InterruptNumber, 1103 ACPI_OSD_HANDLER ServiceRoutine) 1104 { 1105 1106 return (AE_OK); 1107 } 1108 1109 1110 /****************************************************************************** 1111 * 1112 * FUNCTION: AcpiOsStall 1113 * 1114 * PARAMETERS: Microseconds - Time to stall 1115 * 1116 * RETURN: None. Blocks until stall is completed. 1117 * 1118 * DESCRIPTION: Sleep at microsecond granularity 1119 * 1120 *****************************************************************************/ 1121 1122 void 1123 AcpiOsStall ( 1124 UINT32 Microseconds) 1125 { 1126 1127 Sleep ((Microseconds / ACPI_USEC_PER_MSEC) + 1); 1128 return; 1129 } 1130 1131 1132 /****************************************************************************** 1133 * 1134 * FUNCTION: AcpiOsSleep 1135 * 1136 * PARAMETERS: Milliseconds - Time to sleep 1137 * 1138 * RETURN: None. Blocks until sleep is completed. 1139 * 1140 * DESCRIPTION: Sleep at millisecond granularity 1141 * 1142 *****************************************************************************/ 1143 1144 void 1145 AcpiOsSleep ( 1146 UINT64 Milliseconds) 1147 { 1148 1149 /* Add 10ms to account for clock tick granularity */ 1150 1151 Sleep (((unsigned long) Milliseconds) + 10); 1152 return; 1153 } 1154 1155 1156 /****************************************************************************** 1157 * 1158 * FUNCTION: AcpiOsReadPciConfiguration 1159 * 1160 * PARAMETERS: PciId - Seg/Bus/Dev 1161 * Register - Device Register 1162 * Value - Buffer where value is placed 1163 * Width - Number of bits 1164 * 1165 * RETURN: Status 1166 * 1167 * DESCRIPTION: Read data from PCI configuration space 1168 * 1169 *****************************************************************************/ 1170 1171 ACPI_STATUS 1172 AcpiOsReadPciConfiguration ( 1173 ACPI_PCI_ID *PciId, 1174 UINT32 Register, 1175 UINT64 *Value, 1176 UINT32 Width) 1177 { 1178 1179 *Value = 0; 1180 return (AE_OK); 1181 } 1182 1183 1184 /****************************************************************************** 1185 * 1186 * FUNCTION: AcpiOsWritePciConfiguration 1187 * 1188 * PARAMETERS: PciId - Seg/Bus/Dev 1189 * Register - Device Register 1190 * Value - Value to be written 1191 * Width - Number of bits 1192 * 1193 * RETURN: Status 1194 * 1195 * DESCRIPTION: Write data to PCI configuration space 1196 * 1197 *****************************************************************************/ 1198 1199 ACPI_STATUS 1200 AcpiOsWritePciConfiguration ( 1201 ACPI_PCI_ID *PciId, 1202 UINT32 Register, 1203 UINT64 Value, 1204 UINT32 Width) 1205 { 1206 1207 return (AE_OK); 1208 } 1209 1210 1211 /****************************************************************************** 1212 * 1213 * FUNCTION: AcpiOsReadPort 1214 * 1215 * PARAMETERS: Address - Address of I/O port/register to read 1216 * Value - Where value is placed 1217 * Width - Number of bits 1218 * 1219 * RETURN: Value read from port 1220 * 1221 * DESCRIPTION: Read data from an I/O port or register 1222 * 1223 *****************************************************************************/ 1224 1225 ACPI_STATUS 1226 AcpiOsReadPort ( 1227 ACPI_IO_ADDRESS Address, 1228 UINT32 *Value, 1229 UINT32 Width) 1230 { 1231 ACPI_FUNCTION_NAME (OsReadPort); 1232 1233 1234 switch (Width) 1235 { 1236 case 8: 1237 1238 *Value = 0xFF; 1239 break; 1240 1241 case 16: 1242 1243 *Value = 0xFFFF; 1244 break; 1245 1246 case 32: 1247 1248 *Value = 0xFFFFFFFF; 1249 break; 1250 1251 default: 1252 1253 ACPI_ERROR ((AE_INFO, "Bad width parameter: %X", Width)); 1254 return (AE_BAD_PARAMETER); 1255 } 1256 1257 return (AE_OK); 1258 } 1259 1260 1261 /****************************************************************************** 1262 * 1263 * FUNCTION: AcpiOsWritePort 1264 * 1265 * PARAMETERS: Address - Address of I/O port/register to write 1266 * Value - Value to write 1267 * Width - Number of bits 1268 * 1269 * RETURN: None 1270 * 1271 * DESCRIPTION: Write data to an I/O port or register 1272 * 1273 *****************************************************************************/ 1274 1275 ACPI_STATUS 1276 AcpiOsWritePort ( 1277 ACPI_IO_ADDRESS Address, 1278 UINT32 Value, 1279 UINT32 Width) 1280 { 1281 ACPI_FUNCTION_NAME (OsWritePort); 1282 1283 1284 if ((Width == 8) || (Width == 16) || (Width == 32)) 1285 { 1286 return (AE_OK); 1287 } 1288 1289 ACPI_ERROR ((AE_INFO, "Bad width parameter: %X", Width)); 1290 return (AE_BAD_PARAMETER); 1291 } 1292 1293 1294 /****************************************************************************** 1295 * 1296 * FUNCTION: AcpiOsReadMemory 1297 * 1298 * PARAMETERS: Address - Physical Memory Address to read 1299 * Value - Where value is placed 1300 * Width - Number of bits (8,16,32, or 64) 1301 * 1302 * RETURN: Value read from physical memory address. Always returned 1303 * as a 64-bit integer, regardless of the read width. 1304 * 1305 * DESCRIPTION: Read data from a physical memory address 1306 * 1307 *****************************************************************************/ 1308 1309 ACPI_STATUS 1310 AcpiOsReadMemory ( 1311 ACPI_PHYSICAL_ADDRESS Address, 1312 UINT64 *Value, 1313 UINT32 Width) 1314 { 1315 1316 switch (Width) 1317 { 1318 case 8: 1319 case 16: 1320 case 32: 1321 case 64: 1322 1323 *Value = 0; 1324 break; 1325 1326 default: 1327 1328 return (AE_BAD_PARAMETER); 1329 break; 1330 } 1331 1332 return (AE_OK); 1333 } 1334 1335 1336 /****************************************************************************** 1337 * 1338 * FUNCTION: AcpiOsWriteMemory 1339 * 1340 * PARAMETERS: Address - Physical Memory Address to write 1341 * Value - Value to write 1342 * Width - Number of bits (8,16,32, or 64) 1343 * 1344 * RETURN: None 1345 * 1346 * DESCRIPTION: Write data to a physical memory address 1347 * 1348 *****************************************************************************/ 1349 1350 ACPI_STATUS 1351 AcpiOsWriteMemory ( 1352 ACPI_PHYSICAL_ADDRESS Address, 1353 UINT64 Value, 1354 UINT32 Width) 1355 { 1356 1357 return (AE_OK); 1358 } 1359 1360 1361 /****************************************************************************** 1362 * 1363 * FUNCTION: AcpiOsSignal 1364 * 1365 * PARAMETERS: Function - ACPICA 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 1399 /****************************************************************************** 1400 * 1401 * FUNCTION: Local cache interfaces 1402 * 1403 * DESCRIPTION: Implements cache interfaces via malloc/free for testing 1404 * purposes only. 1405 * 1406 *****************************************************************************/ 1407 1408 #ifndef ACPI_USE_LOCAL_CACHE 1409 1410 ACPI_STATUS 1411 AcpiOsCreateCache ( 1412 char *CacheName, 1413 UINT16 ObjectSize, 1414 UINT16 MaxDepth, 1415 ACPI_CACHE_T **ReturnCache) 1416 { 1417 ACPI_MEMORY_LIST *NewCache; 1418 1419 1420 NewCache = malloc (sizeof (ACPI_MEMORY_LIST)); 1421 if (!NewCache) 1422 { 1423 return (AE_NO_MEMORY); 1424 } 1425 1426 memset (NewCache, 0, sizeof (ACPI_MEMORY_LIST)); 1427 NewCache->ListName = CacheName; 1428 NewCache->ObjectSize = ObjectSize; 1429 NewCache->MaxDepth = MaxDepth; 1430 1431 *ReturnCache = (ACPI_CACHE_T) NewCache; 1432 return (AE_OK); 1433 } 1434 1435 ACPI_STATUS 1436 AcpiOsDeleteCache ( 1437 ACPI_CACHE_T *Cache) 1438 { 1439 free (Cache); 1440 return (AE_OK); 1441 } 1442 1443 ACPI_STATUS 1444 AcpiOsPurgeCache ( 1445 ACPI_CACHE_T *Cache) 1446 { 1447 return (AE_OK); 1448 } 1449 1450 void * 1451 AcpiOsAcquireObject ( 1452 ACPI_CACHE_T *Cache) 1453 { 1454 void *NewObject; 1455 1456 NewObject = malloc (((ACPI_MEMORY_LIST *) Cache)->ObjectSize); 1457 memset (NewObject, 0, ((ACPI_MEMORY_LIST *) Cache)->ObjectSize); 1458 1459 return (NewObject); 1460 } 1461 1462 ACPI_STATUS 1463 AcpiOsReleaseObject ( 1464 ACPI_CACHE_T *Cache, 1465 void *Object) 1466 { 1467 free (Object); 1468 return (AE_OK); 1469 } 1470 1471 #endif /* ACPI_USE_LOCAL_CACHE */ 1472 1473 1474 /* Optional multi-thread support */ 1475 1476 #ifndef ACPI_SINGLE_THREADED 1477 /****************************************************************************** 1478 * 1479 * FUNCTION: AcpiOsGetThreadId 1480 * 1481 * PARAMETERS: None 1482 * 1483 * RETURN: Id of the running thread 1484 * 1485 * DESCRIPTION: Get the Id of the current (running) thread 1486 * 1487 *****************************************************************************/ 1488 1489 ACPI_THREAD_ID 1490 AcpiOsGetThreadId ( 1491 void) 1492 { 1493 DWORD ThreadId; 1494 1495 /* Ensure ID is never 0 */ 1496 1497 ThreadId = GetCurrentThreadId (); 1498 return ((ACPI_THREAD_ID) (ThreadId + 1)); 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 1523 _beginthread (Function, (unsigned) 0, Context); 1524 return (0); 1525 } 1526 1527 #else /* ACPI_SINGLE_THREADED */ 1528 ACPI_THREAD_ID 1529 AcpiOsGetThreadId ( 1530 void) 1531 { 1532 return (1); 1533 } 1534 1535 ACPI_STATUS 1536 AcpiOsExecute ( 1537 ACPI_EXECUTE_TYPE Type, 1538 ACPI_OSD_EXEC_CALLBACK Function, 1539 void *Context) 1540 { 1541 1542 Function (Context); 1543 return (AE_OK); 1544 } 1545 1546 #endif /* ACPI_SINGLE_THREADED */ 1547 1548 1549 /****************************************************************************** 1550 * 1551 * FUNCTION: AcpiOsWaitEventsComplete 1552 * 1553 * PARAMETERS: None 1554 * 1555 * RETURN: None 1556 * 1557 * DESCRIPTION: Wait for all asynchronous events to complete. This 1558 * implementation does nothing. 1559 * 1560 *****************************************************************************/ 1561 1562 void 1563 AcpiOsWaitEventsComplete ( 1564 void) 1565 { 1566 1567 return; 1568 } 1569