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