Import acpica-unix-20090521
[dragonfly.git] / sys / contrib / dev / acpica-unix / os_specific / service_layers / oswinxf.c
1 /******************************************************************************
2  *
3  * Module Name: oswinxf - Windows OSL
4  *
5  *****************************************************************************/
6
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights.  You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code.  No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision.  In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change.  Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee.  Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution.  In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government.  In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************/
115
116
117 #ifdef WIN32
118 #pragma warning(disable:4115)   /* warning C4115: named type definition in parentheses (caused by rpcasync.h> */
119
120 #include <windows.h>
121 #include <winbase.h>
122
123 #elif WIN64
124 #include <windowsx.h>
125 #endif
126
127 #include <stdio.h>
128 #include <stdlib.h>
129 #include <stdarg.h>
130 #include <process.h>
131 #include <time.h>
132
133 #include "acpi.h"
134 #include "accommon.h"
135
136 #define _COMPONENT          ACPI_OS_SERVICES
137         ACPI_MODULE_NAME    ("oswinxf")
138
139
140 /* Semaphore information structure */
141
142 typedef struct acpi_os_semaphore_info
143 {
144     UINT16                  MaxUnits;
145     UINT16                  CurrentUnits;
146     void                    *OsHandle;
147
148 } ACPI_OS_SEMAPHORE_INFO;
149
150 /* Need enough semaphores to run the large aslts suite */
151
152 #define ACPI_OS_MAX_SEMAPHORES  256
153
154 ACPI_OS_SEMAPHORE_INFO          AcpiGbl_Semaphores[ACPI_OS_MAX_SEMAPHORES];
155
156
157 /* Upcalls to AcpiExec */
158
159 ACPI_PHYSICAL_ADDRESS
160 AeLocalGetRootPointer (
161     void);
162
163 void
164 AeTableOverride (
165     ACPI_TABLE_HEADER       *ExistingTable,
166     ACPI_TABLE_HEADER       **NewTable);
167
168 ACPI_TABLE_HEADER *
169 OsGetTable (
170     char                    *Signature);
171
172
173 extern FILE                 *AcpiGbl_DebugFile;
174 extern BOOLEAN              AcpiGbl_DebugTimeout;
175
176 FILE                        *AcpiGbl_OutputFile;
177 UINT64                      TimerFrequency;
178 char                        TableName[ACPI_NAME_SIZE + 1];
179
180 #define ACPI_OS_DEBUG_TIMEOUT   30000 /* 30 seconds */
181
182
183 /******************************************************************************
184  *
185  * FUNCTION:    AcpiOsTerminate
186  *
187  * PARAMETERS:  None
188  *
189  * RETURN:      None
190  *
191  * DESCRIPTION: Nothing to do for windows
192  *
193  *****************************************************************************/
194
195 ACPI_STATUS
196 AcpiOsTerminate (void)
197 {
198     return AE_OK;
199 }
200
201
202 /******************************************************************************
203  *
204  * FUNCTION:    AcpiOsInitialize
205  *
206  * PARAMETERS:  None
207  *
208  * RETURN:      Status
209  *
210  * DESCRIPTION: Init this OSL
211  *
212  *****************************************************************************/
213
214 ACPI_STATUS
215 AcpiOsInitialize (void)
216 {
217     LARGE_INTEGER           LocalTimerFrequency;
218
219
220     AcpiGbl_OutputFile = stdout;
221
222     /* Clear the semaphore info array */
223
224     memset (AcpiGbl_Semaphores, 0x00, sizeof (AcpiGbl_Semaphores));
225
226     /* Get the timer frequency for use in AcpiOsGetTimer */
227
228     TimerFrequency = 0;
229     if (QueryPerformanceFrequency (&LocalTimerFrequency))
230     {
231         /* Frequency is in ticks per second */
232
233         TimerFrequency = LocalTimerFrequency.QuadPart;
234     }
235
236     return AE_OK;
237 }
238
239
240 /******************************************************************************
241  *
242  * FUNCTION:    AcpiOsGetRootPointer
243  *
244  * PARAMETERS:  None
245  *
246  * RETURN:      RSDP physical address
247  *
248  * DESCRIPTION: Gets the root pointer (RSDP)
249  *
250  *****************************************************************************/
251
252 ACPI_PHYSICAL_ADDRESS
253 AcpiOsGetRootPointer (
254     void)
255 {
256
257     return (AeLocalGetRootPointer ());
258 }
259
260
261 /******************************************************************************
262  *
263  * FUNCTION:    AcpiOsPredefinedOverride
264  *
265  * PARAMETERS:  InitVal     - Initial value of the predefined object
266  *              NewVal      - The new value for the object
267  *
268  * RETURN:      Status, pointer to value.  Null pointer returned if not
269  *              overriding.
270  *
271  * DESCRIPTION: Allow the OS to override predefined names
272  *
273  *****************************************************************************/
274
275 ACPI_STATUS
276 AcpiOsPredefinedOverride (
277     const ACPI_PREDEFINED_NAMES *InitVal,
278     ACPI_STRING                 *NewVal)
279 {
280
281     if (!InitVal || !NewVal)
282     {
283         return (AE_BAD_PARAMETER);
284     }
285
286     *NewVal = NULL;
287     return (AE_OK);
288 }
289
290
291 /******************************************************************************
292  *
293  * FUNCTION:    AcpiOsTableOverride
294  *
295  * PARAMETERS:  ExistingTable   - Header of current table (probably firmware)
296  *              NewTable        - Where an entire new table is returned.
297  *
298  * RETURN:      Status, pointer to new table.  Null pointer returned if no
299  *              table is available to override
300  *
301  * DESCRIPTION: Return a different version of a table if one is available
302  *
303  *****************************************************************************/
304
305 ACPI_STATUS
306 AcpiOsTableOverride (
307     ACPI_TABLE_HEADER       *ExistingTable,
308     ACPI_TABLE_HEADER       **NewTable)
309 {
310
311     if (!ExistingTable || !NewTable)
312     {
313         return (AE_BAD_PARAMETER);
314     }
315
316     *NewTable = NULL;
317
318
319 #ifdef ACPI_EXEC_APP
320
321     /* Call back up to AcpiExec */
322
323     AeTableOverride (ExistingTable, NewTable);
324 #endif
325
326
327 #ifdef ACPI_ASL_COMPILER
328
329     /* Attempt to get the table from the registry */
330
331     /* Construct a null-terminated string from table signature */
332
333     TableName[ACPI_NAME_SIZE] = 0;
334     ACPI_STRNCPY (TableName, ExistingTable->Signature, ACPI_NAME_SIZE);
335
336     *NewTable = OsGetTable (TableName);
337     if (*NewTable)
338     {
339         AcpiOsPrintf ("Table %s obtained from registry, %d bytes\n",
340             TableName, (*NewTable)->Length);
341     }
342     else
343     {
344         AcpiOsPrintf ("Could not read table %s from registry\n", TableName);
345     }
346 #endif
347
348     return (AE_OK);
349 }
350
351
352 /******************************************************************************
353  *
354  * FUNCTION:    AcpiOsGetTimer
355  *
356  * PARAMETERS:  None
357  *
358  * RETURN:      Current ticks in 100-nanosecond units
359  *
360  * DESCRIPTION: Get the value of a system timer
361  *
362  ******************************************************************************/
363
364 UINT64
365 AcpiOsGetTimer (
366     void)
367 {
368     LARGE_INTEGER           Timer;
369
370
371     /* Attempt to use hi-granularity timer first */
372
373     if (TimerFrequency &&
374         QueryPerformanceCounter (&Timer))
375     {
376         /* Convert to 100 nanosecond ticks */
377
378         return ((UINT64) ((Timer.QuadPart * (UINT64) 10000000) / TimerFrequency));
379     }
380
381     /* Fall back to the lo-granularity timer */
382
383     else
384     {
385         /* Convert milliseconds to 100 nanosecond ticks */
386
387         return ((UINT64) GetTickCount() * 10000);
388     }
389 }
390
391
392 /******************************************************************************
393  *
394  * FUNCTION:    AcpiOsReadable
395  *
396  * PARAMETERS:  Pointer             - Area to be verified
397  *              Length              - Size of area
398  *
399  * RETURN:      TRUE if readable for entire length
400  *
401  * DESCRIPTION: Verify that a pointer is valid for reading
402  *
403  *****************************************************************************/
404
405 BOOLEAN
406 AcpiOsReadable (
407     void                    *Pointer,
408     ACPI_SIZE               Length)
409 {
410
411     return ((BOOLEAN) !IsBadReadPtr (Pointer, Length));
412 }
413
414
415 /******************************************************************************
416  *
417  * FUNCTION:    AcpiOsWritable
418  *
419  * PARAMETERS:  Pointer             - Area to be verified
420  *              Length              - Size of area
421  *
422  * RETURN:      TRUE if writable for entire length
423  *
424  * DESCRIPTION: Verify that a pointer is valid for writing
425  *
426  *****************************************************************************/
427
428 BOOLEAN
429 AcpiOsWritable (
430     void                    *Pointer,
431     ACPI_SIZE               Length)
432 {
433
434     return ((BOOLEAN) !IsBadWritePtr (Pointer, Length));
435 }
436
437
438 /******************************************************************************
439  *
440  * FUNCTION:    AcpiOsRedirectOutput
441  *
442  * PARAMETERS:  Destination         - An open file handle/pointer
443  *
444  * RETURN:      None
445  *
446  * DESCRIPTION: Causes redirect of AcpiOsPrintf and AcpiOsVprintf
447  *
448  *****************************************************************************/
449
450 void
451 AcpiOsRedirectOutput (
452     void                    *Destination)
453 {
454
455     AcpiGbl_OutputFile = Destination;
456 }
457
458
459 /******************************************************************************
460  *
461  * FUNCTION:    AcpiOsPrintf
462  *
463  * PARAMETERS:  fmt, ...            Standard printf format
464  *
465  * RETURN:      None
466  *
467  * DESCRIPTION: Formatted output
468  *
469  *****************************************************************************/
470
471 void ACPI_INTERNAL_VAR_XFACE
472 AcpiOsPrintf (
473     const char              *Fmt,
474     ...)
475 {
476     va_list                 Args;
477
478
479     va_start (Args, Fmt);
480
481     AcpiOsVprintf (Fmt, Args);
482
483     va_end (Args);
484     return;
485 }
486
487
488 /******************************************************************************
489  *
490  * FUNCTION:    AcpiOsVprintf
491  *
492  * PARAMETERS:  fmt                 Standard printf format
493  *              args                Argument list
494  *
495  * RETURN:      None
496  *
497  * DESCRIPTION: Formatted output with argument list pointer
498  *
499  *****************************************************************************/
500
501 void
502 AcpiOsVprintf (
503     const char              *Fmt,
504     va_list                 Args)
505 {
506     INT32                   Count = 0;
507     UINT8                   Flags;
508
509
510     Flags = AcpiGbl_DbOutputFlags;
511     if (Flags & ACPI_DB_REDIRECTABLE_OUTPUT)
512     {
513         /* Output is directable to either a file (if open) or the console */
514
515         if (AcpiGbl_DebugFile)
516         {
517             /* Output file is open, send the output there */
518
519             Count = vfprintf (AcpiGbl_DebugFile, Fmt, Args);
520         }
521         else
522         {
523             /* No redirection, send output to console (once only!) */
524
525             Flags |= ACPI_DB_CONSOLE_OUTPUT;
526         }
527     }
528
529     if (Flags & ACPI_DB_CONSOLE_OUTPUT)
530     {
531         Count = vfprintf (AcpiGbl_OutputFile, Fmt, Args);
532     }
533
534     return;
535 }
536
537
538 /******************************************************************************
539  *
540  * FUNCTION:    AcpiOsGetLine
541  *
542  * PARAMETERS:  fmt                 Standard printf format
543  *              args                Argument list
544  *
545  * RETURN:      Actual bytes read
546  *
547  * DESCRIPTION: Formatted input with argument list pointer
548  *
549  *****************************************************************************/
550
551 UINT32
552 AcpiOsGetLine (
553     char                    *Buffer)
554 {
555     char                    Temp;
556     UINT32                  i;
557
558
559     for (i = 0; ; i++)
560     {
561         scanf ("%1c", &Temp);
562         if (!Temp || Temp == '\n')
563         {
564             break;
565         }
566
567         Buffer [i] = Temp;
568     }
569
570     /* Null terminate the buffer */
571
572     Buffer [i] = 0;
573
574     /* Return the number of bytes in the string */
575
576     return (i);
577 }
578
579
580 /******************************************************************************
581  *
582  * FUNCTION:    AcpiOsMapMemory
583  *
584  * PARAMETERS:  where               Physical address of memory to be mapped
585  *              length              How much memory to map
586  *
587  * RETURN:      Pointer to mapped memory.  Null on error.
588  *
589  * DESCRIPTION: Map physical memory into caller's address space
590  *
591  *****************************************************************************/
592
593 void *
594 AcpiOsMapMemory (
595     ACPI_PHYSICAL_ADDRESS   where,
596     ACPI_SIZE               length)
597 {
598
599     return (ACPI_TO_POINTER ((ACPI_SIZE) where));
600 }
601
602
603 /******************************************************************************
604  *
605  * FUNCTION:    AcpiOsUnmapMemory
606  *
607  * PARAMETERS:  where               Logical address of memory to be unmapped
608  *              length              How much memory to unmap
609  *
610  * RETURN:      None.
611  *
612  * DESCRIPTION: Delete a previously created mapping.  Where and Length must
613  *              correspond to a previous mapping exactly.
614  *
615  *****************************************************************************/
616
617 void
618 AcpiOsUnmapMemory (
619     void                    *where,
620     ACPI_SIZE               length)
621 {
622
623     return;
624 }
625
626
627 /******************************************************************************
628  *
629  * FUNCTION:    AcpiOsAllocate
630  *
631  * PARAMETERS:  Size                Amount to allocate, in bytes
632  *
633  * RETURN:      Pointer to the new allocation.  Null on error.
634  *
635  * DESCRIPTION: Allocate memory.  Algorithm is dependent on the OS.
636  *
637  *****************************************************************************/
638
639 void *
640 AcpiOsAllocate (
641     ACPI_SIZE               size)
642 {
643     void                    *Mem;
644
645
646     Mem = (void *) malloc ((size_t) size);
647
648     return Mem;
649 }
650
651
652 /******************************************************************************
653  *
654  * FUNCTION:    AcpiOsFree
655  *
656  * PARAMETERS:  mem                 Pointer to previously allocated memory
657  *
658  * RETURN:      None.
659  *
660  * DESCRIPTION: Free memory allocated via AcpiOsAllocate
661  *
662  *****************************************************************************/
663
664 void
665 AcpiOsFree (
666     void                    *Mem)
667 {
668
669     free (Mem);
670 }
671
672
673 /******************************************************************************
674  *
675  * FUNCTION:    AcpiOsCreateSemaphore
676  *
677  * PARAMETERS:  MaxUnits            - Maximum units that can be sent
678  *              InitialUnits        - Units to be assigned to the new semaphore
679  *              OutHandle           - Where a handle will be returned
680  *
681  * RETURN:      Status
682  *
683  * DESCRIPTION: Create an OS semaphore
684  *
685  *****************************************************************************/
686
687 ACPI_STATUS
688 AcpiOsCreateSemaphore (
689     UINT32              MaxUnits,
690     UINT32              InitialUnits,
691     ACPI_SEMAPHORE      *OutHandle)
692 {
693 #ifdef _MULTI_THREADED
694     void                *Mutex;
695     UINT32              i;
696
697     ACPI_FUNCTION_NAME (OsCreateSemaphore);
698 #endif
699
700
701     if (MaxUnits == ACPI_UINT32_MAX)
702     {
703         MaxUnits = 255;
704     }
705
706     if (InitialUnits == ACPI_UINT32_MAX)
707     {
708         InitialUnits = MaxUnits;
709     }
710
711     if (InitialUnits > MaxUnits)
712     {
713         return AE_BAD_PARAMETER;
714     }
715
716 #ifdef _MULTI_THREADED
717
718     /* Find an empty slot */
719
720     for (i = 0; i < ACPI_OS_MAX_SEMAPHORES; i++)
721     {
722         if (!AcpiGbl_Semaphores[i].OsHandle)
723         {
724             break;
725         }
726     }
727     if (i >= ACPI_OS_MAX_SEMAPHORES)
728     {
729         ACPI_EXCEPTION ((AE_INFO, AE_LIMIT,
730             "Reached max semaphores (%d), could not create", ACPI_OS_MAX_SEMAPHORES));
731         return AE_LIMIT;
732     }
733
734     /* Create an OS semaphore */
735
736     Mutex = CreateSemaphore (NULL, InitialUnits, MaxUnits, NULL);
737     if (!Mutex)
738     {
739         ACPI_ERROR ((AE_INFO, "Could not create semaphore"));
740         return AE_NO_MEMORY;
741     }
742
743     AcpiGbl_Semaphores[i].MaxUnits = (UINT16) MaxUnits;
744     AcpiGbl_Semaphores[i].CurrentUnits = (UINT16) InitialUnits;
745     AcpiGbl_Semaphores[i].OsHandle = Mutex;
746
747     ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Handle=%d, Max=%d, Current=%d, OsHandle=%p\n",
748             i, MaxUnits, InitialUnits, Mutex));
749
750     *OutHandle = (void *) i;
751 #endif
752
753     return AE_OK;
754 }
755
756
757 /******************************************************************************
758  *
759  * FUNCTION:    AcpiOsDeleteSemaphore
760  *
761  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
762  *
763  * RETURN:      Status
764  *
765  * DESCRIPTION: Delete an OS semaphore
766  *
767  *****************************************************************************/
768
769 ACPI_STATUS
770 AcpiOsDeleteSemaphore (
771     ACPI_SEMAPHORE      Handle)
772 {
773     UINT32              Index = (UINT32) Handle;
774
775
776     if ((Index >= ACPI_OS_MAX_SEMAPHORES) ||
777         !AcpiGbl_Semaphores[Index].OsHandle)
778     {
779         return AE_BAD_PARAMETER;
780     }
781
782
783 #ifdef _MULTI_THREADED
784
785     CloseHandle (AcpiGbl_Semaphores[Index].OsHandle);
786     AcpiGbl_Semaphores[Index].OsHandle = NULL;
787 #endif
788
789     return AE_OK;
790 }
791
792
793 /******************************************************************************
794  *
795  * FUNCTION:    AcpiOsWaitSemaphore
796  *
797  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
798  *              Units               - How many units to wait for
799  *              Timeout             - How long to wait
800  *
801  * RETURN:      Status
802  *
803  * DESCRIPTION: Wait for units
804  *
805  *****************************************************************************/
806
807 ACPI_STATUS
808 AcpiOsWaitSemaphore (
809     ACPI_SEMAPHORE      Handle,
810     UINT32              Units,
811     UINT16              Timeout)
812 {
813 #ifdef _MULTI_THREADED
814     UINT32              Index = (UINT32) Handle;
815     UINT32              WaitStatus;
816     UINT32              OsTimeout = Timeout;
817
818
819     ACPI_FUNCTION_ENTRY ();
820
821
822     if ((Index >= ACPI_OS_MAX_SEMAPHORES) ||
823         !AcpiGbl_Semaphores[Index].OsHandle)
824     {
825         return AE_BAD_PARAMETER;
826     }
827
828     if (Units > 1)
829     {
830         printf ("WaitSemaphore: Attempt to receive %d units\n", Units);
831         return AE_NOT_IMPLEMENTED;
832     }
833
834     if (Timeout == ACPI_WAIT_FOREVER)
835     {
836         OsTimeout = INFINITE;
837         if (AcpiGbl_DebugTimeout)
838         {
839             /* The debug timeout will prevent hang conditions */
840
841             OsTimeout = ACPI_OS_DEBUG_TIMEOUT;
842         }
843     }
844     else
845     {
846         /* Add 10ms to account for clock tick granularity */
847
848         OsTimeout += 10;
849     }
850
851     WaitStatus = WaitForSingleObject (AcpiGbl_Semaphores[Index].OsHandle, OsTimeout);
852     if (WaitStatus == WAIT_TIMEOUT)
853     {
854         if (AcpiGbl_DebugTimeout)
855         {
856             ACPI_EXCEPTION ((AE_INFO, AE_TIME,
857                 "Debug timeout on semaphore 0x%04X (%ums)\n",
858                 Index, ACPI_OS_DEBUG_TIMEOUT));
859         }
860         return AE_TIME;
861     }
862
863     if (AcpiGbl_Semaphores[Index].CurrentUnits == 0)
864     {
865         ACPI_ERROR ((AE_INFO, "%s - No unit received. Timeout %X, OSstatus 0x%X",
866             AcpiUtGetMutexName (Index), Timeout, WaitStatus));
867
868         return AE_OK;
869     }
870
871     AcpiGbl_Semaphores[Index].CurrentUnits--;
872 #endif
873
874     return AE_OK;
875 }
876
877
878 /******************************************************************************
879  *
880  * FUNCTION:    AcpiOsSignalSemaphore
881  *
882  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
883  *              Units               - Number of units to send
884  *
885  * RETURN:      Status
886  *
887  * DESCRIPTION: Send units
888  *
889  *****************************************************************************/
890
891 ACPI_STATUS
892 AcpiOsSignalSemaphore (
893     ACPI_SEMAPHORE      Handle,
894     UINT32              Units)
895 {
896 #ifdef _MULTI_THREADED
897
898     UINT32              Index = (UINT32) Handle;
899
900
901     ACPI_FUNCTION_ENTRY ();
902
903
904     if (Index >= ACPI_OS_MAX_SEMAPHORES)
905     {
906         printf ("SignalSemaphore: Index/Handle out of range: %2.2X\n", Index);
907         return AE_BAD_PARAMETER;
908     }
909
910     if (!AcpiGbl_Semaphores[Index].OsHandle)
911     {
912         printf ("SignalSemaphore: Null OS handle, Index %2.2X\n", Index);
913         return AE_BAD_PARAMETER;
914     }
915
916     if (Units > 1)
917     {
918         printf ("SignalSemaphore: Attempt to signal %d units, Index %2.2X\n", Units, Index);
919         return AE_NOT_IMPLEMENTED;
920     }
921
922     if ((AcpiGbl_Semaphores[Index].CurrentUnits + 1) >
923         AcpiGbl_Semaphores[Index].MaxUnits)
924     {
925         ACPI_ERROR ((AE_INFO,
926             "Oversignalled semaphore[%d]! Current %d Max %d",
927             Index, AcpiGbl_Semaphores[Index].CurrentUnits,
928             AcpiGbl_Semaphores[Index].MaxUnits));
929
930         return (AE_LIMIT);
931     }
932
933     AcpiGbl_Semaphores[Index].CurrentUnits++;
934     ReleaseSemaphore (AcpiGbl_Semaphores[Index].OsHandle, Units, NULL);
935
936 #endif
937
938     return (AE_OK);
939 }
940
941
942 /* Spinlock interfaces, just implement with a semaphore */
943
944 ACPI_STATUS
945 AcpiOsCreateLock (
946     ACPI_SPINLOCK           *OutHandle)
947 {
948     return (AcpiOsCreateSemaphore (1, 1, OutHandle));
949 }
950
951 void
952 AcpiOsDeleteLock (
953     ACPI_SPINLOCK           Handle)
954 {
955     AcpiOsDeleteSemaphore (Handle);
956 }
957
958 ACPI_CPU_FLAGS
959 AcpiOsAcquireLock (
960     ACPI_SPINLOCK           Handle)
961 {
962     AcpiOsWaitSemaphore (Handle, 1, 0xFFFF);
963     return (0);
964 }
965
966 void
967 AcpiOsReleaseLock (
968     ACPI_SPINLOCK           Handle,
969     ACPI_CPU_FLAGS          Flags)
970 {
971     AcpiOsSignalSemaphore (Handle, 1);
972 }
973
974
975 #if ACPI_FUTURE_IMPLEMENTATION
976
977 /* Mutex interfaces, just implement with a semaphore */
978
979 ACPI_STATUS
980 AcpiOsCreateMutex (
981     ACPI_MUTEX              *OutHandle)
982 {
983     return (AcpiOsCreateSemaphore (1, 1, OutHandle));
984 }
985
986 void
987 AcpiOsDeleteMutex (
988     ACPI_MUTEX              Handle)
989 {
990     AcpiOsDeleteSemaphore (Handle);
991 }
992
993 ACPI_STATUS
994 AcpiOsAcquireMutex (
995     ACPI_MUTEX              Handle,
996     UINT16                  Timeout)
997 {
998     AcpiOsWaitSemaphore (Handle, 1, Timeout);
999     return (0);
1000 }
1001
1002 void
1003 AcpiOsReleaseMutex (
1004     ACPI_MUTEX              Handle)
1005 {
1006     AcpiOsSignalSemaphore (Handle, 1);
1007 }
1008 #endif
1009
1010
1011 /******************************************************************************
1012  *
1013  * FUNCTION:    AcpiOsInstallInterruptHandler
1014  *
1015  * PARAMETERS:  InterruptNumber     Level handler should respond to.
1016  *              Isr                 Address of the ACPI interrupt handler
1017  *              ExceptPtr           Where status is returned
1018  *
1019  * RETURN:      Handle to the newly installed handler.
1020  *
1021  * DESCRIPTION: Install an interrupt handler.  Used to install the ACPI
1022  *              OS-independent handler.
1023  *
1024  *****************************************************************************/
1025
1026 UINT32
1027 AcpiOsInstallInterruptHandler (
1028     UINT32                  InterruptNumber,
1029     ACPI_OSD_HANDLER        ServiceRoutine,
1030     void                    *Context)
1031 {
1032
1033     return AE_OK;
1034 }
1035
1036
1037 /******************************************************************************
1038  *
1039  * FUNCTION:    AcpiOsRemoveInterruptHandler
1040  *
1041  * PARAMETERS:  Handle              Returned when handler was installed
1042  *
1043  * RETURN:      Status
1044  *
1045  * DESCRIPTION: Uninstalls an interrupt handler.
1046  *
1047  *****************************************************************************/
1048
1049 ACPI_STATUS
1050 AcpiOsRemoveInterruptHandler (
1051     UINT32                  InterruptNumber,
1052     ACPI_OSD_HANDLER        ServiceRoutine)
1053 {
1054
1055     return AE_OK;
1056 }
1057
1058
1059 /******************************************************************************
1060  *
1061  * FUNCTION:    AcpiOsGetThreadId
1062  *
1063  * PARAMETERS:  None
1064  *
1065  * RETURN:      Id of the running thread
1066  *
1067  * DESCRIPTION: Get the Id of the current (running) thread
1068  *
1069  *****************************************************************************/
1070
1071 ACPI_THREAD_ID
1072 AcpiOsGetThreadId (
1073     void)
1074 {
1075     DWORD                   ThreadId;
1076
1077     /* Ensure ID is never 0 */
1078
1079     ThreadId = GetCurrentThreadId ();
1080     return (ThreadId + 1);
1081 }
1082
1083
1084 /******************************************************************************
1085  *
1086  * FUNCTION:    AcpiOsExecute
1087  *
1088  * PARAMETERS:  Type            - Type of execution
1089  *              Function        - Address of the function to execute
1090  *              Context         - Passed as a parameter to the function
1091  *
1092  * RETURN:      Status
1093  *
1094  * DESCRIPTION: Execute a new thread
1095  *
1096  *****************************************************************************/
1097
1098 ACPI_STATUS
1099 AcpiOsExecute (
1100     ACPI_EXECUTE_TYPE       Type,
1101     ACPI_OSD_EXEC_CALLBACK  Function,
1102     void                    *Context)
1103 {
1104
1105 #ifdef _MULTI_THREADED
1106     _beginthread (Function, (unsigned) 0, Context);
1107 #endif
1108
1109     return 0;
1110 }
1111
1112
1113 /******************************************************************************
1114  *
1115  * FUNCTION:    AcpiOsStall
1116  *
1117  * PARAMETERS:  microseconds        To sleep
1118  *
1119  * RETURN:      Blocks until sleep is completed.
1120  *
1121  * DESCRIPTION: Sleep at microsecond granularity
1122  *
1123  *****************************************************************************/
1124
1125 void
1126 AcpiOsStall (
1127     UINT32                  microseconds)
1128 {
1129
1130     Sleep ((microseconds / 1000) + 1);
1131     return;
1132 }
1133
1134
1135 /******************************************************************************
1136  *
1137  * FUNCTION:    AcpiOsSleep
1138  *
1139  * PARAMETERS:  milliseconds        To sleep
1140  *
1141  * RETURN:      Blocks until sleep is completed.
1142  *
1143  * DESCRIPTION: Sleep at millisecond granularity
1144  *
1145  *****************************************************************************/
1146
1147 void
1148 AcpiOsSleep (
1149     ACPI_INTEGER            milliseconds)
1150 {
1151
1152     /* Add 10ms to account for clock tick granularity */
1153
1154     Sleep (((unsigned long) milliseconds) + 10);
1155     return;
1156 }
1157
1158
1159 /******************************************************************************
1160  *
1161  * FUNCTION:    AcpiOsValidateInterface
1162  *
1163  * PARAMETERS:  Interface           - Requested interface to be validated
1164  *
1165  * RETURN:      AE_OK if interface is supported, AE_SUPPORT otherwise
1166  *
1167  * DESCRIPTION: Match an interface string to the interfaces supported by the
1168  *              host. Strings originate from an AML call to the _OSI method.
1169  *
1170  *****************************************************************************/
1171
1172 ACPI_STATUS
1173 AcpiOsValidateInterface (
1174     char                    *Interface)
1175 {
1176
1177     return (AE_SUPPORT);
1178 }
1179
1180
1181 /******************************************************************************
1182  *
1183  * FUNCTION:    AcpiOsReadPciConfiguration
1184  *
1185  * PARAMETERS:  PciId               Seg/Bus/Dev
1186  *              Register            Device Register
1187  *              Value               Buffer where value is placed
1188  *              Width               Number of bits
1189  *
1190  * RETURN:      Status
1191  *
1192  * DESCRIPTION: Read data from PCI configuration space
1193  *
1194  *****************************************************************************/
1195
1196 ACPI_STATUS
1197 AcpiOsReadPciConfiguration (
1198     ACPI_PCI_ID             *PciId,
1199     UINT32                  Register,
1200     void                    *Value,
1201     UINT32                  Width)
1202 {
1203
1204     return (AE_OK);
1205 }
1206
1207
1208 /******************************************************************************
1209  *
1210  * FUNCTION:    AcpiOsWritePciConfiguration
1211  *
1212  * PARAMETERS:  PciId               Seg/Bus/Dev
1213  *              Register            Device Register
1214  *              Value               Value to be written
1215  *              Width               Number of bits
1216  *
1217  * RETURN:      Status.
1218  *
1219  * DESCRIPTION: Write data to PCI configuration space
1220  *
1221  *****************************************************************************/
1222
1223 ACPI_STATUS
1224 AcpiOsWritePciConfiguration (
1225     ACPI_PCI_ID             *PciId,
1226     UINT32                  Register,
1227     ACPI_INTEGER            Value,
1228     UINT32                  Width)
1229 {
1230
1231     return (AE_OK);
1232 }
1233
1234 /* TEMPORARY STUB FUNCTION */
1235 void
1236 AcpiOsDerivePciId(
1237     ACPI_HANDLE             rhandle,
1238     ACPI_HANDLE             chandle,
1239     ACPI_PCI_ID             **PciId)
1240 {
1241
1242     return;
1243 }
1244
1245
1246 /******************************************************************************
1247  *
1248  * FUNCTION:    AcpiOsReadPort
1249  *
1250  * PARAMETERS:  Address             Address of I/O port/register to read
1251  *              Value               Where value is placed
1252  *              Width               Number of bits
1253  *
1254  * RETURN:      Value read from port
1255  *
1256  * DESCRIPTION: Read data from an I/O port or register
1257  *
1258  *****************************************************************************/
1259
1260 ACPI_STATUS
1261 AcpiOsReadPort (
1262     ACPI_IO_ADDRESS         Address,
1263     UINT32                  *Value,
1264     UINT32                  Width)
1265 {
1266
1267     switch (Width)
1268     {
1269     case 8:
1270         *Value = 0xFF;
1271         break;
1272
1273     case 16:
1274         *Value = 0xFFFF;
1275         break;
1276
1277     case 32:
1278         *Value = 0xFFFFFFFF;
1279         break;
1280
1281     default:
1282         return (AE_BAD_PARAMETER);
1283     }
1284
1285     return (AE_OK);
1286 }
1287
1288
1289 /******************************************************************************
1290  *
1291  * FUNCTION:    AcpiOsWritePort
1292  *
1293  * PARAMETERS:  Address             Address of I/O port/register to write
1294  *              Value               Value to write
1295  *              Width               Number of bits
1296  *
1297  * RETURN:      None
1298  *
1299  * DESCRIPTION: Write data to an I/O port or register
1300  *
1301  *****************************************************************************/
1302
1303 ACPI_STATUS
1304 AcpiOsWritePort (
1305     ACPI_IO_ADDRESS         Address,
1306     UINT32                  Value,
1307     UINT32                  Width)
1308 {
1309
1310     return (AE_OK);
1311 }
1312
1313
1314 /******************************************************************************
1315  *
1316  * FUNCTION:    AcpiOsReadMemory
1317  *
1318  * PARAMETERS:  Address             Physical Memory Address to read
1319  *              Value               Where value is placed
1320  *              Width               Number of bits
1321  *
1322  * RETURN:      Value read from physical memory address.  Always returned
1323  *              as a 32-bit integer, regardless of the read width.
1324  *
1325  * DESCRIPTION: Read data from a physical memory address
1326  *
1327  *****************************************************************************/
1328
1329 ACPI_STATUS
1330 AcpiOsReadMemory (
1331     ACPI_PHYSICAL_ADDRESS   Address,
1332     UINT32                  *Value,
1333     UINT32                  Width)
1334 {
1335
1336     switch (Width)
1337     {
1338     case 8:
1339     case 16:
1340     case 32:
1341         *Value = 0;
1342         break;
1343
1344     default:
1345         return (AE_BAD_PARAMETER);
1346         break;
1347     }
1348
1349     return (AE_OK);
1350 }
1351
1352
1353 /******************************************************************************
1354  *
1355  * FUNCTION:    AcpiOsWriteMemory
1356  *
1357  * PARAMETERS:  Address             Physical Memory Address to write
1358  *              Value               Value to write
1359  *              Width               Number of bits
1360  *
1361  * RETURN:      None
1362  *
1363  * DESCRIPTION: Write data to a physical memory address
1364  *
1365  *****************************************************************************/
1366
1367 ACPI_STATUS
1368 AcpiOsWriteMemory (
1369     ACPI_PHYSICAL_ADDRESS   Address,
1370     UINT32                  Value,
1371     UINT32                  Width)
1372 {
1373
1374     return (AE_OK);
1375 }
1376
1377
1378 /******************************************************************************
1379  *
1380  * FUNCTION:    AcpiOsSignal
1381  *
1382  * PARAMETERS:  Function            ACPI CA signal function code
1383  *              Info                Pointer to function-dependent structure
1384  *
1385  * RETURN:      Status
1386  *
1387  * DESCRIPTION: Miscellaneous functions. Example implementation only.
1388  *
1389  *****************************************************************************/
1390
1391 ACPI_STATUS
1392 AcpiOsSignal (
1393     UINT32                  Function,
1394     void                    *Info)
1395 {
1396
1397     switch (Function)
1398     {
1399     case ACPI_SIGNAL_FATAL:
1400         break;
1401
1402     case ACPI_SIGNAL_BREAKPOINT:
1403         break;
1404
1405     default:
1406         break;
1407     }
1408
1409     return (AE_OK);
1410 }
1411