Home | History | Annotate | Line # | Download | only in dispatcher
dsmthdat.c revision 1.1.1.3
      1 /*******************************************************************************
      2  *
      3  * Module Name: dsmthdat - control method arguments and local variables
      4  *
      5  ******************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2013, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #define __DSMTHDAT_C__
     45 
     46 #include "acpi.h"
     47 #include "accommon.h"
     48 #include "acdispat.h"
     49 #include "acnamesp.h"
     50 #include "acinterp.h"
     51 
     52 
     53 #define _COMPONENT          ACPI_DISPATCHER
     54         ACPI_MODULE_NAME    ("dsmthdat")
     55 
     56 /* Local prototypes */
     57 
     58 static void
     59 AcpiDsMethodDataDeleteValue (
     60     UINT8                   Type,
     61     UINT32                  Index,
     62     ACPI_WALK_STATE         *WalkState);
     63 
     64 static ACPI_STATUS
     65 AcpiDsMethodDataSetValue (
     66     UINT8                   Type,
     67     UINT32                  Index,
     68     ACPI_OPERAND_OBJECT     *Object,
     69     ACPI_WALK_STATE         *WalkState);
     70 
     71 #ifdef ACPI_OBSOLETE_FUNCTIONS
     72 ACPI_OBJECT_TYPE
     73 AcpiDsMethodDataGetType (
     74     UINT16                  Opcode,
     75     UINT32                  Index,
     76     ACPI_WALK_STATE         *WalkState);
     77 #endif
     78 
     79 
     80 /*******************************************************************************
     81  *
     82  * FUNCTION:    AcpiDsMethodDataInit
     83  *
     84  * PARAMETERS:  WalkState           - Current walk state object
     85  *
     86  * RETURN:      Status
     87  *
     88  * DESCRIPTION: Initialize the data structures that hold the method's arguments
     89  *              and locals. The data struct is an array of namespace nodes for
     90  *              each - this allows RefOf and DeRefOf to work properly for these
     91  *              special data types.
     92  *
     93  * NOTES:       WalkState fields are initialized to zero by the
     94  *              ACPI_ALLOCATE_ZEROED().
     95  *
     96  *              A pseudo-Namespace Node is assigned to each argument and local
     97  *              so that RefOf() can return a pointer to the Node.
     98  *
     99  ******************************************************************************/
    100 
    101 void
    102 AcpiDsMethodDataInit (
    103     ACPI_WALK_STATE         *WalkState)
    104 {
    105     UINT32                  i;
    106 
    107 
    108     ACPI_FUNCTION_TRACE (DsMethodDataInit);
    109 
    110 
    111     /* Init the method arguments */
    112 
    113     for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
    114     {
    115         ACPI_MOVE_32_TO_32 (&WalkState->Arguments[i].Name, NAMEOF_ARG_NTE);
    116         WalkState->Arguments[i].Name.Integer |= (i << 24);
    117         WalkState->Arguments[i].DescriptorType = ACPI_DESC_TYPE_NAMED;
    118         WalkState->Arguments[i].Type = ACPI_TYPE_ANY;
    119         WalkState->Arguments[i].Flags = ANOBJ_METHOD_ARG;
    120     }
    121 
    122     /* Init the method locals */
    123 
    124     for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++)
    125     {
    126         ACPI_MOVE_32_TO_32 (&WalkState->LocalVariables[i].Name, NAMEOF_LOCAL_NTE);
    127 
    128         WalkState->LocalVariables[i].Name.Integer |= (i << 24);
    129         WalkState->LocalVariables[i].DescriptorType = ACPI_DESC_TYPE_NAMED;
    130         WalkState->LocalVariables[i].Type = ACPI_TYPE_ANY;
    131         WalkState->LocalVariables[i].Flags = ANOBJ_METHOD_LOCAL;
    132     }
    133 
    134     return_VOID;
    135 }
    136 
    137 
    138 /*******************************************************************************
    139  *
    140  * FUNCTION:    AcpiDsMethodDataDeleteAll
    141  *
    142  * PARAMETERS:  WalkState           - Current walk state object
    143  *
    144  * RETURN:      None
    145  *
    146  * DESCRIPTION: Delete method locals and arguments. Arguments are only
    147  *              deleted if this method was called from another method.
    148  *
    149  ******************************************************************************/
    150 
    151 void
    152 AcpiDsMethodDataDeleteAll (
    153     ACPI_WALK_STATE         *WalkState)
    154 {
    155     UINT32                  Index;
    156 
    157 
    158     ACPI_FUNCTION_TRACE (DsMethodDataDeleteAll);
    159 
    160 
    161     /* Detach the locals */
    162 
    163     for (Index = 0; Index < ACPI_METHOD_NUM_LOCALS; Index++)
    164     {
    165         if (WalkState->LocalVariables[Index].Object)
    166         {
    167             ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%u=%p\n",
    168                     Index, WalkState->LocalVariables[Index].Object));
    169 
    170             /* Detach object (if present) and remove a reference */
    171 
    172             AcpiNsDetachObject (&WalkState->LocalVariables[Index]);
    173         }
    174     }
    175 
    176     /* Detach the arguments */
    177 
    178     for (Index = 0; Index < ACPI_METHOD_NUM_ARGS; Index++)
    179     {
    180         if (WalkState->Arguments[Index].Object)
    181         {
    182             ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%u=%p\n",
    183                     Index, WalkState->Arguments[Index].Object));
    184 
    185             /* Detach object (if present) and remove a reference */
    186 
    187             AcpiNsDetachObject (&WalkState->Arguments[Index]);
    188         }
    189     }
    190 
    191     return_VOID;
    192 }
    193 
    194 
    195 /*******************************************************************************
    196  *
    197  * FUNCTION:    AcpiDsMethodDataInitArgs
    198  *
    199  * PARAMETERS:  *Params         - Pointer to a parameter list for the method
    200  *              MaxParamCount   - The arg count for this method
    201  *              WalkState       - Current walk state object
    202  *
    203  * RETURN:      Status
    204  *
    205  * DESCRIPTION: Initialize arguments for a method. The parameter list is a list
    206  *              of ACPI operand objects, either null terminated or whose length
    207  *              is defined by MaxParamCount.
    208  *
    209  ******************************************************************************/
    210 
    211 ACPI_STATUS
    212 AcpiDsMethodDataInitArgs (
    213     ACPI_OPERAND_OBJECT     **Params,
    214     UINT32                  MaxParamCount,
    215     ACPI_WALK_STATE         *WalkState)
    216 {
    217     ACPI_STATUS             Status;
    218     UINT32                  Index = 0;
    219 
    220 
    221     ACPI_FUNCTION_TRACE_PTR (DsMethodDataInitArgs, Params);
    222 
    223 
    224     if (!Params)
    225     {
    226         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n"));
    227         return_ACPI_STATUS (AE_OK);
    228     }
    229 
    230     /* Copy passed parameters into the new method stack frame */
    231 
    232     while ((Index < ACPI_METHOD_NUM_ARGS) &&
    233            (Index < MaxParamCount)        &&
    234             Params[Index])
    235     {
    236         /*
    237          * A valid parameter.
    238          * Store the argument in the method/walk descriptor.
    239          * Do not copy the arg in order to implement call by reference
    240          */
    241         Status = AcpiDsMethodDataSetValue (ACPI_REFCLASS_ARG, Index,
    242                     Params[Index], WalkState);
    243         if (ACPI_FAILURE (Status))
    244         {
    245             return_ACPI_STATUS (Status);
    246         }
    247 
    248         Index++;
    249     }
    250 
    251     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%u args passed to method\n", Index));
    252     return_ACPI_STATUS (AE_OK);
    253 }
    254 
    255 
    256 /*******************************************************************************
    257  *
    258  * FUNCTION:    AcpiDsMethodDataGetNode
    259  *
    260  * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
    261  *                                    ACPI_REFCLASS_ARG
    262  *              Index               - Which Local or Arg whose type to get
    263  *              WalkState           - Current walk state object
    264  *              Node                - Where the node is returned.
    265  *
    266  * RETURN:      Status and node
    267  *
    268  * DESCRIPTION: Get the Node associated with a local or arg.
    269  *
    270  ******************************************************************************/
    271 
    272 ACPI_STATUS
    273 AcpiDsMethodDataGetNode (
    274     UINT8                   Type,
    275     UINT32                  Index,
    276     ACPI_WALK_STATE         *WalkState,
    277     ACPI_NAMESPACE_NODE     **Node)
    278 {
    279     ACPI_FUNCTION_TRACE (DsMethodDataGetNode);
    280 
    281 
    282     /*
    283      * Method Locals and Arguments are supported
    284      */
    285     switch (Type)
    286     {
    287     case ACPI_REFCLASS_LOCAL:
    288 
    289         if (Index > ACPI_METHOD_MAX_LOCAL)
    290         {
    291             ACPI_ERROR ((AE_INFO,
    292                 "Local index %u is invalid (max %u)",
    293                 Index, ACPI_METHOD_MAX_LOCAL));
    294             return_ACPI_STATUS (AE_AML_INVALID_INDEX);
    295         }
    296 
    297         /* Return a pointer to the pseudo-node */
    298 
    299         *Node = &WalkState->LocalVariables[Index];
    300         break;
    301 
    302     case ACPI_REFCLASS_ARG:
    303 
    304         if (Index > ACPI_METHOD_MAX_ARG)
    305         {
    306             ACPI_ERROR ((AE_INFO,
    307                 "Arg index %u is invalid (max %u)",
    308                 Index, ACPI_METHOD_MAX_ARG));
    309             return_ACPI_STATUS (AE_AML_INVALID_INDEX);
    310         }
    311 
    312         /* Return a pointer to the pseudo-node */
    313 
    314         *Node = &WalkState->Arguments[Index];
    315         break;
    316 
    317     default:
    318 
    319         ACPI_ERROR ((AE_INFO, "Type %u is invalid", Type));
    320         return_ACPI_STATUS (AE_TYPE);
    321     }
    322 
    323     return_ACPI_STATUS (AE_OK);
    324 }
    325 
    326 
    327 /*******************************************************************************
    328  *
    329  * FUNCTION:    AcpiDsMethodDataSetValue
    330  *
    331  * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
    332  *                                    ACPI_REFCLASS_ARG
    333  *              Index               - Which Local or Arg to get
    334  *              Object              - Object to be inserted into the stack entry
    335  *              WalkState           - Current walk state object
    336  *
    337  * RETURN:      Status
    338  *
    339  * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index.
    340  *              Note: There is no "implicit conversion" for locals.
    341  *
    342  ******************************************************************************/
    343 
    344 static ACPI_STATUS
    345 AcpiDsMethodDataSetValue (
    346     UINT8                   Type,
    347     UINT32                  Index,
    348     ACPI_OPERAND_OBJECT     *Object,
    349     ACPI_WALK_STATE         *WalkState)
    350 {
    351     ACPI_STATUS             Status;
    352     ACPI_NAMESPACE_NODE     *Node;
    353 
    354 
    355     ACPI_FUNCTION_TRACE (DsMethodDataSetValue);
    356 
    357 
    358     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
    359         "NewObj %p Type %2.2X, Refs=%u [%s]\n", Object,
    360         Type, Object->Common.ReferenceCount,
    361         AcpiUtGetTypeName (Object->Common.Type)));
    362 
    363     /* Get the namespace node for the arg/local */
    364 
    365     Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
    366     if (ACPI_FAILURE (Status))
    367     {
    368         return_ACPI_STATUS (Status);
    369     }
    370 
    371     /*
    372      * Increment ref count so object can't be deleted while installed.
    373      * NOTE: We do not copy the object in order to preserve the call by
    374      * reference semantics of ACPI Control Method invocation.
    375      * (See ACPI Specification 2.0C)
    376      */
    377     AcpiUtAddReference (Object);
    378 
    379     /* Install the object */
    380 
    381     Node->Object = Object;
    382     return_ACPI_STATUS (Status);
    383 }
    384 
    385 
    386 /*******************************************************************************
    387  *
    388  * FUNCTION:    AcpiDsMethodDataGetValue
    389  *
    390  * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
    391  *                                    ACPI_REFCLASS_ARG
    392  *              Index               - Which localVar or argument to get
    393  *              WalkState           - Current walk state object
    394  *              DestDesc            - Where Arg or Local value is returned
    395  *
    396  * RETURN:      Status
    397  *
    398  * DESCRIPTION: Retrieve value of selected Arg or Local for this method
    399  *              Used only in AcpiExResolveToValue().
    400  *
    401  ******************************************************************************/
    402 
    403 ACPI_STATUS
    404 AcpiDsMethodDataGetValue (
    405     UINT8                   Type,
    406     UINT32                  Index,
    407     ACPI_WALK_STATE         *WalkState,
    408     ACPI_OPERAND_OBJECT     **DestDesc)
    409 {
    410     ACPI_STATUS             Status;
    411     ACPI_NAMESPACE_NODE     *Node;
    412     ACPI_OPERAND_OBJECT     *Object;
    413 
    414 
    415     ACPI_FUNCTION_TRACE (DsMethodDataGetValue);
    416 
    417 
    418     /* Validate the object descriptor */
    419 
    420     if (!DestDesc)
    421     {
    422         ACPI_ERROR ((AE_INFO, "Null object descriptor pointer"));
    423         return_ACPI_STATUS (AE_BAD_PARAMETER);
    424     }
    425 
    426     /* Get the namespace node for the arg/local */
    427 
    428     Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
    429     if (ACPI_FAILURE (Status))
    430     {
    431         return_ACPI_STATUS (Status);
    432     }
    433 
    434     /* Get the object from the node */
    435 
    436     Object = Node->Object;
    437 
    438     /* Examine the returned object, it must be valid. */
    439 
    440     if (!Object)
    441     {
    442         /*
    443          * Index points to uninitialized object.
    444          * This means that either 1) The expected argument was
    445          * not passed to the method, or 2) A local variable
    446          * was referenced by the method (via the ASL)
    447          * before it was initialized. Either case is an error.
    448          */
    449 
    450         /* If slack enabled, init the LocalX/ArgX to an Integer of value zero */
    451 
    452         if (AcpiGbl_EnableInterpreterSlack)
    453         {
    454             Object = AcpiUtCreateIntegerObject ((UINT64) 0);
    455             if (!Object)
    456             {
    457                 return_ACPI_STATUS (AE_NO_MEMORY);
    458             }
    459 
    460             Node->Object = Object;
    461         }
    462 
    463         /* Otherwise, return the error */
    464 
    465         else switch (Type)
    466         {
    467         case ACPI_REFCLASS_ARG:
    468 
    469             ACPI_ERROR ((AE_INFO,
    470                 "Uninitialized Arg[%u] at node %p",
    471                 Index, Node));
    472 
    473             return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
    474 
    475         case ACPI_REFCLASS_LOCAL:
    476             /*
    477              * No error message for this case, will be trapped again later to
    478              * detect and ignore cases of Store(LocalX,LocalX)
    479              */
    480             return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL);
    481 
    482         default:
    483 
    484             ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: 0x%X", Type));
    485             return_ACPI_STATUS (AE_AML_INTERNAL);
    486         }
    487     }
    488 
    489     /*
    490      * The Index points to an initialized and valid object.
    491      * Return an additional reference to the object
    492      */
    493     *DestDesc = Object;
    494     AcpiUtAddReference (Object);
    495 
    496     return_ACPI_STATUS (AE_OK);
    497 }
    498 
    499 
    500 /*******************************************************************************
    501  *
    502  * FUNCTION:    AcpiDsMethodDataDeleteValue
    503  *
    504  * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
    505  *                                    ACPI_REFCLASS_ARG
    506  *              Index               - Which localVar or argument to delete
    507  *              WalkState           - Current walk state object
    508  *
    509  * RETURN:      None
    510  *
    511  * DESCRIPTION: Delete the entry at Opcode:Index. Inserts
    512  *              a null into the stack slot after the object is deleted.
    513  *
    514  ******************************************************************************/
    515 
    516 static void
    517 AcpiDsMethodDataDeleteValue (
    518     UINT8                   Type,
    519     UINT32                  Index,
    520     ACPI_WALK_STATE         *WalkState)
    521 {
    522     ACPI_STATUS             Status;
    523     ACPI_NAMESPACE_NODE     *Node;
    524     ACPI_OPERAND_OBJECT     *Object;
    525 
    526 
    527     ACPI_FUNCTION_TRACE (DsMethodDataDeleteValue);
    528 
    529 
    530     /* Get the namespace node for the arg/local */
    531 
    532     Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
    533     if (ACPI_FAILURE (Status))
    534     {
    535         return_VOID;
    536     }
    537 
    538     /* Get the associated object */
    539 
    540     Object = AcpiNsGetAttachedObject (Node);
    541 
    542     /*
    543      * Undefine the Arg or Local by setting its descriptor
    544      * pointer to NULL. Locals/Args can contain both
    545      * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
    546      */
    547     Node->Object = NULL;
    548 
    549     if ((Object) &&
    550         (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_OPERAND))
    551     {
    552         /*
    553          * There is a valid object.
    554          * Decrement the reference count by one to balance the
    555          * increment when the object was stored.
    556          */
    557         AcpiUtRemoveReference (Object);
    558     }
    559 
    560     return_VOID;
    561 }
    562 
    563 
    564 /*******************************************************************************
    565  *
    566  * FUNCTION:    AcpiDsStoreObjectToLocal
    567  *
    568  * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
    569  *                                    ACPI_REFCLASS_ARG
    570  *              Index               - Which Local or Arg to set
    571  *              ObjDesc             - Value to be stored
    572  *              WalkState           - Current walk state
    573  *
    574  * RETURN:      Status
    575  *
    576  * DESCRIPTION: Store a value in an Arg or Local. The ObjDesc is installed
    577  *              as the new value for the Arg or Local and the reference count
    578  *              for ObjDesc is incremented.
    579  *
    580  ******************************************************************************/
    581 
    582 ACPI_STATUS
    583 AcpiDsStoreObjectToLocal (
    584     UINT8                   Type,
    585     UINT32                  Index,
    586     ACPI_OPERAND_OBJECT     *ObjDesc,
    587     ACPI_WALK_STATE         *WalkState)
    588 {
    589     ACPI_STATUS             Status;
    590     ACPI_NAMESPACE_NODE     *Node;
    591     ACPI_OPERAND_OBJECT     *CurrentObjDesc;
    592     ACPI_OPERAND_OBJECT     *NewObjDesc;
    593 
    594 
    595     ACPI_FUNCTION_TRACE (DsStoreObjectToLocal);
    596     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Type=%2.2X Index=%u Obj=%p\n",
    597         Type, Index, ObjDesc));
    598 
    599     /* Parameter validation */
    600 
    601     if (!ObjDesc)
    602     {
    603         return_ACPI_STATUS (AE_BAD_PARAMETER);
    604     }
    605 
    606     /* Get the namespace node for the arg/local */
    607 
    608     Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
    609     if (ACPI_FAILURE (Status))
    610     {
    611         return_ACPI_STATUS (Status);
    612     }
    613 
    614     CurrentObjDesc = AcpiNsGetAttachedObject (Node);
    615     if (CurrentObjDesc == ObjDesc)
    616     {
    617         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n",
    618             ObjDesc));
    619         return_ACPI_STATUS (Status);
    620     }
    621 
    622     /*
    623      * If the reference count on the object is more than one, we must
    624      * take a copy of the object before we store. A reference count
    625      * of exactly 1 means that the object was just created during the
    626      * evaluation of an expression, and we can safely use it since it
    627      * is not used anywhere else.
    628      */
    629     NewObjDesc = ObjDesc;
    630     if (ObjDesc->Common.ReferenceCount > 1)
    631     {
    632         Status = AcpiUtCopyIobjectToIobject (ObjDesc, &NewObjDesc, WalkState);
    633         if (ACPI_FAILURE (Status))
    634         {
    635             return_ACPI_STATUS (Status);
    636         }
    637     }
    638 
    639     /*
    640      * If there is an object already in this slot, we either
    641      * have to delete it, or if this is an argument and there
    642      * is an object reference stored there, we have to do
    643      * an indirect store!
    644      */
    645     if (CurrentObjDesc)
    646     {
    647         /*
    648          * Check for an indirect store if an argument
    649          * contains an object reference (stored as an Node).
    650          * We don't allow this automatic dereferencing for
    651          * locals, since a store to a local should overwrite
    652          * anything there, including an object reference.
    653          *
    654          * If both Arg0 and Local0 contain RefOf (Local4):
    655          *
    656          * Store (1, Arg0)             - Causes indirect store to local4
    657          * Store (1, Local0)           - Stores 1 in local0, overwriting
    658          *                                  the reference to local4
    659          * Store (1, DeRefof (Local0)) - Causes indirect store to local4
    660          *
    661          * Weird, but true.
    662          */
    663         if (Type == ACPI_REFCLASS_ARG)
    664         {
    665             /*
    666              * If we have a valid reference object that came from RefOf(),
    667              * do the indirect store
    668              */
    669             if ((ACPI_GET_DESCRIPTOR_TYPE (CurrentObjDesc) == ACPI_DESC_TYPE_OPERAND) &&
    670                 (CurrentObjDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
    671                 (CurrentObjDesc->Reference.Class == ACPI_REFCLASS_REFOF))
    672             {
    673                 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
    674                         "Arg (%p) is an ObjRef(Node), storing in node %p\n",
    675                         NewObjDesc, CurrentObjDesc));
    676 
    677                 /*
    678                  * Store this object to the Node (perform the indirect store)
    679                  * NOTE: No implicit conversion is performed, as per the ACPI
    680                  * specification rules on storing to Locals/Args.
    681                  */
    682                 Status = AcpiExStoreObjectToNode (NewObjDesc,
    683                             CurrentObjDesc->Reference.Object, WalkState,
    684                             ACPI_NO_IMPLICIT_CONVERSION);
    685 
    686                 /* Remove local reference if we copied the object above */
    687 
    688                 if (NewObjDesc != ObjDesc)
    689                 {
    690                     AcpiUtRemoveReference (NewObjDesc);
    691                 }
    692                 return_ACPI_STATUS (Status);
    693             }
    694         }
    695 
    696         /* Delete the existing object before storing the new one */
    697 
    698         AcpiDsMethodDataDeleteValue (Type, Index, WalkState);
    699     }
    700 
    701     /*
    702      * Install the Obj descriptor (*NewObjDesc) into
    703      * the descriptor for the Arg or Local.
    704      * (increments the object reference count by one)
    705      */
    706     Status = AcpiDsMethodDataSetValue (Type, Index, NewObjDesc, WalkState);
    707 
    708     /* Remove local reference if we copied the object above */
    709 
    710     if (NewObjDesc != ObjDesc)
    711     {
    712         AcpiUtRemoveReference (NewObjDesc);
    713     }
    714 
    715     return_ACPI_STATUS (Status);
    716 }
    717 
    718 
    719 #ifdef ACPI_OBSOLETE_FUNCTIONS
    720 /*******************************************************************************
    721  *
    722  * FUNCTION:    AcpiDsMethodDataGetType
    723  *
    724  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
    725  *              Index               - Which Local or Arg whose type to get
    726  *              WalkState           - Current walk state object
    727  *
    728  * RETURN:      Data type of current value of the selected Arg or Local
    729  *
    730  * DESCRIPTION: Get the type of the object stored in the Local or Arg
    731  *
    732  ******************************************************************************/
    733 
    734 ACPI_OBJECT_TYPE
    735 AcpiDsMethodDataGetType (
    736     UINT16                  Opcode,
    737     UINT32                  Index,
    738     ACPI_WALK_STATE         *WalkState)
    739 {
    740     ACPI_STATUS             Status;
    741     ACPI_NAMESPACE_NODE     *Node;
    742     ACPI_OPERAND_OBJECT     *Object;
    743 
    744 
    745     ACPI_FUNCTION_TRACE (DsMethodDataGetType);
    746 
    747 
    748     /* Get the namespace node for the arg/local */
    749 
    750     Status = AcpiDsMethodDataGetNode (Opcode, Index, WalkState, &Node);
    751     if (ACPI_FAILURE (Status))
    752     {
    753         return_VALUE ((ACPI_TYPE_NOT_FOUND));
    754     }
    755 
    756     /* Get the object */
    757 
    758     Object = AcpiNsGetAttachedObject (Node);
    759     if (!Object)
    760     {
    761         /* Uninitialized local/arg, return TYPE_ANY */
    762 
    763         return_VALUE (ACPI_TYPE_ANY);
    764     }
    765 
    766     /* Get the object type */
    767 
    768     return_VALUE (Object->Type);
    769 }
    770 #endif
    771