dsmthdat.c revision 67754
1/*******************************************************************************
2 *
3 * Module Name: dsmthdat - control method arguments and local variables
4 *              $Revision: 34 $
5 *
6 ******************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999, Intel Corp.  All rights
13 * 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 "acparser.h"
121#include "acdispat.h"
122#include "acinterp.h"
123#include "amlcode.h"
124#include "acnamesp.h"
125
126
127#define _COMPONENT          DISPATCHER
128        MODULE_NAME         ("dsmthdat")
129
130
131/*******************************************************************************
132 *
133 * FUNCTION:    AcpiDsMethodDataInit
134 *
135 * PARAMETERS:  *ObjDesc
136 *
137 * RETURN:      Status
138 *
139 * DESCRIPTION: Initialize the data structures that hold the method's arguments
140 *              and locals.  The data struct is an array of NTEs for each.
141 *              This allows RefOf and DeRefOf to work properly for these
142 *              special data types.
143 *
144 ******************************************************************************/
145
146ACPI_STATUS
147AcpiDsMethodDataInit (
148    ACPI_WALK_STATE         *WalkState)
149{
150    UINT32                  i;
151
152
153    FUNCTION_TRACE ("DsMethodDataInit");
154
155    /*
156     * WalkState fields are initialized to zero by the
157     * AcpiCmCallocate().
158     *
159     * An Node is assigned to each argument and local so
160     * that RefOf() can return a pointer to the Node.
161     */
162
163    /* Init the method arguments */
164
165    for (i = 0; i < MTH_NUM_ARGS; i++)
166    {
167        MOVE_UNALIGNED32_TO_32 (&WalkState->Arguments[i].Name,
168                                NAMEOF_ARG_NTE);
169
170        WalkState->Arguments[i].Name       |= (i << 24);
171        WalkState->Arguments[i].DataType    = ACPI_DESC_TYPE_NAMED;
172        WalkState->Arguments[i].Type        = INTERNAL_TYPE_METHOD_ARGUMENT;
173    }
174
175    /* Init the method locals */
176
177    for (i = 0; i < MTH_NUM_LOCALS; i++)
178    {
179        MOVE_UNALIGNED32_TO_32 (&WalkState->LocalVariables[i].Name,
180                                NAMEOF_LOCAL_NTE);
181
182        WalkState->LocalVariables[i].Name    |= (i << 24);
183        WalkState->LocalVariables[i].DataType = ACPI_DESC_TYPE_NAMED;
184        WalkState->LocalVariables[i].Type     = INTERNAL_TYPE_METHOD_LOCAL_VAR;
185    }
186
187    return_ACPI_STATUS (AE_OK);
188}
189
190
191/*******************************************************************************
192 *
193 * FUNCTION:    AcpiDsMethodDataDeleteAll
194 *
195 * PARAMETERS:  None
196 *
197 * RETURN:      Status
198 *
199 * DESCRIPTION: Delete method locals and arguments.  Arguments are only
200 *              deleted if this method was called from another method.
201 *
202 ******************************************************************************/
203
204ACPI_STATUS
205AcpiDsMethodDataDeleteAll (
206    ACPI_WALK_STATE         *WalkState)
207{
208    UINT32                  Index;
209    ACPI_OPERAND_OBJECT     *Object;
210
211
212    FUNCTION_TRACE ("DsMethodDataDeleteAll");
213
214
215    /* Delete the locals */
216
217    DEBUG_PRINT (ACPI_INFO,
218        ("MethodDeleteAll: Deleting local variables in %p\n", WalkState));
219
220    for (Index = 0; Index < MTH_NUM_LOCALS; Index++)
221    {
222        Object = WalkState->LocalVariables[Index].Object;
223        if (Object)
224        {
225            DEBUG_PRINT (TRACE_EXEC,
226                ("MethodDeleteAll: Deleting Local%d=%p\n", Index, Object));
227
228            /* Remove first */
229
230            WalkState->LocalVariables[Index].Object = NULL;
231
232            /* Was given a ref when stored */
233
234            AcpiCmRemoveReference (Object);
235       }
236    }
237
238
239    /* Delete the arguments */
240
241    DEBUG_PRINT (ACPI_INFO,
242        ("MethodDeleteAll: Deleting arguments in %p\n", WalkState));
243
244    for (Index = 0; Index < MTH_NUM_ARGS; Index++)
245    {
246        Object = WalkState->Arguments[Index].Object;
247        if (Object)
248        {
249            DEBUG_PRINT (TRACE_EXEC,
250                ("MethodDeleteAll: Deleting Arg%d=%p\n", Index, Object));
251
252            /* Remove first */
253
254            WalkState->Arguments[Index].Object = NULL;
255
256             /* Was given a ref when stored */
257
258            AcpiCmRemoveReference (Object);
259        }
260    }
261
262    return_ACPI_STATUS (AE_OK);
263}
264
265
266/*******************************************************************************
267 *
268 * FUNCTION:    AcpiDsMethodDataInitArgs
269 *
270 * PARAMETERS:  None
271 *
272 * RETURN:      Status
273 *
274 * DESCRIPTION: Initialize arguments for a method
275 *
276 ******************************************************************************/
277
278ACPI_STATUS
279AcpiDsMethodDataInitArgs (
280    ACPI_OPERAND_OBJECT     **Params,
281    UINT32                  MaxParamCount,
282    ACPI_WALK_STATE         *WalkState)
283{
284    ACPI_STATUS             Status;
285    UINT32                  Mindex;
286    UINT32                  Pindex;
287
288
289    FUNCTION_TRACE_PTR ("DsMethodDataInitArgs", Params);
290
291
292    if (!Params)
293    {
294        DEBUG_PRINT (TRACE_EXEC,
295            ("DsMethodDataInitArgs: No param list passed to method\n"));
296        return_ACPI_STATUS (AE_OK);
297    }
298
299    /* Copy passed parameters into the new method stack frame  */
300
301    for (Pindex = Mindex = 0;
302        (Mindex < MTH_NUM_ARGS) && (Pindex < MaxParamCount);
303        Mindex++)
304    {
305        if (Params[Pindex])
306        {
307            /*
308             * A valid parameter.
309             * Set the current method argument to the
310             * Params[Pindex++] argument object descriptor
311             */
312            Status = AcpiDsMethodDataSetValue (MTH_TYPE_ARG, Mindex,
313                                                Params[Pindex], WalkState);
314            if (ACPI_FAILURE (Status))
315            {
316                break;
317            }
318
319            Pindex++;
320        }
321
322        else
323        {
324            break;
325        }
326    }
327
328    DEBUG_PRINT (TRACE_EXEC,
329        ("DsMethodDataInitArgs: %d args passed to method\n", Pindex));
330    return_ACPI_STATUS (AE_OK);
331}
332
333
334/*******************************************************************************
335 *
336 * FUNCTION:    AcpiDsMethodDataGetEntry
337 *
338 * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
339 *              Index               - Which localVar or argument to get
340 *              Entry               - Pointer to where a pointer to the stack
341 *                                    entry is returned.
342 *
343 * RETURN:      Status
344 *
345 * DESCRIPTION: Get the address of the stack entry given by Type:Index
346 *
347 ******************************************************************************/
348
349ACPI_STATUS
350AcpiDsMethodDataGetEntry (
351    UINT32                  Type,
352    UINT32                  Index,
353    ACPI_WALK_STATE         *WalkState,
354    ACPI_OPERAND_OBJECT     ***Entry)
355{
356
357    FUNCTION_TRACE_U32 ("DsMethodDataGetEntry", Index);
358
359
360    /*
361     * Get the requested object.
362     * The stack "Type" is either a LocalVariable or an Argument
363     */
364
365    switch (Type)
366    {
367
368    case MTH_TYPE_LOCAL:
369
370        if (Index > MTH_MAX_LOCAL)
371        {
372            DEBUG_PRINT (ACPI_ERROR,
373                ("DsMethodDataGetEntry: LocalVar index %d is invalid (max %d)\n",
374                Index, MTH_MAX_LOCAL));
375            return_ACPI_STATUS (AE_BAD_PARAMETER);
376        }
377
378        *Entry =
379            (ACPI_OPERAND_OBJECT  **) &WalkState->LocalVariables[Index].Object;
380        break;
381
382
383    case MTH_TYPE_ARG:
384
385        if (Index > MTH_MAX_ARG)
386        {
387            DEBUG_PRINT (ACPI_ERROR,
388                ("DsMethodDataGetEntry: Argument index %d is invalid (max %d)\n",
389                Index, MTH_MAX_ARG));
390            return_ACPI_STATUS (AE_BAD_PARAMETER);
391        }
392
393        *Entry =
394            (ACPI_OPERAND_OBJECT  **) &WalkState->Arguments[Index].Object;
395        break;
396
397
398    default:
399        DEBUG_PRINT (ACPI_ERROR,
400            ("DsMethodDataGetEntry: Stack type %d is invalid\n",
401            Type));
402        return_ACPI_STATUS (AE_BAD_PARAMETER);
403    }
404
405
406    return_ACPI_STATUS (AE_OK);
407}
408
409
410/*******************************************************************************
411 *
412 * FUNCTION:    AcpiDsMethodDataSetEntry
413 *
414 * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
415 *              Index               - Which localVar or argument to get
416 *              Object              - Object to be inserted into the stack entry
417 *
418 * RETURN:      Status
419 *
420 * DESCRIPTION: Insert an object onto the method stack at entry Type:Index.
421 *
422 ******************************************************************************/
423
424ACPI_STATUS
425AcpiDsMethodDataSetEntry (
426    UINT32                  Type,
427    UINT32                  Index,
428    ACPI_OPERAND_OBJECT     *Object,
429    ACPI_WALK_STATE         *WalkState)
430{
431    ACPI_STATUS             Status;
432    ACPI_OPERAND_OBJECT     **Entry;
433
434
435    FUNCTION_TRACE ("DsMethodDataSetEntry");
436
437    /* Get a pointer to the stack entry to set */
438
439    Status = AcpiDsMethodDataGetEntry (Type, Index, WalkState, &Entry);
440    if (ACPI_FAILURE (Status))
441    {
442        return_ACPI_STATUS (Status);
443    }
444
445    /* Increment ref count so object can't be deleted while installed */
446
447    AcpiCmAddReference (Object);
448
449    /* Install the object into the stack entry */
450
451    *Entry = Object;
452
453    return_ACPI_STATUS (AE_OK);
454}
455
456
457/*******************************************************************************
458 *
459 * FUNCTION:    AcpiDsMethodDataGetType
460 *
461 * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
462 *              Index               - Which localVar or argument whose type
463 *                                      to get
464 *
465 * RETURN:      Data type of selected Arg or Local
466 *              Used only in ExecMonadic2()/TypeOp.
467 *
468 ******************************************************************************/
469
470OBJECT_TYPE_INTERNAL
471AcpiDsMethodDataGetType (
472    UINT32                  Type,
473    UINT32                  Index,
474    ACPI_WALK_STATE         *WalkState)
475{
476    ACPI_STATUS             Status;
477    ACPI_OPERAND_OBJECT     **Entry;
478    ACPI_OPERAND_OBJECT     *Object;
479
480
481    FUNCTION_TRACE ("DsMethodDataGetType");
482
483
484    /* Get a pointer to the requested stack entry */
485
486    Status = AcpiDsMethodDataGetEntry (Type, Index, WalkState, &Entry);
487    if (ACPI_FAILURE (Status))
488    {
489        return_VALUE ((ACPI_TYPE_NOT_FOUND));
490    }
491
492    /* Get the object from the method stack */
493
494    Object = *Entry;
495
496    /* Get the object type */
497
498    if (!Object)
499    {
500        /* Any == 0 => "uninitialized" -- see spec 15.2.3.5.2.28 */
501        return_VALUE (ACPI_TYPE_ANY);
502    }
503
504    return_VALUE (Object->Common.Type);
505}
506
507
508/*******************************************************************************
509 *
510 * FUNCTION:    AcpiDsMethodDataGetNte
511 *
512 * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
513 *              Index               - Which localVar or argument whose type
514 *                                      to get
515 *
516 * RETURN:      Get the Node associated with a local or arg.
517 *
518 ******************************************************************************/
519
520ACPI_NAMESPACE_NODE *
521AcpiDsMethodDataGetNte (
522    UINT32                  Type,
523    UINT32                  Index,
524    ACPI_WALK_STATE         *WalkState)
525{
526    ACPI_NAMESPACE_NODE     *Node = NULL;
527
528
529    FUNCTION_TRACE ("DsMethodDataGetNte");
530
531
532    switch (Type)
533    {
534
535    case MTH_TYPE_LOCAL:
536
537        if (Index > MTH_MAX_LOCAL)
538        {
539            DEBUG_PRINT (ACPI_ERROR,
540                ("DsMethodDataGetEntry: LocalVar index %d is invalid (max %d)\n",
541                Index, MTH_MAX_LOCAL));
542            return_PTR (Node);
543        }
544
545        Node =  &WalkState->LocalVariables[Index];
546        break;
547
548
549    case MTH_TYPE_ARG:
550
551        if (Index > MTH_MAX_ARG)
552        {
553            DEBUG_PRINT (ACPI_ERROR,
554                ("DsMethodDataGetEntry: Argument index %d is invalid (max %d)\n",
555                Index, MTH_MAX_ARG));
556            return_PTR (Node);
557        }
558
559        Node = &WalkState->Arguments[Index];
560        break;
561
562
563    default:
564        DEBUG_PRINT (ACPI_ERROR,
565            ("DsMethodDataGetEntry: Stack type %d is invalid\n",
566            Type));
567        break;
568    }
569
570
571    return_PTR (Node);
572}
573
574
575/*******************************************************************************
576 *
577 * FUNCTION:    AcpiDsMethodDataGetValue
578 *
579 * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
580 *              Index               - Which localVar or argument to get
581 *              *DestDesc            - Descriptor into which selected Arg
582 *                                    or Local value should be copied
583 *
584 * RETURN:      Status
585 *
586 * DESCRIPTION: Retrieve value of selected Arg or Local from the method frame
587 *              at the current top of the method stack.
588 *              Used only in AcpiAmlResolveToValue().
589 *
590 ******************************************************************************/
591
592ACPI_STATUS
593AcpiDsMethodDataGetValue (
594    UINT32                  Type,
595    UINT32                  Index,
596    ACPI_WALK_STATE         *WalkState,
597    ACPI_OPERAND_OBJECT     **DestDesc)
598{
599    ACPI_STATUS             Status;
600    ACPI_OPERAND_OBJECT     **Entry;
601    ACPI_OPERAND_OBJECT     *Object;
602
603
604    FUNCTION_TRACE ("DsMethodDataGetValue");
605
606
607    /* Validate the object descriptor */
608
609    if (!DestDesc)
610    {
611        DEBUG_PRINT (ACPI_ERROR,
612            ("DsMethodDataGetValue: NULL object descriptor pointer\n"));
613        return_ACPI_STATUS (AE_BAD_PARAMETER);
614    }
615
616
617    /* Get a pointer to the requested method stack entry */
618
619    Status = AcpiDsMethodDataGetEntry (Type, Index, WalkState, &Entry);
620    if (ACPI_FAILURE (Status))
621    {
622        return_ACPI_STATUS (Status);
623    }
624
625    /* Get the object from the method stack */
626
627    Object = *Entry;
628
629
630    /* Examine the returned object, it must be valid. */
631
632    if (!Object)
633    {
634        /*
635         * Index points to uninitialized object stack value.
636         * This means that either 1) The expected argument was
637         * not passed to the method, or 2) A local variable
638         * was referenced by the method (via the ASL)
639         * before it was initialized.  Either case is an error.
640         */
641
642        switch (Type)
643        {
644        case MTH_TYPE_ARG:
645            DEBUG_PRINT (ACPI_ERROR,
646                ("DsMethodDataGetValue: Uninitialized Arg[%d] at entry %X\n",
647                Index, Entry));
648            return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
649            break;
650
651        case MTH_TYPE_LOCAL:
652            DEBUG_PRINT (ACPI_ERROR,
653                ("DsMethodDataGetValue: Uninitialized Local[%d] at entry %X\n",
654                Index, Entry));
655            return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL);
656            break;
657        }
658    }
659
660
661    /*
662     * Index points to initialized and valid object stack value.
663     * Return an additional reference to the object
664     */
665
666    *DestDesc = Object;
667    AcpiCmAddReference (Object);
668
669    return_ACPI_STATUS (AE_OK);
670}
671
672
673/*******************************************************************************
674 *
675 * FUNCTION:    AcpiDsMethodDataDeleteValue
676 *
677 * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
678 *              Index               - Which localVar or argument to delete
679 *
680 * RETURN:      Status
681 *
682 * DESCRIPTION: Delete the entry at Type:Index on the method stack.  Inserts
683 *              a null into the stack slot after the object is deleted.
684 *
685 ******************************************************************************/
686
687ACPI_STATUS
688AcpiDsMethodDataDeleteValue (
689    UINT32                  Type,
690    UINT32                  Index,
691    ACPI_WALK_STATE         *WalkState)
692{
693    ACPI_STATUS             Status;
694    ACPI_OPERAND_OBJECT     **Entry;
695    ACPI_OPERAND_OBJECT     *Object;
696
697
698    FUNCTION_TRACE ("DsMethodDataDeleteValue");
699
700
701    /* Get a pointer to the requested entry */
702
703    Status = AcpiDsMethodDataGetEntry (Type, Index, WalkState, &Entry);
704    if (ACPI_FAILURE (Status))
705    {
706        return_ACPI_STATUS (Status);
707    }
708
709    /* Get the current entry in this slot k */
710
711    Object = *Entry;
712
713    /*
714     * Undefine the Arg or Local by setting its descriptor
715     * pointer to NULL. Locals/Args can contain both
716     * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
717     */
718    *Entry = NULL;
719
720
721    if ((Object) &&
722        (VALID_DESCRIPTOR_TYPE (Object, ACPI_DESC_TYPE_INTERNAL)))
723    {
724        /*
725         * There is a valid object in this slot
726         * Decrement the reference count by one to balance the
727         * increment when the object was stored in the slot.
728         */
729
730        AcpiCmRemoveReference (Object);
731    }
732
733
734    return_ACPI_STATUS (AE_OK);
735}
736
737
738/*******************************************************************************
739 *
740 * FUNCTION:    AcpiDsMethodDataSetValue
741 *
742 * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
743 *              Index               - Which localVar or argument to set
744 *              *SrcDesc            - Value to be stored
745 *              *DestDesc           - Descriptor into which *SrcDesc
746 *                                    can be copied, or NULL if one must
747 *                                    be allocated for the purpose.  If
748 *                                    provided, this descriptor will be
749 *                                    used for the new value.
750 *
751 * RETURN:      Status
752 *
753 * DESCRIPTION: Store a value in an Arg or Local.  The SrcDesc is installed
754 *              as the new value for the Arg or Local and the reference count
755 *              is incremented.
756 *
757 ******************************************************************************/
758
759ACPI_STATUS
760AcpiDsMethodDataSetValue (
761    UINT32                  Type,
762    UINT32                  Index,
763    ACPI_OPERAND_OBJECT     *SrcDesc,
764    ACPI_WALK_STATE         *WalkState)
765{
766    ACPI_STATUS             Status;
767    ACPI_OPERAND_OBJECT     **Entry;
768
769
770    FUNCTION_TRACE ("DsMethodDataSetValue");
771    DEBUG_PRINT (TRACE_EXEC,
772        ("DsMethodDataSetValue: Type=%d Idx=%d Obj=%p\n",
773        Type, Index, SrcDesc));
774
775
776    /* Parameter validation */
777
778    if (!SrcDesc)
779    {
780        return_ACPI_STATUS (AE_BAD_PARAMETER);
781    }
782
783
784    /* Get a pointer to the requested method stack entry */
785
786    Status = AcpiDsMethodDataGetEntry (Type, Index, WalkState, &Entry);
787    if (ACPI_FAILURE (Status))
788    {
789        goto Cleanup;
790    }
791
792    if (*Entry == SrcDesc)
793    {
794        DEBUG_PRINT (TRACE_EXEC,
795            ("DsMethodDataSetValue: Obj=%p already installed!\n",
796            SrcDesc));
797        goto Cleanup;
798    }
799
800
801    /*
802     * If there is an object already in this slot, we either
803     * have to delete it, or if this is an argument and there
804     * is an object reference stored there, we have to do
805     * an indirect store!
806     */
807
808    if (*Entry)
809    {
810        /*
811         * Check for an indirect store if an argument
812         * contains an object reference (stored as an Node).
813         * We don't allow this automatic dereferencing for
814         * locals, since a store to a local should overwrite
815         * anything there, including an object reference.
816         *
817         * If both Arg0 and Local0 contain RefOf (Local4):
818         *
819         * Store (1, Arg0)             - Causes indirect store to local4
820         * Store (1, Local0)           - Stores 1 in local0, overwriting
821         *                                  the reference to local4
822         * Store (1, DeRefof (Local0)) - Causes indirect store to local4
823         *
824         * Weird, but true.
825         */
826
827        if ((Type == MTH_TYPE_ARG) &&
828            (VALID_DESCRIPTOR_TYPE (*Entry, ACPI_DESC_TYPE_NAMED)))
829        {
830            DEBUG_PRINT (TRACE_EXEC,
831                ("DsMethodDataSetValue: Arg (%p) is an ObjRef(Node), storing in %p\n",
832                SrcDesc, *Entry));
833
834            /* Detach an existing object from the Node */
835
836            AcpiNsDetachObject ((ACPI_NAMESPACE_NODE *) *Entry);
837
838            /*
839             * Store this object into the Node
840             * (do the indirect store)
841             */
842
843            Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) *Entry, SrcDesc,
844                                            SrcDesc->Common.Type);
845            return_ACPI_STATUS (Status);
846        }
847
848
849        /*
850         * Otherwise, just delete the existing object
851         * before storing the new one
852         */
853
854        AcpiDsMethodDataDeleteValue (Type, Index, WalkState);
855    }
856
857
858    /*
859     * Install the ObjStack descriptor (*SrcDesc) into
860     * the descriptor for the Arg or Local.
861     * Install the new object in the stack entry
862     * (increments the object reference count by one)
863     */
864
865    Status = AcpiDsMethodDataSetEntry (Type, Index, SrcDesc, WalkState);
866    if (ACPI_FAILURE (Status))
867    {
868        goto Cleanup;
869    }
870
871    /* Normal exit */
872
873    return_ACPI_STATUS (AE_OK);
874
875
876    /* Error exit */
877
878Cleanup:
879
880    return_ACPI_STATUS (Status);
881}
882
883