exsystem.c revision 193335
150128Swpaul
250128Swpaul/******************************************************************************
350128Swpaul *
450128Swpaul * Module Name: exsystem - Interface to OS services
550128Swpaul *
650128Swpaul *****************************************************************************/
750128Swpaul
850128Swpaul/******************************************************************************
950128Swpaul *
1050128Swpaul * 1. Copyright Notice
1150128Swpaul *
1250128Swpaul * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
1350128Swpaul * All rights reserved.
1450128Swpaul *
1550128Swpaul * 2. License
1650128Swpaul *
1750128Swpaul * 2.1. This is your license from Intel Corp. under its intellectual property
1850128Swpaul * rights.  You may have additional license terms from the party that provided
1950128Swpaul * you this software, covering your right to use that party's intellectual
2050128Swpaul * property rights.
2150128Swpaul *
2250128Swpaul * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2350128Swpaul * copy of the source code appearing in this file ("Covered Code") an
2450128Swpaul * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2550128Swpaul * base code distributed originally by Intel ("Original Intel Code") to copy,
2650128Swpaul * make derivatives, distribute, use and display any portion of the Covered
2750128Swpaul * Code in any form, with the right to sublicense such rights; and
2850128Swpaul *
2950128Swpaul * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
3050128Swpaul * license (with the right to sublicense), under only those claims of Intel
3150128Swpaul * patents that are infringed by the Original Intel Code, to make, use, sell,
3250477Speter * offer to sell, and import the Covered Code and derivative works thereof
3350128Swpaul * solely to the minimum extent necessary to exercise the above copyright
3450128Swpaul * license, and in no event shall the patent license extend to any additions
3550128Swpaul * to or modifications of the Original Intel Code.  No other license or right
3650128Swpaul * is granted directly or by implication, estoppel or otherwise;
3750128Swpaul *
3850128Swpaul * The above copyright and patent license is granted only if the following
3950128Swpaul * conditions are met:
4050128Swpaul *
4150128Swpaul * 3. Conditions
4250128Swpaul *
4350128Swpaul * 3.1. Redistribution of Source with Rights to Further Distribute Source.
4450128Swpaul * Redistribution of source code of any substantial portion of the Covered
4550128Swpaul * Code or modification with rights to further distribute source must include
4650128Swpaul * the above Copyright Notice, the above License, this list of Conditions,
4750128Swpaul * and the following Disclaimer and Export Compliance provision.  In addition,
4850128Swpaul * Licensee must cause all Covered Code to which Licensee contributes to
4950128Swpaul * contain a file documenting the changes Licensee made to create that Covered
5050128Swpaul * Code and the date of any change.  Licensee must include in that file the
5150128Swpaul * documentation of any changes made by any predecessor Licensee.  Licensee
5250128Swpaul * must include a prominent statement that the modification is derived,
5350128Swpaul * directly or indirectly, from Original Intel Code.
5450128Swpaul *
5550128Swpaul * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5650128Swpaul * Redistribution of source code of any substantial portion of the Covered
5750128Swpaul * Code or modification without rights to further distribute source must
5850128Swpaul * include the following Disclaimer and Export Compliance provision in the
5950128Swpaul * documentation and/or other materials provided with distribution.  In
6050128Swpaul * addition, Licensee may not authorize further sublicense of source of any
6150128Swpaul * portion of the Covered Code, and must include terms to the effect that the
6250128Swpaul * license from Licensee to its licensee is limited to the intellectual
6350128Swpaul * property embodied in the software Licensee provides to its licensee, and
6450128Swpaul * not to intellectual property embodied in modifications its licensee may
6550128Swpaul * make.
6650128Swpaul *
6750128Swpaul * 3.3. Redistribution of Executable. Redistribution in executable form of any
6850128Swpaul * substantial portion of the Covered Code or modification must reproduce the
6950128Swpaul * above Copyright Notice, and the following Disclaimer and Export Compliance
7050128Swpaul * provision in the documentation and/or other materials provided with the
7150128Swpaul * distribution.
7250128Swpaul *
7350128Swpaul * 3.4. Intel retains all right, title, and interest in and to the Original
7450128Swpaul * Intel Code.
7550128Swpaul *
7650128Swpaul * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7750128Swpaul * Intel shall be used in advertising or otherwise to promote the sale, use or
7850128Swpaul * other dealings in products derived from or relating to the Covered Code
7950128Swpaul * without prior written authorization from Intel.
8050128Swpaul *
8150128Swpaul * 4. Disclaimer and Export Compliance
8250128Swpaul *
8350128Swpaul * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8450128Swpaul * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
8550128Swpaul * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
8650128Swpaul * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
8750128Swpaul * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
8850128Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
8950128Swpaul * PARTICULAR PURPOSE.
9050128Swpaul *
9150128Swpaul * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
9250128Swpaul * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9350128Swpaul * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
9450128Swpaul * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9550128Swpaul * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9650128Swpaul * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
9750128Swpaul * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9850128Swpaul * LIMITED REMEDY.
9950128Swpaul *
10050128Swpaul * 4.3. Licensee shall not export, either directly or indirectly, any of this
10150128Swpaul * software or system incorporating such software without first obtaining any
10250128Swpaul * required license or other approval from the U. S. Department of Commerce or
10350128Swpaul * any other agency or department of the United States Government.  In the
10450128Swpaul * event Licensee exports any such software from the United States or
10550128Swpaul * re-exports any such software from a foreign destination, Licensee shall
10650128Swpaul * ensure that the distribution and export/re-export of the software is in
10750128Swpaul * compliance with all laws, regulations, orders, or other restrictions of the
10850128Swpaul * U.S. Export Administration Regulations. Licensee agrees that neither it nor
10950128Swpaul * any of its subsidiaries will export/re-export any technical data, process,
11050128Swpaul * software, or service, directly or indirectly, to any country for which the
11150128Swpaul * United States government or any agency thereof requires an export license,
11250128Swpaul * other governmental approval, or letter of assurance, without first obtaining
11350128Swpaul * such license, approval or letter.
11450128Swpaul *
11550128Swpaul *****************************************************************************/
11650128Swpaul
11750128Swpaul#define __EXSYSTEM_C__
11850128Swpaul
11950128Swpaul#include "acpi.h"
12050128Swpaul#include "accommon.h"
12150128Swpaul#include "acinterp.h"
12250128Swpaul
12350128Swpaul#define _COMPONENT          ACPI_EXECUTER
12450128Swpaul        ACPI_MODULE_NAME    ("exsystem")
12550128Swpaul
12650128Swpaul
12750128Swpaul/*******************************************************************************
12850128Swpaul *
12950128Swpaul * FUNCTION:    AcpiExSystemWaitSemaphore
13050128Swpaul *
13150128Swpaul * PARAMETERS:  Semaphore       - Semaphore to wait on
13250128Swpaul *              Timeout         - Max time to wait
13350128Swpaul *
13450128Swpaul * RETURN:      Status
13550128Swpaul *
13650128Swpaul * DESCRIPTION: Implements a semaphore wait with a check to see if the
13750128Swpaul *              semaphore is available immediately.  If it is not, the
13850128Swpaul *              interpreter is released before waiting.
13950128Swpaul *
14050128Swpaul ******************************************************************************/
14150128Swpaul
14250128SwpaulACPI_STATUS
14350128SwpaulAcpiExSystemWaitSemaphore (
14450128Swpaul    ACPI_SEMAPHORE          Semaphore,
14550128Swpaul    UINT16                  Timeout)
14650128Swpaul{
14750128Swpaul    ACPI_STATUS             Status;
14850128Swpaul
14950128Swpaul
15050128Swpaul    ACPI_FUNCTION_TRACE (ExSystemWaitSemaphore);
15150128Swpaul
15250128Swpaul
15350128Swpaul    Status = AcpiOsWaitSemaphore (Semaphore, 1, ACPI_DO_NOT_WAIT);
15450128Swpaul    if (ACPI_SUCCESS (Status))
15550128Swpaul    {
15650128Swpaul        return_ACPI_STATUS (Status);
15750128Swpaul    }
15850128Swpaul
15950128Swpaul    if (Status == AE_TIME)
16050128Swpaul    {
16150128Swpaul        /* We must wait, so unlock the interpreter */
16250128Swpaul
16350128Swpaul        AcpiExRelinquishInterpreter ();
16450128Swpaul
16550128Swpaul        Status = AcpiOsWaitSemaphore (Semaphore, 1, Timeout);
16650128Swpaul
16750128Swpaul        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
16850128Swpaul            "*** Thread awake after blocking, %s\n",
16950128Swpaul            AcpiFormatException (Status)));
17050128Swpaul
17150128Swpaul        /* Reacquire the interpreter */
17250128Swpaul
17350128Swpaul       AcpiExReacquireInterpreter ();
17450128Swpaul    }
17550128Swpaul
17650128Swpaul    return_ACPI_STATUS (Status);
17750128Swpaul}
17850128Swpaul
17950128Swpaul
18050128Swpaul/*******************************************************************************
18150128Swpaul *
18250128Swpaul * FUNCTION:    AcpiExSystemWaitMutex
18350128Swpaul *
18450128Swpaul * PARAMETERS:  Mutex           - Mutex to wait on
18550128Swpaul *              Timeout         - Max time to wait
18650128Swpaul *
18750128Swpaul * RETURN:      Status
18850128Swpaul *
18950128Swpaul * DESCRIPTION: Implements a mutex wait with a check to see if the
19050128Swpaul *              mutex is available immediately.  If it is not, the
19150128Swpaul *              interpreter is released before waiting.
19250128Swpaul *
19350128Swpaul ******************************************************************************/
19450128Swpaul
19550128SwpaulACPI_STATUS
19650128SwpaulAcpiExSystemWaitMutex (
19750128Swpaul    ACPI_MUTEX              Mutex,
19850128Swpaul    UINT16                  Timeout)
19950128Swpaul{
20050128Swpaul    ACPI_STATUS             Status;
20150128Swpaul
20250128Swpaul
20350128Swpaul    ACPI_FUNCTION_TRACE (ExSystemWaitMutex);
20450128Swpaul
20550128Swpaul
20650128Swpaul    Status = AcpiOsAcquireMutex (Mutex, ACPI_DO_NOT_WAIT);
20750128Swpaul    if (ACPI_SUCCESS (Status))
20850128Swpaul    {
20950128Swpaul        return_ACPI_STATUS (Status);
21050128Swpaul    }
21150128Swpaul
21250128Swpaul    if (Status == AE_TIME)
21350128Swpaul    {
21450128Swpaul        /* We must wait, so unlock the interpreter */
21550128Swpaul
21650128Swpaul        AcpiExRelinquishInterpreter ();
21750128Swpaul
21850128Swpaul        Status = AcpiOsAcquireMutex (Mutex, Timeout);
21950128Swpaul
22050128Swpaul        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
22150128Swpaul            "*** Thread awake after blocking, %s\n",
22250128Swpaul            AcpiFormatException (Status)));
22350128Swpaul
22450128Swpaul        /* Reacquire the interpreter */
22550128Swpaul
22650128Swpaul        AcpiExReacquireInterpreter ();
22750128Swpaul    }
22850128Swpaul
22950128Swpaul    return_ACPI_STATUS (Status);
23050128Swpaul}
23150128Swpaul
23250128Swpaul
23350128Swpaul/*******************************************************************************
23450128Swpaul *
23550128Swpaul * FUNCTION:    AcpiExSystemDoStall
23650128Swpaul *
23750128Swpaul * PARAMETERS:  HowLong         - The amount of time to stall,
23850128Swpaul *                                in microseconds
23950128Swpaul *
24050128Swpaul * RETURN:      Status
24150128Swpaul *
24250128Swpaul * DESCRIPTION: Suspend running thread for specified amount of time.
24350128Swpaul *              Note: ACPI specification requires that Stall() does not
24450128Swpaul *              relinquish the processor, and delays longer than 100 usec
24550128Swpaul *              should use Sleep() instead.  We allow stalls up to 255 usec
24650128Swpaul *              for compatibility with other interpreters and existing BIOSs.
24750128Swpaul *
24850128Swpaul ******************************************************************************/
24950128Swpaul
25050128SwpaulACPI_STATUS
25150128SwpaulAcpiExSystemDoStall (
25250128Swpaul    UINT32                  HowLong)
25350128Swpaul{
25450128Swpaul    ACPI_STATUS             Status = AE_OK;
25550128Swpaul
25650128Swpaul
25750128Swpaul    ACPI_FUNCTION_ENTRY ();
25850128Swpaul
25950128Swpaul
26050128Swpaul    if (HowLong > 255) /* 255 microseconds */
26150128Swpaul    {
26250128Swpaul        /*
26350128Swpaul         * Longer than 255 usec, this is an error
26450128Swpaul         *
26550128Swpaul         * (ACPI specifies 100 usec as max, but this gives some slack in
26650128Swpaul         * order to support existing BIOSs)
26750128Swpaul         */
26850128Swpaul        ACPI_ERROR ((AE_INFO, "Time parameter is too large (%d)",
26950128Swpaul            HowLong));
27050128Swpaul        Status = AE_AML_OPERAND_VALUE;
27150128Swpaul    }
27250128Swpaul    else
27350128Swpaul    {
27450128Swpaul        AcpiOsStall (HowLong);
27550128Swpaul    }
27650128Swpaul
27750128Swpaul    return (Status);
27850128Swpaul}
27950128Swpaul
28050128Swpaul
28150128Swpaul/*******************************************************************************
28250128Swpaul *
28350128Swpaul * FUNCTION:    AcpiExSystemDoSuspend
28450128Swpaul *
28550128Swpaul * PARAMETERS:  HowLong         - The amount of time to suspend,
28650128Swpaul *                                in milliseconds
28750128Swpaul *
28850128Swpaul * RETURN:      None
28950128Swpaul *
29050128Swpaul * DESCRIPTION: Suspend running thread for specified amount of time.
29150128Swpaul *
29250128Swpaul ******************************************************************************/
29350128Swpaul
29450128SwpaulACPI_STATUS
29550128SwpaulAcpiExSystemDoSuspend (
29650128Swpaul    ACPI_INTEGER            HowLong)
29750128Swpaul{
29850128Swpaul    ACPI_FUNCTION_ENTRY ();
29950128Swpaul
30050128Swpaul
30150128Swpaul    /* Since this thread will sleep, we must release the interpreter */
30250128Swpaul
30350128Swpaul    AcpiExRelinquishInterpreter ();
30450128Swpaul
30550128Swpaul    AcpiOsSleep (HowLong);
30650128Swpaul
30750128Swpaul    /* And now we must get the interpreter again */
30850128Swpaul
30950128Swpaul    AcpiExReacquireInterpreter ();
31050128Swpaul    return (AE_OK);
31150128Swpaul}
31250128Swpaul
31350128Swpaul
31450128Swpaul/*******************************************************************************
31550128Swpaul *
31650128Swpaul * FUNCTION:    AcpiExSystemSignalEvent
31750128Swpaul *
31850128Swpaul * PARAMETERS:  ObjDesc         - The object descriptor for this op
31950128Swpaul *
32050128Swpaul * RETURN:      Status
32150128Swpaul *
32250128Swpaul * DESCRIPTION: Provides an access point to perform synchronization operations
32350128Swpaul *              within the AML.
32450128Swpaul *
32550128Swpaul ******************************************************************************/
32650128Swpaul
32750128SwpaulACPI_STATUS
32850128SwpaulAcpiExSystemSignalEvent (
32950128Swpaul    ACPI_OPERAND_OBJECT     *ObjDesc)
33050128Swpaul{
33150128Swpaul    ACPI_STATUS             Status = AE_OK;
33250128Swpaul
33350128Swpaul
33450128Swpaul    ACPI_FUNCTION_TRACE (ExSystemSignalEvent);
33550128Swpaul
33650128Swpaul
33750128Swpaul    if (ObjDesc)
33850128Swpaul    {
33950128Swpaul        Status = AcpiOsSignalSemaphore (ObjDesc->Event.OsSemaphore, 1);
34050128Swpaul    }
34150128Swpaul
34250128Swpaul    return_ACPI_STATUS (Status);
34350128Swpaul}
34450128Swpaul
34550128Swpaul
34650128Swpaul/*******************************************************************************
34750128Swpaul *
34850128Swpaul * FUNCTION:    AcpiExSystemWaitEvent
34950128Swpaul *
35050128Swpaul * PARAMETERS:  TimeDesc        - The 'time to delay' object descriptor
35150128Swpaul *              ObjDesc         - The object descriptor for this op
35250128Swpaul *
35350128Swpaul * RETURN:      Status
35450128Swpaul *
35550128Swpaul * DESCRIPTION: Provides an access point to perform synchronization operations
35650128Swpaul *              within the AML.  This operation is a request to wait for an
35750128Swpaul *              event.
35850128Swpaul *
35950128Swpaul ******************************************************************************/
36050128Swpaul
36150128SwpaulACPI_STATUS
36250128SwpaulAcpiExSystemWaitEvent (
36350128Swpaul    ACPI_OPERAND_OBJECT     *TimeDesc,
36450128Swpaul    ACPI_OPERAND_OBJECT     *ObjDesc)
36550128Swpaul{
36650128Swpaul    ACPI_STATUS             Status = AE_OK;
36750128Swpaul
36850128Swpaul
36950128Swpaul    ACPI_FUNCTION_TRACE (ExSystemWaitEvent);
37050128Swpaul
37150128Swpaul
37250128Swpaul    if (ObjDesc)
37350128Swpaul    {
37450128Swpaul        Status = AcpiExSystemWaitSemaphore (ObjDesc->Event.OsSemaphore,
37550128Swpaul                    (UINT16) TimeDesc->Integer.Value);
37650128Swpaul    }
37750128Swpaul
37850128Swpaul    return_ACPI_STATUS (Status);
37950128Swpaul}
38050128Swpaul
38150128Swpaul
38250128Swpaul/*******************************************************************************
38350128Swpaul *
38450128Swpaul * FUNCTION:    AcpiExSystemResetEvent
38550128Swpaul *
38650128Swpaul * PARAMETERS:  ObjDesc         - The object descriptor for this op
38750128Swpaul *
38850128Swpaul * RETURN:      Status
38950128Swpaul *
39050128Swpaul * DESCRIPTION: Reset an event to a known state.
39150128Swpaul *
39250128Swpaul ******************************************************************************/
39350128Swpaul
39450128SwpaulACPI_STATUS
39550128SwpaulAcpiExSystemResetEvent (
39650128Swpaul    ACPI_OPERAND_OBJECT     *ObjDesc)
39750128Swpaul{
39850128Swpaul    ACPI_STATUS             Status = AE_OK;
39950128Swpaul    ACPI_SEMAPHORE          TempSemaphore;
40050128Swpaul
40150128Swpaul
40250128Swpaul    ACPI_FUNCTION_ENTRY ();
40350128Swpaul
40450128Swpaul
40550128Swpaul    /*
40650128Swpaul     * We are going to simply delete the existing semaphore and
40750128Swpaul     * create a new one!
40850128Swpaul     */
40950128Swpaul    Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0, &TempSemaphore);
41050128Swpaul    if (ACPI_SUCCESS (Status))
41150128Swpaul    {
41250128Swpaul        (void) AcpiOsDeleteSemaphore (ObjDesc->Event.OsSemaphore);
41350128Swpaul        ObjDesc->Event.OsSemaphore = TempSemaphore;
41450128Swpaul    }
41550128Swpaul
41650128Swpaul    return (Status);
41750128Swpaul}
41850128Swpaul
41950128Swpaul