167754Smsmith/*******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: dsmthdat - control method arguments and local variables
467754Smsmith *
567754Smsmith ******************************************************************************/
667754Smsmith
7217365Sjkim/*
8245582Sjkim * Copyright (C) 2000 - 2013, 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
4467754Smsmith#define __DSMTHDAT_C__
4567754Smsmith
46193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
47193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
48193341Sjkim#include <contrib/dev/acpica/include/acdispat.h>
49193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
50193341Sjkim#include <contrib/dev/acpica/include/acinterp.h>
5167754Smsmith
5267754Smsmith
5377424Smsmith#define _COMPONENT          ACPI_DISPATCHER
5491116Smsmith        ACPI_MODULE_NAME    ("dsmthdat")
5567754Smsmith
56151937Sjkim/* Local prototypes */
5767754Smsmith
58151937Sjkimstatic void
59151937SjkimAcpiDsMethodDataDeleteValue (
60193267Sjkim    UINT8                   Type,
61151937Sjkim    UINT32                  Index,
62151937Sjkim    ACPI_WALK_STATE         *WalkState);
63151937Sjkim
64151937Sjkimstatic ACPI_STATUS
65151937SjkimAcpiDsMethodDataSetValue (
66193267Sjkim    UINT8                   Type,
67151937Sjkim    UINT32                  Index,
68151937Sjkim    ACPI_OPERAND_OBJECT     *Object,
69151937Sjkim    ACPI_WALK_STATE         *WalkState);
70151937Sjkim
71151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS
72151937SjkimACPI_OBJECT_TYPE
73151937SjkimAcpiDsMethodDataGetType (
74151937Sjkim    UINT16                  Opcode,
75151937Sjkim    UINT32                  Index,
76151937Sjkim    ACPI_WALK_STATE         *WalkState);
77151937Sjkim#endif
78151937Sjkim
79151937Sjkim
8067754Smsmith/*******************************************************************************
8167754Smsmith *
8267754Smsmith * FUNCTION:    AcpiDsMethodDataInit
8367754Smsmith *
8471867Smsmith * PARAMETERS:  WalkState           - Current walk state object
8567754Smsmith *
8667754Smsmith * RETURN:      Status
8767754Smsmith *
8867754Smsmith * DESCRIPTION: Initialize the data structures that hold the method's arguments
89241973Sjkim *              and locals. The data struct is an array of namespace nodes for
90151937Sjkim *              each - this allows RefOf and DeRefOf to work properly for these
9167754Smsmith *              special data types.
9267754Smsmith *
9387031Smsmith * NOTES:       WalkState fields are initialized to zero by the
94167802Sjkim *              ACPI_ALLOCATE_ZEROED().
9587031Smsmith *
9687031Smsmith *              A pseudo-Namespace Node is assigned to each argument and local
9787031Smsmith *              so that RefOf() can return a pointer to the Node.
9887031Smsmith *
9967754Smsmith ******************************************************************************/
10067754Smsmith
10199679Siwasakivoid
10267754SmsmithAcpiDsMethodDataInit (
10367754Smsmith    ACPI_WALK_STATE         *WalkState)
10467754Smsmith{
10567754Smsmith    UINT32                  i;
10667754Smsmith
10767754Smsmith
108167802Sjkim    ACPI_FUNCTION_TRACE (DsMethodDataInit);
10967754Smsmith
11067754Smsmith
11167754Smsmith    /* Init the method arguments */
11267754Smsmith
113114237Snjl    for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
11467754Smsmith    {
115167802Sjkim        ACPI_MOVE_32_TO_32 (&WalkState->Arguments[i].Name, NAMEOF_ARG_NTE);
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    {
126167802Sjkim        ACPI_MOVE_32_TO_32 (&WalkState->LocalVariables[i].Name, NAMEOF_LOCAL_NTE);
12767754Smsmith
12899146Siwasaki        WalkState->LocalVariables[i].Name.Integer |= (i << 24);
129167802Sjkim        WalkState->LocalVariables[i].DescriptorType = ACPI_DESC_TYPE_NAMED;
130167802Sjkim        WalkState->LocalVariables[i].Type = ACPI_TYPE_ANY;
131209746Sjkim        WalkState->LocalVariables[i].Flags = ANOBJ_METHOD_LOCAL;
13267754Smsmith    }
13367754Smsmith
13499679Siwasaki    return_VOID;
13567754Smsmith}
13667754Smsmith
13767754Smsmith
13867754Smsmith/*******************************************************************************
13967754Smsmith *
14067754Smsmith * FUNCTION:    AcpiDsMethodDataDeleteAll
14167754Smsmith *
14271867Smsmith * PARAMETERS:  WalkState           - Current walk state object
14367754Smsmith *
14499679Siwasaki * RETURN:      None
14567754Smsmith *
146241973Sjkim * DESCRIPTION: Delete method locals and arguments. Arguments are only
14767754Smsmith *              deleted if this method was called from another method.
14867754Smsmith *
14967754Smsmith ******************************************************************************/
15067754Smsmith
15199679Siwasakivoid
15267754SmsmithAcpiDsMethodDataDeleteAll (
15367754Smsmith    ACPI_WALK_STATE         *WalkState)
15467754Smsmith{
15567754Smsmith    UINT32                  Index;
15667754Smsmith
15767754Smsmith
158167802Sjkim    ACPI_FUNCTION_TRACE (DsMethodDataDeleteAll);
15967754Smsmith
16067754Smsmith
16187031Smsmith    /* Detach the locals */
16267754Smsmith
163114237Snjl    for (Index = 0; Index < ACPI_METHOD_NUM_LOCALS; Index++)
16467754Smsmith    {
16587031Smsmith        if (WalkState->LocalVariables[Index].Object)
16667754Smsmith        {
167209746Sjkim            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%u=%p\n",
16887031Smsmith                    Index, WalkState->LocalVariables[Index].Object));
16967754Smsmith
17087031Smsmith            /* Detach object (if present) and remove a reference */
17167754Smsmith
17287031Smsmith            AcpiNsDetachObject (&WalkState->LocalVariables[Index]);
17399679Siwasaki        }
17467754Smsmith    }
17567754Smsmith
17687031Smsmith    /* Detach the arguments */
17767754Smsmith
178114237Snjl    for (Index = 0; Index < ACPI_METHOD_NUM_ARGS; Index++)
17967754Smsmith    {
18087031Smsmith        if (WalkState->Arguments[Index].Object)
18167754Smsmith        {
182209746Sjkim            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%u=%p\n",
18387031Smsmith                    Index, WalkState->Arguments[Index].Object));
18467754Smsmith
18587031Smsmith            /* Detach object (if present) and remove a reference */
18667754Smsmith
18787031Smsmith            AcpiNsDetachObject (&WalkState->Arguments[Index]);
18867754Smsmith        }
18967754Smsmith    }
19067754Smsmith
19199679Siwasaki    return_VOID;
19267754Smsmith}
19367754Smsmith
19467754Smsmith
19567754Smsmith/*******************************************************************************
19667754Smsmith *
19767754Smsmith * FUNCTION:    AcpiDsMethodDataInitArgs
19867754Smsmith *
19971867Smsmith * PARAMETERS:  *Params         - Pointer to a parameter list for the method
20071867Smsmith *              MaxParamCount   - The arg count for this method
20171867Smsmith *              WalkState       - Current walk state object
20267754Smsmith *
20367754Smsmith * RETURN:      Status
20467754Smsmith *
205241973Sjkim * DESCRIPTION: Initialize arguments for a method. The parameter list is a list
20687031Smsmith *              of ACPI operand objects, either null terminated or whose length
20787031Smsmith *              is defined by MaxParamCount.
20867754Smsmith *
20967754Smsmith ******************************************************************************/
21067754Smsmith
21167754SmsmithACPI_STATUS
21267754SmsmithAcpiDsMethodDataInitArgs (
21367754Smsmith    ACPI_OPERAND_OBJECT     **Params,
21467754Smsmith    UINT32                  MaxParamCount,
21567754Smsmith    ACPI_WALK_STATE         *WalkState)
21667754Smsmith{
21767754Smsmith    ACPI_STATUS             Status;
21887031Smsmith    UINT32                  Index = 0;
21967754Smsmith
22067754Smsmith
221167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsMethodDataInitArgs, Params);
22267754Smsmith
22367754Smsmith
22467754Smsmith    if (!Params)
22567754Smsmith    {
22682367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n"));
22767754Smsmith        return_ACPI_STATUS (AE_OK);
22867754Smsmith    }
22967754Smsmith
230151937Sjkim    /* Copy passed parameters into the new method stack frame */
23167754Smsmith
232151937Sjkim    while ((Index < ACPI_METHOD_NUM_ARGS) &&
233151937Sjkim           (Index < MaxParamCount)        &&
234151937Sjkim            Params[Index])
23567754Smsmith    {
23687031Smsmith        /*
23787031Smsmith         * A valid parameter.
238126372Snjl         * Store the argument in the method/walk descriptor.
239126372Snjl         * Do not copy the arg in order to implement call by reference
24087031Smsmith         */
241193267Sjkim        Status = AcpiDsMethodDataSetValue (ACPI_REFCLASS_ARG, Index,
242151937Sjkim                    Params[Index], WalkState);
24387031Smsmith        if (ACPI_FAILURE (Status))
24467754Smsmith        {
24587031Smsmith            return_ACPI_STATUS (Status);
24667754Smsmith        }
24767754Smsmith
24887031Smsmith        Index++;
24967754Smsmith    }
25067754Smsmith
251209746Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%u args passed to method\n", Index));
25267754Smsmith    return_ACPI_STATUS (AE_OK);
25367754Smsmith}
25467754Smsmith
25567754Smsmith
25667754Smsmith/*******************************************************************************
25767754Smsmith *
25887031Smsmith * FUNCTION:    AcpiDsMethodDataGetNode
25967754Smsmith *
260193267Sjkim * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
261193267Sjkim *                                    ACPI_REFCLASS_ARG
262151937Sjkim *              Index               - Which Local or Arg whose type to get
26371867Smsmith *              WalkState           - Current walk state object
264151937Sjkim *              Node                - Where the node is returned.
26567754Smsmith *
266151937Sjkim * RETURN:      Status and node
26767754Smsmith *
268151937Sjkim * DESCRIPTION: Get the Node associated with a local or arg.
269151937Sjkim *
27067754Smsmith ******************************************************************************/
27167754Smsmith
27267754SmsmithACPI_STATUS
27387031SmsmithAcpiDsMethodDataGetNode (
274193267Sjkim    UINT8                   Type,
27567754Smsmith    UINT32                  Index,
27667754Smsmith    ACPI_WALK_STATE         *WalkState,
27787031Smsmith    ACPI_NAMESPACE_NODE     **Node)
27867754Smsmith{
279167802Sjkim    ACPI_FUNCTION_TRACE (DsMethodDataGetNode);
28067754Smsmith
28167754Smsmith
28267754Smsmith    /*
28387031Smsmith     * Method Locals and Arguments are supported
28467754Smsmith     */
285193267Sjkim    switch (Type)
28667754Smsmith    {
287193267Sjkim    case ACPI_REFCLASS_LOCAL:
28867754Smsmith
289114237Snjl        if (Index > ACPI_METHOD_MAX_LOCAL)
29067754Smsmith        {
291167802Sjkim            ACPI_ERROR ((AE_INFO,
292204773Sjkim                "Local index %u is invalid (max %u)",
293114237Snjl                Index, ACPI_METHOD_MAX_LOCAL));
29487031Smsmith            return_ACPI_STATUS (AE_AML_INVALID_INDEX);
29567754Smsmith        }
29667754Smsmith
29787031Smsmith        /* Return a pointer to the pseudo-node */
29887031Smsmith
29987031Smsmith        *Node = &WalkState->LocalVariables[Index];
30067754Smsmith        break;
30167754Smsmith
302193267Sjkim    case ACPI_REFCLASS_ARG:
30367754Smsmith
304114237Snjl        if (Index > ACPI_METHOD_MAX_ARG)
30567754Smsmith        {
306167802Sjkim            ACPI_ERROR ((AE_INFO,
307204773Sjkim                "Arg index %u is invalid (max %u)",
308114237Snjl                Index, ACPI_METHOD_MAX_ARG));
30987031Smsmith            return_ACPI_STATUS (AE_AML_INVALID_INDEX);
31067754Smsmith        }
31167754Smsmith
31287031Smsmith        /* Return a pointer to the pseudo-node */
31387031Smsmith
31487031Smsmith        *Node = &WalkState->Arguments[Index];
31567754Smsmith        break;
31667754Smsmith
31767754Smsmith    default:
318250838Sjkim
319204773Sjkim        ACPI_ERROR ((AE_INFO, "Type %u is invalid", Type));
320193267Sjkim        return_ACPI_STATUS (AE_TYPE);
32167754Smsmith    }
32267754Smsmith
32367754Smsmith    return_ACPI_STATUS (AE_OK);
32467754Smsmith}
32567754Smsmith
32667754Smsmith
32767754Smsmith/*******************************************************************************
32867754Smsmith *
32987031Smsmith * FUNCTION:    AcpiDsMethodDataSetValue
33067754Smsmith *
331193267Sjkim * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
332193267Sjkim *                                    ACPI_REFCLASS_ARG
333151937Sjkim *              Index               - Which Local or Arg to get
33467754Smsmith *              Object              - Object to be inserted into the stack entry
33571867Smsmith *              WalkState           - Current walk state object
33667754Smsmith *
33767754Smsmith * RETURN:      Status
33867754Smsmith *
33977424Smsmith * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index.
340114237Snjl *              Note: There is no "implicit conversion" for locals.
34167754Smsmith *
34267754Smsmith ******************************************************************************/
34367754Smsmith
344151937Sjkimstatic ACPI_STATUS
34587031SmsmithAcpiDsMethodDataSetValue (
346193267Sjkim    UINT8                   Type,
34767754Smsmith    UINT32                  Index,
34867754Smsmith    ACPI_OPERAND_OBJECT     *Object,
34967754Smsmith    ACPI_WALK_STATE         *WalkState)
35067754Smsmith{
35167754Smsmith    ACPI_STATUS             Status;
35287031Smsmith    ACPI_NAMESPACE_NODE     *Node;
35367754Smsmith
35467754Smsmith
355167802Sjkim    ACPI_FUNCTION_TRACE (DsMethodDataSetValue);
35667754Smsmith
35783174Smsmith
358114237Snjl    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
359209746Sjkim        "NewObj %p Type %2.2X, Refs=%u [%s]\n", Object,
360193267Sjkim        Type, Object->Common.ReferenceCount,
361114237Snjl        AcpiUtGetTypeName (Object->Common.Type)));
362114237Snjl
36387031Smsmith    /* Get the namespace node for the arg/local */
36467754Smsmith
365193267Sjkim    Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
36667754Smsmith    if (ACPI_FAILURE (Status))
36767754Smsmith    {
36867754Smsmith        return_ACPI_STATUS (Status);
36967754Smsmith    }
37067754Smsmith
371123315Snjl    /*
372122945Snjl     * Increment ref count so object can't be deleted while installed.
373122945Snjl     * NOTE: We do not copy the object in order to preserve the call by
374122945Snjl     * reference semantics of ACPI Control Method invocation.
375122945Snjl     * (See ACPI Specification 2.0C)
376114237Snjl     */
377122945Snjl    AcpiUtAddReference (Object);
37867754Smsmith
379114237Snjl    /* Install the object */
380114237Snjl
381122945Snjl    Node->Object = Object;
382114237Snjl    return_ACPI_STATUS (Status);
38367754Smsmith}
38467754Smsmith
38567754Smsmith
38667754Smsmith/*******************************************************************************
38767754Smsmith *
38867754Smsmith * FUNCTION:    AcpiDsMethodDataGetValue
38967754Smsmith *
390193267Sjkim * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
391193267Sjkim *                                    ACPI_REFCLASS_ARG
39267754Smsmith *              Index               - Which localVar or argument to get
39371867Smsmith *              WalkState           - Current walk state object
394151937Sjkim *              DestDesc            - Where Arg or Local value is returned
39567754Smsmith *
39667754Smsmith * RETURN:      Status
39767754Smsmith *
398151937Sjkim * DESCRIPTION: Retrieve value of selected Arg or Local for this method
39977424Smsmith *              Used only in AcpiExResolveToValue().
40067754Smsmith *
40167754Smsmith ******************************************************************************/
40267754Smsmith
40367754SmsmithACPI_STATUS
40467754SmsmithAcpiDsMethodDataGetValue (
405193267Sjkim    UINT8                   Type,
40667754Smsmith    UINT32                  Index,
40767754Smsmith    ACPI_WALK_STATE         *WalkState,
40867754Smsmith    ACPI_OPERAND_OBJECT     **DestDesc)
40967754Smsmith{
41067754Smsmith    ACPI_STATUS             Status;
41187031Smsmith    ACPI_NAMESPACE_NODE     *Node;
41267754Smsmith    ACPI_OPERAND_OBJECT     *Object;
41367754Smsmith
41467754Smsmith
415167802Sjkim    ACPI_FUNCTION_TRACE (DsMethodDataGetValue);
41667754Smsmith
41767754Smsmith
41867754Smsmith    /* Validate the object descriptor */
41967754Smsmith
42067754Smsmith    if (!DestDesc)
42167754Smsmith    {
422167802Sjkim        ACPI_ERROR ((AE_INFO, "Null object descriptor pointer"));
42367754Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
42467754Smsmith    }
42567754Smsmith
42687031Smsmith    /* Get the namespace node for the arg/local */
42767754Smsmith
428193267Sjkim    Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
42967754Smsmith    if (ACPI_FAILURE (Status))
43067754Smsmith    {
43167754Smsmith        return_ACPI_STATUS (Status);
43267754Smsmith    }
43367754Smsmith
43487031Smsmith    /* Get the object from the node */
43567754Smsmith
43687031Smsmith    Object = Node->Object;
43767754Smsmith
43867754Smsmith    /* Examine the returned object, it must be valid. */
43967754Smsmith
44067754Smsmith    if (!Object)
44167754Smsmith    {
44267754Smsmith        /*
44387031Smsmith         * Index points to uninitialized object.
44467754Smsmith         * This means that either 1) The expected argument was
44567754Smsmith         * not passed to the method, or 2) A local variable
44667754Smsmith         * was referenced by the method (via the ASL)
447241973Sjkim         * before it was initialized. Either case is an error.
44867754Smsmith         */
449138287Smarks
450138287Smarks        /* If slack enabled, init the LocalX/ArgX to an Integer of value zero */
451138287Smarks
452138287Smarks        if (AcpiGbl_EnableInterpreterSlack)
45367754Smsmith        {
454199337Sjkim            Object = AcpiUtCreateIntegerObject ((UINT64) 0);
455138287Smarks            if (!Object)
456138287Smarks            {
457138287Smarks                return_ACPI_STATUS (AE_NO_MEMORY);
458138287Smarks            }
459138287Smarks
460138287Smarks            Node->Object = Object;
461138287Smarks        }
462138287Smarks
463138287Smarks        /* Otherwise, return the error */
464138287Smarks
465193267Sjkim        else switch (Type)
466138287Smarks        {
467193267Sjkim        case ACPI_REFCLASS_ARG:
46871867Smsmith
469167802Sjkim            ACPI_ERROR ((AE_INFO,
470204773Sjkim                "Uninitialized Arg[%u] at node %p",
47187031Smsmith                Index, Node));
47271867Smsmith
47367754Smsmith            return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
47467754Smsmith
475193267Sjkim        case ACPI_REFCLASS_LOCAL:
476197104Sjkim            /*
477197104Sjkim             * No error message for this case, will be trapped again later to
478197104Sjkim             * detect and ignore cases of Store(LocalX,LocalX)
479197104Sjkim             */
48067754Smsmith            return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL);
48199679Siwasaki
48299679Siwasaki        default:
483193267Sjkim
484204773Sjkim            ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: 0x%X", Type));
48599679Siwasaki            return_ACPI_STATUS (AE_AML_INTERNAL);
48667754Smsmith        }
48767754Smsmith    }
48867754Smsmith
48967754Smsmith    /*
49087031Smsmith     * The Index points to an initialized and valid object.
49167754Smsmith     * Return an additional reference to the object
49267754Smsmith     */
49367754Smsmith    *DestDesc = Object;
49477424Smsmith    AcpiUtAddReference (Object);
49567754Smsmith
49667754Smsmith    return_ACPI_STATUS (AE_OK);
49767754Smsmith}
49867754Smsmith
49967754Smsmith
50067754Smsmith/*******************************************************************************
50167754Smsmith *
50267754Smsmith * FUNCTION:    AcpiDsMethodDataDeleteValue
50367754Smsmith *
504193267Sjkim * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
505193267Sjkim *                                    ACPI_REFCLASS_ARG
50667754Smsmith *              Index               - Which localVar or argument to delete
50771867Smsmith *              WalkState           - Current walk state object
50867754Smsmith *
50999679Siwasaki * RETURN:      None
51067754Smsmith *
511241973Sjkim * DESCRIPTION: Delete the entry at Opcode:Index. Inserts
51267754Smsmith *              a null into the stack slot after the object is deleted.
51367754Smsmith *
51467754Smsmith ******************************************************************************/
51567754Smsmith
516151937Sjkimstatic void
51767754SmsmithAcpiDsMethodDataDeleteValue (
518193267Sjkim    UINT8                   Type,
51967754Smsmith    UINT32                  Index,
52067754Smsmith    ACPI_WALK_STATE         *WalkState)
52167754Smsmith{
52267754Smsmith    ACPI_STATUS             Status;
52387031Smsmith    ACPI_NAMESPACE_NODE     *Node;
52467754Smsmith    ACPI_OPERAND_OBJECT     *Object;
52567754Smsmith
52667754Smsmith
527167802Sjkim    ACPI_FUNCTION_TRACE (DsMethodDataDeleteValue);
52867754Smsmith
52967754Smsmith
53087031Smsmith    /* Get the namespace node for the arg/local */
53167754Smsmith
532193267Sjkim    Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
53367754Smsmith    if (ACPI_FAILURE (Status))
53467754Smsmith    {
53599679Siwasaki        return_VOID;
53667754Smsmith    }
53767754Smsmith
53887031Smsmith    /* Get the associated object */
53967754Smsmith
54087031Smsmith    Object = AcpiNsGetAttachedObject (Node);
54167754Smsmith
54267754Smsmith    /*
54367754Smsmith     * Undefine the Arg or Local by setting its descriptor
54467754Smsmith     * pointer to NULL. Locals/Args can contain both
54567754Smsmith     * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
54667754Smsmith     */
54787031Smsmith    Node->Object = NULL;
54867754Smsmith
54967754Smsmith    if ((Object) &&
55099679Siwasaki        (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_OPERAND))
55167754Smsmith    {
55267754Smsmith        /*
55387031Smsmith         * There is a valid object.
55467754Smsmith         * Decrement the reference count by one to balance the
55587031Smsmith         * increment when the object was stored.
55667754Smsmith         */
55777424Smsmith        AcpiUtRemoveReference (Object);
55867754Smsmith    }
55967754Smsmith
56099679Siwasaki    return_VOID;
56167754Smsmith}
56267754Smsmith
56367754Smsmith
56467754Smsmith/*******************************************************************************
56567754Smsmith *
56677424Smsmith * FUNCTION:    AcpiDsStoreObjectToLocal
56767754Smsmith *
568193267Sjkim * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
569193267Sjkim *                                    ACPI_REFCLASS_ARG
570151937Sjkim *              Index               - Which Local or Arg to set
57187031Smsmith *              ObjDesc             - Value to be stored
57271867Smsmith *              WalkState           - Current walk state
57367754Smsmith *
57467754Smsmith * RETURN:      Status
57567754Smsmith *
576241973Sjkim * DESCRIPTION: Store a value in an Arg or Local. The ObjDesc is installed
57767754Smsmith *              as the new value for the Arg or Local and the reference count
57887031Smsmith *              for ObjDesc is incremented.
57967754Smsmith *
58067754Smsmith ******************************************************************************/
58167754Smsmith
58267754SmsmithACPI_STATUS
58377424SmsmithAcpiDsStoreObjectToLocal (
584193267Sjkim    UINT8                   Type,
58567754Smsmith    UINT32                  Index,
58687031Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc,
58767754Smsmith    ACPI_WALK_STATE         *WalkState)
58867754Smsmith{
58967754Smsmith    ACPI_STATUS             Status;
59087031Smsmith    ACPI_NAMESPACE_NODE     *Node;
59187031Smsmith    ACPI_OPERAND_OBJECT     *CurrentObjDesc;
592123315Snjl    ACPI_OPERAND_OBJECT     *NewObjDesc;
59367754Smsmith
59467754Smsmith
595167802Sjkim    ACPI_FUNCTION_TRACE (DsStoreObjectToLocal);
596209746Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Type=%2.2X Index=%u Obj=%p\n",
597193267Sjkim        Type, Index, ObjDesc));
59867754Smsmith
59967754Smsmith    /* Parameter validation */
60067754Smsmith
60187031Smsmith    if (!ObjDesc)
60267754Smsmith    {
60367754Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
60467754Smsmith    }
60567754Smsmith
60687031Smsmith    /* Get the namespace node for the arg/local */
60767754Smsmith
608193267Sjkim    Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
60967754Smsmith    if (ACPI_FAILURE (Status))
61067754Smsmith    {
61187031Smsmith        return_ACPI_STATUS (Status);
61267754Smsmith    }
61367754Smsmith
61487031Smsmith    CurrentObjDesc = AcpiNsGetAttachedObject (Node);
61587031Smsmith    if (CurrentObjDesc == ObjDesc)
61667754Smsmith    {
617114237Snjl        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n",
618114237Snjl            ObjDesc));
61987031Smsmith        return_ACPI_STATUS (Status);
62067754Smsmith    }
62167754Smsmith
62267754Smsmith    /*
623123315Snjl     * If the reference count on the object is more than one, we must
624241973Sjkim     * take a copy of the object before we store. A reference count
625126372Snjl     * of exactly 1 means that the object was just created during the
626126372Snjl     * evaluation of an expression, and we can safely use it since it
627126372Snjl     * is not used anywhere else.
628123315Snjl     */
629123315Snjl    NewObjDesc = ObjDesc;
630126372Snjl    if (ObjDesc->Common.ReferenceCount > 1)
631123315Snjl    {
632123315Snjl        Status = AcpiUtCopyIobjectToIobject (ObjDesc, &NewObjDesc, WalkState);
633123315Snjl        if (ACPI_FAILURE (Status))
634123315Snjl        {
635123315Snjl            return_ACPI_STATUS (Status);
636123315Snjl        }
637123315Snjl    }
638123315Snjl
639123315Snjl    /*
64067754Smsmith     * If there is an object already in this slot, we either
64167754Smsmith     * have to delete it, or if this is an argument and there
64267754Smsmith     * is an object reference stored there, we have to do
64367754Smsmith     * an indirect store!
64467754Smsmith     */
64587031Smsmith    if (CurrentObjDesc)
64667754Smsmith    {
64767754Smsmith        /*
64867754Smsmith         * Check for an indirect store if an argument
64967754Smsmith         * contains an object reference (stored as an Node).
65067754Smsmith         * We don't allow this automatic dereferencing for
65167754Smsmith         * locals, since a store to a local should overwrite
65267754Smsmith         * anything there, including an object reference.
65367754Smsmith         *
65467754Smsmith         * If both Arg0 and Local0 contain RefOf (Local4):
65567754Smsmith         *
65667754Smsmith         * Store (1, Arg0)             - Causes indirect store to local4
65767754Smsmith         * Store (1, Local0)           - Stores 1 in local0, overwriting
65867754Smsmith         *                                  the reference to local4
65967754Smsmith         * Store (1, DeRefof (Local0)) - Causes indirect store to local4
66067754Smsmith         *
66167754Smsmith         * Weird, but true.
66267754Smsmith         */
663193267Sjkim        if (Type == ACPI_REFCLASS_ARG)
66467754Smsmith        {
665114237Snjl            /*
666151937Sjkim             * If we have a valid reference object that came from RefOf(),
667151937Sjkim             * do the indirect store
668102550Siwasaki             */
669151937Sjkim            if ((ACPI_GET_DESCRIPTOR_TYPE (CurrentObjDesc) == ACPI_DESC_TYPE_OPERAND) &&
670151937Sjkim                (CurrentObjDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
671193267Sjkim                (CurrentObjDesc->Reference.Class == ACPI_REFCLASS_REFOF))
672102550Siwasaki            {
673102550Siwasaki                ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
674123315Snjl                        "Arg (%p) is an ObjRef(Node), storing in node %p\n",
675123315Snjl                        NewObjDesc, CurrentObjDesc));
67667754Smsmith
677102550Siwasaki                /*
678128212Snjl                 * Store this object to the Node (perform the indirect store)
679128212Snjl                 * NOTE: No implicit conversion is performed, as per the ACPI
680128212Snjl                 * specification rules on storing to Locals/Args.
681102550Siwasaki                 */
682123315Snjl                Status = AcpiExStoreObjectToNode (NewObjDesc,
683128212Snjl                            CurrentObjDesc->Reference.Object, WalkState,
684128212Snjl                            ACPI_NO_IMPLICIT_CONVERSION);
685123315Snjl
686123315Snjl                /* Remove local reference if we copied the object above */
687123315Snjl
688123315Snjl                if (NewObjDesc != ObjDesc)
689123315Snjl                {
690123315Snjl                    AcpiUtRemoveReference (NewObjDesc);
691123315Snjl                }
692102550Siwasaki                return_ACPI_STATUS (Status);
693102550Siwasaki            }
69467754Smsmith        }
69567754Smsmith
696193267Sjkim        /* Delete the existing object before storing the new one */
697193267Sjkim
698193267Sjkim        AcpiDsMethodDataDeleteValue (Type, Index, WalkState);
69967754Smsmith    }
70067754Smsmith
70167754Smsmith    /*
702123315Snjl     * Install the Obj descriptor (*NewObjDesc) into
70367754Smsmith     * the descriptor for the Arg or Local.
70467754Smsmith     * (increments the object reference count by one)
70567754Smsmith     */
706193267Sjkim    Status = AcpiDsMethodDataSetValue (Type, Index, NewObjDesc, WalkState);
707123315Snjl
708123315Snjl    /* Remove local reference if we copied the object above */
709123315Snjl
710123315Snjl    if (NewObjDesc != ObjDesc)
711123315Snjl    {
712123315Snjl        AcpiUtRemoveReference (NewObjDesc);
713123315Snjl    }
714123315Snjl
71567754Smsmith    return_ACPI_STATUS (Status);
71667754Smsmith}
71767754Smsmith
71887031Smsmith
719151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS
720151937Sjkim/*******************************************************************************
721151937Sjkim *
722151937Sjkim * FUNCTION:    AcpiDsMethodDataGetType
723151937Sjkim *
724151937Sjkim * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
725151937Sjkim *              Index               - Which Local or Arg whose type to get
726151937Sjkim *              WalkState           - Current walk state object
727151937Sjkim *
728151937Sjkim * RETURN:      Data type of current value of the selected Arg or Local
729151937Sjkim *
730151937Sjkim * DESCRIPTION: Get the type of the object stored in the Local or Arg
731151937Sjkim *
732151937Sjkim ******************************************************************************/
733151937Sjkim
734151937SjkimACPI_OBJECT_TYPE
735151937SjkimAcpiDsMethodDataGetType (
736151937Sjkim    UINT16                  Opcode,
737151937Sjkim    UINT32                  Index,
738151937Sjkim    ACPI_WALK_STATE         *WalkState)
739151937Sjkim{
740151937Sjkim    ACPI_STATUS             Status;
741151937Sjkim    ACPI_NAMESPACE_NODE     *Node;
742151937Sjkim    ACPI_OPERAND_OBJECT     *Object;
743151937Sjkim
744151937Sjkim
745167802Sjkim    ACPI_FUNCTION_TRACE (DsMethodDataGetType);
746151937Sjkim
747151937Sjkim
748151937Sjkim    /* Get the namespace node for the arg/local */
749151937Sjkim
750151937Sjkim    Status = AcpiDsMethodDataGetNode (Opcode, Index, WalkState, &Node);
751151937Sjkim    if (ACPI_FAILURE (Status))
752151937Sjkim    {
753151937Sjkim        return_VALUE ((ACPI_TYPE_NOT_FOUND));
754151937Sjkim    }
755151937Sjkim
756151937Sjkim    /* Get the object */
757151937Sjkim
758151937Sjkim    Object = AcpiNsGetAttachedObject (Node);
759151937Sjkim    if (!Object)
760151937Sjkim    {
761151937Sjkim        /* Uninitialized local/arg, return TYPE_ANY */
762151937Sjkim
763151937Sjkim        return_VALUE (ACPI_TYPE_ANY);
764151937Sjkim    }
765151937Sjkim
766151937Sjkim    /* Get the object type */
767151937Sjkim
768193267Sjkim    return_VALUE (Object->Type);
769151937Sjkim}
770151937Sjkim#endif
771