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