dsmthdat.c revision 197104
168349Sobrien/*******************************************************************************
268349Sobrien *
368349Sobrien * Module Name: dsmthdat - control method arguments and local variables
468349Sobrien *
568349Sobrien ******************************************************************************/
668349Sobrien
768349Sobrien/******************************************************************************
868349Sobrien *
968349Sobrien * 1. Copyright Notice
1068349Sobrien *
1168349Sobrien * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
1268349Sobrien * All rights reserved.
1368349Sobrien *
1468349Sobrien * 2. License
1568349Sobrien *
1668349Sobrien * 2.1. This is your license from Intel Corp. under its intellectual property
1768349Sobrien * rights.  You may have additional license terms from the party that provided
1868349Sobrien * you this software, covering your right to use that party's intellectual
1968349Sobrien * property rights.
2068349Sobrien *
2168349Sobrien * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2268349Sobrien * copy of the source code appearing in this file ("Covered Code") an
2368349Sobrien * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2468349Sobrien * base code distributed originally by Intel ("Original Intel Code") to copy,
2568349Sobrien * make derivatives, distribute, use and display any portion of the Covered
2668349Sobrien * Code in any form, with the right to sublicense such rights; and
2768349Sobrien *
2880588Sobrien * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
2968349Sobrien * license (with the right to sublicense), under only those claims of Intel
3068349Sobrien * patents that are infringed by the Original Intel Code, to make, use, sell,
3168349Sobrien * offer to sell, and import the Covered Code and derivative works thereof
3268349Sobrien * solely to the minimum extent necessary to exercise the above copyright
3368349Sobrien * license, and in no event shall the patent license extend to any additions
3474784Sobrien * to or modifications of the Original Intel Code.  No other license or right
3574784Sobrien * is granted directly or by implication, estoppel or otherwise;
3680588Sobrien *
3774784Sobrien * The above copyright and patent license is granted only if the following
3874784Sobrien * conditions are met:
3974784Sobrien *
4068349Sobrien * 3. Conditions
4168349Sobrien *
4280588Sobrien * 3.1. Redistribution of Source with Rights to Further Distribute Source.
4368349Sobrien * Redistribution of source code of any substantial portion of the Covered
4468349Sobrien * Code or modification with rights to further distribute source must include
4568349Sobrien * the above Copyright Notice, the above License, this list of Conditions,
4668349Sobrien * and the following Disclaimer and Export Compliance provision.  In addition,
4768349Sobrien * Licensee must cause all Covered Code to which Licensee contributes to
4868349Sobrien * contain a file documenting the changes Licensee made to create that Covered
4975937Sobrien * Code and the date of any change.  Licensee must include in that file the
5075937Sobrien * documentation of any changes made by any predecessor Licensee.  Licensee
5175937Sobrien * must include a prominent statement that the modification is derived,
5275937Sobrien * directly or indirectly, from Original Intel Code.
5375937Sobrien *
5475937Sobrien * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5575937Sobrien * Redistribution of source code of any substantial portion of the Covered
5675937Sobrien * Code or modification without rights to further distribute source must
5775937Sobrien * include the following Disclaimer and Export Compliance provision in the
5868349Sobrien * documentation and/or other materials provided with distribution.  In
5975937Sobrien * addition, Licensee may not authorize further sublicense of source of any
6075937Sobrien * portion of the Covered Code, and must include terms to the effect that the
6175937Sobrien * license from Licensee to its licensee is limited to the intellectual
6268349Sobrien * property embodied in the software Licensee provides to its licensee, and
6375937Sobrien * not to intellectual property embodied in modifications its licensee may
6475937Sobrien * make.
6575937Sobrien *
6675937Sobrien * 3.3. Redistribution of Executable. Redistribution in executable form of any
6768349Sobrien * substantial portion of the Covered Code or modification must reproduce the
6868349Sobrien * above Copyright Notice, and the following Disclaimer and Export Compliance
6968349Sobrien * provision in the documentation and/or other materials provided with the
7068349Sobrien * distribution.
7168349Sobrien *
7268349Sobrien * 3.4. Intel retains all right, title, and interest in and to the Original
7368349Sobrien * Intel Code.
7468349Sobrien *
7568349Sobrien * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7668349Sobrien * Intel shall be used in advertising or otherwise to promote the sale, use or
7774784Sobrien * other dealings in products derived from or relating to the Covered Code
7868349Sobrien * without prior written authorization from Intel.
7974784Sobrien *
8074784Sobrien * 4. Disclaimer and Export Compliance
8174784Sobrien *
8274784Sobrien * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8374784Sobrien * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
8474784Sobrien * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
8574784Sobrien * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
8680588Sobrien * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
8774784Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
8874784Sobrien * PARTICULAR PURPOSE.
8974784Sobrien *
9074784Sobrien * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
9168349Sobrien * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9268349Sobrien * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
9368349Sobrien * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9474784Sobrien * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9568349Sobrien * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
9680588Sobrien * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9780588Sobrien * LIMITED REMEDY.
9880588Sobrien *
9980588Sobrien * 4.3. Licensee shall not export, either directly or indirectly, any of this
10074784Sobrien * software or system incorporating such software without first obtaining any
10180588Sobrien * required license or other approval from the U. S. Department of Commerce or
10280588Sobrien * any other agency or department of the United States Government.  In the
10380588Sobrien * event Licensee exports any such software from the United States or
10480588Sobrien * re-exports any such software from a foreign destination, Licensee shall
10580588Sobrien * ensure that the distribution and export/re-export of the software is in
10680588Sobrien * compliance with all laws, regulations, orders, or other restrictions of the
10780588Sobrien * U.S. Export Administration Regulations. Licensee agrees that neither it nor
10880588Sobrien * any of its subsidiaries will export/re-export any technical data, process,
10980588Sobrien * software, or service, directly or indirectly, to any country for which the
11080588Sobrien * United States government or any agency thereof requires an export license,
11180588Sobrien * other governmental approval, or letter of assurance, without first obtaining
11280588Sobrien * such license, approval or letter.
11380588Sobrien *
11480588Sobrien *****************************************************************************/
11580588Sobrien
11680588Sobrien#define __DSMTHDAT_C__
11780588Sobrien
11880588Sobrien#include <contrib/dev/acpica/include/acpi.h>
11980588Sobrien#include <contrib/dev/acpica/include/accommon.h>
12080588Sobrien#include <contrib/dev/acpica/include/acdispat.h>
12180588Sobrien#include <contrib/dev/acpica/include/acnamesp.h>
12280588Sobrien#include <contrib/dev/acpica/include/acinterp.h>
12380588Sobrien
12480588Sobrien
12580588Sobrien#define _COMPONENT          ACPI_DISPATCHER
12674784Sobrien        ACPI_MODULE_NAME    ("dsmthdat")
12774784Sobrien
12874784Sobrien/* Local prototypes */
12974784Sobrien
13074784Sobrienstatic void
13174784SobrienAcpiDsMethodDataDeleteValue (
13274784Sobrien    UINT8                   Type,
13374784Sobrien    UINT32                  Index,
13474784Sobrien    ACPI_WALK_STATE         *WalkState);
13574784Sobrien
13674784Sobrienstatic ACPI_STATUS
13774784SobrienAcpiDsMethodDataSetValue (
13874784Sobrien    UINT8                   Type,
13974784Sobrien    UINT32                  Index,
14074784Sobrien    ACPI_OPERAND_OBJECT     *Object,
14174784Sobrien    ACPI_WALK_STATE         *WalkState);
14274784Sobrien
14374784Sobrien#ifdef ACPI_OBSOLETE_FUNCTIONS
14474784SobrienACPI_OBJECT_TYPE
14574784SobrienAcpiDsMethodDataGetType (
14680588Sobrien    UINT16                  Opcode,
14774784Sobrien    UINT32                  Index,
14874784Sobrien    ACPI_WALK_STATE         *WalkState);
14974784Sobrien#endif
15074784Sobrien
15174784Sobrien
15274784Sobrien/*******************************************************************************
15374784Sobrien *
15474784Sobrien * FUNCTION:    AcpiDsMethodDataInit
15574784Sobrien *
15674784Sobrien * PARAMETERS:  WalkState           - Current walk state object
15774784Sobrien *
15880588Sobrien * RETURN:      Status
15980588Sobrien *
16074784Sobrien * DESCRIPTION: Initialize the data structures that hold the method's arguments
16174784Sobrien *              and locals.  The data struct is an array of namespace nodes for
16274784Sobrien *              each - this allows RefOf and DeRefOf to work properly for these
16374784Sobrien *              special data types.
16474784Sobrien *
16574784Sobrien * NOTES:       WalkState fields are initialized to zero by the
16674784Sobrien *              ACPI_ALLOCATE_ZEROED().
16774784Sobrien *
16874784Sobrien *              A pseudo-Namespace Node is assigned to each argument and local
16974784Sobrien *              so that RefOf() can return a pointer to the Node.
17074784Sobrien *
17174784Sobrien ******************************************************************************/
17274784Sobrien
17374784Sobrienvoid
17474784SobrienAcpiDsMethodDataInit (
17574784Sobrien    ACPI_WALK_STATE         *WalkState)
17680588Sobrien{
17774784Sobrien    UINT32                  i;
17874784Sobrien
17974784Sobrien
18068349Sobrien    ACPI_FUNCTION_TRACE (DsMethodDataInit);
18174784Sobrien
18268349Sobrien
18374784Sobrien    /* Init the method arguments */
18468349Sobrien
18568349Sobrien    for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
18668349Sobrien    {
18768349Sobrien        ACPI_MOVE_32_TO_32 (&WalkState->Arguments[i].Name, NAMEOF_ARG_NTE);
18874784Sobrien        WalkState->Arguments[i].Name.Integer |= (i << 24);
18968349Sobrien        WalkState->Arguments[i].DescriptorType = ACPI_DESC_TYPE_NAMED;
19074784Sobrien        WalkState->Arguments[i].Type = ACPI_TYPE_ANY;
19180588Sobrien        WalkState->Arguments[i].Flags =
19280588Sobrien            ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG;
19374784Sobrien    }
19468349Sobrien
19568349Sobrien    /* Init the method locals */
19668349Sobrien
19768349Sobrien    for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++)
19868349Sobrien    {
19968349Sobrien        ACPI_MOVE_32_TO_32 (&WalkState->LocalVariables[i].Name, NAMEOF_LOCAL_NTE);
20068349Sobrien
20168349Sobrien        WalkState->LocalVariables[i].Name.Integer |= (i << 24);
20268349Sobrien        WalkState->LocalVariables[i].DescriptorType = ACPI_DESC_TYPE_NAMED;
20368349Sobrien        WalkState->LocalVariables[i].Type = ACPI_TYPE_ANY;
20474784Sobrien        WalkState->LocalVariables[i].Flags =
20568349Sobrien            ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL;
20668349Sobrien    }
20768349Sobrien
20868349Sobrien    return_VOID;
20968349Sobrien}
21068349Sobrien
21174784Sobrien
21274784Sobrien/*******************************************************************************
21368349Sobrien *
21468349Sobrien * FUNCTION:    AcpiDsMethodDataDeleteAll
21568349Sobrien *
21668349Sobrien * PARAMETERS:  WalkState           - Current walk state object
21768349Sobrien *
21868349Sobrien * RETURN:      None
21974784Sobrien *
22074784Sobrien * DESCRIPTION: Delete method locals and arguments.  Arguments are only
22174784Sobrien *              deleted if this method was called from another method.
22268349Sobrien *
22374784Sobrien ******************************************************************************/
22474784Sobrien
22574784Sobrienvoid
22668349SobrienAcpiDsMethodDataDeleteAll (
22774784Sobrien    ACPI_WALK_STATE         *WalkState)
22868349Sobrien{
22968349Sobrien    UINT32                  Index;
23068349Sobrien
23168349Sobrien
23268349Sobrien    ACPI_FUNCTION_TRACE (DsMethodDataDeleteAll);
23368349Sobrien
23468349Sobrien
23568349Sobrien    /* Detach the locals */
23674784Sobrien
23768349Sobrien    for (Index = 0; Index < ACPI_METHOD_NUM_LOCALS; Index++)
23868349Sobrien    {
23968349Sobrien        if (WalkState->LocalVariables[Index].Object)
24068349Sobrien        {
24168349Sobrien            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%d=%p\n",
24268349Sobrien                    Index, WalkState->LocalVariables[Index].Object));
24368349Sobrien
24474784Sobrien            /* Detach object (if present) and remove a reference */
24574784Sobrien
24674784Sobrien            AcpiNsDetachObject (&WalkState->LocalVariables[Index]);
24780588Sobrien        }
24880588Sobrien    }
24974784Sobrien
25074784Sobrien    /* Detach the arguments */
25174784Sobrien
25274784Sobrien    for (Index = 0; Index < ACPI_METHOD_NUM_ARGS; Index++)
25368349Sobrien    {
25474784Sobrien        if (WalkState->Arguments[Index].Object)
25568349Sobrien        {
25668349Sobrien            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%d=%p\n",
25768349Sobrien                    Index, WalkState->Arguments[Index].Object));
25868349Sobrien
25968349Sobrien            /* Detach object (if present) and remove a reference */
26068349Sobrien
26168349Sobrien            AcpiNsDetachObject (&WalkState->Arguments[Index]);
26268349Sobrien        }
26374784Sobrien    }
26468349Sobrien
26568349Sobrien    return_VOID;
26668349Sobrien}
26768349Sobrien
26874784Sobrien
26974784Sobrien/*******************************************************************************
27074784Sobrien *
27174784Sobrien * FUNCTION:    AcpiDsMethodDataInitArgs
27274784Sobrien *
27368349Sobrien * PARAMETERS:  *Params         - Pointer to a parameter list for the method
27468349Sobrien *              MaxParamCount   - The arg count for this method
27568349Sobrien *              WalkState       - Current walk state object
27668349Sobrien *
27768349Sobrien * RETURN:      Status
27868349Sobrien *
27968349Sobrien * DESCRIPTION: Initialize arguments for a method.  The parameter list is a list
28068349Sobrien *              of ACPI operand objects, either null terminated or whose length
28168349Sobrien *              is defined by MaxParamCount.
28268349Sobrien *
28368349Sobrien ******************************************************************************/
28468349Sobrien
28568349SobrienACPI_STATUS
28668349SobrienAcpiDsMethodDataInitArgs (
28768349Sobrien    ACPI_OPERAND_OBJECT     **Params,
28868349Sobrien    UINT32                  MaxParamCount,
28968349Sobrien    ACPI_WALK_STATE         *WalkState)
29068349Sobrien{
29168349Sobrien    ACPI_STATUS             Status;
29268349Sobrien    UINT32                  Index = 0;
29368349Sobrien
29468349Sobrien
29568349Sobrien    ACPI_FUNCTION_TRACE_PTR (DsMethodDataInitArgs, Params);
29668349Sobrien
29768349Sobrien
29868349Sobrien    if (!Params)
29968349Sobrien    {
30068349Sobrien        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n"));
30168349Sobrien        return_ACPI_STATUS (AE_OK);
30280588Sobrien    }
30380588Sobrien
30480588Sobrien    /* Copy passed parameters into the new method stack frame */
30568349Sobrien
30668349Sobrien    while ((Index < ACPI_METHOD_NUM_ARGS) &&
30768349Sobrien           (Index < MaxParamCount)        &&
30868349Sobrien            Params[Index])
30968349Sobrien    {
31068349Sobrien        /*
31180588Sobrien         * A valid parameter.
31268349Sobrien         * Store the argument in the method/walk descriptor.
31368349Sobrien         * Do not copy the arg in order to implement call by reference
31468349Sobrien         */
31568349Sobrien        Status = AcpiDsMethodDataSetValue (ACPI_REFCLASS_ARG, Index,
31668349Sobrien                    Params[Index], WalkState);
31768349Sobrien        if (ACPI_FAILURE (Status))
31868349Sobrien        {
31968349Sobrien            return_ACPI_STATUS (Status);
32068349Sobrien        }
32168349Sobrien
32268349Sobrien        Index++;
32368349Sobrien    }
32468349Sobrien
32574784Sobrien    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%d args passed to method\n", Index));
32674784Sobrien    return_ACPI_STATUS (AE_OK);
32774784Sobrien}
32868349Sobrien
32974784Sobrien
33068349Sobrien/*******************************************************************************
33174784Sobrien *
33268349Sobrien * FUNCTION:    AcpiDsMethodDataGetNode
33368349Sobrien *
33468349Sobrien * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
33568349Sobrien *                                    ACPI_REFCLASS_ARG
33674784Sobrien *              Index               - Which Local or Arg whose type to get
33768349Sobrien *              WalkState           - Current walk state object
33874784Sobrien *              Node                - Where the node is returned.
33974784Sobrien *
34080588Sobrien * RETURN:      Status and node
34180588Sobrien *
34274784Sobrien * DESCRIPTION: Get the Node associated with a local or arg.
34374784Sobrien *
34474784Sobrien ******************************************************************************/
34568349Sobrien
34668349SobrienACPI_STATUS
34768349SobrienAcpiDsMethodDataGetNode (
34868349Sobrien    UINT8                   Type,
34974784Sobrien    UINT32                  Index,
35074784Sobrien    ACPI_WALK_STATE         *WalkState,
35174784Sobrien    ACPI_NAMESPACE_NODE     **Node)
35268349Sobrien{
35374784Sobrien    ACPI_FUNCTION_TRACE (DsMethodDataGetNode);
35468349Sobrien
35568349Sobrien
35668349Sobrien    /*
35768349Sobrien     * Method Locals and Arguments are supported
35868349Sobrien     */
35968349Sobrien    switch (Type)
36068349Sobrien    {
36168349Sobrien    case ACPI_REFCLASS_LOCAL:
36268349Sobrien
36368349Sobrien        if (Index > ACPI_METHOD_MAX_LOCAL)
36468349Sobrien        {
36568349Sobrien            ACPI_ERROR ((AE_INFO,
36668349Sobrien                "Local index %d is invalid (max %d)",
36768349Sobrien                Index, ACPI_METHOD_MAX_LOCAL));
36880588Sobrien            return_ACPI_STATUS (AE_AML_INVALID_INDEX);
36968349Sobrien        }
37068349Sobrien
37168349Sobrien        /* Return a pointer to the pseudo-node */
37268349Sobrien
37368349Sobrien        *Node = &WalkState->LocalVariables[Index];
37468349Sobrien        break;
37568349Sobrien
37668349Sobrien    case ACPI_REFCLASS_ARG:
37768349Sobrien
37874784Sobrien        if (Index > ACPI_METHOD_MAX_ARG)
37974784Sobrien        {
38068349Sobrien            ACPI_ERROR ((AE_INFO,
38168349Sobrien                "Arg index %d is invalid (max %d)",
38268349Sobrien                Index, ACPI_METHOD_MAX_ARG));
38368349Sobrien            return_ACPI_STATUS (AE_AML_INVALID_INDEX);
38468349Sobrien        }
38568349Sobrien
38668349Sobrien        /* Return a pointer to the pseudo-node */
38774784Sobrien
38868349Sobrien        *Node = &WalkState->Arguments[Index];
38968349Sobrien        break;
39074784Sobrien
39168349Sobrien    default:
39268349Sobrien        ACPI_ERROR ((AE_INFO, "Type %d is invalid", Type));
39368349Sobrien        return_ACPI_STATUS (AE_TYPE);
39474784Sobrien    }
39568349Sobrien
39668349Sobrien    return_ACPI_STATUS (AE_OK);
39768349Sobrien}
39874784Sobrien
39968349Sobrien
40068349Sobrien/*******************************************************************************
40168349Sobrien *
40268349Sobrien * FUNCTION:    AcpiDsMethodDataSetValue
40368349Sobrien *
40474784Sobrien * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
40568349Sobrien *                                    ACPI_REFCLASS_ARG
40668349Sobrien *              Index               - Which Local or Arg to get
40768349Sobrien *              Object              - Object to be inserted into the stack entry
40868349Sobrien *              WalkState           - Current walk state object
40968349Sobrien *
41068349Sobrien * RETURN:      Status
41168349Sobrien *
41280588Sobrien * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index.
41380588Sobrien *              Note: There is no "implicit conversion" for locals.
41480588Sobrien *
41580588Sobrien ******************************************************************************/
41680588Sobrien
41780588Sobrienstatic ACPI_STATUS
41880588SobrienAcpiDsMethodDataSetValue (
41980588Sobrien    UINT8                   Type,
42080588Sobrien    UINT32                  Index,
42180588Sobrien    ACPI_OPERAND_OBJECT     *Object,
42280588Sobrien    ACPI_WALK_STATE         *WalkState)
42380588Sobrien{
42480588Sobrien    ACPI_STATUS             Status;
42580588Sobrien    ACPI_NAMESPACE_NODE     *Node;
42680588Sobrien
42780588Sobrien
42880588Sobrien    ACPI_FUNCTION_TRACE (DsMethodDataSetValue);
42980588Sobrien
43080588Sobrien
43180588Sobrien    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
43280588Sobrien        "NewObj %p Type %2.2X, Refs=%d [%s]\n", Object,
43380588Sobrien        Type, Object->Common.ReferenceCount,
43480588Sobrien        AcpiUtGetTypeName (Object->Common.Type)));
43580588Sobrien
43680588Sobrien    /* Get the namespace node for the arg/local */
43780588Sobrien
43880588Sobrien    Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
43980588Sobrien    if (ACPI_FAILURE (Status))
44080588Sobrien    {
44180588Sobrien        return_ACPI_STATUS (Status);
44280588Sobrien    }
44380588Sobrien
44480588Sobrien    /*
44580588Sobrien     * Increment ref count so object can't be deleted while installed.
44680588Sobrien     * NOTE: We do not copy the object in order to preserve the call by
44780588Sobrien     * reference semantics of ACPI Control Method invocation.
44880588Sobrien     * (See ACPI Specification 2.0C)
44980588Sobrien     */
45080588Sobrien    AcpiUtAddReference (Object);
45174784Sobrien
45268349Sobrien    /* Install the object */
45368349Sobrien
45468349Sobrien    Node->Object = Object;
45568349Sobrien    return_ACPI_STATUS (Status);
45668349Sobrien}
45768349Sobrien
45868349Sobrien
45968349Sobrien/*******************************************************************************
46068349Sobrien *
46168349Sobrien * FUNCTION:    AcpiDsMethodDataGetValue
46268349Sobrien *
46368349Sobrien * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
46468349Sobrien *                                    ACPI_REFCLASS_ARG
46568349Sobrien *              Index               - Which localVar or argument to get
46668349Sobrien *              WalkState           - Current walk state object
46768349Sobrien *              DestDesc            - Where Arg or Local value is returned
46868349Sobrien *
46968349Sobrien * RETURN:      Status
47068349Sobrien *
47168349Sobrien * DESCRIPTION: Retrieve value of selected Arg or Local for this method
47268349Sobrien *              Used only in AcpiExResolveToValue().
47368349Sobrien *
47468349Sobrien ******************************************************************************/
47580588Sobrien
47680588SobrienACPI_STATUS
47780588SobrienAcpiDsMethodDataGetValue (
47880588Sobrien    UINT8                   Type,
47968349Sobrien    UINT32                  Index,
48068349Sobrien    ACPI_WALK_STATE         *WalkState,
48168349Sobrien    ACPI_OPERAND_OBJECT     **DestDesc)
48268349Sobrien{
48368349Sobrien    ACPI_STATUS             Status;
48468349Sobrien    ACPI_NAMESPACE_NODE     *Node;
48568349Sobrien    ACPI_OPERAND_OBJECT     *Object;
48668349Sobrien
48768349Sobrien
48868349Sobrien    ACPI_FUNCTION_TRACE (DsMethodDataGetValue);
48968349Sobrien
49068349Sobrien
49168349Sobrien    /* Validate the object descriptor */
49268349Sobrien
49368349Sobrien    if (!DestDesc)
49468349Sobrien    {
49568349Sobrien        ACPI_ERROR ((AE_INFO, "Null object descriptor pointer"));
49668349Sobrien        return_ACPI_STATUS (AE_BAD_PARAMETER);
49768349Sobrien    }
49868349Sobrien
49968349Sobrien    /* Get the namespace node for the arg/local */
50068349Sobrien
50168349Sobrien    Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
50268349Sobrien    if (ACPI_FAILURE (Status))
50368349Sobrien    {
50468349Sobrien        return_ACPI_STATUS (Status);
50568349Sobrien    }
50668349Sobrien
50768349Sobrien    /* Get the object from the node */
50868349Sobrien
50968349Sobrien    Object = Node->Object;
51068349Sobrien
51168349Sobrien    /* Examine the returned object, it must be valid. */
51268349Sobrien
51368349Sobrien    if (!Object)
51468349Sobrien    {
51568349Sobrien        /*
51668349Sobrien         * Index points to uninitialized object.
51768349Sobrien         * This means that either 1) The expected argument was
51868349Sobrien         * not passed to the method, or 2) A local variable
51968349Sobrien         * was referenced by the method (via the ASL)
52068349Sobrien         * before it was initialized.  Either case is an error.
52168349Sobrien         */
52280588Sobrien
52380588Sobrien        /* If slack enabled, init the LocalX/ArgX to an Integer of value zero */
52480588Sobrien
52580588Sobrien        if (AcpiGbl_EnableInterpreterSlack)
52680588Sobrien        {
52780588Sobrien            Object = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
52880588Sobrien            if (!Object)
52980588Sobrien            {
53080588Sobrien                return_ACPI_STATUS (AE_NO_MEMORY);
53180588Sobrien            }
53280588Sobrien
53380588Sobrien            Object->Integer.Value = 0;
53468349Sobrien            Node->Object = Object;
53568349Sobrien        }
53668349Sobrien
53768349Sobrien        /* Otherwise, return the error */
53868349Sobrien
53980588Sobrien        else switch (Type)
54080588Sobrien        {
54180588Sobrien        case ACPI_REFCLASS_ARG:
54280588Sobrien
54368349Sobrien            ACPI_ERROR ((AE_INFO,
54480588Sobrien                "Uninitialized Arg[%d] at node %p",
54580588Sobrien                Index, Node));
54680588Sobrien
54780588Sobrien            return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
54880588Sobrien
54968349Sobrien        case ACPI_REFCLASS_LOCAL:
55068349Sobrien
55180588Sobrien            /*
55280588Sobrien             * No error message for this case, will be trapped again later to
55380588Sobrien             * detect and ignore cases of Store(LocalX,LocalX)
55480588Sobrien             */
55580588Sobrien            return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL);
55680588Sobrien
55780588Sobrien        default:
55880588Sobrien
55980588Sobrien            ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: %X", Type));
56080588Sobrien            return_ACPI_STATUS (AE_AML_INTERNAL);
56180588Sobrien        }
56280588Sobrien    }
56380588Sobrien
56480588Sobrien    /*
56580588Sobrien     * The Index points to an initialized and valid object.
56680588Sobrien     * Return an additional reference to the object
56780588Sobrien     */
56880588Sobrien    *DestDesc = Object;
56980588Sobrien    AcpiUtAddReference (Object);
57080588Sobrien
57180588Sobrien    return_ACPI_STATUS (AE_OK);
57280588Sobrien}
57380588Sobrien
57480588Sobrien
57580588Sobrien/*******************************************************************************
57680588Sobrien *
57780588Sobrien * FUNCTION:    AcpiDsMethodDataDeleteValue
57880588Sobrien *
57980588Sobrien * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
58080588Sobrien *                                    ACPI_REFCLASS_ARG
58180588Sobrien *              Index               - Which localVar or argument to delete
58280588Sobrien *              WalkState           - Current walk state object
58380588Sobrien *
58480588Sobrien * RETURN:      None
58580588Sobrien *
58680588Sobrien * DESCRIPTION: Delete the entry at Opcode:Index.  Inserts
58780588Sobrien *              a null into the stack slot after the object is deleted.
58880588Sobrien *
58980588Sobrien ******************************************************************************/
59080588Sobrien
59180588Sobrienstatic void
59280588SobrienAcpiDsMethodDataDeleteValue (
59380588Sobrien    UINT8                   Type,
59480588Sobrien    UINT32                  Index,
59580588Sobrien    ACPI_WALK_STATE         *WalkState)
59668349Sobrien{
59768349Sobrien    ACPI_STATUS             Status;
59868349Sobrien    ACPI_NAMESPACE_NODE     *Node;
59968349Sobrien    ACPI_OPERAND_OBJECT     *Object;
60068349Sobrien
60168349Sobrien
60268349Sobrien    ACPI_FUNCTION_TRACE (DsMethodDataDeleteValue);
60368349Sobrien
60468349Sobrien
60568349Sobrien    /* Get the namespace node for the arg/local */
60668349Sobrien
60768349Sobrien    Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
60868349Sobrien    if (ACPI_FAILURE (Status))
60968349Sobrien    {
61068349Sobrien        return_VOID;
61168349Sobrien    }
61268349Sobrien
61368349Sobrien    /* Get the associated object */
61468349Sobrien
61580588Sobrien    Object = AcpiNsGetAttachedObject (Node);
61680588Sobrien
61780588Sobrien    /*
61880588Sobrien     * Undefine the Arg or Local by setting its descriptor
61968349Sobrien     * pointer to NULL. Locals/Args can contain both
62068349Sobrien     * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
62168349Sobrien     */
62268349Sobrien    Node->Object = NULL;
62368349Sobrien
62468349Sobrien    if ((Object) &&
62568349Sobrien        (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_OPERAND))
62668349Sobrien    {
62768349Sobrien        /*
62868349Sobrien         * There is a valid object.
62968349Sobrien         * Decrement the reference count by one to balance the
63068349Sobrien         * increment when the object was stored.
63168349Sobrien         */
63268349Sobrien        AcpiUtRemoveReference (Object);
63368349Sobrien    }
63468349Sobrien
63568349Sobrien    return_VOID;
63680588Sobrien}
63768349Sobrien
63868349Sobrien
63968349Sobrien/*******************************************************************************
64068349Sobrien *
64168349Sobrien * FUNCTION:    AcpiDsStoreObjectToLocal
64268349Sobrien *
64368349Sobrien * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
64468349Sobrien *                                    ACPI_REFCLASS_ARG
64568349Sobrien *              Index               - Which Local or Arg to set
64668349Sobrien *              ObjDesc             - Value to be stored
64768349Sobrien *              WalkState           - Current walk state
64868349Sobrien *
64968349Sobrien * RETURN:      Status
65068349Sobrien *
65168349Sobrien * DESCRIPTION: Store a value in an Arg or Local.  The ObjDesc is installed
65268349Sobrien *              as the new value for the Arg or Local and the reference count
65368349Sobrien *              for ObjDesc is incremented.
65468349Sobrien *
65568349Sobrien ******************************************************************************/
65668349Sobrien
65768349SobrienACPI_STATUS
65868349SobrienAcpiDsStoreObjectToLocal (
65968349Sobrien    UINT8                   Type,
66068349Sobrien    UINT32                  Index,
66168349Sobrien    ACPI_OPERAND_OBJECT     *ObjDesc,
66268349Sobrien    ACPI_WALK_STATE         *WalkState)
66368349Sobrien{
66468349Sobrien    ACPI_STATUS             Status;
66568349Sobrien    ACPI_NAMESPACE_NODE     *Node;
66668349Sobrien    ACPI_OPERAND_OBJECT     *CurrentObjDesc;
66768349Sobrien    ACPI_OPERAND_OBJECT     *NewObjDesc;
66868349Sobrien
66968349Sobrien
67068349Sobrien    ACPI_FUNCTION_TRACE (DsStoreObjectToLocal);
67168349Sobrien    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Type=%2.2X Index=%d Obj=%p\n",
67268349Sobrien        Type, Index, ObjDesc));
67368349Sobrien
67468349Sobrien    /* Parameter validation */
67568349Sobrien
67668349Sobrien    if (!ObjDesc)
67768349Sobrien    {
67868349Sobrien        return_ACPI_STATUS (AE_BAD_PARAMETER);
67974784Sobrien    }
68068349Sobrien
68168349Sobrien    /* Get the namespace node for the arg/local */
68274784Sobrien
68368349Sobrien    Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
68468349Sobrien    if (ACPI_FAILURE (Status))
68568349Sobrien    {
68668349Sobrien        return_ACPI_STATUS (Status);
68768349Sobrien    }
68868349Sobrien
68968349Sobrien    CurrentObjDesc = AcpiNsGetAttachedObject (Node);
69068349Sobrien    if (CurrentObjDesc == ObjDesc)
69168349Sobrien    {
69268349Sobrien        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n",
69368349Sobrien            ObjDesc));
69468349Sobrien        return_ACPI_STATUS (Status);
69568349Sobrien    }
69668349Sobrien
69768349Sobrien    /*
69880588Sobrien     * If the reference count on the object is more than one, we must
69968349Sobrien     * take a copy of the object before we store.  A reference count
70068349Sobrien     * of exactly 1 means that the object was just created during the
70168349Sobrien     * evaluation of an expression, and we can safely use it since it
70268349Sobrien     * is not used anywhere else.
70368349Sobrien     */
70468349Sobrien    NewObjDesc = ObjDesc;
70568349Sobrien    if (ObjDesc->Common.ReferenceCount > 1)
70668349Sobrien    {
70768349Sobrien        Status = AcpiUtCopyIobjectToIobject (ObjDesc, &NewObjDesc, WalkState);
70868349Sobrien        if (ACPI_FAILURE (Status))
70968349Sobrien        {
71068349Sobrien            return_ACPI_STATUS (Status);
71168349Sobrien        }
71268349Sobrien    }
71368349Sobrien
71468349Sobrien    /*
71568349Sobrien     * If there is an object already in this slot, we either
71668349Sobrien     * have to delete it, or if this is an argument and there
71768349Sobrien     * is an object reference stored there, we have to do
71868349Sobrien     * an indirect store!
71968349Sobrien     */
72068349Sobrien    if (CurrentObjDesc)
72168349Sobrien    {
72268349Sobrien        /*
72368349Sobrien         * Check for an indirect store if an argument
72468349Sobrien         * contains an object reference (stored as an Node).
72568349Sobrien         * We don't allow this automatic dereferencing for
72668349Sobrien         * locals, since a store to a local should overwrite
72768349Sobrien         * anything there, including an object reference.
72868349Sobrien         *
72968349Sobrien         * If both Arg0 and Local0 contain RefOf (Local4):
73068349Sobrien         *
73168349Sobrien         * Store (1, Arg0)             - Causes indirect store to local4
73268349Sobrien         * Store (1, Local0)           - Stores 1 in local0, overwriting
73368349Sobrien         *                                  the reference to local4
73468349Sobrien         * Store (1, DeRefof (Local0)) - Causes indirect store to local4
73568349Sobrien         *
73668349Sobrien         * Weird, but true.
73768349Sobrien         */
73868349Sobrien        if (Type == ACPI_REFCLASS_ARG)
73968349Sobrien        {
74068349Sobrien            /*
74168349Sobrien             * If we have a valid reference object that came from RefOf(),
74268349Sobrien             * do the indirect store
74368349Sobrien             */
74468349Sobrien            if ((ACPI_GET_DESCRIPTOR_TYPE (CurrentObjDesc) == ACPI_DESC_TYPE_OPERAND) &&
74568349Sobrien                (CurrentObjDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
74668349Sobrien                (CurrentObjDesc->Reference.Class == ACPI_REFCLASS_REFOF))
74768349Sobrien            {
74868349Sobrien                ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
74968349Sobrien                        "Arg (%p) is an ObjRef(Node), storing in node %p\n",
75068349Sobrien                        NewObjDesc, CurrentObjDesc));
75168349Sobrien
75268349Sobrien                /*
75368349Sobrien                 * Store this object to the Node (perform the indirect store)
75468349Sobrien                 * NOTE: No implicit conversion is performed, as per the ACPI
75568349Sobrien                 * specification rules on storing to Locals/Args.
75668349Sobrien                 */
75768349Sobrien                Status = AcpiExStoreObjectToNode (NewObjDesc,
75868349Sobrien                            CurrentObjDesc->Reference.Object, WalkState,
75968349Sobrien                            ACPI_NO_IMPLICIT_CONVERSION);
76068349Sobrien
76168349Sobrien                /* Remove local reference if we copied the object above */
76268349Sobrien
76368349Sobrien                if (NewObjDesc != ObjDesc)
76468349Sobrien                {
76568349Sobrien                    AcpiUtRemoveReference (NewObjDesc);
76668349Sobrien                }
76768349Sobrien                return_ACPI_STATUS (Status);
76868349Sobrien            }
76968349Sobrien        }
77068349Sobrien
77168349Sobrien        /* Delete the existing object before storing the new one */
77268349Sobrien
77368349Sobrien        AcpiDsMethodDataDeleteValue (Type, Index, WalkState);
77468349Sobrien    }
77568349Sobrien
77668349Sobrien    /*
77768349Sobrien     * Install the Obj descriptor (*NewObjDesc) into
77868349Sobrien     * the descriptor for the Arg or Local.
77968349Sobrien     * (increments the object reference count by one)
78068349Sobrien     */
78168349Sobrien    Status = AcpiDsMethodDataSetValue (Type, Index, NewObjDesc, WalkState);
78268349Sobrien
78368349Sobrien    /* Remove local reference if we copied the object above */
78468349Sobrien
78568349Sobrien    if (NewObjDesc != ObjDesc)
78668349Sobrien    {
78768349Sobrien        AcpiUtRemoveReference (NewObjDesc);
78868349Sobrien    }
78968349Sobrien
79068349Sobrien    return_ACPI_STATUS (Status);
79168349Sobrien}
79268349Sobrien
79368349Sobrien
79468349Sobrien#ifdef ACPI_OBSOLETE_FUNCTIONS
79568349Sobrien/*******************************************************************************
79668349Sobrien *
79768349Sobrien * FUNCTION:    AcpiDsMethodDataGetType
79868349Sobrien *
79968349Sobrien * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
80068349Sobrien *              Index               - Which Local or Arg whose type to get
80168349Sobrien *              WalkState           - Current walk state object
80268349Sobrien *
80368349Sobrien * RETURN:      Data type of current value of the selected Arg or Local
80468349Sobrien *
80568349Sobrien * DESCRIPTION: Get the type of the object stored in the Local or Arg
80668349Sobrien *
80768349Sobrien ******************************************************************************/
80868349Sobrien
80968349SobrienACPI_OBJECT_TYPE
81068349SobrienAcpiDsMethodDataGetType (
81168349Sobrien    UINT16                  Opcode,
81268349Sobrien    UINT32                  Index,
81368349Sobrien    ACPI_WALK_STATE         *WalkState)
81468349Sobrien{
81568349Sobrien    ACPI_STATUS             Status;
81668349Sobrien    ACPI_NAMESPACE_NODE     *Node;
81768349Sobrien    ACPI_OPERAND_OBJECT     *Object;
81868349Sobrien
81968349Sobrien
82068349Sobrien    ACPI_FUNCTION_TRACE (DsMethodDataGetType);
82168349Sobrien
82268349Sobrien
82368349Sobrien    /* Get the namespace node for the arg/local */
82468349Sobrien
82568349Sobrien    Status = AcpiDsMethodDataGetNode (Opcode, Index, WalkState, &Node);
82668349Sobrien    if (ACPI_FAILURE (Status))
82768349Sobrien    {
82868349Sobrien        return_VALUE ((ACPI_TYPE_NOT_FOUND));
82968349Sobrien    }
83068349Sobrien
83168349Sobrien    /* Get the object */
83268349Sobrien
83368349Sobrien    Object = AcpiNsGetAttachedObject (Node);
83468349Sobrien    if (!Object)
83568349Sobrien    {
83668349Sobrien        /* Uninitialized local/arg, return TYPE_ANY */
83768349Sobrien
83868349Sobrien        return_VALUE (ACPI_TYPE_ANY);
83968349Sobrien    }
84068349Sobrien
84168349Sobrien    /* Get the object type */
84268349Sobrien
84368349Sobrien    return_VALUE (Object->Type);
84468349Sobrien}
84568349Sobrien#endif
84668349Sobrien
84768349Sobrien
84868349Sobrien