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