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