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 631 return (Mem); 632 } 633 634 635 #ifdef USE_NATIVE_ALLOCATE_ZEROED 636 /****************************************************************************** 637 * 638 * FUNCTION: AcpiOsAllocateZeroed 639 * 640 * PARAMETERS: Size - Amount to allocate, in bytes 641 * 642 * RETURN: Pointer to the new allocation. Null on error. 643 * 644 * DESCRIPTION: Allocate and zero memory. Algorithm is dependent on the OS. 645 * 646 *****************************************************************************/ 647 648 void * 649 AcpiOsAllocateZeroed ( 650 ACPI_SIZE Size) 651 { 652 void *Mem; 653 654 655 Mem = (void *) calloc (1, (size_t) Size); 656 657 return (Mem); 658 } 659 #endif 660 661 662 /****************************************************************************** 663 * 664 * FUNCTION: AcpiOsFree 665 * 666 * PARAMETERS: Mem - Pointer to previously allocated memory 667 * 668 * RETURN: None. 669 * 670 * DESCRIPTION: Free memory allocated via AcpiOsAllocate 671 * 672 *****************************************************************************/ 673 674 void 675 AcpiOsFree ( 676 void *Mem) 677 { 678 679 free (Mem); 680 } 681 682 683 #ifdef ACPI_SINGLE_THREADED 684 /****************************************************************************** 685 * 686 * FUNCTION: Semaphore stub functions 687 * 688 * DESCRIPTION: Stub functions used for single-thread applications that do 689 * not require semaphore synchronization. Full implementations 690 * of these functions appear after the stubs. 691 * 692 *****************************************************************************/ 693 694 ACPI_STATUS 695 AcpiOsCreateSemaphore ( 696 UINT32 MaxUnits, 697 UINT32 InitialUnits, 698 ACPI_HANDLE *OutHandle) 699 { 700 *OutHandle = (ACPI_HANDLE) 1; 701 return (AE_OK); 702 } 703 704 ACPI_STATUS 705 AcpiOsDeleteSemaphore ( 706 ACPI_HANDLE Handle) 707 { 708 return (AE_OK); 709 } 710 711 ACPI_STATUS 712 AcpiOsWaitSemaphore ( 713 ACPI_HANDLE Handle, 714 UINT32 Units, 715 UINT16 Timeout) 716 { 717 return (AE_OK); 718 } 719 720 ACPI_STATUS 721 AcpiOsSignalSemaphore ( 722 ACPI_HANDLE Handle, 723 UINT32 Units) 724 { 725 return (AE_OK); 726 } 727 728 #else 729 /****************************************************************************** 730 * 731 * FUNCTION: AcpiOsCreateSemaphore 732 * 733 * PARAMETERS: MaxUnits - Maximum units that can be sent 734 * InitialUnits - Units to be assigned to the new semaphore 735 * OutHandle - Where a handle will be returned 736 * 737 * RETURN: Status 738 * 739 * DESCRIPTION: Create an OS semaphore 740 * 741 *****************************************************************************/ 742 743 ACPI_STATUS 744 AcpiOsCreateSemaphore ( 745 UINT32 MaxUnits, 746 UINT32 InitialUnits, 747 ACPI_SEMAPHORE *OutHandle) 748 { 749 void *Mutex; 750 UINT32 i; 751 752 ACPI_FUNCTION_NAME (OsCreateSemaphore); 753 754 755 if (MaxUnits == ACPI_UINT32_MAX) 756 { 757 MaxUnits = 255; 758 } 759 760 if (InitialUnits == ACPI_UINT32_MAX) 761 { 762 InitialUnits = MaxUnits; 763 } 764 765 if (InitialUnits > MaxUnits) 766 { 767 return (AE_BAD_PARAMETER); 768 } 769 770 /* Find an empty slot */ 771 772 for (i = 0; i < ACPI_OS_MAX_SEMAPHORES; i++) 773 { 774 if (!AcpiGbl_Semaphores[i].OsHandle) 775 { 776 break; 777 } 778 } 779 if (i >= ACPI_OS_MAX_SEMAPHORES) 780 { 781 ACPI_EXCEPTION ((AE_INFO, AE_LIMIT, 782 "Reached max semaphores (%u), could not create", ACPI_OS_MAX_SEMAPHORES)); 783 return (AE_LIMIT); 784 } 785 786 /* Create an OS semaphore */ 787 788 Mutex = CreateSemaphore (NULL, InitialUnits, MaxUnits, NULL); 789 if (!Mutex) 790 { 791 ACPI_ERROR ((AE_INFO, "Could not create semaphore")); 792 return (AE_NO_MEMORY); 793 } 794 795 AcpiGbl_Semaphores[i].MaxUnits = (UINT16) MaxUnits; 796 AcpiGbl_Semaphores[i].CurrentUnits = (UINT16) InitialUnits; 797 AcpiGbl_Semaphores[i].OsHandle = Mutex; 798 799 ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Handle=%u, Max=%u, Current=%u, OsHandle=%p\n", 800 i, MaxUnits, InitialUnits, Mutex)); 801 802 *OutHandle = (void *) i; 803 return (AE_OK); 804 } 805 806 807 /****************************************************************************** 808 * 809 * FUNCTION: AcpiOsDeleteSemaphore 810 * 811 * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore 812 * 813 * RETURN: Status 814 * 815 * DESCRIPTION: Delete an OS semaphore 816 * 817 *****************************************************************************/ 818 819 ACPI_STATUS 820 AcpiOsDeleteSemaphore ( 821 ACPI_SEMAPHORE Handle) 822 { 823 UINT32 Index = (UINT32) Handle; 824 825 826 if ((Index >= ACPI_OS_MAX_SEMAPHORES) || 827 !AcpiGbl_Semaphores[Index].OsHandle) 828 { 829 return (AE_BAD_PARAMETER); 830 } 831 832 CloseHandle (AcpiGbl_Semaphores[Index].OsHandle); 833 AcpiGbl_Semaphores[Index].OsHandle = NULL; 834 return (AE_OK); 835 } 836 837 838 /****************************************************************************** 839 * 840 * FUNCTION: AcpiOsWaitSemaphore 841 * 842 * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore 843 * Units - How many units to wait for 844 * Timeout - How long to wait 845 * 846 * RETURN: Status 847 * 848 * DESCRIPTION: Wait for units 849 * 850 *****************************************************************************/ 851 852 ACPI_STATUS 853 AcpiOsWaitSemaphore ( 854 ACPI_SEMAPHORE Handle, 855 UINT32 Units, 856 UINT16 Timeout) 857 { 858 UINT32 Index = (UINT32) Handle; 859 UINT32 WaitStatus; 860 UINT32 OsTimeout = Timeout; 861 862 863 ACPI_FUNCTION_ENTRY (); 864 865 866 if ((Index >= ACPI_OS_MAX_SEMAPHORES) || 867 !AcpiGbl_Semaphores[Index].OsHandle) 868 { 869 return (AE_BAD_PARAMETER); 870 } 871 872 if (Units > 1) 873 { 874 printf ("WaitSemaphore: Attempt to receive %u units\n", Units); 875 return (AE_NOT_IMPLEMENTED); 876 } 877 878 if (Timeout == ACPI_WAIT_FOREVER) 879 { 880 OsTimeout = INFINITE; 881 if (AcpiGbl_DebugTimeout) 882 { 883 /* The debug timeout will prevent hang conditions */ 884 885 OsTimeout = ACPI_OS_DEBUG_TIMEOUT; 886 } 887 } 888 else 889 { 890 /* Add 10ms to account for clock tick granularity */ 891 892 OsTimeout += 10; 893 } 894 895 WaitStatus = WaitForSingleObject (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 return (AE_TIME); 905 } 906 907 if (AcpiGbl_Semaphores[Index].CurrentUnits == 0) 908 { 909 ACPI_ERROR ((AE_INFO, "%s - No unit received. Timeout 0x%X, OS_Status 0x%X", 910 AcpiUtGetMutexName (Index), Timeout, WaitStatus)); 911 912 return (AE_OK); 913 } 914 915 AcpiGbl_Semaphores[Index].CurrentUnits--; 916 return (AE_OK); 917 } 918 919 920 /****************************************************************************** 921 * 922 * FUNCTION: AcpiOsSignalSemaphore 923 * 924 * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore 925 * Units - Number of units to send 926 * 927 * RETURN: Status 928 * 929 * DESCRIPTION: Send units 930 * 931 *****************************************************************************/ 932 933 ACPI_STATUS 934 AcpiOsSignalSemaphore ( 935 ACPI_SEMAPHORE Handle, 936 UINT32 Units) 937 { 938 UINT32 Index = (UINT32) Handle; 939 940 941 ACPI_FUNCTION_ENTRY (); 942 943 944 if (Index >= ACPI_OS_MAX_SEMAPHORES) 945 { 946 printf ("SignalSemaphore: Index/Handle out of range: %2.2X\n", Index); 947 return (AE_BAD_PARAMETER); 948 } 949 950 if (!AcpiGbl_Semaphores[Index].OsHandle) 951 { 952 printf ("SignalSemaphore: Null OS handle, Index %2.2X\n", Index); 953 return (AE_BAD_PARAMETER); 954 } 955 956 if (Units > 1) 957 { 958 printf ("SignalSemaphore: Attempt to signal %u units, Index %2.2X\n", Units, Index); 959 return (AE_NOT_IMPLEMENTED); 960 } 961 962 if ((AcpiGbl_Semaphores[Index].CurrentUnits + 1) > 963 AcpiGbl_Semaphores[Index].MaxUnits) 964 { 965 ACPI_ERROR ((AE_INFO, 966 "Oversignalled semaphore[%u]! Current %u Max %u", 967 Index, AcpiGbl_Semaphores[Index].CurrentUnits, 968 AcpiGbl_Semaphores[Index].MaxUnits)); 969 970 return (AE_LIMIT); 971 } 972 973 AcpiGbl_Semaphores[Index].CurrentUnits++; 974 ReleaseSemaphore (AcpiGbl_Semaphores[Index].OsHandle, Units, NULL); 975 976 return (AE_OK); 977 } 978 979 #endif /* ACPI_SINGLE_THREADED */ 980 981 982 /****************************************************************************** 983 * 984 * FUNCTION: Spinlock interfaces 985 * 986 * DESCRIPTION: Map these interfaces to semaphore interfaces 987 * 988 *****************************************************************************/ 989 990 ACPI_STATUS 991 AcpiOsCreateLock ( 992 ACPI_SPINLOCK *OutHandle) 993 { 994 return (AcpiOsCreateSemaphore (1, 1, OutHandle)); 995 } 996 997 void 998 AcpiOsDeleteLock ( 999 ACPI_SPINLOCK Handle) 1000 { 1001 AcpiOsDeleteSemaphore (Handle); 1002 } 1003 1004 ACPI_CPU_FLAGS 1005 AcpiOsAcquireLock ( 1006 ACPI_SPINLOCK Handle) 1007 { 1008 AcpiOsWaitSemaphore (Handle, 1, 0xFFFF); 1009 return (0); 1010 } 1011 1012 void 1013 AcpiOsReleaseLock ( 1014 ACPI_SPINLOCK Handle, 1015 ACPI_CPU_FLAGS Flags) 1016 { 1017 AcpiOsSignalSemaphore (Handle, 1); 1018 } 1019 1020 1021 #if ACPI_FUTURE_IMPLEMENTATION 1022 1023 /* Mutex interfaces, just implement with a semaphore */ 1024 1025 ACPI_STATUS 1026 AcpiOsCreateMutex ( 1027 ACPI_MUTEX *OutHandle) 1028 { 1029 return (AcpiOsCreateSemaphore (1, 1, OutHandle)); 1030 } 1031 1032 void 1033 AcpiOsDeleteMutex ( 1034 ACPI_MUTEX Handle) 1035 { 1036 AcpiOsDeleteSemaphore (Handle); 1037 } 1038 1039 ACPI_STATUS 1040 AcpiOsAcquireMutex ( 1041 ACPI_MUTEX Handle, 1042 UINT16 Timeout) 1043 { 1044 AcpiOsWaitSemaphore (Handle, 1, Timeout); 1045 return (0); 1046 } 1047 1048 void 1049 AcpiOsReleaseMutex ( 1050 ACPI_MUTEX Handle) 1051 { 1052 AcpiOsSignalSemaphore (Handle, 1); 1053 } 1054 #endif 1055 1056 1057 /****************************************************************************** 1058 * 1059 * FUNCTION: AcpiOsInstallInterruptHandler 1060 * 1061 * PARAMETERS: InterruptNumber - Level handler should respond to. 1062 * ServiceRoutine - Address of the ACPI interrupt handler 1063 * Context - User context 1064 * 1065 * RETURN: Handle to the newly installed handler. 1066 * 1067 * DESCRIPTION: Install an interrupt handler. Used to install the ACPI 1068 * OS-independent handler. 1069 * 1070 *****************************************************************************/ 1071 1072 UINT32 1073 AcpiOsInstallInterruptHandler ( 1074 UINT32 InterruptNumber, 1075 ACPI_OSD_HANDLER ServiceRoutine, 1076 void *Context) 1077 { 1078 1079 return (AE_OK); 1080 } 1081 1082 1083 /****************************************************************************** 1084 * 1085 * FUNCTION: AcpiOsRemoveInterruptHandler 1086 * 1087 * PARAMETERS: Handle - Returned when handler was installed 1088 * 1089 * RETURN: Status 1090 * 1091 * DESCRIPTION: Uninstalls an interrupt handler. 1092 * 1093 *****************************************************************************/ 1094 1095 ACPI_STATUS 1096 AcpiOsRemoveInterruptHandler ( 1097 UINT32 InterruptNumber, 1098 ACPI_OSD_HANDLER ServiceRoutine) 1099 { 1100 1101 return (AE_OK); 1102 } 1103 1104 1105 /****************************************************************************** 1106 * 1107 * FUNCTION: AcpiOsStall 1108 * 1109 * PARAMETERS: Microseconds - Time to stall 1110 * 1111 * RETURN: None. Blocks until stall is completed. 1112 * 1113 * DESCRIPTION: Sleep at microsecond granularity 1114 * 1115 *****************************************************************************/ 1116 1117 void 1118 AcpiOsStall ( 1119 UINT32 Microseconds) 1120 { 1121 1122 Sleep ((Microseconds / ACPI_USEC_PER_MSEC) + 1); 1123 return; 1124 } 1125 1126 1127 /****************************************************************************** 1128 * 1129 * FUNCTION: AcpiOsSleep 1130 * 1131 * PARAMETERS: Milliseconds - Time to sleep 1132 * 1133 * RETURN: None. Blocks until sleep is completed. 1134 * 1135 * DESCRIPTION: Sleep at millisecond granularity 1136 * 1137 *****************************************************************************/ 1138 1139 void 1140 AcpiOsSleep ( 1141 UINT64 Milliseconds) 1142 { 1143 1144 /* Add 10ms to account for clock tick granularity */ 1145 1146 Sleep (((unsigned long) Milliseconds) + 10); 1147 return; 1148 } 1149 1150 1151 /****************************************************************************** 1152 * 1153 * FUNCTION: AcpiOsReadPciConfiguration 1154 * 1155 * PARAMETERS: PciId - Seg/Bus/Dev 1156 * Register - Device Register 1157 * Value - Buffer where value is placed 1158 * Width - Number of bits 1159 * 1160 * RETURN: Status 1161 * 1162 * DESCRIPTION: Read data from PCI configuration space 1163 * 1164 *****************************************************************************/ 1165 1166 ACPI_STATUS 1167 AcpiOsReadPciConfiguration ( 1168 ACPI_PCI_ID *PciId, 1169 UINT32 Register, 1170 UINT64 *Value, 1171 UINT32 Width) 1172 { 1173 1174 *Value = 0; 1175 return (AE_OK); 1176 } 1177 1178 1179 /****************************************************************************** 1180 * 1181 * FUNCTION: AcpiOsWritePciConfiguration 1182 * 1183 * PARAMETERS: PciId - Seg/Bus/Dev 1184 * Register - Device Register 1185 * Value - Value to be written 1186 * Width - Number of bits 1187 * 1188 * RETURN: Status 1189 * 1190 * DESCRIPTION: Write data to PCI configuration space 1191 * 1192 *****************************************************************************/ 1193 1194 ACPI_STATUS 1195 AcpiOsWritePciConfiguration ( 1196 ACPI_PCI_ID *PciId, 1197 UINT32 Register, 1198 UINT64 Value, 1199 UINT32 Width) 1200 { 1201 1202 return (AE_OK); 1203 } 1204 1205 1206 /****************************************************************************** 1207 * 1208 * FUNCTION: AcpiOsReadPort 1209 * 1210 * PARAMETERS: Address - Address of I/O port/register to read 1211 * Value - Where value is placed 1212 * Width - Number of bits 1213 * 1214 * RETURN: Value read from port 1215 * 1216 * DESCRIPTION: Read data from an I/O port or register 1217 * 1218 *****************************************************************************/ 1219 1220 ACPI_STATUS 1221 AcpiOsReadPort ( 1222 ACPI_IO_ADDRESS Address, 1223 UINT32 *Value, 1224 UINT32 Width) 1225 { 1226 ACPI_FUNCTION_NAME (OsReadPort); 1227 1228 1229 switch (Width) 1230 { 1231 case 8: 1232 1233 *Value = 0xFF; 1234 break; 1235 1236 case 16: 1237 1238 *Value = 0xFFFF; 1239 break; 1240 1241 case 32: 1242 1243 *Value = 0xFFFFFFFF; 1244 break; 1245 1246 default: 1247 1248 ACPI_ERROR ((AE_INFO, "Bad width parameter: %X", Width)); 1249 return (AE_BAD_PARAMETER); 1250 } 1251 1252 return (AE_OK); 1253 } 1254 1255 1256 /****************************************************************************** 1257 * 1258 * FUNCTION: AcpiOsWritePort 1259 * 1260 * PARAMETERS: Address - Address of I/O port/register to write 1261 * Value - Value to write 1262 * Width - Number of bits 1263 * 1264 * RETURN: None 1265 * 1266 * DESCRIPTION: Write data to an I/O port or register 1267 * 1268 *****************************************************************************/ 1269 1270 ACPI_STATUS 1271 AcpiOsWritePort ( 1272 ACPI_IO_ADDRESS Address, 1273 UINT32 Value, 1274 UINT32 Width) 1275 { 1276 ACPI_FUNCTION_NAME (OsWritePort); 1277 1278 1279 if ((Width == 8) || (Width == 16) || (Width == 32)) 1280 { 1281 return (AE_OK); 1282 } 1283 1284 ACPI_ERROR ((AE_INFO, "Bad width parameter: %X", Width)); 1285 return (AE_BAD_PARAMETER); 1286 } 1287 1288 1289 /****************************************************************************** 1290 * 1291 * FUNCTION: AcpiOsReadMemory 1292 * 1293 * PARAMETERS: Address - Physical Memory Address to read 1294 * Value - Where value is placed 1295 * Width - Number of bits (8,16,32, or 64) 1296 * 1297 * RETURN: Value read from physical memory address. Always returned 1298 * as a 64-bit integer, regardless of the read width. 1299 * 1300 * DESCRIPTION: Read data from a physical memory address 1301 * 1302 *****************************************************************************/ 1303 1304 ACPI_STATUS 1305 AcpiOsReadMemory ( 1306 ACPI_PHYSICAL_ADDRESS Address, 1307 UINT64 *Value, 1308 UINT32 Width) 1309 { 1310 1311 switch (Width) 1312 { 1313 case 8: 1314 case 16: 1315 case 32: 1316 case 64: 1317 1318 *Value = 0; 1319 break; 1320 1321 default: 1322 1323 return (AE_BAD_PARAMETER); 1324 break; 1325 } 1326 1327 return (AE_OK); 1328 } 1329 1330 1331 /****************************************************************************** 1332 * 1333 * FUNCTION: AcpiOsWriteMemory 1334 * 1335 * PARAMETERS: Address - Physical Memory Address to write 1336 * Value - Value to write 1337 * Width - Number of bits (8,16,32, or 64) 1338 * 1339 * RETURN: None 1340 * 1341 * DESCRIPTION: Write data to a physical memory address 1342 * 1343 *****************************************************************************/ 1344 1345 ACPI_STATUS 1346 AcpiOsWriteMemory ( 1347 ACPI_PHYSICAL_ADDRESS Address, 1348 UINT64 Value, 1349 UINT32 Width) 1350 { 1351 1352 return (AE_OK); 1353 } 1354 1355 1356 /****************************************************************************** 1357 * 1358 * FUNCTION: AcpiOsSignal 1359 * 1360 * PARAMETERS: Function - ACPICA signal function code 1361 * Info - Pointer to function-dependent structure 1362 * 1363 * RETURN: Status 1364 * 1365 * DESCRIPTION: Miscellaneous functions. Example implementation only. 1366 * 1367 *****************************************************************************/ 1368 1369 ACPI_STATUS 1370 AcpiOsSignal ( 1371 UINT32 Function, 1372 void *Info) 1373 { 1374 1375 switch (Function) 1376 { 1377 case ACPI_SIGNAL_FATAL: 1378 1379 break; 1380 1381 case ACPI_SIGNAL_BREAKPOINT: 1382 1383 break; 1384 1385 default: 1386 1387 break; 1388 } 1389 1390 return (AE_OK); 1391 } 1392 1393 1394 /****************************************************************************** 1395 * 1396 * FUNCTION: Local cache interfaces 1397 * 1398 * DESCRIPTION: Implements cache interfaces via malloc/free for testing 1399 * purposes only. 1400 * 1401 *****************************************************************************/ 1402 1403 #ifndef ACPI_USE_LOCAL_CACHE 1404 1405 ACPI_STATUS 1406 AcpiOsCreateCache ( 1407 char *CacheName, 1408 UINT16 ObjectSize, 1409 UINT16 MaxDepth, 1410 ACPI_CACHE_T **ReturnCache) 1411 { 1412 ACPI_MEMORY_LIST *NewCache; 1413 1414 1415 NewCache = malloc (sizeof (ACPI_MEMORY_LIST)); 1416 if (!NewCache) 1417 { 1418 return (AE_NO_MEMORY); 1419 } 1420 1421 memset (NewCache, 0, sizeof (ACPI_MEMORY_LIST)); 1422 NewCache->ListName = CacheName; 1423 NewCache->ObjectSize = ObjectSize; 1424 NewCache->MaxDepth = MaxDepth; 1425 1426 *ReturnCache = (ACPI_CACHE_T) NewCache; 1427 return (AE_OK); 1428 } 1429 1430 ACPI_STATUS 1431 AcpiOsDeleteCache ( 1432 ACPI_CACHE_T *Cache) 1433 { 1434 free (Cache); 1435 return (AE_OK); 1436 } 1437 1438 ACPI_STATUS 1439 AcpiOsPurgeCache ( 1440 ACPI_CACHE_T *Cache) 1441 { 1442 return (AE_OK); 1443 } 1444 1445 void * 1446 AcpiOsAcquireObject ( 1447 ACPI_CACHE_T *Cache) 1448 { 1449 void *NewObject; 1450 1451 NewObject = malloc (((ACPI_MEMORY_LIST *) Cache)->ObjectSize); 1452 memset (NewObject, 0, ((ACPI_MEMORY_LIST *) Cache)->ObjectSize); 1453 1454 return (NewObject); 1455 } 1456 1457 ACPI_STATUS 1458 AcpiOsReleaseObject ( 1459 ACPI_CACHE_T *Cache, 1460 void *Object) 1461 { 1462 free (Object); 1463 return (AE_OK); 1464 } 1465 1466 #endif /* ACPI_USE_LOCAL_CACHE */ 1467 1468 1469 /* Optional multi-thread support */ 1470 1471 #ifndef ACPI_SINGLE_THREADED 1472 /****************************************************************************** 1473 * 1474 * FUNCTION: AcpiOsGetThreadId 1475 * 1476 * PARAMETERS: None 1477 * 1478 * RETURN: Id of the running thread 1479 * 1480 * DESCRIPTION: Get the Id of the current (running) thread 1481 * 1482 *****************************************************************************/ 1483 1484 ACPI_THREAD_ID 1485 AcpiOsGetThreadId ( 1486 void) 1487 { 1488 DWORD ThreadId; 1489 1490 /* Ensure ID is never 0 */ 1491 1492 ThreadId = GetCurrentThreadId (); 1493 return ((ACPI_THREAD_ID) (ThreadId + 1)); 1494 } 1495 1496 1497 /****************************************************************************** 1498 * 1499 * FUNCTION: AcpiOsExecute 1500 * 1501 * PARAMETERS: Type - Type of execution 1502 * Function - Address of the function to execute 1503 * Context - Passed as a parameter to the function 1504 * 1505 * RETURN: Status 1506 * 1507 * DESCRIPTION: Execute a new thread 1508 * 1509 *****************************************************************************/ 1510 1511 ACPI_STATUS 1512 AcpiOsExecute ( 1513 ACPI_EXECUTE_TYPE Type, 1514 ACPI_OSD_EXEC_CALLBACK Function, 1515 void *Context) 1516 { 1517 1518 _beginthread (Function, (unsigned) 0, Context); 1519 return (0); 1520 } 1521 1522 #else /* ACPI_SINGLE_THREADED */ 1523 ACPI_THREAD_ID 1524 AcpiOsGetThreadId ( 1525 void) 1526 { 1527 return (1); 1528 } 1529 1530 ACPI_STATUS 1531 AcpiOsExecute ( 1532 ACPI_EXECUTE_TYPE Type, 1533 ACPI_OSD_EXEC_CALLBACK Function, 1534 void *Context) 1535 { 1536 1537 Function (Context); 1538 1539 return (AE_OK); 1540 } 1541 1542 #endif /* ACPI_SINGLE_THREADED */ 1543 1544 1545 /****************************************************************************** 1546 * 1547 * FUNCTION: AcpiOsWaitEventsComplete 1548 * 1549 * PARAMETERS: None 1550 * 1551 * RETURN: None 1552 * 1553 * DESCRIPTION: Wait for all asynchronous events to complete. This 1554 * implementation does nothing. 1555 * 1556 *****************************************************************************/ 1557 1558 void 1559 AcpiOsWaitEventsComplete ( 1560 void) 1561 { 1562 return; 1563 } 1564