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