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