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