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