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