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