xref: /titanic_41/usr/src/uts/intel/io/acpica/dispatcher/dsmthdat.c (revision 35a5a3587fd94b666239c157d3722745250ccbd7)
1 /*******************************************************************************
2  *
3  * Module Name: dsmthdat - control method arguments and local variables
4  *
5  ******************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights.  You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code.  No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision.  In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change.  Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee.  Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution.  In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government.  In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************/
115 
116 #define __DSMTHDAT_C__
117 
118 #include "acpi.h"
119 #include "accommon.h"
120 #include "acdispat.h"
121 #include "acnamesp.h"
122 #include "acinterp.h"
123 
124 
125 #define _COMPONENT          ACPI_DISPATCHER
126         ACPI_MODULE_NAME    ("dsmthdat")
127 
128 /* Local prototypes */
129 
130 static void
131 AcpiDsMethodDataDeleteValue (
132     UINT8                   Type,
133     UINT32                  Index,
134     ACPI_WALK_STATE         *WalkState);
135 
136 static ACPI_STATUS
137 AcpiDsMethodDataSetValue (
138     UINT8                   Type,
139     UINT32                  Index,
140     ACPI_OPERAND_OBJECT     *Object,
141     ACPI_WALK_STATE         *WalkState);
142 
143 #ifdef ACPI_OBSOLETE_FUNCTIONS
144 ACPI_OBJECT_TYPE
145 AcpiDsMethodDataGetType (
146     UINT16                  Opcode,
147     UINT32                  Index,
148     ACPI_WALK_STATE         *WalkState);
149 #endif
150 
151 
152 /*******************************************************************************
153  *
154  * FUNCTION:    AcpiDsMethodDataInit
155  *
156  * PARAMETERS:  WalkState           - Current walk state object
157  *
158  * RETURN:      Status
159  *
160  * DESCRIPTION: Initialize the data structures that hold the method's arguments
161  *              and locals.  The data struct is an array of namespace nodes for
162  *              each - this allows RefOf and DeRefOf to work properly for these
163  *              special data types.
164  *
165  * NOTES:       WalkState fields are initialized to zero by the
166  *              ACPI_ALLOCATE_ZEROED().
167  *
168  *              A pseudo-Namespace Node is assigned to each argument and local
169  *              so that RefOf() can return a pointer to the Node.
170  *
171  ******************************************************************************/
172 
173 void
174 AcpiDsMethodDataInit (
175     ACPI_WALK_STATE         *WalkState)
176 {
177     UINT32                  i;
178 
179 
180     ACPI_FUNCTION_TRACE (DsMethodDataInit);
181 
182 
183     /* Init the method arguments */
184 
185     for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
186     {
187         ACPI_MOVE_32_TO_32 (&WalkState->Arguments[i].Name, NAMEOF_ARG_NTE);
188         WalkState->Arguments[i].Name.Integer |= (i << 24);
189         WalkState->Arguments[i].DescriptorType = ACPI_DESC_TYPE_NAMED;
190         WalkState->Arguments[i].Type = ACPI_TYPE_ANY;
191         WalkState->Arguments[i].Flags =
192             ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG;
193     }
194 
195     /* Init the method locals */
196 
197     for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++)
198     {
199         ACPI_MOVE_32_TO_32 (&WalkState->LocalVariables[i].Name, NAMEOF_LOCAL_NTE);
200 
201         WalkState->LocalVariables[i].Name.Integer |= (i << 24);
202         WalkState->LocalVariables[i].DescriptorType = ACPI_DESC_TYPE_NAMED;
203         WalkState->LocalVariables[i].Type = ACPI_TYPE_ANY;
204         WalkState->LocalVariables[i].Flags =
205             ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL;
206     }
207 
208     return_VOID;
209 }
210 
211 
212 /*******************************************************************************
213  *
214  * FUNCTION:    AcpiDsMethodDataDeleteAll
215  *
216  * PARAMETERS:  WalkState           - Current walk state object
217  *
218  * RETURN:      None
219  *
220  * DESCRIPTION: Delete method locals and arguments.  Arguments are only
221  *              deleted if this method was called from another method.
222  *
223  ******************************************************************************/
224 
225 void
226 AcpiDsMethodDataDeleteAll (
227     ACPI_WALK_STATE         *WalkState)
228 {
229     UINT32                  Index;
230 
231 
232     ACPI_FUNCTION_TRACE (DsMethodDataDeleteAll);
233 
234 
235     /* Detach the locals */
236 
237     for (Index = 0; Index < ACPI_METHOD_NUM_LOCALS; Index++)
238     {
239         if (WalkState->LocalVariables[Index].Object)
240         {
241             ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%d=%p\n",
242                     Index, WalkState->LocalVariables[Index].Object));
243 
244             /* Detach object (if present) and remove a reference */
245 
246             AcpiNsDetachObject (&WalkState->LocalVariables[Index]);
247         }
248     }
249 
250     /* Detach the arguments */
251 
252     for (Index = 0; Index < ACPI_METHOD_NUM_ARGS; Index++)
253     {
254         if (WalkState->Arguments[Index].Object)
255         {
256             ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%d=%p\n",
257                     Index, WalkState->Arguments[Index].Object));
258 
259             /* Detach object (if present) and remove a reference */
260 
261             AcpiNsDetachObject (&WalkState->Arguments[Index]);
262         }
263     }
264 
265     return_VOID;
266 }
267 
268 
269 /*******************************************************************************
270  *
271  * FUNCTION:    AcpiDsMethodDataInitArgs
272  *
273  * PARAMETERS:  *Params         - Pointer to a parameter list for the method
274  *              MaxParamCount   - The arg count for this method
275  *              WalkState       - Current walk state object
276  *
277  * RETURN:      Status
278  *
279  * DESCRIPTION: Initialize arguments for a method.  The parameter list is a list
280  *              of ACPI operand objects, either null terminated or whose length
281  *              is defined by MaxParamCount.
282  *
283  ******************************************************************************/
284 
285 ACPI_STATUS
286 AcpiDsMethodDataInitArgs (
287     ACPI_OPERAND_OBJECT     **Params,
288     UINT32                  MaxParamCount,
289     ACPI_WALK_STATE         *WalkState)
290 {
291     ACPI_STATUS             Status;
292     UINT32                  Index = 0;
293 
294 
295     ACPI_FUNCTION_TRACE_PTR (DsMethodDataInitArgs, Params);
296 
297 
298     if (!Params)
299     {
300         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n"));
301         return_ACPI_STATUS (AE_OK);
302     }
303 
304     /* Copy passed parameters into the new method stack frame */
305 
306     while ((Index < ACPI_METHOD_NUM_ARGS) &&
307            (Index < MaxParamCount)        &&
308             Params[Index])
309     {
310         /*
311          * A valid parameter.
312          * Store the argument in the method/walk descriptor.
313          * Do not copy the arg in order to implement call by reference
314          */
315         Status = AcpiDsMethodDataSetValue (ACPI_REFCLASS_ARG, Index,
316                     Params[Index], WalkState);
317         if (ACPI_FAILURE (Status))
318         {
319             return_ACPI_STATUS (Status);
320         }
321 
322         Index++;
323     }
324 
325     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%d args passed to method\n", Index));
326     return_ACPI_STATUS (AE_OK);
327 }
328 
329 
330 /*******************************************************************************
331  *
332  * FUNCTION:    AcpiDsMethodDataGetNode
333  *
334  * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
335  *                                    ACPI_REFCLASS_ARG
336  *              Index               - Which Local or Arg whose type to get
337  *              WalkState           - Current walk state object
338  *              Node                - Where the node is returned.
339  *
340  * RETURN:      Status and node
341  *
342  * DESCRIPTION: Get the Node associated with a local or arg.
343  *
344  ******************************************************************************/
345 
346 ACPI_STATUS
347 AcpiDsMethodDataGetNode (
348     UINT8                   Type,
349     UINT32                  Index,
350     ACPI_WALK_STATE         *WalkState,
351     ACPI_NAMESPACE_NODE     **Node)
352 {
353     ACPI_FUNCTION_TRACE (DsMethodDataGetNode);
354 
355 
356     /*
357      * Method Locals and Arguments are supported
358      */
359     switch (Type)
360     {
361     case ACPI_REFCLASS_LOCAL:
362 
363         if (Index > ACPI_METHOD_MAX_LOCAL)
364         {
365             ACPI_ERROR ((AE_INFO,
366                 "Local index %d is invalid (max %d)",
367                 Index, ACPI_METHOD_MAX_LOCAL));
368             return_ACPI_STATUS (AE_AML_INVALID_INDEX);
369         }
370 
371         /* Return a pointer to the pseudo-node */
372 
373         *Node = &WalkState->LocalVariables[Index];
374         break;
375 
376     case ACPI_REFCLASS_ARG:
377 
378         if (Index > ACPI_METHOD_MAX_ARG)
379         {
380             ACPI_ERROR ((AE_INFO,
381                 "Arg index %d is invalid (max %d)",
382                 Index, ACPI_METHOD_MAX_ARG));
383             return_ACPI_STATUS (AE_AML_INVALID_INDEX);
384         }
385 
386         /* Return a pointer to the pseudo-node */
387 
388         *Node = &WalkState->Arguments[Index];
389         break;
390 
391     default:
392         ACPI_ERROR ((AE_INFO, "Type %d is invalid", Type));
393         return_ACPI_STATUS (AE_TYPE);
394     }
395 
396     return_ACPI_STATUS (AE_OK);
397 }
398 
399 
400 /*******************************************************************************
401  *
402  * FUNCTION:    AcpiDsMethodDataSetValue
403  *
404  * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
405  *                                    ACPI_REFCLASS_ARG
406  *              Index               - Which Local or Arg to get
407  *              Object              - Object to be inserted into the stack entry
408  *              WalkState           - Current walk state object
409  *
410  * RETURN:      Status
411  *
412  * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index.
413  *              Note: There is no "implicit conversion" for locals.
414  *
415  ******************************************************************************/
416 
417 static ACPI_STATUS
418 AcpiDsMethodDataSetValue (
419     UINT8                   Type,
420     UINT32                  Index,
421     ACPI_OPERAND_OBJECT     *Object,
422     ACPI_WALK_STATE         *WalkState)
423 {
424     ACPI_STATUS             Status;
425     ACPI_NAMESPACE_NODE     *Node;
426 
427 
428     ACPI_FUNCTION_TRACE (DsMethodDataSetValue);
429 
430 
431     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
432         "NewObj %p Type %2.2X, Refs=%d [%s]\n", Object,
433         Type, Object->Common.ReferenceCount,
434         AcpiUtGetTypeName (Object->Common.Type)));
435 
436     /* Get the namespace node for the arg/local */
437 
438     Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
439     if (ACPI_FAILURE (Status))
440     {
441         return_ACPI_STATUS (Status);
442     }
443 
444     /*
445      * Increment ref count so object can't be deleted while installed.
446      * NOTE: We do not copy the object in order to preserve the call by
447      * reference semantics of ACPI Control Method invocation.
448      * (See ACPI Specification 2.0C)
449      */
450     AcpiUtAddReference (Object);
451 
452     /* Install the object */
453 
454     Node->Object = Object;
455     return_ACPI_STATUS (Status);
456 }
457 
458 
459 /*******************************************************************************
460  *
461  * FUNCTION:    AcpiDsMethodDataGetValue
462  *
463  * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
464  *                                    ACPI_REFCLASS_ARG
465  *              Index               - Which localVar or argument to get
466  *              WalkState           - Current walk state object
467  *              DestDesc            - Where Arg or Local value is returned
468  *
469  * RETURN:      Status
470  *
471  * DESCRIPTION: Retrieve value of selected Arg or Local for this method
472  *              Used only in AcpiExResolveToValue().
473  *
474  ******************************************************************************/
475 
476 ACPI_STATUS
477 AcpiDsMethodDataGetValue (
478     UINT8                   Type,
479     UINT32                  Index,
480     ACPI_WALK_STATE         *WalkState,
481     ACPI_OPERAND_OBJECT     **DestDesc)
482 {
483     ACPI_STATUS             Status;
484     ACPI_NAMESPACE_NODE     *Node;
485     ACPI_OPERAND_OBJECT     *Object;
486 
487 
488     ACPI_FUNCTION_TRACE (DsMethodDataGetValue);
489 
490 
491     /* Validate the object descriptor */
492 
493     if (!DestDesc)
494     {
495         ACPI_ERROR ((AE_INFO, "Null object descriptor pointer"));
496         return_ACPI_STATUS (AE_BAD_PARAMETER);
497     }
498 
499     /* Get the namespace node for the arg/local */
500 
501     Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
502     if (ACPI_FAILURE (Status))
503     {
504         return_ACPI_STATUS (Status);
505     }
506 
507     /* Get the object from the node */
508 
509     Object = Node->Object;
510 
511     /* Examine the returned object, it must be valid. */
512 
513     if (!Object)
514     {
515         /*
516          * Index points to uninitialized object.
517          * This means that either 1) The expected argument was
518          * not passed to the method, or 2) A local variable
519          * was referenced by the method (via the ASL)
520          * before it was initialized.  Either case is an error.
521          */
522 
523         /* If slack enabled, init the LocalX/ArgX to an Integer of value zero */
524 
525         if (AcpiGbl_EnableInterpreterSlack)
526         {
527             Object = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
528             if (!Object)
529             {
530                 return_ACPI_STATUS (AE_NO_MEMORY);
531             }
532 
533             Object->Integer.Value = 0;
534             Node->Object = Object;
535         }
536 
537         /* Otherwise, return the error */
538 
539         else switch (Type)
540         {
541         case ACPI_REFCLASS_ARG:
542 
543             ACPI_ERROR ((AE_INFO,
544                 "Uninitialized Arg[%d] at node %p",
545                 Index, Node));
546 
547             return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
548 
549         case ACPI_REFCLASS_LOCAL:
550 
551             ACPI_ERROR ((AE_INFO,
552                 "Uninitialized Local[%d] at node %p", Index, Node));
553 
554             return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL);
555 
556         default:
557 
558             ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: %X", Type));
559             return_ACPI_STATUS (AE_AML_INTERNAL);
560         }
561     }
562 
563     /*
564      * The Index points to an initialized and valid object.
565      * Return an additional reference to the object
566      */
567     *DestDesc = Object;
568     AcpiUtAddReference (Object);
569 
570     return_ACPI_STATUS (AE_OK);
571 }
572 
573 
574 /*******************************************************************************
575  *
576  * FUNCTION:    AcpiDsMethodDataDeleteValue
577  *
578  * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
579  *                                    ACPI_REFCLASS_ARG
580  *              Index               - Which localVar or argument to delete
581  *              WalkState           - Current walk state object
582  *
583  * RETURN:      None
584  *
585  * DESCRIPTION: Delete the entry at Opcode:Index.  Inserts
586  *              a null into the stack slot after the object is deleted.
587  *
588  ******************************************************************************/
589 
590 static void
591 AcpiDsMethodDataDeleteValue (
592     UINT8                   Type,
593     UINT32                  Index,
594     ACPI_WALK_STATE         *WalkState)
595 {
596     ACPI_STATUS             Status;
597     ACPI_NAMESPACE_NODE     *Node;
598     ACPI_OPERAND_OBJECT     *Object;
599 
600 
601     ACPI_FUNCTION_TRACE (DsMethodDataDeleteValue);
602 
603 
604     /* Get the namespace node for the arg/local */
605 
606     Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
607     if (ACPI_FAILURE (Status))
608     {
609         return_VOID;
610     }
611 
612     /* Get the associated object */
613 
614     Object = AcpiNsGetAttachedObject (Node);
615 
616     /*
617      * Undefine the Arg or Local by setting its descriptor
618      * pointer to NULL. Locals/Args can contain both
619      * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
620      */
621     Node->Object = NULL;
622 
623     if ((Object) &&
624         (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_OPERAND))
625     {
626         /*
627          * There is a valid object.
628          * Decrement the reference count by one to balance the
629          * increment when the object was stored.
630          */
631         AcpiUtRemoveReference (Object);
632     }
633 
634     return_VOID;
635 }
636 
637 
638 /*******************************************************************************
639  *
640  * FUNCTION:    AcpiDsStoreObjectToLocal
641  *
642  * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
643  *                                    ACPI_REFCLASS_ARG
644  *              Index               - Which Local or Arg to set
645  *              ObjDesc             - Value to be stored
646  *              WalkState           - Current walk state
647  *
648  * RETURN:      Status
649  *
650  * DESCRIPTION: Store a value in an Arg or Local.  The ObjDesc is installed
651  *              as the new value for the Arg or Local and the reference count
652  *              for ObjDesc is incremented.
653  *
654  ******************************************************************************/
655 
656 ACPI_STATUS
657 AcpiDsStoreObjectToLocal (
658     UINT8                   Type,
659     UINT32                  Index,
660     ACPI_OPERAND_OBJECT     *ObjDesc,
661     ACPI_WALK_STATE         *WalkState)
662 {
663     ACPI_STATUS             Status;
664     ACPI_NAMESPACE_NODE     *Node;
665     ACPI_OPERAND_OBJECT     *CurrentObjDesc;
666     ACPI_OPERAND_OBJECT     *NewObjDesc;
667 
668 
669     ACPI_FUNCTION_TRACE (DsStoreObjectToLocal);
670     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Type=%2.2X Index=%d Obj=%p\n",
671         Type, Index, ObjDesc));
672 
673     /* Parameter validation */
674 
675     if (!ObjDesc)
676     {
677         return_ACPI_STATUS (AE_BAD_PARAMETER);
678     }
679 
680     /* Get the namespace node for the arg/local */
681 
682     Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
683     if (ACPI_FAILURE (Status))
684     {
685         return_ACPI_STATUS (Status);
686     }
687 
688     CurrentObjDesc = AcpiNsGetAttachedObject (Node);
689     if (CurrentObjDesc == ObjDesc)
690     {
691         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n",
692             ObjDesc));
693         return_ACPI_STATUS (Status);
694     }
695 
696     /*
697      * If the reference count on the object is more than one, we must
698      * take a copy of the object before we store.  A reference count
699      * of exactly 1 means that the object was just created during the
700      * evaluation of an expression, and we can safely use it since it
701      * is not used anywhere else.
702      */
703     NewObjDesc = ObjDesc;
704     if (ObjDesc->Common.ReferenceCount > 1)
705     {
706         Status = AcpiUtCopyIobjectToIobject (ObjDesc, &NewObjDesc, WalkState);
707         if (ACPI_FAILURE (Status))
708         {
709             return_ACPI_STATUS (Status);
710         }
711     }
712 
713     /*
714      * If there is an object already in this slot, we either
715      * have to delete it, or if this is an argument and there
716      * is an object reference stored there, we have to do
717      * an indirect store!
718      */
719     if (CurrentObjDesc)
720     {
721         /*
722          * Check for an indirect store if an argument
723          * contains an object reference (stored as an Node).
724          * We don't allow this automatic dereferencing for
725          * locals, since a store to a local should overwrite
726          * anything there, including an object reference.
727          *
728          * If both Arg0 and Local0 contain RefOf (Local4):
729          *
730          * Store (1, Arg0)             - Causes indirect store to local4
731          * Store (1, Local0)           - Stores 1 in local0, overwriting
732          *                                  the reference to local4
733          * Store (1, DeRefof (Local0)) - Causes indirect store to local4
734          *
735          * Weird, but true.
736          */
737         if (Type == ACPI_REFCLASS_ARG)
738         {
739             /*
740              * If we have a valid reference object that came from RefOf(),
741              * do the indirect store
742              */
743             if ((ACPI_GET_DESCRIPTOR_TYPE (CurrentObjDesc) == ACPI_DESC_TYPE_OPERAND) &&
744                 (CurrentObjDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
745                 (CurrentObjDesc->Reference.Class == ACPI_REFCLASS_REFOF))
746             {
747                 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
748                         "Arg (%p) is an ObjRef(Node), storing in node %p\n",
749                         NewObjDesc, CurrentObjDesc));
750 
751                 /*
752                  * Store this object to the Node (perform the indirect store)
753                  * NOTE: No implicit conversion is performed, as per the ACPI
754                  * specification rules on storing to Locals/Args.
755                  */
756                 Status = AcpiExStoreObjectToNode (NewObjDesc,
757                             CurrentObjDesc->Reference.Object, WalkState,
758                             ACPI_NO_IMPLICIT_CONVERSION);
759 
760                 /* Remove local reference if we copied the object above */
761 
762                 if (NewObjDesc != ObjDesc)
763                 {
764                     AcpiUtRemoveReference (NewObjDesc);
765                 }
766                 return_ACPI_STATUS (Status);
767             }
768         }
769 
770         /* Delete the existing object before storing the new one */
771 
772         AcpiDsMethodDataDeleteValue (Type, Index, WalkState);
773     }
774 
775     /*
776      * Install the Obj descriptor (*NewObjDesc) into
777      * the descriptor for the Arg or Local.
778      * (increments the object reference count by one)
779      */
780     Status = AcpiDsMethodDataSetValue (Type, Index, NewObjDesc, WalkState);
781 
782     /* Remove local reference if we copied the object above */
783 
784     if (NewObjDesc != ObjDesc)
785     {
786         AcpiUtRemoveReference (NewObjDesc);
787     }
788 
789     return_ACPI_STATUS (Status);
790 }
791 
792 
793 #ifdef ACPI_OBSOLETE_FUNCTIONS
794 /*******************************************************************************
795  *
796  * FUNCTION:    AcpiDsMethodDataGetType
797  *
798  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
799  *              Index               - Which Local or Arg whose type to get
800  *              WalkState           - Current walk state object
801  *
802  * RETURN:      Data type of current value of the selected Arg or Local
803  *
804  * DESCRIPTION: Get the type of the object stored in the Local or Arg
805  *
806  ******************************************************************************/
807 
808 ACPI_OBJECT_TYPE
809 AcpiDsMethodDataGetType (
810     UINT16                  Opcode,
811     UINT32                  Index,
812     ACPI_WALK_STATE         *WalkState)
813 {
814     ACPI_STATUS             Status;
815     ACPI_NAMESPACE_NODE     *Node;
816     ACPI_OPERAND_OBJECT     *Object;
817 
818 
819     ACPI_FUNCTION_TRACE (DsMethodDataGetType);
820 
821 
822     /* Get the namespace node for the arg/local */
823 
824     Status = AcpiDsMethodDataGetNode (Opcode, Index, WalkState, &Node);
825     if (ACPI_FAILURE (Status))
826     {
827         return_VALUE ((ACPI_TYPE_NOT_FOUND));
828     }
829 
830     /* Get the object */
831 
832     Object = AcpiNsGetAttachedObject (Node);
833     if (!Object)
834     {
835         /* Uninitialized local/arg, return TYPE_ANY */
836 
837         return_VALUE (ACPI_TYPE_ANY);
838     }
839 
840     /* Get the object type */
841 
842     return_VALUE (Object->Type);
843 }
844 #endif
845 
846 
847