osunixxf.c revision 1.1.1.4 1 /******************************************************************************
2 *
3 * Module Name: osunixxf - UNIX OSL interfaces
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2013, 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
45 /*
46 * These interfaces are required in order to compile the ASL compiler and the
47 * various ACPICA tools under Linux or other Unix-like system.
48 */
49 #include "acpi.h"
50 #include "accommon.h"
51 #include "amlcode.h"
52 #include "acparser.h"
53 #include "acdebug.h"
54
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <stdarg.h>
58 #include <unistd.h>
59 #include <sys/time.h>
60 #include <semaphore.h>
61 #include <pthread.h>
62 #include <errno.h>
63
64 #define _COMPONENT ACPI_OS_SERVICES
65 ACPI_MODULE_NAME ("osunixxf")
66
67
68 FILE *AcpiGbl_OutputFile;
69 BOOLEAN AcpiGbl_DebugTimeout = FALSE;
70
71
72 /* Upcalls to AcpiExec */
73
74 ACPI_PHYSICAL_ADDRESS
75 AeLocalGetRootPointer (
76 void);
77
78 void
79 AeTableOverride (
80 ACPI_TABLE_HEADER *ExistingTable,
81 ACPI_TABLE_HEADER **NewTable);
82
83 typedef void* (*PTHREAD_CALLBACK) (void *);
84
85 /* Buffer used by AcpiOsVprintf */
86
87 #define ACPI_VPRINTF_BUFFER_SIZE 512
88 #define _ASCII_NEWLINE '\n'
89
90 /* Terminal support for AcpiExec only */
91
92 #ifdef ACPI_EXEC_APP
93 #include <termios.h>
94
95 struct termios OriginalTermAttributes;
96
97 ACPI_STATUS
98 AcpiUtReadLine (
99 char *Buffer,
100 UINT32 BufferLength,
101 UINT32 *BytesRead);
102
103 static void
104 OsEnterLineEditMode (
105 void);
106
107 static void
108 OsExitLineEditMode (
109 void);
110
111
112 /******************************************************************************
113 *
114 * FUNCTION: OsEnterLineEditMode, OsExitLineEditMode
115 *
116 * PARAMETERS: None
117 *
118 * RETURN: None
119 *
120 * DESCRIPTION: Enter/Exit the raw character input mode for the terminal.
121 *
122 * Interactive line-editing support for the AML debugger. Used with the
123 * common/acgetline module.
124 *
125 * readline() is not used because of non-portability. It is not available
126 * on all systems, and if it is, often the package must be manually installed.
127 *
128 * Therefore, we use the POSIX tcgetattr/tcsetattr and do the minimal line
129 * editing that we need in AcpiOsGetLine.
130 *
131 * If the POSIX tcgetattr/tcsetattr interfaces are unavailable, these
132 * calls will also work:
133 * For OsEnterLineEditMode: system ("stty cbreak -echo")
134 * For OsExitLineEditMode: system ("stty cooked echo")
135 *
136 *****************************************************************************/
137
138 static void
139 OsEnterLineEditMode (
140 void)
141 {
142 struct termios LocalTermAttributes;
143
144
145 /* Get and keep the original attributes */
146
147 if (tcgetattr (STDIN_FILENO, &OriginalTermAttributes))
148 {
149 fprintf (stderr, "Could not get/set terminal attributes!\n");
150 return;
151 }
152
153 /* Set the new attributes to enable raw character input */
154
155 memcpy (&LocalTermAttributes, &OriginalTermAttributes,
156 sizeof (struct termios));
157
158 LocalTermAttributes.c_lflag &= ~(ICANON | ECHO);
159 LocalTermAttributes.c_cc[VMIN] = 1;
160 LocalTermAttributes.c_cc[VTIME] = 0;
161
162 tcsetattr (STDIN_FILENO, TCSANOW, &LocalTermAttributes);
163 }
164
165 static void
166 OsExitLineEditMode (
167 void)
168 {
169 /* Set terminal attributes back to the original values */
170
171 tcsetattr (STDIN_FILENO, TCSANOW, &OriginalTermAttributes);
172 }
173
174
175 #else
176
177 /* These functions are not needed for other ACPICA utilities */
178
179 #define OsEnterLineEditMode()
180 #define OsExitLineEditMode()
181 #endif
182
183
184 /******************************************************************************
185 *
186 * FUNCTION: AcpiOsInitialize, AcpiOsTerminate
187 *
188 * PARAMETERS: None
189 *
190 * RETURN: Status
191 *
192 * DESCRIPTION: Initialize and terminate this module.
193 *
194 *****************************************************************************/
195
196 ACPI_STATUS
197 AcpiOsInitialize (
198 void)
199 {
200
201 AcpiGbl_OutputFile = stdout;
202
203 OsEnterLineEditMode ();
204 return (AE_OK);
205 }
206
207 ACPI_STATUS
208 AcpiOsTerminate (
209 void)
210 {
211
212 OsExitLineEditMode ();
213 return (AE_OK);
214 }
215
216
217 /******************************************************************************
218 *
219 * FUNCTION: AcpiOsGetRootPointer
220 *
221 * PARAMETERS: None
222 *
223 * RETURN: RSDP physical address
224 *
225 * DESCRIPTION: Gets the ACPI root pointer (RSDP)
226 *
227 *****************************************************************************/
228
229 ACPI_PHYSICAL_ADDRESS
230 AcpiOsGetRootPointer (
231 void)
232 {
233
234 return (AeLocalGetRootPointer ());
235 }
236
237
238 /******************************************************************************
239 *
240 * FUNCTION: AcpiOsPredefinedOverride
241 *
242 * PARAMETERS: InitVal - Initial value of the predefined object
243 * NewVal - The new value for the object
244 *
245 * RETURN: Status, pointer to value. Null pointer returned if not
246 * overriding.
247 *
248 * DESCRIPTION: Allow the OS to override predefined names
249 *
250 *****************************************************************************/
251
252 ACPI_STATUS
253 AcpiOsPredefinedOverride (
254 const ACPI_PREDEFINED_NAMES *InitVal,
255 ACPI_STRING *NewVal)
256 {
257
258 if (!InitVal || !NewVal)
259 {
260 return (AE_BAD_PARAMETER);
261 }
262
263 *NewVal = NULL;
264 return (AE_OK);
265 }
266
267
268 /******************************************************************************
269 *
270 * FUNCTION: AcpiOsTableOverride
271 *
272 * PARAMETERS: ExistingTable - Header of current table (probably
273 * firmware)
274 * NewTable - Where an entire new table is returned.
275 *
276 * RETURN: Status, pointer to new table. Null pointer returned if no
277 * table is available to override
278 *
279 * DESCRIPTION: Return a different version of a table if one is available
280 *
281 *****************************************************************************/
282
283 ACPI_STATUS
284 AcpiOsTableOverride (
285 ACPI_TABLE_HEADER *ExistingTable,
286 ACPI_TABLE_HEADER **NewTable)
287 {
288
289 if (!ExistingTable || !NewTable)
290 {
291 return (AE_BAD_PARAMETER);
292 }
293
294 *NewTable = NULL;
295
296 #ifdef ACPI_EXEC_APP
297
298 AeTableOverride (ExistingTable, NewTable);
299 return (AE_OK);
300 #else
301
302 return (AE_NO_ACPI_TABLES);
303 #endif
304 }
305
306
307 /******************************************************************************
308 *
309 * FUNCTION: AcpiOsPhysicalTableOverride
310 *
311 * PARAMETERS: ExistingTable - Header of current table (probably firmware)
312 * NewAddress - Where new table address is returned
313 * (Physical address)
314 * NewTableLength - Where new table length is returned
315 *
316 * RETURN: Status, address/length of new table. Null pointer returned
317 * if no table is available to override.
318 *
319 * DESCRIPTION: Returns AE_SUPPORT, function not used in user space.
320 *
321 *****************************************************************************/
322
323 ACPI_STATUS
324 AcpiOsPhysicalTableOverride (
325 ACPI_TABLE_HEADER *ExistingTable,
326 ACPI_PHYSICAL_ADDRESS *NewAddress,
327 UINT32 *NewTableLength)
328 {
329
330 return (AE_SUPPORT);
331 }
332
333
334 /******************************************************************************
335 *
336 * FUNCTION: AcpiOsRedirectOutput
337 *
338 * PARAMETERS: Destination - An open file handle/pointer
339 *
340 * RETURN: None
341 *
342 * DESCRIPTION: Causes redirect of AcpiOsPrintf and AcpiOsVprintf
343 *
344 *****************************************************************************/
345
346 void
347 AcpiOsRedirectOutput (
348 void *Destination)
349 {
350
351 AcpiGbl_OutputFile = Destination;
352 }
353
354
355 /******************************************************************************
356 *
357 * FUNCTION: AcpiOsPrintf
358 *
359 * PARAMETERS: fmt, ... - Standard printf format
360 *
361 * RETURN: None
362 *
363 * DESCRIPTION: Formatted output. Note: very similar to AcpiOsVprintf
364 * (performance), changes should be tracked in both functions.
365 *
366 *****************************************************************************/
367
368 void ACPI_INTERNAL_VAR_XFACE
369 AcpiOsPrintf (
370 const char *Fmt,
371 ...)
372 {
373 va_list Args;
374 UINT8 Flags;
375
376
377 Flags = AcpiGbl_DbOutputFlags;
378 if (Flags & ACPI_DB_REDIRECTABLE_OUTPUT)
379 {
380 /* Output is directable to either a file (if open) or the console */
381
382 if (AcpiGbl_DebugFile)
383 {
384 /* Output file is open, send the output there */
385
386 va_start (Args, Fmt);
387 vfprintf (AcpiGbl_DebugFile, Fmt, Args);
388 va_end (Args);
389 }
390 else
391 {
392 /* No redirection, send output to console (once only!) */
393
394 Flags |= ACPI_DB_CONSOLE_OUTPUT;
395 }
396 }
397
398 if (Flags & ACPI_DB_CONSOLE_OUTPUT)
399 {
400 va_start (Args, Fmt);
401 vfprintf (AcpiGbl_OutputFile, Fmt, Args);
402 va_end (Args);
403 }
404 }
405
406
407 /******************************************************************************
408 *
409 * FUNCTION: AcpiOsVprintf
410 *
411 * PARAMETERS: fmt - Standard printf format
412 * args - Argument list
413 *
414 * RETURN: None
415 *
416 * DESCRIPTION: Formatted output with argument list pointer. Note: very
417 * similar to AcpiOsPrintf, changes should be tracked in both
418 * functions.
419 *
420 *****************************************************************************/
421
422 void
423 AcpiOsVprintf (
424 const char *Fmt,
425 va_list Args)
426 {
427 UINT8 Flags;
428 char Buffer[ACPI_VPRINTF_BUFFER_SIZE];
429
430
431 /*
432 * We build the output string in a local buffer because we may be
433 * outputting the buffer twice. Using vfprintf is problematic because
434 * some implementations modify the args pointer/structure during
435 * execution. Thus, we use the local buffer for portability.
436 *
437 * Note: Since this module is intended for use by the various ACPICA
438 * utilities/applications, we can safely declare the buffer on the stack.
439 * Also, This function is used for relatively small error messages only.
440 */
441 vsnprintf (Buffer, ACPI_VPRINTF_BUFFER_SIZE, Fmt, Args);
442
443 Flags = AcpiGbl_DbOutputFlags;
444 if (Flags & ACPI_DB_REDIRECTABLE_OUTPUT)
445 {
446 /* Output is directable to either a file (if open) or the console */
447
448 if (AcpiGbl_DebugFile)
449 {
450 /* Output file is open, send the output there */
451
452 fputs (Buffer, AcpiGbl_DebugFile);
453 }
454 else
455 {
456 /* No redirection, send output to console (once only!) */
457
458 Flags |= ACPI_DB_CONSOLE_OUTPUT;
459 }
460 }
461
462 if (Flags & ACPI_DB_CONSOLE_OUTPUT)
463 {
464 fputs (Buffer, AcpiGbl_OutputFile);
465 }
466 }
467
468
469 #ifndef ACPI_EXEC_APP
470 /******************************************************************************
471 *
472 * FUNCTION: AcpiOsGetLine
473 *
474 * PARAMETERS: Buffer - Where to return the command line
475 * BufferLength - Maximum length of Buffer
476 * BytesRead - Where the actual byte count is returned
477 *
478 * RETURN: Status and actual bytes read
479 *
480 * DESCRIPTION: Get the next input line from the terminal. NOTE: For the
481 * AcpiExec utility, we use the acgetline module instead to
482 * provide line-editing and history support.
483 *
484 *****************************************************************************/
485
486 ACPI_STATUS
487 AcpiOsGetLine (
488 char *Buffer,
489 UINT32 BufferLength,
490 UINT32 *BytesRead)
491 {
492 int InputChar;
493 UINT32 EndOfLine;
494
495
496 /* Standard AcpiOsGetLine for all utilities except AcpiExec */
497
498 for (EndOfLine = 0; ; EndOfLine++)
499 {
500 if (EndOfLine >= BufferLength)
501 {
502 return (AE_BUFFER_OVERFLOW);
503 }
504
505 if ((InputChar = getchar ()) == EOF)
506 {
507 return (AE_ERROR);
508 }
509
510 if (!InputChar || InputChar == _ASCII_NEWLINE)
511 {
512 break;
513 }
514
515 Buffer[EndOfLine] = (char) InputChar;
516 }
517
518 /* Null terminate the buffer */
519
520 Buffer[EndOfLine] = 0;
521
522 /* Return the number of bytes in the string */
523
524 if (BytesRead)
525 {
526 *BytesRead = EndOfLine;
527 }
528
529 return (AE_OK);
530 }
531 #endif
532
533
534 /******************************************************************************
535 *
536 * FUNCTION: AcpiOsMapMemory
537 *
538 * PARAMETERS: where - Physical address of memory to be mapped
539 * length - How much memory to map
540 *
541 * RETURN: Pointer to mapped memory. Null on error.
542 *
543 * DESCRIPTION: Map physical memory into caller's address space
544 *
545 *****************************************************************************/
546
547 void *
548 AcpiOsMapMemory (
549 ACPI_PHYSICAL_ADDRESS where,
550 ACPI_SIZE length)
551 {
552
553 return (ACPI_TO_POINTER ((ACPI_SIZE) where));
554 }
555
556
557 /******************************************************************************
558 *
559 * FUNCTION: AcpiOsUnmapMemory
560 *
561 * PARAMETERS: where - Logical address of memory to be unmapped
562 * length - How much memory to unmap
563 *
564 * RETURN: None.
565 *
566 * DESCRIPTION: Delete a previously created mapping. Where and Length must
567 * correspond to a previous mapping exactly.
568 *
569 *****************************************************************************/
570
571 void
572 AcpiOsUnmapMemory (
573 void *where,
574 ACPI_SIZE length)
575 {
576
577 return;
578 }
579
580
581 /******************************************************************************
582 *
583 * FUNCTION: AcpiOsAllocate
584 *
585 * PARAMETERS: Size - Amount to allocate, in bytes
586 *
587 * RETURN: Pointer to the new allocation. Null on error.
588 *
589 * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS.
590 *
591 *****************************************************************************/
592
593 void *
594 AcpiOsAllocate (
595 ACPI_SIZE size)
596 {
597 void *Mem;
598
599
600 Mem = (void *) malloc ((size_t) size);
601 return (Mem);
602 }
603
604
605 /******************************************************************************
606 *
607 * FUNCTION: AcpiOsFree
608 *
609 * PARAMETERS: mem - Pointer to previously allocated memory
610 *
611 * RETURN: None.
612 *
613 * DESCRIPTION: Free memory allocated via AcpiOsAllocate
614 *
615 *****************************************************************************/
616
617 void
618 AcpiOsFree (
619 void *mem)
620 {
621
622 free (mem);
623 }
624
625
626 #ifdef ACPI_SINGLE_THREADED
627 /******************************************************************************
628 *
629 * FUNCTION: Semaphore stub functions
630 *
631 * DESCRIPTION: Stub functions used for single-thread applications that do
632 * not require semaphore synchronization. Full implementations
633 * of these functions appear after the stubs.
634 *
635 *****************************************************************************/
636
637 ACPI_STATUS
638 AcpiOsCreateSemaphore (
639 UINT32 MaxUnits,
640 UINT32 InitialUnits,
641 ACPI_HANDLE *OutHandle)
642 {
643 *OutHandle = (ACPI_HANDLE) 1;
644 return (AE_OK);
645 }
646
647 ACPI_STATUS
648 AcpiOsDeleteSemaphore (
649 ACPI_HANDLE Handle)
650 {
651 return (AE_OK);
652 }
653
654 ACPI_STATUS
655 AcpiOsWaitSemaphore (
656 ACPI_HANDLE Handle,
657 UINT32 Units,
658 UINT16 Timeout)
659 {
660 return (AE_OK);
661 }
662
663 ACPI_STATUS
664 AcpiOsSignalSemaphore (
665 ACPI_HANDLE Handle,
666 UINT32 Units)
667 {
668 return (AE_OK);
669 }
670
671 #else
672 /******************************************************************************
673 *
674 * FUNCTION: AcpiOsCreateSemaphore
675 *
676 * PARAMETERS: InitialUnits - Units to be assigned to the new semaphore
677 * OutHandle - Where a handle will be returned
678 *
679 * RETURN: Status
680 *
681 * DESCRIPTION: Create an OS semaphore
682 *
683 *****************************************************************************/
684
685 ACPI_STATUS
686 AcpiOsCreateSemaphore (
687 UINT32 MaxUnits,
688 UINT32 InitialUnits,
689 ACPI_HANDLE *OutHandle)
690 {
691 sem_t *Sem;
692
693
694 if (!OutHandle)
695 {
696 return (AE_BAD_PARAMETER);
697 }
698
699 #ifdef __APPLE__
700 {
701 char *SemaphoreName = tmpnam (NULL);
702
703 Sem = sem_open (SemaphoreName, O_EXCL|O_CREAT, 0755, InitialUnits);
704 if (!Sem)
705 {
706 return (AE_NO_MEMORY);
707 }
708 sem_unlink (SemaphoreName); /* This just deletes the name */
709 }
710
711 #else
712 Sem = AcpiOsAllocate (sizeof (sem_t));
713 if (!Sem)
714 {
715 return (AE_NO_MEMORY);
716 }
717
718 if (sem_init (Sem, 0, InitialUnits) == -1)
719 {
720 AcpiOsFree (Sem);
721 return (AE_BAD_PARAMETER);
722 }
723 #endif
724
725 *OutHandle = (ACPI_HANDLE) Sem;
726 return (AE_OK);
727 }
728
729
730 /******************************************************************************
731 *
732 * FUNCTION: AcpiOsDeleteSemaphore
733 *
734 * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore
735 *
736 * RETURN: Status
737 *
738 * DESCRIPTION: Delete an OS semaphore
739 *
740 *****************************************************************************/
741
742 ACPI_STATUS
743 AcpiOsDeleteSemaphore (
744 ACPI_HANDLE Handle)
745 {
746 sem_t *Sem = (sem_t *) Handle;
747
748
749 if (!Sem)
750 {
751 return (AE_BAD_PARAMETER);
752 }
753
754 if (sem_destroy (Sem) == -1)
755 {
756 return (AE_BAD_PARAMETER);
757 }
758
759 return (AE_OK);
760 }
761
762
763 /******************************************************************************
764 *
765 * FUNCTION: AcpiOsWaitSemaphore
766 *
767 * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore
768 * Units - How many units to wait for
769 * MsecTimeout - How long to wait (milliseconds)
770 *
771 * RETURN: Status
772 *
773 * DESCRIPTION: Wait for units
774 *
775 *****************************************************************************/
776
777 ACPI_STATUS
778 AcpiOsWaitSemaphore (
779 ACPI_HANDLE Handle,
780 UINT32 Units,
781 UINT16 MsecTimeout)
782 {
783 ACPI_STATUS Status = AE_OK;
784 sem_t *Sem = (sem_t *) Handle;
785 #ifndef ACPI_USE_ALTERNATE_TIMEOUT
786 struct timespec Time;
787 int RetVal;
788 #endif
789
790
791 if (!Sem)
792 {
793 return (AE_BAD_PARAMETER);
794 }
795
796 switch (MsecTimeout)
797 {
798 /*
799 * No Wait:
800 * --------
801 * A zero timeout value indicates that we shouldn't wait - just
802 * acquire the semaphore if available otherwise return AE_TIME
803 * (a.k.a. 'would block').
804 */
805 case 0:
806
807 if (sem_trywait(Sem) == -1)
808 {
809 Status = (AE_TIME);
810 }
811 break;
812
813 /* Wait Indefinitely */
814
815 case ACPI_WAIT_FOREVER:
816
817 if (sem_wait (Sem))
818 {
819 Status = (AE_TIME);
820 }
821 break;
822
823 /* Wait with MsecTimeout */
824
825 default:
826
827 #ifdef ACPI_USE_ALTERNATE_TIMEOUT
828 /*
829 * Alternate timeout mechanism for environments where
830 * sem_timedwait is not available or does not work properly.
831 */
832 while (MsecTimeout)
833 {
834 if (sem_trywait (Sem) == 0)
835 {
836 /* Got the semaphore */
837 return (AE_OK);
838 }
839
840 if (MsecTimeout >= 10)
841 {
842 MsecTimeout -= 10;
843 usleep (10 * ACPI_USEC_PER_MSEC); /* ten milliseconds */
844 }
845 else
846 {
847 MsecTimeout--;
848 usleep (ACPI_USEC_PER_MSEC); /* one millisecond */
849 }
850 }
851 Status = (AE_TIME);
852 #else
853 /*
854 * The interface to sem_timedwait is an absolute time, so we need to
855 * get the current time, then add in the millisecond Timeout value.
856 */
857 if (clock_gettime (CLOCK_REALTIME, &Time) == -1)
858 {
859 perror ("clock_gettime");
860 return (AE_TIME);
861 }
862
863 Time.tv_sec += (MsecTimeout / ACPI_MSEC_PER_SEC);
864 Time.tv_nsec += ((MsecTimeout % ACPI_MSEC_PER_SEC) * ACPI_NSEC_PER_MSEC);
865
866 /* Handle nanosecond overflow (field must be less than one second) */
867
868 if (Time.tv_nsec >= ACPI_NSEC_PER_SEC)
869 {
870 Time.tv_sec += (Time.tv_nsec / ACPI_NSEC_PER_SEC);
871 Time.tv_nsec = (Time.tv_nsec % ACPI_NSEC_PER_SEC);
872 }
873
874 while (((RetVal = sem_timedwait (Sem, &Time)) == -1) && (errno == EINTR))
875 {
876 continue;
877 }
878
879 if (RetVal != 0)
880 {
881 if (errno != ETIMEDOUT)
882 {
883 perror ("sem_timedwait");
884 }
885 Status = (AE_TIME);
886 }
887 #endif
888 break;
889 }
890
891 return (Status);
892 }
893
894
895 /******************************************************************************
896 *
897 * FUNCTION: AcpiOsSignalSemaphore
898 *
899 * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore
900 * Units - Number of units to send
901 *
902 * RETURN: Status
903 *
904 * DESCRIPTION: Send units
905 *
906 *****************************************************************************/
907
908 ACPI_STATUS
909 AcpiOsSignalSemaphore (
910 ACPI_HANDLE Handle,
911 UINT32 Units)
912 {
913 sem_t *Sem = (sem_t *)Handle;
914
915
916 if (!Sem)
917 {
918 return (AE_BAD_PARAMETER);
919 }
920
921 if (sem_post (Sem) == -1)
922 {
923 return (AE_LIMIT);
924 }
925
926 return (AE_OK);
927 }
928
929 #endif /* ACPI_SINGLE_THREADED */
930
931
932 /******************************************************************************
933 *
934 * FUNCTION: Spinlock interfaces
935 *
936 * DESCRIPTION: Map these interfaces to semaphore interfaces
937 *
938 *****************************************************************************/
939
940 ACPI_STATUS
941 AcpiOsCreateLock (
942 ACPI_SPINLOCK *OutHandle)
943 {
944
945 return (AcpiOsCreateSemaphore (1, 1, OutHandle));
946 }
947
948
949 void
950 AcpiOsDeleteLock (
951 ACPI_SPINLOCK Handle)
952 {
953 AcpiOsDeleteSemaphore (Handle);
954 }
955
956
957 ACPI_CPU_FLAGS
958 AcpiOsAcquireLock (
959 ACPI_HANDLE Handle)
960 {
961 AcpiOsWaitSemaphore (Handle, 1, 0xFFFF);
962 return (0);
963 }
964
965
966 void
967 AcpiOsReleaseLock (
968 ACPI_SPINLOCK Handle,
969 ACPI_CPU_FLAGS Flags)
970 {
971 AcpiOsSignalSemaphore (Handle, 1);
972 }
973
974
975 /******************************************************************************
976 *
977 * FUNCTION: AcpiOsInstallInterruptHandler
978 *
979 * PARAMETERS: InterruptNumber - Level handler should respond to.
980 * Isr - Address of the ACPI interrupt handler
981 * ExceptPtr - Where status is returned
982 *
983 * RETURN: Handle to the newly installed handler.
984 *
985 * DESCRIPTION: Install an interrupt handler. Used to install the ACPI
986 * OS-independent handler.
987 *
988 *****************************************************************************/
989
990 UINT32
991 AcpiOsInstallInterruptHandler (
992 UINT32 InterruptNumber,
993 ACPI_OSD_HANDLER ServiceRoutine,
994 void *Context)
995 {
996
997 return (AE_OK);
998 }
999
1000
1001 /******************************************************************************
1002 *
1003 * FUNCTION: AcpiOsRemoveInterruptHandler
1004 *
1005 * PARAMETERS: Handle - Returned when handler was installed
1006 *
1007 * RETURN: Status
1008 *
1009 * DESCRIPTION: Uninstalls an interrupt handler.
1010 *
1011 *****************************************************************************/
1012
1013 ACPI_STATUS
1014 AcpiOsRemoveInterruptHandler (
1015 UINT32 InterruptNumber,
1016 ACPI_OSD_HANDLER ServiceRoutine)
1017 {
1018
1019 return (AE_OK);
1020 }
1021
1022
1023 /******************************************************************************
1024 *
1025 * FUNCTION: AcpiOsStall
1026 *
1027 * PARAMETERS: microseconds - Time to sleep
1028 *
1029 * RETURN: Blocks until sleep is completed.
1030 *
1031 * DESCRIPTION: Sleep at microsecond granularity
1032 *
1033 *****************************************************************************/
1034
1035 void
1036 AcpiOsStall (
1037 UINT32 microseconds)
1038 {
1039
1040 if (microseconds)
1041 {
1042 usleep (microseconds);
1043 }
1044 }
1045
1046
1047 /******************************************************************************
1048 *
1049 * FUNCTION: AcpiOsSleep
1050 *
1051 * PARAMETERS: milliseconds - Time to sleep
1052 *
1053 * RETURN: Blocks until sleep is completed.
1054 *
1055 * DESCRIPTION: Sleep at millisecond granularity
1056 *
1057 *****************************************************************************/
1058
1059 void
1060 AcpiOsSleep (
1061 UINT64 milliseconds)
1062 {
1063
1064 /* Sleep for whole seconds */
1065
1066 sleep (milliseconds / ACPI_MSEC_PER_SEC);
1067
1068 /*
1069 * Sleep for remaining microseconds.
1070 * Arg to usleep() is in usecs and must be less than 1,000,000 (1 second).
1071 */
1072 usleep ((milliseconds % ACPI_MSEC_PER_SEC) * ACPI_USEC_PER_MSEC);
1073 }
1074
1075
1076 /******************************************************************************
1077 *
1078 * FUNCTION: AcpiOsGetTimer
1079 *
1080 * PARAMETERS: None
1081 *
1082 * RETURN: Current time in 100 nanosecond units
1083 *
1084 * DESCRIPTION: Get the current system time
1085 *
1086 *****************************************************************************/
1087
1088 UINT64
1089 AcpiOsGetTimer (
1090 void)
1091 {
1092 struct timeval time;
1093
1094
1095 /* This timer has sufficient resolution for user-space application code */
1096
1097 gettimeofday (&time, NULL);
1098
1099 /* (Seconds * 10^7 = 100ns(10^-7)) + (Microseconds(10^-6) * 10^1 = 100ns) */
1100
1101 return (((UINT64) time.tv_sec * ACPI_100NSEC_PER_SEC) +
1102 ((UINT64) time.tv_usec * ACPI_100NSEC_PER_USEC));
1103 }
1104
1105
1106 /******************************************************************************
1107 *
1108 * FUNCTION: AcpiOsReadPciConfiguration
1109 *
1110 * PARAMETERS: PciId - Seg/Bus/Dev
1111 * Register - Device Register
1112 * Value - Buffer where value is placed
1113 * Width - Number of bits
1114 *
1115 * RETURN: Status
1116 *
1117 * DESCRIPTION: Read data from PCI configuration space
1118 *
1119 *****************************************************************************/
1120
1121 ACPI_STATUS
1122 AcpiOsReadPciConfiguration (
1123 ACPI_PCI_ID *PciId,
1124 UINT32 Register,
1125 UINT64 *Value,
1126 UINT32 Width)
1127 {
1128
1129 *Value = 0;
1130 return (AE_OK);
1131 }
1132
1133
1134 /******************************************************************************
1135 *
1136 * FUNCTION: AcpiOsWritePciConfiguration
1137 *
1138 * PARAMETERS: PciId - Seg/Bus/Dev
1139 * Register - Device Register
1140 * Value - Value to be written
1141 * Width - Number of bits
1142 *
1143 * RETURN: Status.
1144 *
1145 * DESCRIPTION: Write data to PCI configuration space
1146 *
1147 *****************************************************************************/
1148
1149 ACPI_STATUS
1150 AcpiOsWritePciConfiguration (
1151 ACPI_PCI_ID *PciId,
1152 UINT32 Register,
1153 UINT64 Value,
1154 UINT32 Width)
1155 {
1156
1157 return (AE_OK);
1158 }
1159
1160
1161 /******************************************************************************
1162 *
1163 * FUNCTION: AcpiOsReadPort
1164 *
1165 * PARAMETERS: Address - Address of I/O port/register to read
1166 * Value - Where value is placed
1167 * Width - Number of bits
1168 *
1169 * RETURN: Value read from port
1170 *
1171 * DESCRIPTION: Read data from an I/O port or register
1172 *
1173 *****************************************************************************/
1174
1175 ACPI_STATUS
1176 AcpiOsReadPort (
1177 ACPI_IO_ADDRESS Address,
1178 UINT32 *Value,
1179 UINT32 Width)
1180 {
1181
1182 switch (Width)
1183 {
1184 case 8:
1185
1186 *Value = 0xFF;
1187 break;
1188
1189 case 16:
1190
1191 *Value = 0xFFFF;
1192 break;
1193
1194 case 32:
1195
1196 *Value = 0xFFFFFFFF;
1197 break;
1198
1199 default:
1200
1201 return (AE_BAD_PARAMETER);
1202 }
1203
1204 return (AE_OK);
1205 }
1206
1207
1208 /******************************************************************************
1209 *
1210 * FUNCTION: AcpiOsWritePort
1211 *
1212 * PARAMETERS: Address - Address of I/O port/register to write
1213 * Value - Value to write
1214 * Width - Number of bits
1215 *
1216 * RETURN: None
1217 *
1218 * DESCRIPTION: Write data to an I/O port or register
1219 *
1220 *****************************************************************************/
1221
1222 ACPI_STATUS
1223 AcpiOsWritePort (
1224 ACPI_IO_ADDRESS Address,
1225 UINT32 Value,
1226 UINT32 Width)
1227 {
1228
1229 return (AE_OK);
1230 }
1231
1232
1233 /******************************************************************************
1234 *
1235 * FUNCTION: AcpiOsReadMemory
1236 *
1237 * PARAMETERS: Address - Physical Memory Address to read
1238 * Value - Where value is placed
1239 * Width - Number of bits (8,16,32, or 64)
1240 *
1241 * RETURN: Value read from physical memory address. Always returned
1242 * as a 64-bit integer, regardless of the read width.
1243 *
1244 * DESCRIPTION: Read data from a physical memory address
1245 *
1246 *****************************************************************************/
1247
1248 ACPI_STATUS
1249 AcpiOsReadMemory (
1250 ACPI_PHYSICAL_ADDRESS Address,
1251 UINT64 *Value,
1252 UINT32 Width)
1253 {
1254
1255 switch (Width)
1256 {
1257 case 8:
1258 case 16:
1259 case 32:
1260 case 64:
1261
1262 *Value = 0;
1263 break;
1264
1265 default:
1266
1267 return (AE_BAD_PARAMETER);
1268 }
1269 return (AE_OK);
1270 }
1271
1272
1273 /******************************************************************************
1274 *
1275 * FUNCTION: AcpiOsWriteMemory
1276 *
1277 * PARAMETERS: Address - Physical Memory Address to write
1278 * Value - Value to write
1279 * Width - Number of bits (8,16,32, or 64)
1280 *
1281 * RETURN: None
1282 *
1283 * DESCRIPTION: Write data to a physical memory address
1284 *
1285 *****************************************************************************/
1286
1287 ACPI_STATUS
1288 AcpiOsWriteMemory (
1289 ACPI_PHYSICAL_ADDRESS Address,
1290 UINT64 Value,
1291 UINT32 Width)
1292 {
1293
1294 return (AE_OK);
1295 }
1296
1297
1298 /******************************************************************************
1299 *
1300 * FUNCTION: AcpiOsReadable
1301 *
1302 * PARAMETERS: Pointer - Area to be verified
1303 * Length - Size of area
1304 *
1305 * RETURN: TRUE if readable for entire length
1306 *
1307 * DESCRIPTION: Verify that a pointer is valid for reading
1308 *
1309 *****************************************************************************/
1310
1311 BOOLEAN
1312 AcpiOsReadable (
1313 void *Pointer,
1314 ACPI_SIZE Length)
1315 {
1316
1317 return (TRUE);
1318 }
1319
1320
1321 /******************************************************************************
1322 *
1323 * FUNCTION: AcpiOsWritable
1324 *
1325 * PARAMETERS: Pointer - Area to be verified
1326 * Length - Size of area
1327 *
1328 * RETURN: TRUE if writable for entire length
1329 *
1330 * DESCRIPTION: Verify that a pointer is valid for writing
1331 *
1332 *****************************************************************************/
1333
1334 BOOLEAN
1335 AcpiOsWritable (
1336 void *Pointer,
1337 ACPI_SIZE Length)
1338 {
1339
1340 return (TRUE);
1341 }
1342
1343
1344 /******************************************************************************
1345 *
1346 * FUNCTION: AcpiOsSignal
1347 *
1348 * PARAMETERS: Function - ACPI CA signal function code
1349 * Info - Pointer to function-dependent structure
1350 *
1351 * RETURN: Status
1352 *
1353 * DESCRIPTION: Miscellaneous functions. Example implementation only.
1354 *
1355 *****************************************************************************/
1356
1357 ACPI_STATUS
1358 AcpiOsSignal (
1359 UINT32 Function,
1360 void *Info)
1361 {
1362
1363 switch (Function)
1364 {
1365 case ACPI_SIGNAL_FATAL:
1366
1367 break;
1368
1369 case ACPI_SIGNAL_BREAKPOINT:
1370
1371 break;
1372
1373 default:
1374
1375 break;
1376 }
1377
1378 return (AE_OK);
1379 }
1380
1381 /* Optional multi-thread support */
1382
1383 #ifndef ACPI_SINGLE_THREADED
1384 /******************************************************************************
1385 *
1386 * FUNCTION: AcpiOsGetThreadId
1387 *
1388 * PARAMETERS: None
1389 *
1390 * RETURN: Id of the running thread
1391 *
1392 * DESCRIPTION: Get the ID of the current (running) thread
1393 *
1394 *****************************************************************************/
1395
1396 ACPI_THREAD_ID
1397 AcpiOsGetThreadId (
1398 void)
1399 {
1400 pthread_t thread;
1401
1402
1403 thread = pthread_self();
1404 return (ACPI_CAST_PTHREAD_T (thread));
1405 }
1406
1407
1408 /******************************************************************************
1409 *
1410 * FUNCTION: AcpiOsExecute
1411 *
1412 * PARAMETERS: Type - Type of execution
1413 * Function - Address of the function to execute
1414 * Context - Passed as a parameter to the function
1415 *
1416 * RETURN: Status.
1417 *
1418 * DESCRIPTION: Execute a new thread
1419 *
1420 *****************************************************************************/
1421
1422 ACPI_STATUS
1423 AcpiOsExecute (
1424 ACPI_EXECUTE_TYPE Type,
1425 ACPI_OSD_EXEC_CALLBACK Function,
1426 void *Context)
1427 {
1428 pthread_t thread;
1429 int ret;
1430
1431
1432 ret = pthread_create (&thread, NULL, (PTHREAD_CALLBACK) Function, Context);
1433 if (ret)
1434 {
1435 AcpiOsPrintf("Create thread failed");
1436 }
1437 return (0);
1438 }
1439
1440 #endif /* ACPI_SINGLE_THREADED */
1441
1442
1443 /******************************************************************************
1444 *
1445 * FUNCTION: AcpiOsWaitEventsComplete
1446 *
1447 * PARAMETERS: None
1448 *
1449 * RETURN: None
1450 *
1451 * DESCRIPTION: Wait for all asynchronous events to complete. This
1452 * implementation does nothing.
1453 *
1454 *****************************************************************************/
1455
1456 void
1457 AcpiOsWaitEventsComplete (
1458 void)
1459 {
1460 return;
1461 }
1462