xref: /dflybsd-src/sys/contrib/dev/acpica/source/os_specific/service_layers/oswinxf.c (revision 5f39c7e70ca0960d1868c75a449064df712dbb10)
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 }
1564