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