1 /******************************************************************************
2 *
3 * Module Name: osunixxf - UNIX OSL interfaces
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2023, 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 MERCHANTABILITY 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
OsEnterLineEditMode(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
OsExitLineEditMode(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
AcpiOsInitialize(void)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
AcpiOsTerminate(void)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
AcpiOsGetRootPointer(void)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
AcpiOsPredefinedOverride(const ACPI_PREDEFINED_NAMES * InitVal,ACPI_STRING * NewVal)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
AcpiOsTableOverride(ACPI_TABLE_HEADER * ExistingTable,ACPI_TABLE_HEADER ** NewTable)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
AcpiOsPhysicalTableOverride(ACPI_TABLE_HEADER * ExistingTable,ACPI_PHYSICAL_ADDRESS * NewAddress,UINT32 * NewTableLength)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: AcpiOsEnterSleep
365 *
366 * PARAMETERS: SleepState - Which sleep state to enter
367 * RegaValue - Register A value
368 * RegbValue - Register B value
369 *
370 * RETURN: Status
371 *
372 * DESCRIPTION: A hook before writing sleep registers to enter the sleep
373 * state. Return AE_CTRL_TERMINATE to skip further sleep register
374 * writes.
375 *
376 *****************************************************************************/
377
378 ACPI_STATUS
AcpiOsEnterSleep(UINT8 SleepState,UINT32 RegaValue,UINT32 RegbValue)379 AcpiOsEnterSleep (
380 UINT8 SleepState,
381 UINT32 RegaValue,
382 UINT32 RegbValue)
383 {
384
385 return (AE_OK);
386 }
387
388
389 /******************************************************************************
390 *
391 * FUNCTION: AcpiOsRedirectOutput
392 *
393 * PARAMETERS: Destination - An open file handle/pointer
394 *
395 * RETURN: None
396 *
397 * DESCRIPTION: Causes redirect of AcpiOsPrintf and AcpiOsVprintf
398 *
399 *****************************************************************************/
400
401 void
AcpiOsRedirectOutput(void * Destination)402 AcpiOsRedirectOutput (
403 void *Destination)
404 {
405
406 AcpiGbl_OutputFile = Destination;
407 }
408
409
410 /******************************************************************************
411 *
412 * FUNCTION: AcpiOsPrintf
413 *
414 * PARAMETERS: fmt, ... - Standard printf format
415 *
416 * RETURN: None
417 *
418 * DESCRIPTION: Formatted output. Note: very similar to AcpiOsVprintf
419 * (performance), changes should be tracked in both functions.
420 *
421 *****************************************************************************/
422
423 void ACPI_INTERNAL_VAR_XFACE
AcpiOsPrintf(const char * Fmt,...)424 AcpiOsPrintf (
425 const char *Fmt,
426 ...)
427 {
428 va_list Args;
429 UINT8 Flags;
430
431
432 Flags = AcpiGbl_DbOutputFlags;
433 if (Flags & ACPI_DB_REDIRECTABLE_OUTPUT)
434 {
435 /* Output is directable to either a file (if open) or the console */
436
437 if (AcpiGbl_DebugFile)
438 {
439 /* Output file is open, send the output there */
440
441 va_start (Args, Fmt);
442 vfprintf (AcpiGbl_DebugFile, Fmt, Args);
443 va_end (Args);
444 }
445 else
446 {
447 /* No redirection, send output to console (once only!) */
448
449 Flags |= ACPI_DB_CONSOLE_OUTPUT;
450 }
451 }
452
453 if (Flags & ACPI_DB_CONSOLE_OUTPUT)
454 {
455 va_start (Args, Fmt);
456 vfprintf (AcpiGbl_OutputFile, Fmt, Args);
457 va_end (Args);
458 }
459 }
460
461
462 /******************************************************************************
463 *
464 * FUNCTION: AcpiOsVprintf
465 *
466 * PARAMETERS: fmt - Standard printf format
467 * args - Argument list
468 *
469 * RETURN: None
470 *
471 * DESCRIPTION: Formatted output with argument list pointer. Note: very
472 * similar to AcpiOsPrintf, changes should be tracked in both
473 * functions.
474 *
475 *****************************************************************************/
476
477 void
AcpiOsVprintf(const char * Fmt,va_list Args)478 AcpiOsVprintf (
479 const char *Fmt,
480 va_list Args)
481 {
482 UINT8 Flags;
483 char Buffer[ACPI_VPRINTF_BUFFER_SIZE];
484
485
486 /*
487 * We build the output string in a local buffer because we may be
488 * outputting the buffer twice. Using vfprintf is problematic because
489 * some implementations modify the args pointer/structure during
490 * execution. Thus, we use the local buffer for portability.
491 *
492 * Note: Since this module is intended for use by the various ACPICA
493 * utilities/applications, we can safely declare the buffer on the stack.
494 * Also, This function is used for relatively small error messages only.
495 */
496 vsnprintf (Buffer, ACPI_VPRINTF_BUFFER_SIZE, Fmt, Args);
497
498 Flags = AcpiGbl_DbOutputFlags;
499 if (Flags & ACPI_DB_REDIRECTABLE_OUTPUT)
500 {
501 /* Output is directable to either a file (if open) or the console */
502
503 if (AcpiGbl_DebugFile)
504 {
505 /* Output file is open, send the output there */
506
507 fputs (Buffer, AcpiGbl_DebugFile);
508 }
509 else
510 {
511 /* No redirection, send output to console (once only!) */
512
513 Flags |= ACPI_DB_CONSOLE_OUTPUT;
514 }
515 }
516
517 if (Flags & ACPI_DB_CONSOLE_OUTPUT)
518 {
519 fputs (Buffer, AcpiGbl_OutputFile);
520 }
521 }
522
523
524 #ifndef ACPI_EXEC_APP
525 /******************************************************************************
526 *
527 * FUNCTION: AcpiOsGetLine
528 *
529 * PARAMETERS: Buffer - Where to return the command line
530 * BufferLength - Maximum length of Buffer
531 * BytesRead - Where the actual byte count is returned
532 *
533 * RETURN: Status and actual bytes read
534 *
535 * DESCRIPTION: Get the next input line from the terminal. NOTE: For the
536 * AcpiExec utility, we use the acgetline module instead to
537 * provide line-editing and history support.
538 *
539 *****************************************************************************/
540
541 ACPI_STATUS
AcpiOsGetLine(char * Buffer,UINT32 BufferLength,UINT32 * BytesRead)542 AcpiOsGetLine (
543 char *Buffer,
544 UINT32 BufferLength,
545 UINT32 *BytesRead)
546 {
547 int InputChar;
548 UINT32 EndOfLine;
549
550
551 /* Standard AcpiOsGetLine for all utilities except AcpiExec */
552
553 for (EndOfLine = 0; ; EndOfLine++)
554 {
555 if (EndOfLine >= BufferLength)
556 {
557 return (AE_BUFFER_OVERFLOW);
558 }
559
560 if ((InputChar = getchar ()) == EOF)
561 {
562 return (AE_ERROR);
563 }
564
565 if (!InputChar || InputChar == _ASCII_NEWLINE)
566 {
567 break;
568 }
569
570 Buffer[EndOfLine] = (char) InputChar;
571 }
572
573 /* Null terminate the buffer */
574
575 Buffer[EndOfLine] = 0;
576
577 /* Return the number of bytes in the string */
578
579 if (BytesRead)
580 {
581 *BytesRead = EndOfLine;
582 }
583
584 return (AE_OK);
585 }
586 #endif
587
588
589 #ifndef ACPI_USE_NATIVE_MEMORY_MAPPING
590 /******************************************************************************
591 *
592 * FUNCTION: AcpiOsMapMemory
593 *
594 * PARAMETERS: where - Physical address of memory to be mapped
595 * length - How much memory to map
596 *
597 * RETURN: Pointer to mapped memory. Null on error.
598 *
599 * DESCRIPTION: Map physical memory into caller's address space
600 *
601 *****************************************************************************/
602
603 void *
AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS where,ACPI_SIZE length)604 AcpiOsMapMemory (
605 ACPI_PHYSICAL_ADDRESS where,
606 ACPI_SIZE length)
607 {
608
609 return (ACPI_TO_POINTER ((ACPI_SIZE) where));
610 }
611
612
613 /******************************************************************************
614 *
615 * FUNCTION: AcpiOsUnmapMemory
616 *
617 * PARAMETERS: where - Logical address of memory to be unmapped
618 * length - How much memory to unmap
619 *
620 * RETURN: None.
621 *
622 * DESCRIPTION: Delete a previously created mapping. Where and Length must
623 * correspond to a previous mapping exactly.
624 *
625 *****************************************************************************/
626
627 void
AcpiOsUnmapMemory(void * where,ACPI_SIZE length)628 AcpiOsUnmapMemory (
629 void *where,
630 ACPI_SIZE length)
631 {
632
633 return;
634 }
635 #endif
636
637
638 /******************************************************************************
639 *
640 * FUNCTION: AcpiOsAllocate
641 *
642 * PARAMETERS: Size - Amount to allocate, in bytes
643 *
644 * RETURN: Pointer to the new allocation. Null on error.
645 *
646 * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS.
647 *
648 *****************************************************************************/
649
650 void *
AcpiOsAllocate(ACPI_SIZE size)651 AcpiOsAllocate (
652 ACPI_SIZE size)
653 {
654 void *Mem;
655
656
657 Mem = (void *) malloc ((size_t) size);
658 return (Mem);
659 }
660
661
662 #ifdef USE_NATIVE_ALLOCATE_ZEROED
663 /******************************************************************************
664 *
665 * FUNCTION: AcpiOsAllocateZeroed
666 *
667 * PARAMETERS: Size - Amount to allocate, in bytes
668 *
669 * RETURN: Pointer to the new allocation. Null on error.
670 *
671 * DESCRIPTION: Allocate and zero memory. Algorithm is dependent on the OS.
672 *
673 *****************************************************************************/
674
675 void *
AcpiOsAllocateZeroed(ACPI_SIZE size)676 AcpiOsAllocateZeroed (
677 ACPI_SIZE size)
678 {
679 void *Mem;
680
681
682 Mem = (void *) calloc (1, (size_t) size);
683 return (Mem);
684 }
685 #endif
686
687
688 /******************************************************************************
689 *
690 * FUNCTION: AcpiOsFree
691 *
692 * PARAMETERS: mem - Pointer to previously allocated memory
693 *
694 * RETURN: None.
695 *
696 * DESCRIPTION: Free memory allocated via AcpiOsAllocate
697 *
698 *****************************************************************************/
699
700 void
AcpiOsFree(void * mem)701 AcpiOsFree (
702 void *mem)
703 {
704
705 free (mem);
706 }
707
708
709 #ifdef ACPI_SINGLE_THREADED
710 /******************************************************************************
711 *
712 * FUNCTION: Semaphore stub functions
713 *
714 * DESCRIPTION: Stub functions used for single-thread applications that do
715 * not require semaphore synchronization. Full implementations
716 * of these functions appear after the stubs.
717 *
718 *****************************************************************************/
719
720 ACPI_STATUS
AcpiOsCreateSemaphore(UINT32 MaxUnits,UINT32 InitialUnits,ACPI_HANDLE * OutHandle)721 AcpiOsCreateSemaphore (
722 UINT32 MaxUnits,
723 UINT32 InitialUnits,
724 ACPI_HANDLE *OutHandle)
725 {
726 *OutHandle = (ACPI_HANDLE) 1;
727 return (AE_OK);
728 }
729
730 ACPI_STATUS
AcpiOsDeleteSemaphore(ACPI_HANDLE Handle)731 AcpiOsDeleteSemaphore (
732 ACPI_HANDLE Handle)
733 {
734 return (AE_OK);
735 }
736
737 ACPI_STATUS
AcpiOsWaitSemaphore(ACPI_HANDLE Handle,UINT32 Units,UINT16 Timeout)738 AcpiOsWaitSemaphore (
739 ACPI_HANDLE Handle,
740 UINT32 Units,
741 UINT16 Timeout)
742 {
743 return (AE_OK);
744 }
745
746 ACPI_STATUS
AcpiOsSignalSemaphore(ACPI_HANDLE Handle,UINT32 Units)747 AcpiOsSignalSemaphore (
748 ACPI_HANDLE Handle,
749 UINT32 Units)
750 {
751 return (AE_OK);
752 }
753
754 #else
755 /******************************************************************************
756 *
757 * FUNCTION: AcpiOsCreateSemaphore
758 *
759 * PARAMETERS: InitialUnits - Units to be assigned to the new semaphore
760 * OutHandle - Where a handle will be returned
761 *
762 * RETURN: Status
763 *
764 * DESCRIPTION: Create an OS semaphore
765 *
766 *****************************************************************************/
767
768 ACPI_STATUS
AcpiOsCreateSemaphore(UINT32 MaxUnits,UINT32 InitialUnits,ACPI_HANDLE * OutHandle)769 AcpiOsCreateSemaphore (
770 UINT32 MaxUnits,
771 UINT32 InitialUnits,
772 ACPI_HANDLE *OutHandle)
773 {
774 sem_t *Sem;
775
776
777 if (!OutHandle)
778 {
779 return (AE_BAD_PARAMETER);
780 }
781
782 #ifdef __APPLE__
783 {
784 static int SemaphoreCount = 0;
785 char SemaphoreName[32];
786
787 snprintf (SemaphoreName, sizeof (SemaphoreName), "acpi_sem_%d",
788 SemaphoreCount++);
789 printf ("%s\n", SemaphoreName);
790 Sem = sem_open (SemaphoreName, O_EXCL|O_CREAT, 0755, InitialUnits);
791 if (!Sem)
792 {
793 return (AE_NO_MEMORY);
794 }
795 sem_unlink (SemaphoreName); /* This just deletes the name */
796 }
797
798 #else
799 Sem = AcpiOsAllocate (sizeof (sem_t));
800 if (!Sem)
801 {
802 return (AE_NO_MEMORY);
803 }
804
805 if (sem_init (Sem, 0, InitialUnits) == -1)
806 {
807 AcpiOsFree (Sem);
808 return (AE_BAD_PARAMETER);
809 }
810 #endif
811
812 *OutHandle = (ACPI_HANDLE) Sem;
813 return (AE_OK);
814 }
815
816
817 /******************************************************************************
818 *
819 * FUNCTION: AcpiOsDeleteSemaphore
820 *
821 * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore
822 *
823 * RETURN: Status
824 *
825 * DESCRIPTION: Delete an OS semaphore
826 *
827 *****************************************************************************/
828
829 ACPI_STATUS
AcpiOsDeleteSemaphore(ACPI_HANDLE Handle)830 AcpiOsDeleteSemaphore (
831 ACPI_HANDLE Handle)
832 {
833 sem_t *Sem = (sem_t *) Handle;
834
835
836 if (!Sem)
837 {
838 return (AE_BAD_PARAMETER);
839 }
840
841 #ifdef __APPLE__
842 if (sem_close (Sem) == -1)
843 {
844 return (AE_BAD_PARAMETER);
845 }
846 #else
847 if (sem_destroy (Sem) == -1)
848 {
849 return (AE_BAD_PARAMETER);
850 }
851 #endif
852
853 return (AE_OK);
854 }
855
856
857 /******************************************************************************
858 *
859 * FUNCTION: AcpiOsWaitSemaphore
860 *
861 * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore
862 * Units - How many units to wait for
863 * MsecTimeout - How long to wait (milliseconds)
864 *
865 * RETURN: Status
866 *
867 * DESCRIPTION: Wait for units
868 *
869 *****************************************************************************/
870
871 ACPI_STATUS
AcpiOsWaitSemaphore(ACPI_HANDLE Handle,UINT32 Units,UINT16 MsecTimeout)872 AcpiOsWaitSemaphore (
873 ACPI_HANDLE Handle,
874 UINT32 Units,
875 UINT16 MsecTimeout)
876 {
877 ACPI_STATUS Status = AE_OK;
878 sem_t *Sem = (sem_t *) Handle;
879 int RetVal;
880 #ifndef ACPI_USE_ALTERNATE_TIMEOUT
881 struct timespec Time;
882 #endif
883
884
885 if (!Sem)
886 {
887 return (AE_BAD_PARAMETER);
888 }
889
890 switch (MsecTimeout)
891 {
892 /*
893 * No Wait:
894 * --------
895 * A zero timeout value indicates that we shouldn't wait - just
896 * acquire the semaphore if available otherwise return AE_TIME
897 * (a.k.a. 'would block').
898 */
899 case 0:
900
901 if (sem_trywait(Sem) == -1)
902 {
903 Status = (AE_TIME);
904 }
905 break;
906
907 /* Wait Indefinitely */
908
909 case ACPI_WAIT_FOREVER:
910
911 while (((RetVal = sem_wait (Sem)) == -1) && (errno == EINTR))
912 {
913 continue; /* Restart if interrupted */
914 }
915 if (RetVal != 0)
916 {
917 Status = (AE_TIME);
918 }
919 break;
920
921
922 /* Wait with MsecTimeout */
923
924 default:
925
926 #ifdef ACPI_USE_ALTERNATE_TIMEOUT
927 /*
928 * Alternate timeout mechanism for environments where
929 * sem_timedwait is not available or does not work properly.
930 */
931 while (MsecTimeout)
932 {
933 if (sem_trywait (Sem) == 0)
934 {
935 /* Got the semaphore */
936 return (AE_OK);
937 }
938
939 if (MsecTimeout >= 10)
940 {
941 MsecTimeout -= 10;
942 usleep (10 * ACPI_USEC_PER_MSEC); /* ten milliseconds */
943 }
944 else
945 {
946 MsecTimeout--;
947 usleep (ACPI_USEC_PER_MSEC); /* one millisecond */
948 }
949 }
950 Status = (AE_TIME);
951 #else
952 /*
953 * The interface to sem_timedwait is an absolute time, so we need to
954 * get the current time, then add in the millisecond Timeout value.
955 */
956 if (clock_gettime (CLOCK_REALTIME, &Time) == -1)
957 {
958 perror ("clock_gettime");
959 return (AE_TIME);
960 }
961
962 Time.tv_sec += (MsecTimeout / ACPI_MSEC_PER_SEC);
963 Time.tv_nsec += ((MsecTimeout % ACPI_MSEC_PER_SEC) * ACPI_NSEC_PER_MSEC);
964
965 /* Handle nanosecond overflow (field must be less than one second) */
966
967 if (Time.tv_nsec >= ACPI_NSEC_PER_SEC)
968 {
969 Time.tv_sec += (Time.tv_nsec / ACPI_NSEC_PER_SEC);
970 Time.tv_nsec = (Time.tv_nsec % ACPI_NSEC_PER_SEC);
971 }
972
973 while (((RetVal = sem_timedwait (Sem, &Time)) == -1) && (errno == EINTR))
974 {
975 continue; /* Restart if interrupted */
976
977 }
978
979 if (RetVal != 0)
980 {
981 if (errno != ETIMEDOUT)
982 {
983 perror ("sem_timedwait");
984 }
985 Status = (AE_TIME);
986 }
987 #endif
988 break;
989 }
990
991 return (Status);
992 }
993
994
995 /******************************************************************************
996 *
997 * FUNCTION: AcpiOsSignalSemaphore
998 *
999 * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore
1000 * Units - Number of units to send
1001 *
1002 * RETURN: Status
1003 *
1004 * DESCRIPTION: Send units
1005 *
1006 *****************************************************************************/
1007
1008 ACPI_STATUS
AcpiOsSignalSemaphore(ACPI_HANDLE Handle,UINT32 Units)1009 AcpiOsSignalSemaphore (
1010 ACPI_HANDLE Handle,
1011 UINT32 Units)
1012 {
1013 sem_t *Sem = (sem_t *)Handle;
1014
1015
1016 if (!Sem)
1017 {
1018 return (AE_BAD_PARAMETER);
1019 }
1020
1021 if (sem_post (Sem) == -1)
1022 {
1023 return (AE_LIMIT);
1024 }
1025
1026 return (AE_OK);
1027 }
1028
1029 #endif /* ACPI_SINGLE_THREADED */
1030
1031
1032 /******************************************************************************
1033 *
1034 * FUNCTION: Spinlock interfaces
1035 *
1036 * DESCRIPTION: Map these interfaces to semaphore interfaces
1037 *
1038 *****************************************************************************/
1039
1040 ACPI_STATUS
AcpiOsCreateLock(ACPI_SPINLOCK * OutHandle)1041 AcpiOsCreateLock (
1042 ACPI_SPINLOCK *OutHandle)
1043 {
1044
1045 return (AcpiOsCreateSemaphore (1, 1, OutHandle));
1046 }
1047
1048
1049 void
AcpiOsDeleteLock(ACPI_SPINLOCK Handle)1050 AcpiOsDeleteLock (
1051 ACPI_SPINLOCK Handle)
1052 {
1053 AcpiOsDeleteSemaphore (Handle);
1054 }
1055
1056
1057 ACPI_CPU_FLAGS
AcpiOsAcquireLock(ACPI_HANDLE Handle)1058 AcpiOsAcquireLock (
1059 ACPI_HANDLE Handle)
1060 {
1061 AcpiOsWaitSemaphore (Handle, 1, 0xFFFF);
1062 return (0);
1063 }
1064
1065
1066 void
AcpiOsReleaseLock(ACPI_SPINLOCK Handle,ACPI_CPU_FLAGS Flags)1067 AcpiOsReleaseLock (
1068 ACPI_SPINLOCK Handle,
1069 ACPI_CPU_FLAGS Flags)
1070 {
1071 AcpiOsSignalSemaphore (Handle, 1);
1072 }
1073
1074
1075 /******************************************************************************
1076 *
1077 * FUNCTION: AcpiOsInstallInterruptHandler
1078 *
1079 * PARAMETERS: InterruptNumber - Level handler should respond to.
1080 * Isr - Address of the ACPI interrupt handler
1081 * ExceptPtr - Where status is returned
1082 *
1083 * RETURN: Handle to the newly installed handler.
1084 *
1085 * DESCRIPTION: Install an interrupt handler. Used to install the ACPI
1086 * OS-independent handler.
1087 *
1088 *****************************************************************************/
1089
1090 UINT32
AcpiOsInstallInterruptHandler(UINT32 InterruptNumber,ACPI_OSD_HANDLER ServiceRoutine,void * Context)1091 AcpiOsInstallInterruptHandler (
1092 UINT32 InterruptNumber,
1093 ACPI_OSD_HANDLER ServiceRoutine,
1094 void *Context)
1095 {
1096
1097 return (AE_OK);
1098 }
1099
1100
1101 /******************************************************************************
1102 *
1103 * FUNCTION: AcpiOsRemoveInterruptHandler
1104 *
1105 * PARAMETERS: Handle - Returned when handler was installed
1106 *
1107 * RETURN: Status
1108 *
1109 * DESCRIPTION: Uninstalls an interrupt handler.
1110 *
1111 *****************************************************************************/
1112
1113 ACPI_STATUS
AcpiOsRemoveInterruptHandler(UINT32 InterruptNumber,ACPI_OSD_HANDLER ServiceRoutine)1114 AcpiOsRemoveInterruptHandler (
1115 UINT32 InterruptNumber,
1116 ACPI_OSD_HANDLER ServiceRoutine)
1117 {
1118
1119 return (AE_OK);
1120 }
1121
1122
1123 /******************************************************************************
1124 *
1125 * FUNCTION: AcpiOsStall
1126 *
1127 * PARAMETERS: microseconds - Time to sleep
1128 *
1129 * RETURN: Blocks until sleep is completed.
1130 *
1131 * DESCRIPTION: Sleep at microsecond granularity
1132 *
1133 *****************************************************************************/
1134
1135 void
AcpiOsStall(UINT32 microseconds)1136 AcpiOsStall (
1137 UINT32 microseconds)
1138 {
1139
1140 if (microseconds)
1141 {
1142 usleep (microseconds);
1143 }
1144 }
1145
1146
1147 /******************************************************************************
1148 *
1149 * FUNCTION: AcpiOsSleep
1150 *
1151 * PARAMETERS: milliseconds - Time to sleep
1152 *
1153 * RETURN: Blocks until sleep is completed.
1154 *
1155 * DESCRIPTION: Sleep at millisecond granularity
1156 *
1157 *****************************************************************************/
1158
1159 void
AcpiOsSleep(UINT64 milliseconds)1160 AcpiOsSleep (
1161 UINT64 milliseconds)
1162 {
1163
1164 /* Sleep for whole seconds */
1165
1166 sleep (milliseconds / ACPI_MSEC_PER_SEC);
1167
1168 /*
1169 * Sleep for remaining microseconds.
1170 * Arg to usleep() is in usecs and must be less than 1,000,000 (1 second).
1171 */
1172 usleep ((milliseconds % ACPI_MSEC_PER_SEC) * ACPI_USEC_PER_MSEC);
1173 }
1174
1175
1176 /******************************************************************************
1177 *
1178 * FUNCTION: AcpiOsGetTimer
1179 *
1180 * PARAMETERS: None
1181 *
1182 * RETURN: Current time in 100 nanosecond units
1183 *
1184 * DESCRIPTION: Get the current system time
1185 *
1186 *****************************************************************************/
1187
1188 UINT64
AcpiOsGetTimer(void)1189 AcpiOsGetTimer (
1190 void)
1191 {
1192 struct timeval time;
1193
1194
1195 /* This timer has sufficient resolution for user-space application code */
1196
1197 gettimeofday (&time, NULL);
1198
1199 /* (Seconds * 10^7 = 100ns(10^-7)) + (Microseconds(10^-6) * 10^1 = 100ns) */
1200
1201 return (((UINT64) time.tv_sec * ACPI_100NSEC_PER_SEC) +
1202 ((UINT64) time.tv_usec * ACPI_100NSEC_PER_USEC));
1203 }
1204
1205
1206 /******************************************************************************
1207 *
1208 * FUNCTION: AcpiOsReadPciConfiguration
1209 *
1210 * PARAMETERS: PciId - Seg/Bus/Dev
1211 * PciRegister - Device Register
1212 * Value - Buffer where value is placed
1213 * Width - Number of bits
1214 *
1215 * RETURN: Status
1216 *
1217 * DESCRIPTION: Read data from PCI configuration space
1218 *
1219 *****************************************************************************/
1220
1221 ACPI_STATUS
AcpiOsReadPciConfiguration(ACPI_PCI_ID * PciId,UINT32 PciRegister,UINT64 * Value,UINT32 Width)1222 AcpiOsReadPciConfiguration (
1223 ACPI_PCI_ID *PciId,
1224 UINT32 PciRegister,
1225 UINT64 *Value,
1226 UINT32 Width)
1227 {
1228
1229 *Value = 0;
1230 return (AE_OK);
1231 }
1232
1233
1234 /******************************************************************************
1235 *
1236 * FUNCTION: AcpiOsWritePciConfiguration
1237 *
1238 * PARAMETERS: PciId - Seg/Bus/Dev
1239 * PciRegister - Device Register
1240 * Value - Value to be written
1241 * Width - Number of bits
1242 *
1243 * RETURN: Status.
1244 *
1245 * DESCRIPTION: Write data to PCI configuration space
1246 *
1247 *****************************************************************************/
1248
1249 ACPI_STATUS
AcpiOsWritePciConfiguration(ACPI_PCI_ID * PciId,UINT32 PciRegister,UINT64 Value,UINT32 Width)1250 AcpiOsWritePciConfiguration (
1251 ACPI_PCI_ID *PciId,
1252 UINT32 PciRegister,
1253 UINT64 Value,
1254 UINT32 Width)
1255 {
1256
1257 return (AE_OK);
1258 }
1259
1260
1261 /******************************************************************************
1262 *
1263 * FUNCTION: AcpiOsReadPort
1264 *
1265 * PARAMETERS: Address - Address of I/O port/register to read
1266 * Value - Where value is placed
1267 * Width - Number of bits
1268 *
1269 * RETURN: Value read from port
1270 *
1271 * DESCRIPTION: Read data from an I/O port or register
1272 *
1273 *****************************************************************************/
1274
1275 ACPI_STATUS
AcpiOsReadPort(ACPI_IO_ADDRESS Address,UINT32 * Value,UINT32 Width)1276 AcpiOsReadPort (
1277 ACPI_IO_ADDRESS Address,
1278 UINT32 *Value,
1279 UINT32 Width)
1280 {
1281
1282 switch (Width)
1283 {
1284 case 8:
1285
1286 *Value = 0xFF;
1287 break;
1288
1289 case 16:
1290
1291 *Value = 0xFFFF;
1292 break;
1293
1294 case 32:
1295
1296 *Value = 0xFFFFFFFF;
1297 break;
1298
1299 default:
1300
1301 return (AE_BAD_PARAMETER);
1302 }
1303
1304 return (AE_OK);
1305 }
1306
1307
1308 /******************************************************************************
1309 *
1310 * FUNCTION: AcpiOsWritePort
1311 *
1312 * PARAMETERS: Address - Address of I/O port/register to write
1313 * Value - Value to write
1314 * Width - Number of bits
1315 *
1316 * RETURN: None
1317 *
1318 * DESCRIPTION: Write data to an I/O port or register
1319 *
1320 *****************************************************************************/
1321
1322 ACPI_STATUS
AcpiOsWritePort(ACPI_IO_ADDRESS Address,UINT32 Value,UINT32 Width)1323 AcpiOsWritePort (
1324 ACPI_IO_ADDRESS Address,
1325 UINT32 Value,
1326 UINT32 Width)
1327 {
1328
1329 return (AE_OK);
1330 }
1331
1332
1333 /******************************************************************************
1334 *
1335 * FUNCTION: AcpiOsReadMemory
1336 *
1337 * PARAMETERS: Address - Physical Memory Address to read
1338 * Value - Where value is placed
1339 * Width - Number of bits (8,16,32, or 64)
1340 *
1341 * RETURN: Value read from physical memory address. Always returned
1342 * as a 64-bit integer, regardless of the read width.
1343 *
1344 * DESCRIPTION: Read data from a physical memory address
1345 *
1346 *****************************************************************************/
1347
1348 ACPI_STATUS
AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address,UINT64 * Value,UINT32 Width)1349 AcpiOsReadMemory (
1350 ACPI_PHYSICAL_ADDRESS Address,
1351 UINT64 *Value,
1352 UINT32 Width)
1353 {
1354
1355 switch (Width)
1356 {
1357 case 8:
1358 case 16:
1359 case 32:
1360 case 64:
1361
1362 *Value = 0;
1363 break;
1364
1365 default:
1366
1367 return (AE_BAD_PARAMETER);
1368 }
1369 return (AE_OK);
1370 }
1371
1372
1373 /******************************************************************************
1374 *
1375 * FUNCTION: AcpiOsWriteMemory
1376 *
1377 * PARAMETERS: Address - Physical Memory Address to write
1378 * Value - Value to write
1379 * Width - Number of bits (8,16,32, or 64)
1380 *
1381 * RETURN: None
1382 *
1383 * DESCRIPTION: Write data to a physical memory address
1384 *
1385 *****************************************************************************/
1386
1387 ACPI_STATUS
AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address,UINT64 Value,UINT32 Width)1388 AcpiOsWriteMemory (
1389 ACPI_PHYSICAL_ADDRESS Address,
1390 UINT64 Value,
1391 UINT32 Width)
1392 {
1393
1394 return (AE_OK);
1395 }
1396
1397
1398 /******************************************************************************
1399 *
1400 * FUNCTION: AcpiOsReadable
1401 *
1402 * PARAMETERS: Pointer - Area to be verified
1403 * Length - Size of area
1404 *
1405 * RETURN: TRUE if readable for entire length
1406 *
1407 * DESCRIPTION: Verify that a pointer is valid for reading
1408 *
1409 *****************************************************************************/
1410
1411 BOOLEAN
AcpiOsReadable(void * Pointer,ACPI_SIZE Length)1412 AcpiOsReadable (
1413 void *Pointer,
1414 ACPI_SIZE Length)
1415 {
1416
1417 return (TRUE);
1418 }
1419
1420
1421 /******************************************************************************
1422 *
1423 * FUNCTION: AcpiOsWritable
1424 *
1425 * PARAMETERS: Pointer - Area to be verified
1426 * Length - Size of area
1427 *
1428 * RETURN: TRUE if writable for entire length
1429 *
1430 * DESCRIPTION: Verify that a pointer is valid for writing
1431 *
1432 *****************************************************************************/
1433
1434 BOOLEAN
AcpiOsWritable(void * Pointer,ACPI_SIZE Length)1435 AcpiOsWritable (
1436 void *Pointer,
1437 ACPI_SIZE Length)
1438 {
1439
1440 return (TRUE);
1441 }
1442
1443
1444 /******************************************************************************
1445 *
1446 * FUNCTION: AcpiOsSignal
1447 *
1448 * PARAMETERS: Function - ACPI A signal function code
1449 * Info - Pointer to function-dependent structure
1450 *
1451 * RETURN: Status
1452 *
1453 * DESCRIPTION: Miscellaneous functions. Example implementation only.
1454 *
1455 *****************************************************************************/
1456
1457 ACPI_STATUS
AcpiOsSignal(UINT32 Function,void * Info)1458 AcpiOsSignal (
1459 UINT32 Function,
1460 void *Info)
1461 {
1462
1463 switch (Function)
1464 {
1465 case ACPI_SIGNAL_FATAL:
1466
1467 break;
1468
1469 case ACPI_SIGNAL_BREAKPOINT:
1470
1471 break;
1472
1473 default:
1474
1475 break;
1476 }
1477
1478 return (AE_OK);
1479 }
1480
1481 /* Optional multi-thread support */
1482
1483 #ifndef ACPI_SINGLE_THREADED
1484 /******************************************************************************
1485 *
1486 * FUNCTION: AcpiOsGetThreadId
1487 *
1488 * PARAMETERS: None
1489 *
1490 * RETURN: Id of the running thread
1491 *
1492 * DESCRIPTION: Get the ID of the current (running) thread
1493 *
1494 *****************************************************************************/
1495
1496 ACPI_THREAD_ID
AcpiOsGetThreadId(void)1497 AcpiOsGetThreadId (
1498 void)
1499 {
1500 pthread_t thread;
1501
1502
1503 thread = pthread_self();
1504 return (ACPI_CAST_PTHREAD_T (thread));
1505 }
1506
1507
1508 /******************************************************************************
1509 *
1510 * FUNCTION: AcpiOsExecute
1511 *
1512 * PARAMETERS: Type - Type of execution
1513 * Function - Address of the function to execute
1514 * Context - Passed as a parameter to the function
1515 *
1516 * RETURN: Status.
1517 *
1518 * DESCRIPTION: Execute a new thread
1519 *
1520 *****************************************************************************/
1521
1522 ACPI_STATUS
AcpiOsExecute(ACPI_EXECUTE_TYPE Type,ACPI_OSD_EXEC_CALLBACK Function,void * Context)1523 AcpiOsExecute (
1524 ACPI_EXECUTE_TYPE Type,
1525 ACPI_OSD_EXEC_CALLBACK Function,
1526 void *Context)
1527 {
1528 pthread_t thread;
1529 int ret;
1530
1531
1532 ret = pthread_create (&thread, NULL, (PTHREAD_CALLBACK) Function, Context);
1533 if (ret)
1534 {
1535 AcpiOsPrintf("Create thread failed");
1536 }
1537 return (0);
1538 }
1539
1540 #else /* ACPI_SINGLE_THREADED */
1541 ACPI_THREAD_ID
AcpiOsGetThreadId(void)1542 AcpiOsGetThreadId (
1543 void)
1544 {
1545 return (1);
1546 }
1547
1548 ACPI_STATUS
AcpiOsExecute(ACPI_EXECUTE_TYPE Type,ACPI_OSD_EXEC_CALLBACK Function,void * Context)1549 AcpiOsExecute (
1550 ACPI_EXECUTE_TYPE Type,
1551 ACPI_OSD_EXEC_CALLBACK Function,
1552 void *Context)
1553 {
1554
1555 Function (Context);
1556
1557 return (AE_OK);
1558 }
1559
1560 #endif /* ACPI_SINGLE_THREADED */
1561
1562
1563 /******************************************************************************
1564 *
1565 * FUNCTION: AcpiOsWaitEventsComplete
1566 *
1567 * PARAMETERS: None
1568 *
1569 * RETURN: None
1570 *
1571 * DESCRIPTION: Wait for all asynchronous events to complete. This
1572 * implementation does nothing.
1573 *
1574 *****************************************************************************/
1575
1576 void
AcpiOsWaitEventsComplete(void)1577 AcpiOsWaitEventsComplete (
1578 void)
1579 {
1580 return;
1581 }
1582