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