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