167754Smsmith/*******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: dsmthdat - control method arguments and local variables
467754Smsmith *
567754Smsmith ******************************************************************************/
667754Smsmith
7217365Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
970243Smsmith * All rights reserved.
1067754Smsmith *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
2567754Smsmith *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
2967754Smsmith *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
4367754Smsmith
44193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
45193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
46193341Sjkim#include <contrib/dev/acpica/include/acdispat.h>
47193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
48193341Sjkim#include <contrib/dev/acpica/include/acinterp.h>
4967754Smsmith
5067754Smsmith
5177424Smsmith#define _COMPONENT          ACPI_DISPATCHER
5291116Smsmith        ACPI_MODULE_NAME    ("dsmthdat")
5367754Smsmith
54151937Sjkim/* Local prototypes */
5567754Smsmith
56151937Sjkimstatic void
57151937SjkimAcpiDsMethodDataDeleteValue (
58193267Sjkim    UINT8                   Type,
59151937Sjkim    UINT32                  Index,
60151937Sjkim    ACPI_WALK_STATE         *WalkState);
61151937Sjkim
62151937Sjkimstatic ACPI_STATUS
63151937SjkimAcpiDsMethodDataSetValue (
64193267Sjkim    UINT8                   Type,
65151937Sjkim    UINT32                  Index,
66151937Sjkim    ACPI_OPERAND_OBJECT     *Object,
67151937Sjkim    ACPI_WALK_STATE         *WalkState);
68151937Sjkim
69151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS
70151937SjkimACPI_OBJECT_TYPE
71151937SjkimAcpiDsMethodDataGetType (
72151937Sjkim    UINT16                  Opcode,
73151937Sjkim    UINT32                  Index,
74151937Sjkim    ACPI_WALK_STATE         *WalkState);
75151937Sjkim#endif
76151937Sjkim
77151937Sjkim
7867754Smsmith/*******************************************************************************
7967754Smsmith *
8067754Smsmith * FUNCTION:    AcpiDsMethodDataInit
8167754Smsmith *
8271867Smsmith * PARAMETERS:  WalkState           - Current walk state object
8367754Smsmith *
8467754Smsmith * RETURN:      Status
8567754Smsmith *
8667754Smsmith * DESCRIPTION: Initialize the data structures that hold the method's arguments
87241973Sjkim *              and locals. The data struct is an array of namespace nodes for
88151937Sjkim *              each - this allows RefOf and DeRefOf to work properly for these
8967754Smsmith *              special data types.
9067754Smsmith *
9187031Smsmith * NOTES:       WalkState fields are initialized to zero by the
92167802Sjkim *              ACPI_ALLOCATE_ZEROED().
9387031Smsmith *
9487031Smsmith *              A pseudo-Namespace Node is assigned to each argument and local
9587031Smsmith *              so that RefOf() can return a pointer to the Node.
9687031Smsmith *
9767754Smsmith ******************************************************************************/
9867754Smsmith
9999679Siwasakivoid
10067754SmsmithAcpiDsMethodDataInit (
10167754Smsmith    ACPI_WALK_STATE         *WalkState)
10267754Smsmith{
10367754Smsmith    UINT32                  i;
10467754Smsmith
10567754Smsmith
106167802Sjkim    ACPI_FUNCTION_TRACE (DsMethodDataInit);
10767754Smsmith
10867754Smsmith
10967754Smsmith    /* Init the method arguments */
11067754Smsmith
111114237Snjl    for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
11267754Smsmith    {
113306536Sjkim        ACPI_MOVE_32_TO_32 (&WalkState->Arguments[i].Name,
114306536Sjkim            NAMEOF_ARG_NTE);
115306536Sjkim
11699146Siwasaki        WalkState->Arguments[i].Name.Integer |= (i << 24);
117167802Sjkim        WalkState->Arguments[i].DescriptorType = ACPI_DESC_TYPE_NAMED;
118167802Sjkim        WalkState->Arguments[i].Type = ACPI_TYPE_ANY;
119209746Sjkim        WalkState->Arguments[i].Flags = ANOBJ_METHOD_ARG;
12067754Smsmith    }
12167754Smsmith
12267754Smsmith    /* Init the method locals */
12367754Smsmith
124114237Snjl    for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++)
12567754Smsmith    {
126306536Sjkim        ACPI_MOVE_32_TO_32 (&WalkState->LocalVariables[i].Name,
127306536Sjkim            NAMEOF_LOCAL_NTE);
12867754Smsmith
12999146Siwasaki        WalkState->LocalVariables[i].Name.Integer |= (i << 24);
130167802Sjkim        WalkState->LocalVariables[i].DescriptorType = ACPI_DESC_TYPE_NAMED;
131167802Sjkim        WalkState->LocalVariables[i].Type = ACPI_TYPE_ANY;
132209746Sjkim        WalkState->LocalVariables[i].Flags = ANOBJ_METHOD_LOCAL;
13367754Smsmith    }
13467754Smsmith
13599679Siwasaki    return_VOID;
13667754Smsmith}
13767754Smsmith
13867754Smsmith
13967754Smsmith/*******************************************************************************
14067754Smsmith *
14167754Smsmith * FUNCTION:    AcpiDsMethodDataDeleteAll
14267754Smsmith *
14371867Smsmith * PARAMETERS:  WalkState           - Current walk state object
14467754Smsmith *
14599679Siwasaki * RETURN:      None
14667754Smsmith *
147241973Sjkim * DESCRIPTION: Delete method locals and arguments. Arguments are only
14867754Smsmith *              deleted if this method was called from another method.
14967754Smsmith *
15067754Smsmith ******************************************************************************/
15167754Smsmith
15299679Siwasakivoid
15367754SmsmithAcpiDsMethodDataDeleteAll (
15467754Smsmith    ACPI_WALK_STATE         *WalkState)
15567754Smsmith{
15667754Smsmith    UINT32                  Index;
15767754Smsmith
15867754Smsmith
159167802Sjkim    ACPI_FUNCTION_TRACE (DsMethodDataDeleteAll);
16067754Smsmith
16167754Smsmith
16287031Smsmith    /* Detach the locals */
16367754Smsmith
164114237Snjl    for (Index = 0; Index < ACPI_METHOD_NUM_LOCALS; Index++)
16567754Smsmith    {
16687031Smsmith        if (WalkState->LocalVariables[Index].Object)
16767754Smsmith        {
168209746Sjkim            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%u=%p\n",
169306536Sjkim                Index, WalkState->LocalVariables[Index].Object));
17067754Smsmith
17187031Smsmith            /* Detach object (if present) and remove a reference */
17267754Smsmith
17387031Smsmith            AcpiNsDetachObject (&WalkState->LocalVariables[Index]);
17499679Siwasaki        }
17567754Smsmith    }
17667754Smsmith
17787031Smsmith    /* Detach the arguments */
17867754Smsmith
179114237Snjl    for (Index = 0; Index < ACPI_METHOD_NUM_ARGS; Index++)
18067754Smsmith    {
18187031Smsmith        if (WalkState->Arguments[Index].Object)
18267754Smsmith        {
183209746Sjkim            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%u=%p\n",
184306536Sjkim                Index, WalkState->Arguments[Index].Object));
18567754Smsmith
18687031Smsmith            /* Detach object (if present) and remove a reference */
18767754Smsmith
18887031Smsmith            AcpiNsDetachObject (&WalkState->Arguments[Index]);
18967754Smsmith        }
19067754Smsmith    }
19167754Smsmith
19299679Siwasaki    return_VOID;
19367754Smsmith}
19467754Smsmith
19567754Smsmith
19667754Smsmith/*******************************************************************************
19767754Smsmith *
19867754Smsmith * FUNCTION:    AcpiDsMethodDataInitArgs
19967754Smsmith *
20071867Smsmith * PARAMETERS:  *Params         - Pointer to a parameter list for the method
20171867Smsmith *              MaxParamCount   - The arg count for this method
20271867Smsmith *              WalkState       - Current walk state object
20367754Smsmith *
20467754Smsmith * RETURN:      Status
20567754Smsmith *
206241973Sjkim * DESCRIPTION: Initialize arguments for a method. The parameter list is a list
20787031Smsmith *              of ACPI operand objects, either null terminated or whose length
20887031Smsmith *              is defined by MaxParamCount.
20967754Smsmith *
21067754Smsmith ******************************************************************************/
21167754Smsmith
21267754SmsmithACPI_STATUS
21367754SmsmithAcpiDsMethodDataInitArgs (
21467754Smsmith    ACPI_OPERAND_OBJECT     **Params,
21567754Smsmith    UINT32                  MaxParamCount,
21667754Smsmith    ACPI_WALK_STATE         *WalkState)
21767754Smsmith{
21867754Smsmith    ACPI_STATUS             Status;
21987031Smsmith    UINT32                  Index = 0;
22067754Smsmith
22167754Smsmith
222167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsMethodDataInitArgs, Params);
22367754Smsmith
22467754Smsmith
22567754Smsmith    if (!Params)
22667754Smsmith    {
227306536Sjkim        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
228306536Sjkim            "No parameter list passed to method\n"));
22967754Smsmith        return_ACPI_STATUS (AE_OK);
23067754Smsmith    }
23167754Smsmith
232151937Sjkim    /* Copy passed parameters into the new method stack frame */
23367754Smsmith
234151937Sjkim    while ((Index < ACPI_METHOD_NUM_ARGS) &&
235151937Sjkim           (Index < MaxParamCount)        &&
236151937Sjkim            Params[Index])
23767754Smsmith    {
23887031Smsmith        /*
23987031Smsmith         * A valid parameter.
240126372Snjl         * Store the argument in the method/walk descriptor.
241126372Snjl         * Do not copy the arg in order to implement call by reference
24287031Smsmith         */
243306536Sjkim        Status = AcpiDsMethodDataSetValue (
244306536Sjkim            ACPI_REFCLASS_ARG, Index, Params[Index], WalkState);
24587031Smsmith        if (ACPI_FAILURE (Status))
24667754Smsmith        {
24787031Smsmith            return_ACPI_STATUS (Status);
24867754Smsmith        }
24967754Smsmith
25087031Smsmith        Index++;
25167754Smsmith    }
25267754Smsmith
253209746Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%u args passed to method\n", Index));
25467754Smsmith    return_ACPI_STATUS (AE_OK);
25567754Smsmith}
25667754Smsmith
25767754Smsmith
25867754Smsmith/*******************************************************************************
25967754Smsmith *
26087031Smsmith * FUNCTION:    AcpiDsMethodDataGetNode
26167754Smsmith *
262193267Sjkim * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
263193267Sjkim *                                    ACPI_REFCLASS_ARG
264151937Sjkim *              Index               - Which Local or Arg whose type to get
26571867Smsmith *              WalkState           - Current walk state object
266151937Sjkim *              Node                - Where the node is returned.
26767754Smsmith *
268151937Sjkim * RETURN:      Status and node
26967754Smsmith *
270151937Sjkim * DESCRIPTION: Get the Node associated with a local or arg.
271151937Sjkim *
27267754Smsmith ******************************************************************************/
27367754Smsmith
27467754SmsmithACPI_STATUS
27587031SmsmithAcpiDsMethodDataGetNode (
276193267Sjkim    UINT8                   Type,
27767754Smsmith    UINT32                  Index,
27867754Smsmith    ACPI_WALK_STATE         *WalkState,
27987031Smsmith    ACPI_NAMESPACE_NODE     **Node)
28067754Smsmith{
281167802Sjkim    ACPI_FUNCTION_TRACE (DsMethodDataGetNode);
28267754Smsmith
28367754Smsmith
28467754Smsmith    /*
28587031Smsmith     * Method Locals and Arguments are supported
28667754Smsmith     */
287193267Sjkim    switch (Type)
28867754Smsmith    {
289193267Sjkim    case ACPI_REFCLASS_LOCAL:
29067754Smsmith
291114237Snjl        if (Index > ACPI_METHOD_MAX_LOCAL)
29267754Smsmith        {
293167802Sjkim            ACPI_ERROR ((AE_INFO,
294204773Sjkim                "Local index %u is invalid (max %u)",
295114237Snjl                Index, ACPI_METHOD_MAX_LOCAL));
29687031Smsmith            return_ACPI_STATUS (AE_AML_INVALID_INDEX);
29767754Smsmith        }
29867754Smsmith
29987031Smsmith        /* Return a pointer to the pseudo-node */
30087031Smsmith
30187031Smsmith        *Node = &WalkState->LocalVariables[Index];
30267754Smsmith        break;
30367754Smsmith
304193267Sjkim    case ACPI_REFCLASS_ARG:
30567754Smsmith
306114237Snjl        if (Index > ACPI_METHOD_MAX_ARG)
30767754Smsmith        {
308167802Sjkim            ACPI_ERROR ((AE_INFO,
309204773Sjkim                "Arg index %u is invalid (max %u)",
310114237Snjl                Index, ACPI_METHOD_MAX_ARG));
31187031Smsmith            return_ACPI_STATUS (AE_AML_INVALID_INDEX);
31267754Smsmith        }
31367754Smsmith
31487031Smsmith        /* Return a pointer to the pseudo-node */
31587031Smsmith
31687031Smsmith        *Node = &WalkState->Arguments[Index];
31767754Smsmith        break;
31867754Smsmith
31967754Smsmith    default:
320250838Sjkim
321204773Sjkim        ACPI_ERROR ((AE_INFO, "Type %u is invalid", Type));
322193267Sjkim        return_ACPI_STATUS (AE_TYPE);
32367754Smsmith    }
32467754Smsmith
32567754Smsmith    return_ACPI_STATUS (AE_OK);
32667754Smsmith}
32767754Smsmith
32867754Smsmith
32967754Smsmith/*******************************************************************************
33067754Smsmith *
33187031Smsmith * FUNCTION:    AcpiDsMethodDataSetValue
33267754Smsmith *
333193267Sjkim * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
334193267Sjkim *                                    ACPI_REFCLASS_ARG
335151937Sjkim *              Index               - Which Local or Arg to get
33667754Smsmith *              Object              - Object to be inserted into the stack entry
33771867Smsmith *              WalkState           - Current walk state object
33867754Smsmith *
33967754Smsmith * RETURN:      Status
34067754Smsmith *
34177424Smsmith * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index.
342114237Snjl *              Note: There is no "implicit conversion" for locals.
34367754Smsmith *
34467754Smsmith ******************************************************************************/
34567754Smsmith
346151937Sjkimstatic ACPI_STATUS
34787031SmsmithAcpiDsMethodDataSetValue (
348193267Sjkim    UINT8                   Type,
34967754Smsmith    UINT32                  Index,
35067754Smsmith    ACPI_OPERAND_OBJECT     *Object,
35167754Smsmith    ACPI_WALK_STATE         *WalkState)
35267754Smsmith{
35367754Smsmith    ACPI_STATUS             Status;
35487031Smsmith    ACPI_NAMESPACE_NODE     *Node;
35567754Smsmith
35667754Smsmith
357167802Sjkim    ACPI_FUNCTION_TRACE (DsMethodDataSetValue);
35867754Smsmith
35983174Smsmith
360114237Snjl    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
361209746Sjkim        "NewObj %p Type %2.2X, Refs=%u [%s]\n", Object,
362193267Sjkim        Type, Object->Common.ReferenceCount,
363114237Snjl        AcpiUtGetTypeName (Object->Common.Type)));
364114237Snjl
36587031Smsmith    /* Get the namespace node for the arg/local */
36667754Smsmith
367193267Sjkim    Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
36867754Smsmith    if (ACPI_FAILURE (Status))
36967754Smsmith    {
37067754Smsmith        return_ACPI_STATUS (Status);
37167754Smsmith    }
37267754Smsmith
373123315Snjl    /*
374122945Snjl     * Increment ref count so object can't be deleted while installed.
375122945Snjl     * NOTE: We do not copy the object in order to preserve the call by
376122945Snjl     * reference semantics of ACPI Control Method invocation.
377122945Snjl     * (See ACPI Specification 2.0C)
378114237Snjl     */
379122945Snjl    AcpiUtAddReference (Object);
38067754Smsmith
381114237Snjl    /* Install the object */
382114237Snjl
383122945Snjl    Node->Object = Object;
384114237Snjl    return_ACPI_STATUS (Status);
38567754Smsmith}
38667754Smsmith
38767754Smsmith
38867754Smsmith/*******************************************************************************
38967754Smsmith *
39067754Smsmith * FUNCTION:    AcpiDsMethodDataGetValue
39167754Smsmith *
392193267Sjkim * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
393193267Sjkim *                                    ACPI_REFCLASS_ARG
39467754Smsmith *              Index               - Which localVar or argument to get
39571867Smsmith *              WalkState           - Current walk state object
396151937Sjkim *              DestDesc            - Where Arg or Local value is returned
39767754Smsmith *
39867754Smsmith * RETURN:      Status
39967754Smsmith *
400151937Sjkim * DESCRIPTION: Retrieve value of selected Arg or Local for this method
40177424Smsmith *              Used only in AcpiExResolveToValue().
40267754Smsmith *
40367754Smsmith ******************************************************************************/
40467754Smsmith
40567754SmsmithACPI_STATUS
40667754SmsmithAcpiDsMethodDataGetValue (
407193267Sjkim    UINT8                   Type,
40867754Smsmith    UINT32                  Index,
40967754Smsmith    ACPI_WALK_STATE         *WalkState,
41067754Smsmith    ACPI_OPERAND_OBJECT     **DestDesc)
41167754Smsmith{
41267754Smsmith    ACPI_STATUS             Status;
41387031Smsmith    ACPI_NAMESPACE_NODE     *Node;
41467754Smsmith    ACPI_OPERAND_OBJECT     *Object;
41567754Smsmith
41667754Smsmith
417167802Sjkim    ACPI_FUNCTION_TRACE (DsMethodDataGetValue);
41867754Smsmith
41967754Smsmith
42067754Smsmith    /* Validate the object descriptor */
42167754Smsmith
42267754Smsmith    if (!DestDesc)
42367754Smsmith    {
424167802Sjkim        ACPI_ERROR ((AE_INFO, "Null object descriptor pointer"));
42567754Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
42667754Smsmith    }
42767754Smsmith
42887031Smsmith    /* Get the namespace node for the arg/local */
42967754Smsmith
430193267Sjkim    Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
43167754Smsmith    if (ACPI_FAILURE (Status))
43267754Smsmith    {
43367754Smsmith        return_ACPI_STATUS (Status);
43467754Smsmith    }
43567754Smsmith
43687031Smsmith    /* Get the object from the node */
43767754Smsmith
43887031Smsmith    Object = Node->Object;
43967754Smsmith
44067754Smsmith    /* Examine the returned object, it must be valid. */
44167754Smsmith
44267754Smsmith    if (!Object)
44367754Smsmith    {
44467754Smsmith        /*
44587031Smsmith         * Index points to uninitialized object.
44667754Smsmith         * This means that either 1) The expected argument was
44767754Smsmith         * not passed to the method, or 2) A local variable
44867754Smsmith         * was referenced by the method (via the ASL)
449241973Sjkim         * before it was initialized. Either case is an error.
45067754Smsmith         */
451138287Smarks
452138287Smarks        /* If slack enabled, init the LocalX/ArgX to an Integer of value zero */
453138287Smarks
454138287Smarks        if (AcpiGbl_EnableInterpreterSlack)
45567754Smsmith        {
456199337Sjkim            Object = AcpiUtCreateIntegerObject ((UINT64) 0);
457138287Smarks            if (!Object)
458138287Smarks            {
459138287Smarks                return_ACPI_STATUS (AE_NO_MEMORY);
460138287Smarks            }
461138287Smarks
462138287Smarks            Node->Object = Object;
463138287Smarks        }
464138287Smarks
465138287Smarks        /* Otherwise, return the error */
466138287Smarks
467193267Sjkim        else switch (Type)
468138287Smarks        {
469193267Sjkim        case ACPI_REFCLASS_ARG:
47071867Smsmith
471167802Sjkim            ACPI_ERROR ((AE_INFO,
472204773Sjkim                "Uninitialized Arg[%u] at node %p",
47387031Smsmith                Index, Node));
47471867Smsmith
47567754Smsmith            return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
47667754Smsmith
477193267Sjkim        case ACPI_REFCLASS_LOCAL:
478197104Sjkim            /*
479197104Sjkim             * No error message for this case, will be trapped again later to
480197104Sjkim             * detect and ignore cases of Store(LocalX,LocalX)
481197104Sjkim             */
48267754Smsmith            return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL);
48399679Siwasaki
48499679Siwasaki        default:
485193267Sjkim
486204773Sjkim            ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: 0x%X", Type));
48799679Siwasaki            return_ACPI_STATUS (AE_AML_INTERNAL);
48867754Smsmith        }
48967754Smsmith    }
49067754Smsmith
49167754Smsmith    /*
49287031Smsmith     * The Index points to an initialized and valid object.
49367754Smsmith     * Return an additional reference to the object
49467754Smsmith     */
49567754Smsmith    *DestDesc = Object;
49677424Smsmith    AcpiUtAddReference (Object);
49767754Smsmith
49867754Smsmith    return_ACPI_STATUS (AE_OK);
49967754Smsmith}
50067754Smsmith
50167754Smsmith
50267754Smsmith/*******************************************************************************
50367754Smsmith *
50467754Smsmith * FUNCTION:    AcpiDsMethodDataDeleteValue
50567754Smsmith *
506193267Sjkim * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
507193267Sjkim *                                    ACPI_REFCLASS_ARG
50867754Smsmith *              Index               - Which localVar or argument to delete
50971867Smsmith *              WalkState           - Current walk state object
51067754Smsmith *
51199679Siwasaki * RETURN:      None
51267754Smsmith *
513241973Sjkim * DESCRIPTION: Delete the entry at Opcode:Index. Inserts
51467754Smsmith *              a null into the stack slot after the object is deleted.
51567754Smsmith *
51667754Smsmith ******************************************************************************/
51767754Smsmith
518151937Sjkimstatic void
51967754SmsmithAcpiDsMethodDataDeleteValue (
520193267Sjkim    UINT8                   Type,
52167754Smsmith    UINT32                  Index,
52267754Smsmith    ACPI_WALK_STATE         *WalkState)
52367754Smsmith{
52467754Smsmith    ACPI_STATUS             Status;
52587031Smsmith    ACPI_NAMESPACE_NODE     *Node;
52667754Smsmith    ACPI_OPERAND_OBJECT     *Object;
52767754Smsmith
52867754Smsmith
529167802Sjkim    ACPI_FUNCTION_TRACE (DsMethodDataDeleteValue);
53067754Smsmith
53167754Smsmith
53287031Smsmith    /* Get the namespace node for the arg/local */
53367754Smsmith
534193267Sjkim    Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
53567754Smsmith    if (ACPI_FAILURE (Status))
53667754Smsmith    {
53799679Siwasaki        return_VOID;
53867754Smsmith    }
53967754Smsmith
54087031Smsmith    /* Get the associated object */
54167754Smsmith
54287031Smsmith    Object = AcpiNsGetAttachedObject (Node);
54367754Smsmith
54467754Smsmith    /*
54567754Smsmith     * Undefine the Arg or Local by setting its descriptor
54667754Smsmith     * pointer to NULL. Locals/Args can contain both
54767754Smsmith     * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
54867754Smsmith     */
54987031Smsmith    Node->Object = NULL;
55067754Smsmith
55167754Smsmith    if ((Object) &&
55299679Siwasaki        (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_OPERAND))
55367754Smsmith    {
55467754Smsmith        /*
55587031Smsmith         * There is a valid object.
55667754Smsmith         * Decrement the reference count by one to balance the
55787031Smsmith         * increment when the object was stored.
55867754Smsmith         */
55977424Smsmith        AcpiUtRemoveReference (Object);
56067754Smsmith    }
56167754Smsmith
56299679Siwasaki    return_VOID;
56367754Smsmith}
56467754Smsmith
56567754Smsmith
56667754Smsmith/*******************************************************************************
56767754Smsmith *
56877424Smsmith * FUNCTION:    AcpiDsStoreObjectToLocal
56967754Smsmith *
570193267Sjkim * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
571193267Sjkim *                                    ACPI_REFCLASS_ARG
572151937Sjkim *              Index               - Which Local or Arg to set
57387031Smsmith *              ObjDesc             - Value to be stored
57471867Smsmith *              WalkState           - Current walk state
57567754Smsmith *
57667754Smsmith * RETURN:      Status
57767754Smsmith *
578241973Sjkim * DESCRIPTION: Store a value in an Arg or Local. The ObjDesc is installed
57967754Smsmith *              as the new value for the Arg or Local and the reference count
58087031Smsmith *              for ObjDesc is incremented.
58167754Smsmith *
58267754Smsmith ******************************************************************************/
58367754Smsmith
58467754SmsmithACPI_STATUS
58577424SmsmithAcpiDsStoreObjectToLocal (
586193267Sjkim    UINT8                   Type,
58767754Smsmith    UINT32                  Index,
58887031Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc,
58967754Smsmith    ACPI_WALK_STATE         *WalkState)
59067754Smsmith{
59167754Smsmith    ACPI_STATUS             Status;
59287031Smsmith    ACPI_NAMESPACE_NODE     *Node;
59387031Smsmith    ACPI_OPERAND_OBJECT     *CurrentObjDesc;
594123315Snjl    ACPI_OPERAND_OBJECT     *NewObjDesc;
59567754Smsmith
59667754Smsmith
597167802Sjkim    ACPI_FUNCTION_TRACE (DsStoreObjectToLocal);
598209746Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Type=%2.2X Index=%u Obj=%p\n",
599193267Sjkim        Type, Index, ObjDesc));
60067754Smsmith
60167754Smsmith    /* Parameter validation */
60267754Smsmith
60387031Smsmith    if (!ObjDesc)
60467754Smsmith    {
60567754Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
60667754Smsmith    }
60767754Smsmith
60887031Smsmith    /* Get the namespace node for the arg/local */
60967754Smsmith
610193267Sjkim    Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
61167754Smsmith    if (ACPI_FAILURE (Status))
61267754Smsmith    {
61387031Smsmith        return_ACPI_STATUS (Status);
61467754Smsmith    }
61567754Smsmith
61687031Smsmith    CurrentObjDesc = AcpiNsGetAttachedObject (Node);
61787031Smsmith    if (CurrentObjDesc == ObjDesc)
61867754Smsmith    {
619114237Snjl        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n",
620114237Snjl            ObjDesc));
62187031Smsmith        return_ACPI_STATUS (Status);
62267754Smsmith    }
62367754Smsmith
62467754Smsmith    /*
625123315Snjl     * If the reference count on the object is more than one, we must
626241973Sjkim     * take a copy of the object before we store. A reference count
627126372Snjl     * of exactly 1 means that the object was just created during the
628126372Snjl     * evaluation of an expression, and we can safely use it since it
629126372Snjl     * is not used anywhere else.
630123315Snjl     */
631123315Snjl    NewObjDesc = ObjDesc;
632126372Snjl    if (ObjDesc->Common.ReferenceCount > 1)
633123315Snjl    {
634306536Sjkim        Status = AcpiUtCopyIobjectToIobject (
635306536Sjkim            ObjDesc, &NewObjDesc, WalkState);
636123315Snjl        if (ACPI_FAILURE (Status))
637123315Snjl        {
638123315Snjl            return_ACPI_STATUS (Status);
639123315Snjl        }
640123315Snjl    }
641123315Snjl
642123315Snjl    /*
64367754Smsmith     * If there is an object already in this slot, we either
64467754Smsmith     * have to delete it, or if this is an argument and there
64567754Smsmith     * is an object reference stored there, we have to do
64667754Smsmith     * an indirect store!
64767754Smsmith     */
64887031Smsmith    if (CurrentObjDesc)
64967754Smsmith    {
65067754Smsmith        /*
65167754Smsmith         * Check for an indirect store if an argument
65267754Smsmith         * contains an object reference (stored as an Node).
65367754Smsmith         * We don't allow this automatic dereferencing for
65467754Smsmith         * locals, since a store to a local should overwrite
65567754Smsmith         * anything there, including an object reference.
65667754Smsmith         *
65767754Smsmith         * If both Arg0 and Local0 contain RefOf (Local4):
65867754Smsmith         *
65967754Smsmith         * Store (1, Arg0)             - Causes indirect store to local4
66067754Smsmith         * Store (1, Local0)           - Stores 1 in local0, overwriting
66167754Smsmith         *                                  the reference to local4
66267754Smsmith         * Store (1, DeRefof (Local0)) - Causes indirect store to local4
66367754Smsmith         *
66467754Smsmith         * Weird, but true.
66567754Smsmith         */
666193267Sjkim        if (Type == ACPI_REFCLASS_ARG)
66767754Smsmith        {
668114237Snjl            /*
669151937Sjkim             * If we have a valid reference object that came from RefOf(),
670151937Sjkim             * do the indirect store
671102550Siwasaki             */
672306536Sjkim            if ((ACPI_GET_DESCRIPTOR_TYPE (CurrentObjDesc) ==
673306536Sjkim                    ACPI_DESC_TYPE_OPERAND) &&
674306536Sjkim                (CurrentObjDesc->Common.Type ==
675306536Sjkim                    ACPI_TYPE_LOCAL_REFERENCE) &&
676306536Sjkim                (CurrentObjDesc->Reference.Class ==
677306536Sjkim                    ACPI_REFCLASS_REFOF))
678102550Siwasaki            {
679102550Siwasaki                ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
680306536Sjkim                    "Arg (%p) is an ObjRef(Node), storing in node %p\n",
681306536Sjkim                    NewObjDesc, CurrentObjDesc));
68267754Smsmith
683102550Siwasaki                /*
684128212Snjl                 * Store this object to the Node (perform the indirect store)
685128212Snjl                 * NOTE: No implicit conversion is performed, as per the ACPI
686128212Snjl                 * specification rules on storing to Locals/Args.
687102550Siwasaki                 */
688123315Snjl                Status = AcpiExStoreObjectToNode (NewObjDesc,
689306536Sjkim                    CurrentObjDesc->Reference.Object, WalkState,
690306536Sjkim                    ACPI_NO_IMPLICIT_CONVERSION);
691123315Snjl
692123315Snjl                /* Remove local reference if we copied the object above */
693123315Snjl
694123315Snjl                if (NewObjDesc != ObjDesc)
695123315Snjl                {
696123315Snjl                    AcpiUtRemoveReference (NewObjDesc);
697123315Snjl                }
698306536Sjkim
699102550Siwasaki                return_ACPI_STATUS (Status);
700102550Siwasaki            }
70167754Smsmith        }
70267754Smsmith
703193267Sjkim        /* Delete the existing object before storing the new one */
704193267Sjkim
705193267Sjkim        AcpiDsMethodDataDeleteValue (Type, Index, WalkState);
70667754Smsmith    }
70767754Smsmith
70867754Smsmith    /*
709123315Snjl     * Install the Obj descriptor (*NewObjDesc) into
71067754Smsmith     * the descriptor for the Arg or Local.
71167754Smsmith     * (increments the object reference count by one)
71267754Smsmith     */
713193267Sjkim    Status = AcpiDsMethodDataSetValue (Type, Index, NewObjDesc, WalkState);
714123315Snjl
715123315Snjl    /* Remove local reference if we copied the object above */
716123315Snjl
717123315Snjl    if (NewObjDesc != ObjDesc)
718123315Snjl    {
719123315Snjl        AcpiUtRemoveReference (NewObjDesc);
720123315Snjl    }
721123315Snjl
72267754Smsmith    return_ACPI_STATUS (Status);
72367754Smsmith}
72467754Smsmith
72587031Smsmith
726151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS
727151937Sjkim/*******************************************************************************
728151937Sjkim *
729151937Sjkim * FUNCTION:    AcpiDsMethodDataGetType
730151937Sjkim *
731151937Sjkim * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
732151937Sjkim *              Index               - Which Local or Arg whose type to get
733151937Sjkim *              WalkState           - Current walk state object
734151937Sjkim *
735151937Sjkim * RETURN:      Data type of current value of the selected Arg or Local
736151937Sjkim *
737151937Sjkim * DESCRIPTION: Get the type of the object stored in the Local or Arg
738151937Sjkim *
739151937Sjkim ******************************************************************************/
740151937Sjkim
741151937SjkimACPI_OBJECT_TYPE
742151937SjkimAcpiDsMethodDataGetType (
743151937Sjkim    UINT16                  Opcode,
744151937Sjkim    UINT32                  Index,
745151937Sjkim    ACPI_WALK_STATE         *WalkState)
746151937Sjkim{
747151937Sjkim    ACPI_STATUS             Status;
748151937Sjkim    ACPI_NAMESPACE_NODE     *Node;
749151937Sjkim    ACPI_OPERAND_OBJECT     *Object;
750151937Sjkim
751151937Sjkim
752167802Sjkim    ACPI_FUNCTION_TRACE (DsMethodDataGetType);
753151937Sjkim
754151937Sjkim
755151937Sjkim    /* Get the namespace node for the arg/local */
756151937Sjkim
757151937Sjkim    Status = AcpiDsMethodDataGetNode (Opcode, Index, WalkState, &Node);
758151937Sjkim    if (ACPI_FAILURE (Status))
759151937Sjkim    {
760151937Sjkim        return_VALUE ((ACPI_TYPE_NOT_FOUND));
761151937Sjkim    }
762151937Sjkim
763151937Sjkim    /* Get the object */
764151937Sjkim
765151937Sjkim    Object = AcpiNsGetAttachedObject (Node);
766151937Sjkim    if (!Object)
767151937Sjkim    {
768151937Sjkim        /* Uninitialized local/arg, return TYPE_ANY */
769151937Sjkim
770151937Sjkim        return_VALUE (ACPI_TYPE_ANY);
771151937Sjkim    }
772151937Sjkim
773151937Sjkim    /* Get the object type */
774151937Sjkim
775193267Sjkim    return_VALUE (Object->Type);
776151937Sjkim}
777151937Sjkim#endif
778