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