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