oswinxf.c revision 1.1.1.3 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 return the command line
481 * BufferLength - Maximum length of Buffer
482 * BytesRead - Where the actual byte count is returned
483 *
484 * RETURN: Status and actual bytes read
485 *
486 * DESCRIPTION: Formatted input with argument list pointer
487 *
488 *****************************************************************************/
489
490 ACPI_STATUS
491 AcpiOsGetLine (
492 char *Buffer,
493 UINT32 BufferLength,
494 UINT32 *BytesRead)
495 {
496 char Temp;
497 UINT32 i;
498
499
500 for (i = 0; ; i++)
501 {
502 if (i >= BufferLength)
503 {
504 return (AE_BUFFER_OVERFLOW);
505 }
506
507 scanf ("%1c", &Temp);
508 if (!Temp || Temp == '\n')
509 {
510 break;
511 }
512
513 Buffer [i] = Temp;
514 }
515
516 /* Null terminate the buffer */
517
518 Buffer [i] = 0;
519
520 /* Return the number of bytes in the string */
521
522 if (BytesRead)
523 {
524 *BytesRead = i;
525 }
526 return (AE_OK);
527 }
528
529
530 /******************************************************************************
531 *
532 * FUNCTION: AcpiOsMapMemory
533 *
534 * PARAMETERS: Where - Physical address of memory to be mapped
535 * Length - How much memory to map
536 *
537 * RETURN: Pointer to mapped memory. Null on error.
538 *
539 * DESCRIPTION: Map physical memory into caller's address space
540 *
541 *****************************************************************************/
542
543 void *
544 AcpiOsMapMemory (
545 ACPI_PHYSICAL_ADDRESS Where,
546 ACPI_SIZE Length)
547 {
548
549 return (ACPI_TO_POINTER ((ACPI_SIZE) Where));
550 }
551
552
553 /******************************************************************************
554 *
555 * FUNCTION: AcpiOsUnmapMemory
556 *
557 * PARAMETERS: Where - Logical address of memory to be unmapped
558 * Length - How much memory to unmap
559 *
560 * RETURN: None.
561 *
562 * DESCRIPTION: Delete a previously created mapping. Where and Length must
563 * correspond to a previous mapping exactly.
564 *
565 *****************************************************************************/
566
567 void
568 AcpiOsUnmapMemory (
569 void *Where,
570 ACPI_SIZE Length)
571 {
572
573 return;
574 }
575
576
577 /******************************************************************************
578 *
579 * FUNCTION: AcpiOsAllocate
580 *
581 * PARAMETERS: Size - Amount to allocate, in bytes
582 *
583 * RETURN: Pointer to the new allocation. Null on error.
584 *
585 * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS.
586 *
587 *****************************************************************************/
588
589 void *
590 AcpiOsAllocate (
591 ACPI_SIZE Size)
592 {
593 void *Mem;
594
595
596 Mem = (void *) malloc ((size_t) Size);
597
598 return (Mem);
599 }
600
601
602 /******************************************************************************
603 *
604 * FUNCTION: AcpiOsFree
605 *
606 * PARAMETERS: Mem - Pointer to previously allocated memory
607 *
608 * RETURN: None.
609 *
610 * DESCRIPTION: Free memory allocated via AcpiOsAllocate
611 *
612 *****************************************************************************/
613
614 void
615 AcpiOsFree (
616 void *Mem)
617 {
618
619 free (Mem);
620 }
621
622
623 #ifdef ACPI_SINGLE_THREADED
624 /******************************************************************************
625 *
626 * FUNCTION: Semaphore stub functions
627 *
628 * DESCRIPTION: Stub functions used for single-thread applications that do
629 * not require semaphore synchronization. Full implementations
630 * of these functions appear after the stubs.
631 *
632 *****************************************************************************/
633
634 ACPI_STATUS
635 AcpiOsCreateSemaphore (
636 UINT32 MaxUnits,
637 UINT32 InitialUnits,
638 ACPI_HANDLE *OutHandle)
639 {
640 *OutHandle = (ACPI_HANDLE) 1;
641 return (AE_OK);
642 }
643
644 ACPI_STATUS
645 AcpiOsDeleteSemaphore (
646 ACPI_HANDLE Handle)
647 {
648 return (AE_OK);
649 }
650
651 ACPI_STATUS
652 AcpiOsWaitSemaphore (
653 ACPI_HANDLE Handle,
654 UINT32 Units,
655 UINT16 Timeout)
656 {
657 return (AE_OK);
658 }
659
660 ACPI_STATUS
661 AcpiOsSignalSemaphore (
662 ACPI_HANDLE Handle,
663 UINT32 Units)
664 {
665 return (AE_OK);
666 }
667
668 #else
669 /******************************************************************************
670 *
671 * FUNCTION: AcpiOsCreateSemaphore
672 *
673 * PARAMETERS: MaxUnits - Maximum units that can be sent
674 * InitialUnits - Units to be assigned to the new semaphore
675 * OutHandle - Where a handle will be returned
676 *
677 * RETURN: Status
678 *
679 * DESCRIPTION: Create an OS semaphore
680 *
681 *****************************************************************************/
682
683 ACPI_STATUS
684 AcpiOsCreateSemaphore (
685 UINT32 MaxUnits,
686 UINT32 InitialUnits,
687 ACPI_SEMAPHORE *OutHandle)
688 {
689 void *Mutex;
690 UINT32 i;
691
692 ACPI_FUNCTION_NAME (OsCreateSemaphore);
693
694
695 if (MaxUnits == ACPI_UINT32_MAX)
696 {
697 MaxUnits = 255;
698 }
699
700 if (InitialUnits == ACPI_UINT32_MAX)
701 {
702 InitialUnits = MaxUnits;
703 }
704
705 if (InitialUnits > MaxUnits)
706 {
707 return (AE_BAD_PARAMETER);
708 }
709
710 /* Find an empty slot */
711
712 for (i = 0; i < ACPI_OS_MAX_SEMAPHORES; i++)
713 {
714 if (!AcpiGbl_Semaphores[i].OsHandle)
715 {
716 break;
717 }
718 }
719 if (i >= ACPI_OS_MAX_SEMAPHORES)
720 {
721 ACPI_EXCEPTION ((AE_INFO, AE_LIMIT,
722 "Reached max semaphores (%u), could not create", ACPI_OS_MAX_SEMAPHORES));
723 return (AE_LIMIT);
724 }
725
726 /* Create an OS semaphore */
727
728 Mutex = CreateSemaphore (NULL, InitialUnits, MaxUnits, NULL);
729 if (!Mutex)
730 {
731 ACPI_ERROR ((AE_INFO, "Could not create semaphore"));
732 return (AE_NO_MEMORY);
733 }
734
735 AcpiGbl_Semaphores[i].MaxUnits = (UINT16) MaxUnits;
736 AcpiGbl_Semaphores[i].CurrentUnits = (UINT16) InitialUnits;
737 AcpiGbl_Semaphores[i].OsHandle = Mutex;
738
739 ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Handle=%u, Max=%u, Current=%u, OsHandle=%p\n",
740 i, MaxUnits, InitialUnits, Mutex));
741
742 *OutHandle = (void *) i;
743 return (AE_OK);
744 }
745
746
747 /******************************************************************************
748 *
749 * FUNCTION: AcpiOsDeleteSemaphore
750 *
751 * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore
752 *
753 * RETURN: Status
754 *
755 * DESCRIPTION: Delete an OS semaphore
756 *
757 *****************************************************************************/
758
759 ACPI_STATUS
760 AcpiOsDeleteSemaphore (
761 ACPI_SEMAPHORE Handle)
762 {
763 UINT32 Index = (UINT32) Handle;
764
765
766 if ((Index >= ACPI_OS_MAX_SEMAPHORES) ||
767 !AcpiGbl_Semaphores[Index].OsHandle)
768 {
769 return (AE_BAD_PARAMETER);
770 }
771
772 CloseHandle (AcpiGbl_Semaphores[Index].OsHandle);
773 AcpiGbl_Semaphores[Index].OsHandle = NULL;
774 return (AE_OK);
775 }
776
777
778 /******************************************************************************
779 *
780 * FUNCTION: AcpiOsWaitSemaphore
781 *
782 * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore
783 * Units - How many units to wait for
784 * Timeout - How long to wait
785 *
786 * RETURN: Status
787 *
788 * DESCRIPTION: Wait for units
789 *
790 *****************************************************************************/
791
792 ACPI_STATUS
793 AcpiOsWaitSemaphore (
794 ACPI_SEMAPHORE Handle,
795 UINT32 Units,
796 UINT16 Timeout)
797 {
798 UINT32 Index = (UINT32) Handle;
799 UINT32 WaitStatus;
800 UINT32 OsTimeout = Timeout;
801
802
803 ACPI_FUNCTION_ENTRY ();
804
805
806 if ((Index >= ACPI_OS_MAX_SEMAPHORES) ||
807 !AcpiGbl_Semaphores[Index].OsHandle)
808 {
809 return (AE_BAD_PARAMETER);
810 }
811
812 if (Units > 1)
813 {
814 printf ("WaitSemaphore: Attempt to receive %u units\n", Units);
815 return (AE_NOT_IMPLEMENTED);
816 }
817
818 if (Timeout == ACPI_WAIT_FOREVER)
819 {
820 OsTimeout = INFINITE;
821 if (AcpiGbl_DebugTimeout)
822 {
823 /* The debug timeout will prevent hang conditions */
824
825 OsTimeout = ACPI_OS_DEBUG_TIMEOUT;
826 }
827 }
828 else
829 {
830 /* Add 10ms to account for clock tick granularity */
831
832 OsTimeout += 10;
833 }
834
835 WaitStatus = WaitForSingleObject (AcpiGbl_Semaphores[Index].OsHandle, OsTimeout);
836 if (WaitStatus == WAIT_TIMEOUT)
837 {
838 if (AcpiGbl_DebugTimeout)
839 {
840 ACPI_EXCEPTION ((AE_INFO, AE_TIME,
841 "Debug timeout on semaphore 0x%04X (%ums)\n",
842 Index, ACPI_OS_DEBUG_TIMEOUT));
843 }
844 return (AE_TIME);
845 }
846
847 if (AcpiGbl_Semaphores[Index].CurrentUnits == 0)
848 {
849 ACPI_ERROR ((AE_INFO, "%s - No unit received. Timeout 0x%X, OS_Status 0x%X",
850 AcpiUtGetMutexName (Index), Timeout, WaitStatus));
851
852 return (AE_OK);
853 }
854
855 AcpiGbl_Semaphores[Index].CurrentUnits--;
856 return (AE_OK);
857 }
858
859
860 /******************************************************************************
861 *
862 * FUNCTION: AcpiOsSignalSemaphore
863 *
864 * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore
865 * Units - Number of units to send
866 *
867 * RETURN: Status
868 *
869 * DESCRIPTION: Send units
870 *
871 *****************************************************************************/
872
873 ACPI_STATUS
874 AcpiOsSignalSemaphore (
875 ACPI_SEMAPHORE Handle,
876 UINT32 Units)
877 {
878 UINT32 Index = (UINT32) Handle;
879
880
881 ACPI_FUNCTION_ENTRY ();
882
883
884 if (Index >= ACPI_OS_MAX_SEMAPHORES)
885 {
886 printf ("SignalSemaphore: Index/Handle out of range: %2.2X\n", Index);
887 return (AE_BAD_PARAMETER);
888 }
889
890 if (!AcpiGbl_Semaphores[Index].OsHandle)
891 {
892 printf ("SignalSemaphore: Null OS handle, Index %2.2X\n", Index);
893 return (AE_BAD_PARAMETER);
894 }
895
896 if (Units > 1)
897 {
898 printf ("SignalSemaphore: Attempt to signal %u units, Index %2.2X\n", Units, Index);
899 return (AE_NOT_IMPLEMENTED);
900 }
901
902 if ((AcpiGbl_Semaphores[Index].CurrentUnits + 1) >
903 AcpiGbl_Semaphores[Index].MaxUnits)
904 {
905 ACPI_ERROR ((AE_INFO,
906 "Oversignalled semaphore[%u]! Current %u Max %u",
907 Index, AcpiGbl_Semaphores[Index].CurrentUnits,
908 AcpiGbl_Semaphores[Index].MaxUnits));
909
910 return (AE_LIMIT);
911 }
912
913 AcpiGbl_Semaphores[Index].CurrentUnits++;
914 ReleaseSemaphore (AcpiGbl_Semaphores[Index].OsHandle, Units, NULL);
915
916 return (AE_OK);
917 }
918
919 #endif /* ACPI_SINGLE_THREADED */
920
921
922 /******************************************************************************
923 *
924 * FUNCTION: Spinlock interfaces
925 *
926 * DESCRIPTION: Map these interfaces to semaphore interfaces
927 *
928 *****************************************************************************/
929
930 ACPI_STATUS
931 AcpiOsCreateLock (
932 ACPI_SPINLOCK *OutHandle)
933 {
934 return (AcpiOsCreateSemaphore (1, 1, OutHandle));
935 }
936
937 void
938 AcpiOsDeleteLock (
939 ACPI_SPINLOCK Handle)
940 {
941 AcpiOsDeleteSemaphore (Handle);
942 }
943
944 ACPI_CPU_FLAGS
945 AcpiOsAcquireLock (
946 ACPI_SPINLOCK Handle)
947 {
948 AcpiOsWaitSemaphore (Handle, 1, 0xFFFF);
949 return (0);
950 }
951
952 void
953 AcpiOsReleaseLock (
954 ACPI_SPINLOCK Handle,
955 ACPI_CPU_FLAGS Flags)
956 {
957 AcpiOsSignalSemaphore (Handle, 1);
958 }
959
960
961 #if ACPI_FUTURE_IMPLEMENTATION
962
963 /* Mutex interfaces, just implement with a semaphore */
964
965 ACPI_STATUS
966 AcpiOsCreateMutex (
967 ACPI_MUTEX *OutHandle)
968 {
969 return (AcpiOsCreateSemaphore (1, 1, OutHandle));
970 }
971
972 void
973 AcpiOsDeleteMutex (
974 ACPI_MUTEX Handle)
975 {
976 AcpiOsDeleteSemaphore (Handle);
977 }
978
979 ACPI_STATUS
980 AcpiOsAcquireMutex (
981 ACPI_MUTEX Handle,
982 UINT16 Timeout)
983 {
984 AcpiOsWaitSemaphore (Handle, 1, Timeout);
985 return (0);
986 }
987
988 void
989 AcpiOsReleaseMutex (
990 ACPI_MUTEX Handle)
991 {
992 AcpiOsSignalSemaphore (Handle, 1);
993 }
994 #endif
995
996
997 /******************************************************************************
998 *
999 * FUNCTION: AcpiOsInstallInterruptHandler
1000 *
1001 * PARAMETERS: InterruptNumber - Level handler should respond to.
1002 * ServiceRoutine - Address of the ACPI interrupt handler
1003 * Context - User context
1004 *
1005 * RETURN: Handle to the newly installed handler.
1006 *
1007 * DESCRIPTION: Install an interrupt handler. Used to install the ACPI
1008 * OS-independent handler.
1009 *
1010 *****************************************************************************/
1011
1012 UINT32
1013 AcpiOsInstallInterruptHandler (
1014 UINT32 InterruptNumber,
1015 ACPI_OSD_HANDLER ServiceRoutine,
1016 void *Context)
1017 {
1018
1019 return (AE_OK);
1020 }
1021
1022
1023 /******************************************************************************
1024 *
1025 * FUNCTION: AcpiOsRemoveInterruptHandler
1026 *
1027 * PARAMETERS: Handle - Returned when handler was installed
1028 *
1029 * RETURN: Status
1030 *
1031 * DESCRIPTION: Uninstalls an interrupt handler.
1032 *
1033 *****************************************************************************/
1034
1035 ACPI_STATUS
1036 AcpiOsRemoveInterruptHandler (
1037 UINT32 InterruptNumber,
1038 ACPI_OSD_HANDLER ServiceRoutine)
1039 {
1040
1041 return (AE_OK);
1042 }
1043
1044
1045 /******************************************************************************
1046 *
1047 * FUNCTION: AcpiOsStall
1048 *
1049 * PARAMETERS: Microseconds - Time to stall
1050 *
1051 * RETURN: None. Blocks until stall is completed.
1052 *
1053 * DESCRIPTION: Sleep at microsecond granularity
1054 *
1055 *****************************************************************************/
1056
1057 void
1058 AcpiOsStall (
1059 UINT32 Microseconds)
1060 {
1061
1062 Sleep ((Microseconds / 1000) + 1);
1063 return;
1064 }
1065
1066
1067 /******************************************************************************
1068 *
1069 * FUNCTION: AcpiOsSleep
1070 *
1071 * PARAMETERS: Milliseconds - Time to sleep
1072 *
1073 * RETURN: None. Blocks until sleep is completed.
1074 *
1075 * DESCRIPTION: Sleep at millisecond granularity
1076 *
1077 *****************************************************************************/
1078
1079 void
1080 AcpiOsSleep (
1081 UINT64 Milliseconds)
1082 {
1083
1084 /* Add 10ms to account for clock tick granularity */
1085
1086 Sleep (((unsigned long) Milliseconds) + 10);
1087 return;
1088 }
1089
1090
1091 /******************************************************************************
1092 *
1093 * FUNCTION: AcpiOsReadPciConfiguration
1094 *
1095 * PARAMETERS: PciId - Seg/Bus/Dev
1096 * Register - Device Register
1097 * Value - Buffer where value is placed
1098 * Width - Number of bits
1099 *
1100 * RETURN: Status
1101 *
1102 * DESCRIPTION: Read data from PCI configuration space
1103 *
1104 *****************************************************************************/
1105
1106 ACPI_STATUS
1107 AcpiOsReadPciConfiguration (
1108 ACPI_PCI_ID *PciId,
1109 UINT32 Register,
1110 UINT64 *Value,
1111 UINT32 Width)
1112 {
1113
1114 return (AE_OK);
1115 }
1116
1117
1118 /******************************************************************************
1119 *
1120 * FUNCTION: AcpiOsWritePciConfiguration
1121 *
1122 * PARAMETERS: PciId - Seg/Bus/Dev
1123 * Register - Device Register
1124 * Value - Value to be written
1125 * Width - Number of bits
1126 *
1127 * RETURN: Status
1128 *
1129 * DESCRIPTION: Write data to PCI configuration space
1130 *
1131 *****************************************************************************/
1132
1133 ACPI_STATUS
1134 AcpiOsWritePciConfiguration (
1135 ACPI_PCI_ID *PciId,
1136 UINT32 Register,
1137 UINT64 Value,
1138 UINT32 Width)
1139 {
1140
1141 return (AE_OK);
1142 }
1143
1144
1145 /******************************************************************************
1146 *
1147 * FUNCTION: AcpiOsReadPort
1148 *
1149 * PARAMETERS: Address - Address of I/O port/register to read
1150 * Value - Where value is placed
1151 * Width - Number of bits
1152 *
1153 * RETURN: Value read from port
1154 *
1155 * DESCRIPTION: Read data from an I/O port or register
1156 *
1157 *****************************************************************************/
1158
1159 ACPI_STATUS
1160 AcpiOsReadPort (
1161 ACPI_IO_ADDRESS Address,
1162 UINT32 *Value,
1163 UINT32 Width)
1164 {
1165
1166 switch (Width)
1167 {
1168 case 8:
1169 *Value = 0xFF;
1170 break;
1171
1172 case 16:
1173 *Value = 0xFFFF;
1174 break;
1175
1176 case 32:
1177 *Value = 0xFFFFFFFF;
1178 break;
1179
1180 default:
1181 return (AE_BAD_PARAMETER);
1182 }
1183
1184 return (AE_OK);
1185 }
1186
1187
1188 /******************************************************************************
1189 *
1190 * FUNCTION: AcpiOsWritePort
1191 *
1192 * PARAMETERS: Address - Address of I/O port/register to write
1193 * Value - Value to write
1194 * Width - Number of bits
1195 *
1196 * RETURN: None
1197 *
1198 * DESCRIPTION: Write data to an I/O port or register
1199 *
1200 *****************************************************************************/
1201
1202 ACPI_STATUS
1203 AcpiOsWritePort (
1204 ACPI_IO_ADDRESS Address,
1205 UINT32 Value,
1206 UINT32 Width)
1207 {
1208
1209 return (AE_OK);
1210 }
1211
1212
1213 /******************************************************************************
1214 *
1215 * FUNCTION: AcpiOsReadMemory
1216 *
1217 * PARAMETERS: Address - Physical Memory Address to read
1218 * Value - Where value is placed
1219 * Width - Number of bits
1220 *
1221 * RETURN: Value read from physical memory address. Always returned
1222 * as a 32-bit integer, regardless of the read width.
1223 *
1224 * DESCRIPTION: Read data from a physical memory address
1225 *
1226 *****************************************************************************/
1227
1228 ACPI_STATUS
1229 AcpiOsReadMemory (
1230 ACPI_PHYSICAL_ADDRESS Address,
1231 UINT32 *Value,
1232 UINT32 Width)
1233 {
1234
1235 switch (Width)
1236 {
1237 case 8:
1238 case 16:
1239 case 32:
1240 *Value = 0;
1241 break;
1242
1243 default:
1244 return (AE_BAD_PARAMETER);
1245 break;
1246 }
1247
1248 return (AE_OK);
1249 }
1250
1251
1252 /******************************************************************************
1253 *
1254 * FUNCTION: AcpiOsWriteMemory
1255 *
1256 * PARAMETERS: Address - Physical Memory Address to write
1257 * Value - Value to write
1258 * Width - Number of bits
1259 *
1260 * RETURN: None
1261 *
1262 * DESCRIPTION: Write data to a physical memory address
1263 *
1264 *****************************************************************************/
1265
1266 ACPI_STATUS
1267 AcpiOsWriteMemory (
1268 ACPI_PHYSICAL_ADDRESS Address,
1269 UINT32 Value,
1270 UINT32 Width)
1271 {
1272
1273 return (AE_OK);
1274 }
1275
1276
1277 /******************************************************************************
1278 *
1279 * FUNCTION: AcpiOsSignal
1280 *
1281 * PARAMETERS: Function - ACPI CA signal function code
1282 * Info - Pointer to function-dependent structure
1283 *
1284 * RETURN: Status
1285 *
1286 * DESCRIPTION: Miscellaneous functions. Example implementation only.
1287 *
1288 *****************************************************************************/
1289
1290 ACPI_STATUS
1291 AcpiOsSignal (
1292 UINT32 Function,
1293 void *Info)
1294 {
1295
1296 switch (Function)
1297 {
1298 case ACPI_SIGNAL_FATAL:
1299 break;
1300
1301 case ACPI_SIGNAL_BREAKPOINT:
1302 break;
1303
1304 default:
1305 break;
1306 }
1307
1308 return (AE_OK);
1309 }
1310
1311
1312 /******************************************************************************
1313 *
1314 * FUNCTION: Local cache interfaces
1315 *
1316 * DESCRIPTION: Implements cache interfaces via malloc/free for testing
1317 * purposes only.
1318 *
1319 *****************************************************************************/
1320
1321 #ifndef ACPI_USE_LOCAL_CACHE
1322
1323 ACPI_STATUS
1324 AcpiOsCreateCache (
1325 char *CacheName,
1326 UINT16 ObjectSize,
1327 UINT16 MaxDepth,
1328 ACPI_CACHE_T **ReturnCache)
1329 {
1330 ACPI_MEMORY_LIST *NewCache;
1331
1332
1333 NewCache = malloc (sizeof (ACPI_MEMORY_LIST));
1334 if (!NewCache)
1335 {
1336 return (AE_NO_MEMORY);
1337 }
1338
1339 memset (NewCache, 0, sizeof (ACPI_MEMORY_LIST));
1340 NewCache->LinkOffset = 8;
1341 NewCache->ListName = CacheName;
1342 NewCache->ObjectSize = ObjectSize;
1343 NewCache->MaxDepth = MaxDepth;
1344
1345 *ReturnCache = (ACPI_CACHE_T) NewCache;
1346 return (AE_OK);
1347 }
1348
1349 ACPI_STATUS
1350 AcpiOsDeleteCache (
1351 ACPI_CACHE_T *Cache)
1352 {
1353 free (Cache);
1354 return (AE_OK);
1355 }
1356
1357 ACPI_STATUS
1358 AcpiOsPurgeCache (
1359 ACPI_CACHE_T *Cache)
1360 {
1361 return (AE_OK);
1362 }
1363
1364 void *
1365 AcpiOsAcquireObject (
1366 ACPI_CACHE_T *Cache)
1367 {
1368 void *NewObject;
1369
1370 NewObject = malloc (((ACPI_MEMORY_LIST *) Cache)->ObjectSize);
1371 memset (NewObject, 0, ((ACPI_MEMORY_LIST *) Cache)->ObjectSize);
1372
1373 return (NewObject);
1374 }
1375
1376 ACPI_STATUS
1377 AcpiOsReleaseObject (
1378 ACPI_CACHE_T *Cache,
1379 void *Object)
1380 {
1381 free (Object);
1382 return (AE_OK);
1383 }
1384
1385 #endif /* ACPI_USE_LOCAL_CACHE */
1386
1387
1388 /* Optional multi-thread support */
1389
1390 #ifndef ACPI_SINGLE_THREADED
1391 /******************************************************************************
1392 *
1393 * FUNCTION: AcpiOsGetThreadId
1394 *
1395 * PARAMETERS: None
1396 *
1397 * RETURN: Id of the running thread
1398 *
1399 * DESCRIPTION: Get the Id of the current (running) thread
1400 *
1401 *****************************************************************************/
1402
1403 ACPI_THREAD_ID
1404 AcpiOsGetThreadId (
1405 void)
1406 {
1407 DWORD ThreadId;
1408
1409 /* Ensure ID is never 0 */
1410
1411 ThreadId = GetCurrentThreadId ();
1412 return ((ACPI_THREAD_ID) (ThreadId + 1));
1413 }
1414
1415
1416 /******************************************************************************
1417 *
1418 * FUNCTION: AcpiOsExecute
1419 *
1420 * PARAMETERS: Type - Type of execution
1421 * Function - Address of the function to execute
1422 * Context - Passed as a parameter to the function
1423 *
1424 * RETURN: Status
1425 *
1426 * DESCRIPTION: Execute a new thread
1427 *
1428 *****************************************************************************/
1429
1430 ACPI_STATUS
1431 AcpiOsExecute (
1432 ACPI_EXECUTE_TYPE Type,
1433 ACPI_OSD_EXEC_CALLBACK Function,
1434 void *Context)
1435 {
1436
1437 _beginthread (Function, (unsigned) 0, Context);
1438 return (0);
1439 }
1440
1441 #endif /* ACPI_SINGLE_THREADED */
1442
1443