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