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