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