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