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