1 /******************************************************************************
3 * Module Name: osunixxf - UNIX OSL interfaces
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2013, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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.
46 * These interfaces are required in order to compile the ASL compiler and the
47 * various ACPICA tools under Linux or other Unix-like system.
49 #include <contrib/dev/acpica/include/acpi.h>
50 #include <contrib/dev/acpica/include/accommon.h>
51 #include <contrib/dev/acpica/include/amlcode.h>
52 #include <contrib/dev/acpica/include/acparser.h>
53 #include <contrib/dev/acpica/include/acdebug.h>
60 #include <semaphore.h>
64 #define _COMPONENT ACPI_OS_SERVICES
65 ACPI_MODULE_NAME ("osunixxf")
68 extern FILE *AcpiGbl_DebugFile;
69 FILE *AcpiGbl_OutputFile;
72 /* Upcalls to AcpiExec */
75 AeLocalGetRootPointer (
80 ACPI_TABLE_HEADER *ExistingTable,
81 ACPI_TABLE_HEADER **NewTable);
83 typedef void* (*PTHREAD_CALLBACK) (void *);
85 /* Buffer used by AcpiOsVprintf */
87 #define ACPI_VPRINTF_BUFFER_SIZE 512
90 /******************************************************************************
92 * FUNCTION: AcpiOsInitialize, AcpiOsTerminate
98 * DESCRIPTION: Init and terminate. Nothing to do.
100 *****************************************************************************/
107 AcpiGbl_OutputFile = stdout;
121 /******************************************************************************
123 * FUNCTION: AcpiOsGetRootPointer
127 * RETURN: RSDP physical address
129 * DESCRIPTION: Gets the ACPI root pointer (RSDP)
131 *****************************************************************************/
133 ACPI_PHYSICAL_ADDRESS
134 AcpiOsGetRootPointer (
138 return (AeLocalGetRootPointer ());
142 /******************************************************************************
144 * FUNCTION: AcpiOsPredefinedOverride
146 * PARAMETERS: InitVal - Initial value of the predefined object
147 * NewVal - The new value for the object
149 * RETURN: Status, pointer to value. Null pointer returned if not
152 * DESCRIPTION: Allow the OS to override predefined names
154 *****************************************************************************/
157 AcpiOsPredefinedOverride (
158 const ACPI_PREDEFINED_NAMES *InitVal,
162 if (!InitVal || !NewVal)
164 return (AE_BAD_PARAMETER);
172 /******************************************************************************
174 * FUNCTION: AcpiOsTableOverride
176 * PARAMETERS: ExistingTable - Header of current table (probably
178 * NewTable - Where an entire new table is returned.
180 * RETURN: Status, pointer to new table. Null pointer returned if no
181 * table is available to override
183 * DESCRIPTION: Return a different version of a table if one is available
185 *****************************************************************************/
188 AcpiOsTableOverride (
189 ACPI_TABLE_HEADER *ExistingTable,
190 ACPI_TABLE_HEADER **NewTable)
193 if (!ExistingTable || !NewTable)
195 return (AE_BAD_PARAMETER);
202 AeTableOverride (ExistingTable, NewTable);
206 return (AE_NO_ACPI_TABLES);
211 /******************************************************************************
213 * FUNCTION: AcpiOsPhysicalTableOverride
215 * PARAMETERS: ExistingTable - Header of current table (probably firmware)
216 * NewAddress - Where new table address is returned
218 * NewTableLength - Where new table length is returned
220 * RETURN: Status, address/length of new table. Null pointer returned
221 * if no table is available to override.
223 * DESCRIPTION: Returns AE_SUPPORT, function not used in user space.
225 *****************************************************************************/
228 AcpiOsPhysicalTableOverride (
229 ACPI_TABLE_HEADER *ExistingTable,
230 ACPI_PHYSICAL_ADDRESS *NewAddress,
231 UINT32 *NewTableLength)
238 /******************************************************************************
240 * FUNCTION: AcpiOsRedirectOutput
242 * PARAMETERS: Destination - An open file handle/pointer
246 * DESCRIPTION: Causes redirect of AcpiOsPrintf and AcpiOsVprintf
248 *****************************************************************************/
251 AcpiOsRedirectOutput (
255 AcpiGbl_OutputFile = Destination;
259 /******************************************************************************
261 * FUNCTION: AcpiOsPrintf
263 * PARAMETERS: fmt, ... - Standard printf format
267 * DESCRIPTION: Formatted output. Note: very similar to AcpiOsVprintf
268 * (performance), changes should be tracked in both functions.
270 *****************************************************************************/
272 void ACPI_INTERNAL_VAR_XFACE
281 Flags = AcpiGbl_DbOutputFlags;
282 if (Flags & ACPI_DB_REDIRECTABLE_OUTPUT)
284 /* Output is directable to either a file (if open) or the console */
286 if (AcpiGbl_DebugFile)
288 /* Output file is open, send the output there */
290 va_start (Args, Fmt);
291 vfprintf (AcpiGbl_DebugFile, Fmt, Args);
296 /* No redirection, send output to console (once only!) */
298 Flags |= ACPI_DB_CONSOLE_OUTPUT;
302 if (Flags & ACPI_DB_CONSOLE_OUTPUT)
304 va_start (Args, Fmt);
305 vfprintf (AcpiGbl_OutputFile, Fmt, Args);
311 /******************************************************************************
313 * FUNCTION: AcpiOsVprintf
315 * PARAMETERS: fmt - Standard printf format
316 * args - Argument list
320 * DESCRIPTION: Formatted output with argument list pointer. Note: very
321 * similar to AcpiOsPrintf, changes should be tracked in both
324 *****************************************************************************/
332 char Buffer[ACPI_VPRINTF_BUFFER_SIZE];
336 * We build the output string in a local buffer because we may be
337 * outputting the buffer twice. Using vfprintf is problematic because
338 * some implementations modify the args pointer/structure during
339 * execution. Thus, we use the local buffer for portability.
341 * Note: Since this module is intended for use by the various ACPICA
342 * utilities/applications, we can safely declare the buffer on the stack.
343 * Also, This function is used for relatively small error messages only.
345 vsnprintf (Buffer, ACPI_VPRINTF_BUFFER_SIZE, Fmt, Args);
347 Flags = AcpiGbl_DbOutputFlags;
348 if (Flags & ACPI_DB_REDIRECTABLE_OUTPUT)
350 /* Output is directable to either a file (if open) or the console */
352 if (AcpiGbl_DebugFile)
354 /* Output file is open, send the output there */
356 fputs (Buffer, AcpiGbl_DebugFile);
360 /* No redirection, send output to console (once only!) */
362 Flags |= ACPI_DB_CONSOLE_OUTPUT;
366 if (Flags & ACPI_DB_CONSOLE_OUTPUT)
368 fputs (Buffer, AcpiGbl_OutputFile);
373 /******************************************************************************
375 * FUNCTION: AcpiOsGetLine
377 * PARAMETERS: Buffer - Where to return the command line
378 * BufferLength - Maximum length of Buffer
379 * BytesRead - Where the actual byte count is returned
381 * RETURN: Status and actual bytes read
383 * DESCRIPTION: Formatted input with argument list pointer
385 *****************************************************************************/
399 if (i >= BufferLength)
401 return (AE_BUFFER_OVERFLOW);
404 if ((Temp = getchar ()) == EOF)
409 if (!Temp || Temp == '\n')
414 Buffer [i] = (char) Temp;
417 /* Null terminate the buffer */
421 /* Return the number of bytes in the string */
431 /******************************************************************************
433 * FUNCTION: AcpiOsMapMemory
435 * PARAMETERS: where - Physical address of memory to be mapped
436 * length - How much memory to map
438 * RETURN: Pointer to mapped memory. Null on error.
440 * DESCRIPTION: Map physical memory into caller's address space
442 *****************************************************************************/
446 ACPI_PHYSICAL_ADDRESS where,
450 return (ACPI_TO_POINTER ((ACPI_SIZE) where));
454 /******************************************************************************
456 * FUNCTION: AcpiOsUnmapMemory
458 * PARAMETERS: where - Logical address of memory to be unmapped
459 * length - How much memory to unmap
463 * DESCRIPTION: Delete a previously created mapping. Where and Length must
464 * correspond to a previous mapping exactly.
466 *****************************************************************************/
478 /******************************************************************************
480 * FUNCTION: AcpiOsAllocate
482 * PARAMETERS: Size - Amount to allocate, in bytes
484 * RETURN: Pointer to the new allocation. Null on error.
486 * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS.
488 *****************************************************************************/
497 Mem = (void *) malloc ((size_t) size);
502 /******************************************************************************
504 * FUNCTION: AcpiOsFree
506 * PARAMETERS: mem - Pointer to previously allocated memory
510 * DESCRIPTION: Free memory allocated via AcpiOsAllocate
512 *****************************************************************************/
523 #ifdef ACPI_SINGLE_THREADED
524 /******************************************************************************
526 * FUNCTION: Semaphore stub functions
528 * DESCRIPTION: Stub functions used for single-thread applications that do
529 * not require semaphore synchronization. Full implementations
530 * of these functions appear after the stubs.
532 *****************************************************************************/
535 AcpiOsCreateSemaphore (
538 ACPI_HANDLE *OutHandle)
540 *OutHandle = (ACPI_HANDLE) 1;
545 AcpiOsDeleteSemaphore (
552 AcpiOsWaitSemaphore (
561 AcpiOsSignalSemaphore (
569 /******************************************************************************
571 * FUNCTION: AcpiOsCreateSemaphore
573 * PARAMETERS: InitialUnits - Units to be assigned to the new semaphore
574 * OutHandle - Where a handle will be returned
578 * DESCRIPTION: Create an OS semaphore
580 *****************************************************************************/
583 AcpiOsCreateSemaphore (
586 ACPI_HANDLE *OutHandle)
593 return (AE_BAD_PARAMETER);
598 char *SemaphoreName = tmpnam (NULL);
600 Sem = sem_open (SemaphoreName, O_EXCL|O_CREAT, 0755, InitialUnits);
603 return (AE_NO_MEMORY);
605 sem_unlink (SemaphoreName); /* This just deletes the name */
609 Sem = AcpiOsAllocate (sizeof (sem_t));
612 return (AE_NO_MEMORY);
615 if (sem_init (Sem, 0, InitialUnits) == -1)
618 return (AE_BAD_PARAMETER);
622 *OutHandle = (ACPI_HANDLE) Sem;
627 /******************************************************************************
629 * FUNCTION: AcpiOsDeleteSemaphore
631 * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore
635 * DESCRIPTION: Delete an OS semaphore
637 *****************************************************************************/
640 AcpiOsDeleteSemaphore (
643 sem_t *Sem = (sem_t *) Handle;
648 return (AE_BAD_PARAMETER);
651 if (sem_destroy (Sem) == -1)
653 return (AE_BAD_PARAMETER);
660 /******************************************************************************
662 * FUNCTION: AcpiOsWaitSemaphore
664 * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore
665 * Units - How many units to wait for
666 * MsecTimeout - How long to wait (milliseconds)
670 * DESCRIPTION: Wait for units
672 *****************************************************************************/
675 AcpiOsWaitSemaphore (
680 ACPI_STATUS Status = AE_OK;
681 sem_t *Sem = (sem_t *) Handle;
682 #ifndef ACPI_USE_ALTERNATE_TIMEOUT
683 struct timespec Time;
690 return (AE_BAD_PARAMETER);
698 * A zero timeout value indicates that we shouldn't wait - just
699 * acquire the semaphore if available otherwise return AE_TIME
700 * (a.k.a. 'would block').
704 if (sem_trywait(Sem) == -1)
710 /* Wait Indefinitely */
712 case ACPI_WAIT_FOREVER:
720 /* Wait with MsecTimeout */
724 #ifdef ACPI_USE_ALTERNATE_TIMEOUT
726 * Alternate timeout mechanism for environments where
727 * sem_timedwait is not available or does not work properly.
731 if (sem_trywait (Sem) == 0)
733 /* Got the semaphore */
737 if (MsecTimeout >= 10)
740 usleep (10 * ACPI_USEC_PER_MSEC); /* ten milliseconds */
745 usleep (ACPI_USEC_PER_MSEC); /* one millisecond */
751 * The interface to sem_timedwait is an absolute time, so we need to
752 * get the current time, then add in the millisecond Timeout value.
754 if (clock_gettime (CLOCK_REALTIME, &Time) == -1)
756 perror ("clock_gettime");
760 Time.tv_sec += (MsecTimeout / ACPI_MSEC_PER_SEC);
761 Time.tv_nsec += ((MsecTimeout % ACPI_MSEC_PER_SEC) * ACPI_NSEC_PER_MSEC);
763 /* Handle nanosecond overflow (field must be less than one second) */
765 if (Time.tv_nsec >= ACPI_NSEC_PER_SEC)
767 Time.tv_sec += (Time.tv_nsec / ACPI_NSEC_PER_SEC);
768 Time.tv_nsec = (Time.tv_nsec % ACPI_NSEC_PER_SEC);
771 while (((RetVal = sem_timedwait (Sem, &Time)) == -1) && (errno == EINTR))
778 if (errno != ETIMEDOUT)
780 perror ("sem_timedwait");
792 /******************************************************************************
794 * FUNCTION: AcpiOsSignalSemaphore
796 * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore
797 * Units - Number of units to send
801 * DESCRIPTION: Send units
803 *****************************************************************************/
806 AcpiOsSignalSemaphore (
810 sem_t *Sem = (sem_t *)Handle;
815 return (AE_BAD_PARAMETER);
818 if (sem_post (Sem) == -1)
826 #endif /* ACPI_SINGLE_THREADED */
829 /******************************************************************************
831 * FUNCTION: Spinlock interfaces
833 * DESCRIPTION: Map these interfaces to semaphore interfaces
835 *****************************************************************************/
839 ACPI_SPINLOCK *OutHandle)
842 return (AcpiOsCreateSemaphore (1, 1, OutHandle));
848 ACPI_SPINLOCK Handle)
850 AcpiOsDeleteSemaphore (Handle);
858 AcpiOsWaitSemaphore (Handle, 1, 0xFFFF);
865 ACPI_SPINLOCK Handle,
866 ACPI_CPU_FLAGS Flags)
868 AcpiOsSignalSemaphore (Handle, 1);
872 /******************************************************************************
874 * FUNCTION: AcpiOsInstallInterruptHandler
876 * PARAMETERS: InterruptNumber - Level handler should respond to.
877 * Isr - Address of the ACPI interrupt handler
878 * ExceptPtr - Where status is returned
880 * RETURN: Handle to the newly installed handler.
882 * DESCRIPTION: Install an interrupt handler. Used to install the ACPI
883 * OS-independent handler.
885 *****************************************************************************/
888 AcpiOsInstallInterruptHandler (
889 UINT32 InterruptNumber,
890 ACPI_OSD_HANDLER ServiceRoutine,
898 /******************************************************************************
900 * FUNCTION: AcpiOsRemoveInterruptHandler
902 * PARAMETERS: Handle - Returned when handler was installed
906 * DESCRIPTION: Uninstalls an interrupt handler.
908 *****************************************************************************/
911 AcpiOsRemoveInterruptHandler (
912 UINT32 InterruptNumber,
913 ACPI_OSD_HANDLER ServiceRoutine)
920 /******************************************************************************
922 * FUNCTION: AcpiOsStall
924 * PARAMETERS: microseconds - Time to sleep
926 * RETURN: Blocks until sleep is completed.
928 * DESCRIPTION: Sleep at microsecond granularity
930 *****************************************************************************/
939 usleep (microseconds);
944 /******************************************************************************
946 * FUNCTION: AcpiOsSleep
948 * PARAMETERS: milliseconds - Time to sleep
950 * RETURN: Blocks until sleep is completed.
952 * DESCRIPTION: Sleep at millisecond granularity
954 *****************************************************************************/
961 /* Sleep for whole seconds */
963 sleep (milliseconds / ACPI_MSEC_PER_SEC);
966 * Sleep for remaining microseconds.
967 * Arg to usleep() is in usecs and must be less than 1,000,000 (1 second).
969 usleep ((milliseconds % ACPI_MSEC_PER_SEC) * ACPI_USEC_PER_MSEC);
973 /******************************************************************************
975 * FUNCTION: AcpiOsGetTimer
979 * RETURN: Current time in 100 nanosecond units
981 * DESCRIPTION: Get the current system time
983 *****************************************************************************/
992 /* This timer has sufficient resolution for user-space application code */
994 gettimeofday (&time, NULL);
996 /* (Seconds * 10^7 = 100ns(10^-7)) + (Microseconds(10^-6) * 10^1 = 100ns) */
998 return (((UINT64) time.tv_sec * ACPI_100NSEC_PER_SEC) +
999 ((UINT64) time.tv_usec * ACPI_100NSEC_PER_USEC));
1003 /******************************************************************************
1005 * FUNCTION: AcpiOsReadPciConfiguration
1007 * PARAMETERS: PciId - Seg/Bus/Dev
1008 * Register - Device Register
1009 * Value - Buffer where value is placed
1010 * Width - Number of bits
1014 * DESCRIPTION: Read data from PCI configuration space
1016 *****************************************************************************/
1019 AcpiOsReadPciConfiguration (
1031 /******************************************************************************
1033 * FUNCTION: AcpiOsWritePciConfiguration
1035 * PARAMETERS: PciId - Seg/Bus/Dev
1036 * Register - Device Register
1037 * Value - Value to be written
1038 * Width - Number of bits
1042 * DESCRIPTION: Write data to PCI configuration space
1044 *****************************************************************************/
1047 AcpiOsWritePciConfiguration (
1058 /******************************************************************************
1060 * FUNCTION: AcpiOsReadPort
1062 * PARAMETERS: Address - Address of I/O port/register to read
1063 * Value - Where value is placed
1064 * Width - Number of bits
1066 * RETURN: Value read from port
1068 * DESCRIPTION: Read data from an I/O port or register
1070 *****************************************************************************/
1074 ACPI_IO_ADDRESS Address,
1093 *Value = 0xFFFFFFFF;
1098 return (AE_BAD_PARAMETER);
1105 /******************************************************************************
1107 * FUNCTION: AcpiOsWritePort
1109 * PARAMETERS: Address - Address of I/O port/register to write
1110 * Value - Value to write
1111 * Width - Number of bits
1115 * DESCRIPTION: Write data to an I/O port or register
1117 *****************************************************************************/
1121 ACPI_IO_ADDRESS Address,
1130 /******************************************************************************
1132 * FUNCTION: AcpiOsReadMemory
1134 * PARAMETERS: Address - Physical Memory Address to read
1135 * Value - Where value is placed
1136 * Width - Number of bits (8,16,32, or 64)
1138 * RETURN: Value read from physical memory address. Always returned
1139 * as a 64-bit integer, regardless of the read width.
1141 * DESCRIPTION: Read data from a physical memory address
1143 *****************************************************************************/
1147 ACPI_PHYSICAL_ADDRESS Address,
1164 return (AE_BAD_PARAMETER);
1170 /******************************************************************************
1172 * FUNCTION: AcpiOsWriteMemory
1174 * PARAMETERS: Address - Physical Memory Address to write
1175 * Value - Value to write
1176 * Width - Number of bits (8,16,32, or 64)
1180 * DESCRIPTION: Write data to a physical memory address
1182 *****************************************************************************/
1186 ACPI_PHYSICAL_ADDRESS Address,
1195 /******************************************************************************
1197 * FUNCTION: AcpiOsReadable
1199 * PARAMETERS: Pointer - Area to be verified
1200 * Length - Size of area
1202 * RETURN: TRUE if readable for entire length
1204 * DESCRIPTION: Verify that a pointer is valid for reading
1206 *****************************************************************************/
1218 /******************************************************************************
1220 * FUNCTION: AcpiOsWritable
1222 * PARAMETERS: Pointer - Area to be verified
1223 * Length - Size of area
1225 * RETURN: TRUE if writable for entire length
1227 * DESCRIPTION: Verify that a pointer is valid for writing
1229 *****************************************************************************/
1241 /******************************************************************************
1243 * FUNCTION: AcpiOsSignal
1245 * PARAMETERS: Function - ACPI CA signal function code
1246 * Info - Pointer to function-dependent structure
1250 * DESCRIPTION: Miscellaneous functions. Example implementation only.
1252 *****************************************************************************/
1262 case ACPI_SIGNAL_FATAL:
1266 case ACPI_SIGNAL_BREAKPOINT:
1278 /* Optional multi-thread support */
1280 #ifndef ACPI_SINGLE_THREADED
1281 /******************************************************************************
1283 * FUNCTION: AcpiOsGetThreadId
1287 * RETURN: Id of the running thread
1289 * DESCRIPTION: Get the ID of the current (running) thread
1291 *****************************************************************************/
1300 thread = pthread_self();
1301 return (ACPI_CAST_PTHREAD_T (thread));
1305 /******************************************************************************
1307 * FUNCTION: AcpiOsExecute
1309 * PARAMETERS: Type - Type of execution
1310 * Function - Address of the function to execute
1311 * Context - Passed as a parameter to the function
1315 * DESCRIPTION: Execute a new thread
1317 *****************************************************************************/
1321 ACPI_EXECUTE_TYPE Type,
1322 ACPI_OSD_EXEC_CALLBACK Function,
1329 ret = pthread_create (&thread, NULL, (PTHREAD_CALLBACK) Function, Context);
1332 AcpiOsPrintf("Create thread failed");
1337 #endif /* ACPI_SINGLE_THREADED */
1340 /******************************************************************************
1342 * FUNCTION: AcpiOsWaitEventsComplete
1348 * DESCRIPTION: Wait for all asynchronous events to complete. This
1349 * implementation does nothing.
1351 *****************************************************************************/
1354 AcpiOsWaitEventsComplete (