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