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