kernel: Sync ACPICA with Intel's version 20140627.
[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
631     return (Mem);
632 }
633
634
635 #ifdef USE_NATIVE_ALLOCATE_ZEROED
636 /******************************************************************************
637  *
638  * FUNCTION:    AcpiOsAllocateZeroed
639  *
640  * PARAMETERS:  Size                - Amount to allocate, in bytes
641  *
642  * RETURN:      Pointer to the new allocation. Null on error.
643  *
644  * DESCRIPTION: Allocate and zero memory. Algorithm is dependent on the OS.
645  *
646  *****************************************************************************/
647
648 void *
649 AcpiOsAllocateZeroed (
650     ACPI_SIZE               Size)
651 {
652     void                    *Mem;
653
654
655     Mem = (void *) calloc (1, (size_t) Size);
656
657     return (Mem);
658 }
659 #endif
660
661
662 /******************************************************************************
663  *
664  * FUNCTION:    AcpiOsFree
665  *
666  * PARAMETERS:  Mem                 - Pointer to previously allocated memory
667  *
668  * RETURN:      None.
669  *
670  * DESCRIPTION: Free memory allocated via AcpiOsAllocate
671  *
672  *****************************************************************************/
673
674 void
675 AcpiOsFree (
676     void                    *Mem)
677 {
678
679     free (Mem);
680 }
681
682
683 #ifdef ACPI_SINGLE_THREADED
684 /******************************************************************************
685  *
686  * FUNCTION:    Semaphore stub functions
687  *
688  * DESCRIPTION: Stub functions used for single-thread applications that do
689  *              not require semaphore synchronization. Full implementations
690  *              of these functions appear after the stubs.
691  *
692  *****************************************************************************/
693
694 ACPI_STATUS
695 AcpiOsCreateSemaphore (
696     UINT32              MaxUnits,
697     UINT32              InitialUnits,
698     ACPI_HANDLE         *OutHandle)
699 {
700     *OutHandle = (ACPI_HANDLE) 1;
701     return (AE_OK);
702 }
703
704 ACPI_STATUS
705 AcpiOsDeleteSemaphore (
706     ACPI_HANDLE         Handle)
707 {
708     return (AE_OK);
709 }
710
711 ACPI_STATUS
712 AcpiOsWaitSemaphore (
713     ACPI_HANDLE         Handle,
714     UINT32              Units,
715     UINT16              Timeout)
716 {
717     return (AE_OK);
718 }
719
720 ACPI_STATUS
721 AcpiOsSignalSemaphore (
722     ACPI_HANDLE         Handle,
723     UINT32              Units)
724 {
725     return (AE_OK);
726 }
727
728 #else
729 /******************************************************************************
730  *
731  * FUNCTION:    AcpiOsCreateSemaphore
732  *
733  * PARAMETERS:  MaxUnits            - Maximum units that can be sent
734  *              InitialUnits        - Units to be assigned to the new semaphore
735  *              OutHandle           - Where a handle will be returned
736  *
737  * RETURN:      Status
738  *
739  * DESCRIPTION: Create an OS semaphore
740  *
741  *****************************************************************************/
742
743 ACPI_STATUS
744 AcpiOsCreateSemaphore (
745     UINT32              MaxUnits,
746     UINT32              InitialUnits,
747     ACPI_SEMAPHORE      *OutHandle)
748 {
749     void                *Mutex;
750     UINT32              i;
751
752     ACPI_FUNCTION_NAME (OsCreateSemaphore);
753
754
755     if (MaxUnits == ACPI_UINT32_MAX)
756     {
757         MaxUnits = 255;
758     }
759
760     if (InitialUnits == ACPI_UINT32_MAX)
761     {
762         InitialUnits = MaxUnits;
763     }
764
765     if (InitialUnits > MaxUnits)
766     {
767         return (AE_BAD_PARAMETER);
768     }
769
770     /* Find an empty slot */
771
772     for (i = 0; i < ACPI_OS_MAX_SEMAPHORES; i++)
773     {
774         if (!AcpiGbl_Semaphores[i].OsHandle)
775         {
776             break;
777         }
778     }
779     if (i >= ACPI_OS_MAX_SEMAPHORES)
780     {
781         ACPI_EXCEPTION ((AE_INFO, AE_LIMIT,
782             "Reached max semaphores (%u), could not create", ACPI_OS_MAX_SEMAPHORES));
783         return (AE_LIMIT);
784     }
785
786     /* Create an OS semaphore */
787
788     Mutex = CreateSemaphore (NULL, InitialUnits, MaxUnits, NULL);
789     if (!Mutex)
790     {
791         ACPI_ERROR ((AE_INFO, "Could not create semaphore"));
792         return (AE_NO_MEMORY);
793     }
794
795     AcpiGbl_Semaphores[i].MaxUnits = (UINT16) MaxUnits;
796     AcpiGbl_Semaphores[i].CurrentUnits = (UINT16) InitialUnits;
797     AcpiGbl_Semaphores[i].OsHandle = Mutex;
798
799     ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Handle=%u, Max=%u, Current=%u, OsHandle=%p\n",
800             i, MaxUnits, InitialUnits, Mutex));
801
802     *OutHandle = (void *) i;
803     return (AE_OK);
804 }
805
806
807 /******************************************************************************
808  *
809  * FUNCTION:    AcpiOsDeleteSemaphore
810  *
811  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
812  *
813  * RETURN:      Status
814  *
815  * DESCRIPTION: Delete an OS semaphore
816  *
817  *****************************************************************************/
818
819 ACPI_STATUS
820 AcpiOsDeleteSemaphore (
821     ACPI_SEMAPHORE      Handle)
822 {
823     UINT32              Index = (UINT32) Handle;
824
825
826     if ((Index >= ACPI_OS_MAX_SEMAPHORES) ||
827         !AcpiGbl_Semaphores[Index].OsHandle)
828     {
829         return (AE_BAD_PARAMETER);
830     }
831
832     CloseHandle (AcpiGbl_Semaphores[Index].OsHandle);
833     AcpiGbl_Semaphores[Index].OsHandle = NULL;
834     return (AE_OK);
835 }
836
837
838 /******************************************************************************
839  *
840  * FUNCTION:    AcpiOsWaitSemaphore
841  *
842  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
843  *              Units               - How many units to wait for
844  *              Timeout             - How long to wait
845  *
846  * RETURN:      Status
847  *
848  * DESCRIPTION: Wait for units
849  *
850  *****************************************************************************/
851
852 ACPI_STATUS
853 AcpiOsWaitSemaphore (
854     ACPI_SEMAPHORE      Handle,
855     UINT32              Units,
856     UINT16              Timeout)
857 {
858     UINT32              Index = (UINT32) Handle;
859     UINT32              WaitStatus;
860     UINT32              OsTimeout = Timeout;
861
862
863     ACPI_FUNCTION_ENTRY ();
864
865
866     if ((Index >= ACPI_OS_MAX_SEMAPHORES) ||
867         !AcpiGbl_Semaphores[Index].OsHandle)
868     {
869         return (AE_BAD_PARAMETER);
870     }
871
872     if (Units > 1)
873     {
874         printf ("WaitSemaphore: Attempt to receive %u units\n", Units);
875         return (AE_NOT_IMPLEMENTED);
876     }
877
878     if (Timeout == ACPI_WAIT_FOREVER)
879     {
880         OsTimeout = INFINITE;
881         if (AcpiGbl_DebugTimeout)
882         {
883             /* The debug timeout will prevent hang conditions */
884
885             OsTimeout = ACPI_OS_DEBUG_TIMEOUT;
886         }
887     }
888     else
889     {
890         /* Add 10ms to account for clock tick granularity */
891
892         OsTimeout += 10;
893     }
894
895     WaitStatus = WaitForSingleObject (AcpiGbl_Semaphores[Index].OsHandle, OsTimeout);
896     if (WaitStatus == WAIT_TIMEOUT)
897     {
898         if (AcpiGbl_DebugTimeout)
899         {
900             ACPI_EXCEPTION ((AE_INFO, AE_TIME,
901                 "Debug timeout on semaphore 0x%04X (%ums)\n",
902                 Index, ACPI_OS_DEBUG_TIMEOUT));
903         }
904         return (AE_TIME);
905     }
906
907     if (AcpiGbl_Semaphores[Index].CurrentUnits == 0)
908     {
909         ACPI_ERROR ((AE_INFO, "%s - No unit received. Timeout 0x%X, OS_Status 0x%X",
910             AcpiUtGetMutexName (Index), Timeout, WaitStatus));
911
912         return (AE_OK);
913     }
914
915     AcpiGbl_Semaphores[Index].CurrentUnits--;
916     return (AE_OK);
917 }
918
919
920 /******************************************************************************
921  *
922  * FUNCTION:    AcpiOsSignalSemaphore
923  *
924  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
925  *              Units               - Number of units to send
926  *
927  * RETURN:      Status
928  *
929  * DESCRIPTION: Send units
930  *
931  *****************************************************************************/
932
933 ACPI_STATUS
934 AcpiOsSignalSemaphore (
935     ACPI_SEMAPHORE      Handle,
936     UINT32              Units)
937 {
938     UINT32              Index = (UINT32) Handle;
939
940
941     ACPI_FUNCTION_ENTRY ();
942
943
944     if (Index >= ACPI_OS_MAX_SEMAPHORES)
945     {
946         printf ("SignalSemaphore: Index/Handle out of range: %2.2X\n", Index);
947         return (AE_BAD_PARAMETER);
948     }
949
950     if (!AcpiGbl_Semaphores[Index].OsHandle)
951     {
952         printf ("SignalSemaphore: Null OS handle, Index %2.2X\n", Index);
953         return (AE_BAD_PARAMETER);
954     }
955
956     if (Units > 1)
957     {
958         printf ("SignalSemaphore: Attempt to signal %u units, Index %2.2X\n", Units, Index);
959         return (AE_NOT_IMPLEMENTED);
960     }
961
962     if ((AcpiGbl_Semaphores[Index].CurrentUnits + 1) >
963         AcpiGbl_Semaphores[Index].MaxUnits)
964     {
965         ACPI_ERROR ((AE_INFO,
966             "Oversignalled semaphore[%u]! Current %u Max %u",
967             Index, AcpiGbl_Semaphores[Index].CurrentUnits,
968             AcpiGbl_Semaphores[Index].MaxUnits));
969
970         return (AE_LIMIT);
971     }
972
973     AcpiGbl_Semaphores[Index].CurrentUnits++;
974     ReleaseSemaphore (AcpiGbl_Semaphores[Index].OsHandle, Units, NULL);
975
976     return (AE_OK);
977 }
978
979 #endif /* ACPI_SINGLE_THREADED */
980
981
982 /******************************************************************************
983  *
984  * FUNCTION:    Spinlock interfaces
985  *
986  * DESCRIPTION: Map these interfaces to semaphore interfaces
987  *
988  *****************************************************************************/
989
990 ACPI_STATUS
991 AcpiOsCreateLock (
992     ACPI_SPINLOCK           *OutHandle)
993 {
994     return (AcpiOsCreateSemaphore (1, 1, OutHandle));
995 }
996
997 void
998 AcpiOsDeleteLock (
999     ACPI_SPINLOCK           Handle)
1000 {
1001     AcpiOsDeleteSemaphore (Handle);
1002 }
1003
1004 ACPI_CPU_FLAGS
1005 AcpiOsAcquireLock (
1006     ACPI_SPINLOCK           Handle)
1007 {
1008     AcpiOsWaitSemaphore (Handle, 1, 0xFFFF);
1009     return (0);
1010 }
1011
1012 void
1013 AcpiOsReleaseLock (
1014     ACPI_SPINLOCK           Handle,
1015     ACPI_CPU_FLAGS          Flags)
1016 {
1017     AcpiOsSignalSemaphore (Handle, 1);
1018 }
1019
1020
1021 #if ACPI_FUTURE_IMPLEMENTATION
1022
1023 /* Mutex interfaces, just implement with a semaphore */
1024
1025 ACPI_STATUS
1026 AcpiOsCreateMutex (
1027     ACPI_MUTEX              *OutHandle)
1028 {
1029     return (AcpiOsCreateSemaphore (1, 1, OutHandle));
1030 }
1031
1032 void
1033 AcpiOsDeleteMutex (
1034     ACPI_MUTEX              Handle)
1035 {
1036     AcpiOsDeleteSemaphore (Handle);
1037 }
1038
1039 ACPI_STATUS
1040 AcpiOsAcquireMutex (
1041     ACPI_MUTEX              Handle,
1042     UINT16                  Timeout)
1043 {
1044     AcpiOsWaitSemaphore (Handle, 1, Timeout);
1045     return (0);
1046 }
1047
1048 void
1049 AcpiOsReleaseMutex (
1050     ACPI_MUTEX              Handle)
1051 {
1052     AcpiOsSignalSemaphore (Handle, 1);
1053 }
1054 #endif
1055
1056
1057 /******************************************************************************
1058  *
1059  * FUNCTION:    AcpiOsInstallInterruptHandler
1060  *
1061  * PARAMETERS:  InterruptNumber     - Level handler should respond to.
1062  *              ServiceRoutine      - Address of the ACPI interrupt handler
1063  *              Context             - User context
1064  *
1065  * RETURN:      Handle to the newly installed handler.
1066  *
1067  * DESCRIPTION: Install an interrupt handler. Used to install the ACPI
1068  *              OS-independent handler.
1069  *
1070  *****************************************************************************/
1071
1072 UINT32
1073 AcpiOsInstallInterruptHandler (
1074     UINT32                  InterruptNumber,
1075     ACPI_OSD_HANDLER        ServiceRoutine,
1076     void                    *Context)
1077 {
1078
1079     return (AE_OK);
1080 }
1081
1082
1083 /******************************************************************************
1084  *
1085  * FUNCTION:    AcpiOsRemoveInterruptHandler
1086  *
1087  * PARAMETERS:  Handle              - Returned when handler was installed
1088  *
1089  * RETURN:      Status
1090  *
1091  * DESCRIPTION: Uninstalls an interrupt handler.
1092  *
1093  *****************************************************************************/
1094
1095 ACPI_STATUS
1096 AcpiOsRemoveInterruptHandler (
1097     UINT32                  InterruptNumber,
1098     ACPI_OSD_HANDLER        ServiceRoutine)
1099 {
1100
1101     return (AE_OK);
1102 }
1103
1104
1105 /******************************************************************************
1106  *
1107  * FUNCTION:    AcpiOsStall
1108  *
1109  * PARAMETERS:  Microseconds        - Time to stall
1110  *
1111  * RETURN:      None. Blocks until stall is completed.
1112  *
1113  * DESCRIPTION: Sleep at microsecond granularity
1114  *
1115  *****************************************************************************/
1116
1117 void
1118 AcpiOsStall (
1119     UINT32                  Microseconds)
1120 {
1121
1122     Sleep ((Microseconds / ACPI_USEC_PER_MSEC) + 1);
1123     return;
1124 }
1125
1126
1127 /******************************************************************************
1128  *
1129  * FUNCTION:    AcpiOsSleep
1130  *
1131  * PARAMETERS:  Milliseconds        - Time to sleep
1132  *
1133  * RETURN:      None. Blocks until sleep is completed.
1134  *
1135  * DESCRIPTION: Sleep at millisecond granularity
1136  *
1137  *****************************************************************************/
1138
1139 void
1140 AcpiOsSleep (
1141     UINT64                  Milliseconds)
1142 {
1143
1144     /* Add 10ms to account for clock tick granularity */
1145
1146     Sleep (((unsigned long) Milliseconds) + 10);
1147     return;
1148 }
1149
1150
1151 /******************************************************************************
1152  *
1153  * FUNCTION:    AcpiOsReadPciConfiguration
1154  *
1155  * PARAMETERS:  PciId               - Seg/Bus/Dev
1156  *              Register            - Device Register
1157  *              Value               - Buffer where value is placed
1158  *              Width               - Number of bits
1159  *
1160  * RETURN:      Status
1161  *
1162  * DESCRIPTION: Read data from PCI configuration space
1163  *
1164  *****************************************************************************/
1165
1166 ACPI_STATUS
1167 AcpiOsReadPciConfiguration (
1168     ACPI_PCI_ID             *PciId,
1169     UINT32                  Register,
1170     UINT64                  *Value,
1171     UINT32                  Width)
1172 {
1173
1174     *Value = 0;
1175     return (AE_OK);
1176 }
1177
1178
1179 /******************************************************************************
1180  *
1181  * FUNCTION:    AcpiOsWritePciConfiguration
1182  *
1183  * PARAMETERS:  PciId               - Seg/Bus/Dev
1184  *              Register            - Device Register
1185  *              Value               - Value to be written
1186  *              Width               - Number of bits
1187  *
1188  * RETURN:      Status
1189  *
1190  * DESCRIPTION: Write data to PCI configuration space
1191  *
1192  *****************************************************************************/
1193
1194 ACPI_STATUS
1195 AcpiOsWritePciConfiguration (
1196     ACPI_PCI_ID             *PciId,
1197     UINT32                  Register,
1198     UINT64                  Value,
1199     UINT32                  Width)
1200 {
1201
1202     return (AE_OK);
1203 }
1204
1205
1206 /******************************************************************************
1207  *
1208  * FUNCTION:    AcpiOsReadPort
1209  *
1210  * PARAMETERS:  Address             - Address of I/O port/register to read
1211  *              Value               - Where value is placed
1212  *              Width               - Number of bits
1213  *
1214  * RETURN:      Value read from port
1215  *
1216  * DESCRIPTION: Read data from an I/O port or register
1217  *
1218  *****************************************************************************/
1219
1220 ACPI_STATUS
1221 AcpiOsReadPort (
1222     ACPI_IO_ADDRESS         Address,
1223     UINT32                  *Value,
1224     UINT32                  Width)
1225 {
1226     ACPI_FUNCTION_NAME (OsReadPort);
1227
1228
1229     switch (Width)
1230     {
1231     case 8:
1232
1233         *Value = 0xFF;
1234         break;
1235
1236     case 16:
1237
1238         *Value = 0xFFFF;
1239         break;
1240
1241     case 32:
1242
1243         *Value = 0xFFFFFFFF;
1244         break;
1245
1246     default:
1247
1248         ACPI_ERROR ((AE_INFO, "Bad width parameter: %X", Width));
1249         return (AE_BAD_PARAMETER);
1250     }
1251
1252     return (AE_OK);
1253 }
1254
1255
1256 /******************************************************************************
1257  *
1258  * FUNCTION:    AcpiOsWritePort
1259  *
1260  * PARAMETERS:  Address             - Address of I/O port/register to write
1261  *              Value               - Value to write
1262  *              Width               - Number of bits
1263  *
1264  * RETURN:      None
1265  *
1266  * DESCRIPTION: Write data to an I/O port or register
1267  *
1268  *****************************************************************************/
1269
1270 ACPI_STATUS
1271 AcpiOsWritePort (
1272     ACPI_IO_ADDRESS         Address,
1273     UINT32                  Value,
1274     UINT32                  Width)
1275 {
1276     ACPI_FUNCTION_NAME (OsWritePort);
1277
1278
1279     if ((Width == 8) || (Width == 16) || (Width == 32))
1280     {
1281         return (AE_OK);
1282     }
1283
1284     ACPI_ERROR ((AE_INFO, "Bad width parameter: %X", Width));
1285     return (AE_BAD_PARAMETER);
1286 }
1287
1288
1289 /******************************************************************************
1290  *
1291  * FUNCTION:    AcpiOsReadMemory
1292  *
1293  * PARAMETERS:  Address             - Physical Memory Address to read
1294  *              Value               - Where value is placed
1295  *              Width               - Number of bits (8,16,32, or 64)
1296  *
1297  * RETURN:      Value read from physical memory address. Always returned
1298  *              as a 64-bit integer, regardless of the read width.
1299  *
1300  * DESCRIPTION: Read data from a physical memory address
1301  *
1302  *****************************************************************************/
1303
1304 ACPI_STATUS
1305 AcpiOsReadMemory (
1306     ACPI_PHYSICAL_ADDRESS   Address,
1307     UINT64                  *Value,
1308     UINT32                  Width)
1309 {
1310
1311     switch (Width)
1312     {
1313     case 8:
1314     case 16:
1315     case 32:
1316     case 64:
1317
1318         *Value = 0;
1319         break;
1320
1321     default:
1322
1323         return (AE_BAD_PARAMETER);
1324         break;
1325     }
1326
1327     return (AE_OK);
1328 }
1329
1330
1331 /******************************************************************************
1332  *
1333  * FUNCTION:    AcpiOsWriteMemory
1334  *
1335  * PARAMETERS:  Address             - Physical Memory Address to write
1336  *              Value               - Value to write
1337  *              Width               - Number of bits (8,16,32, or 64)
1338  *
1339  * RETURN:      None
1340  *
1341  * DESCRIPTION: Write data to a physical memory address
1342  *
1343  *****************************************************************************/
1344
1345 ACPI_STATUS
1346 AcpiOsWriteMemory (
1347     ACPI_PHYSICAL_ADDRESS   Address,
1348     UINT64                  Value,
1349     UINT32                  Width)
1350 {
1351
1352     return (AE_OK);
1353 }
1354
1355
1356 /******************************************************************************
1357  *
1358  * FUNCTION:    AcpiOsSignal
1359  *
1360  * PARAMETERS:  Function            - ACPICA signal function code
1361  *              Info                - Pointer to function-dependent structure
1362  *
1363  * RETURN:      Status
1364  *
1365  * DESCRIPTION: Miscellaneous functions. Example implementation only.
1366  *
1367  *****************************************************************************/
1368
1369 ACPI_STATUS
1370 AcpiOsSignal (
1371     UINT32                  Function,
1372     void                    *Info)
1373 {
1374
1375     switch (Function)
1376     {
1377     case ACPI_SIGNAL_FATAL:
1378
1379         break;
1380
1381     case ACPI_SIGNAL_BREAKPOINT:
1382
1383         break;
1384
1385     default:
1386
1387         break;
1388     }
1389
1390     return (AE_OK);
1391 }
1392
1393
1394 /******************************************************************************
1395  *
1396  * FUNCTION:    Local cache interfaces
1397  *
1398  * DESCRIPTION: Implements cache interfaces via malloc/free for testing
1399  *              purposes only.
1400  *
1401  *****************************************************************************/
1402
1403 #ifndef ACPI_USE_LOCAL_CACHE
1404
1405 ACPI_STATUS
1406 AcpiOsCreateCache (
1407     char                    *CacheName,
1408     UINT16                  ObjectSize,
1409     UINT16                  MaxDepth,
1410     ACPI_CACHE_T            **ReturnCache)
1411 {
1412     ACPI_MEMORY_LIST        *NewCache;
1413
1414
1415     NewCache = malloc (sizeof (ACPI_MEMORY_LIST));
1416     if (!NewCache)
1417     {
1418         return (AE_NO_MEMORY);
1419     }
1420
1421     memset (NewCache, 0, sizeof (ACPI_MEMORY_LIST));
1422     NewCache->ListName = CacheName;
1423     NewCache->ObjectSize = ObjectSize;
1424     NewCache->MaxDepth = MaxDepth;
1425
1426     *ReturnCache = (ACPI_CACHE_T) NewCache;
1427     return (AE_OK);
1428 }
1429
1430 ACPI_STATUS
1431 AcpiOsDeleteCache (
1432     ACPI_CACHE_T            *Cache)
1433 {
1434     free (Cache);
1435     return (AE_OK);
1436 }
1437
1438 ACPI_STATUS
1439 AcpiOsPurgeCache (
1440     ACPI_CACHE_T            *Cache)
1441 {
1442     return (AE_OK);
1443 }
1444
1445 void *
1446 AcpiOsAcquireObject (
1447     ACPI_CACHE_T            *Cache)
1448 {
1449     void                    *NewObject;
1450
1451     NewObject = malloc (((ACPI_MEMORY_LIST *) Cache)->ObjectSize);
1452     memset (NewObject, 0, ((ACPI_MEMORY_LIST *) Cache)->ObjectSize);
1453
1454     return (NewObject);
1455 }
1456
1457 ACPI_STATUS
1458 AcpiOsReleaseObject (
1459     ACPI_CACHE_T            *Cache,
1460     void                    *Object)
1461 {
1462     free (Object);
1463     return (AE_OK);
1464 }
1465
1466 #endif /* ACPI_USE_LOCAL_CACHE */
1467
1468
1469 /* Optional multi-thread support */
1470
1471 #ifndef ACPI_SINGLE_THREADED
1472 /******************************************************************************
1473  *
1474  * FUNCTION:    AcpiOsGetThreadId
1475  *
1476  * PARAMETERS:  None
1477  *
1478  * RETURN:      Id of the running thread
1479  *
1480  * DESCRIPTION: Get the Id of the current (running) thread
1481  *
1482  *****************************************************************************/
1483
1484 ACPI_THREAD_ID
1485 AcpiOsGetThreadId (
1486     void)
1487 {
1488     DWORD                   ThreadId;
1489
1490     /* Ensure ID is never 0 */
1491
1492     ThreadId = GetCurrentThreadId ();
1493     return ((ACPI_THREAD_ID) (ThreadId + 1));
1494 }
1495
1496
1497 /******************************************************************************
1498  *
1499  * FUNCTION:    AcpiOsExecute
1500  *
1501  * PARAMETERS:  Type                - Type of execution
1502  *              Function            - Address of the function to execute
1503  *              Context             - Passed as a parameter to the function
1504  *
1505  * RETURN:      Status
1506  *
1507  * DESCRIPTION: Execute a new thread
1508  *
1509  *****************************************************************************/
1510
1511 ACPI_STATUS
1512 AcpiOsExecute (
1513     ACPI_EXECUTE_TYPE       Type,
1514     ACPI_OSD_EXEC_CALLBACK  Function,
1515     void                    *Context)
1516 {
1517
1518     _beginthread (Function, (unsigned) 0, Context);
1519     return (0);
1520 }
1521
1522 #else /* ACPI_SINGLE_THREADED */
1523 ACPI_THREAD_ID
1524 AcpiOsGetThreadId (
1525     void)
1526 {
1527     return (1);
1528 }
1529
1530 ACPI_STATUS
1531 AcpiOsExecute (
1532     ACPI_EXECUTE_TYPE       Type,
1533     ACPI_OSD_EXEC_CALLBACK  Function,
1534     void                    *Context)
1535 {
1536
1537     Function (Context);
1538
1539     return (AE_OK);
1540 }
1541
1542 #endif /* ACPI_SINGLE_THREADED */
1543
1544
1545 /******************************************************************************
1546  *
1547  * FUNCTION:    AcpiOsWaitEventsComplete
1548  *
1549  * PARAMETERS:  None
1550  *
1551  * RETURN:      None
1552  *
1553  * DESCRIPTION: Wait for all asynchronous events to complete. This
1554  *              implementation does nothing.
1555  *
1556  *****************************************************************************/
1557
1558 void
1559 AcpiOsWaitEventsComplete (
1560     void)
1561 {
1562     return;
1563 }