Subversion Repositories Kolibri OS

Rev

Rev 1498 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1498 serge 1
/*******************************************************************************
2
 *
3
 * Module Name: dsmthdat - control method arguments and local variables
4
 *
5
 ******************************************************************************/
6
 
7
/******************************************************************************
8
 *
9
 * 1. Copyright Notice
10
 *
2216 Serge 11
 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
1498 serge 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 = ANOBJ_METHOD_ARG;
192
    }
193
 
194
    /* Init the method locals */
195
 
196
    for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++)
197
    {
198
        ACPI_MOVE_32_TO_32 (&WalkState->LocalVariables[i].Name, NAMEOF_LOCAL_NTE);
199
 
200
        WalkState->LocalVariables[i].Name.Integer |= (i << 24);
201
        WalkState->LocalVariables[i].DescriptorType = ACPI_DESC_TYPE_NAMED;
202
        WalkState->LocalVariables[i].Type = ACPI_TYPE_ANY;
203
        WalkState->LocalVariables[i].Flags = ANOBJ_METHOD_LOCAL;
204
    }
205
 
206
    return_VOID;
207
}
208
 
209
 
210
/*******************************************************************************
211
 *
212
 * FUNCTION:    AcpiDsMethodDataDeleteAll
213
 *
214
 * PARAMETERS:  WalkState           - Current walk state object
215
 *
216
 * RETURN:      None
217
 *
218
 * DESCRIPTION: Delete method locals and arguments.  Arguments are only
219
 *              deleted if this method was called from another method.
220
 *
221
 ******************************************************************************/
222
 
223
void
224
AcpiDsMethodDataDeleteAll (
225
    ACPI_WALK_STATE         *WalkState)
226
{
227
    UINT32                  Index;
228
 
229
 
230
    ACPI_FUNCTION_TRACE (DsMethodDataDeleteAll);
231
 
232
 
233
    /* Detach the locals */
234
 
235
    for (Index = 0; Index < ACPI_METHOD_NUM_LOCALS; Index++)
236
    {
237
        if (WalkState->LocalVariables[Index].Object)
238
        {
239
            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%u=%p\n",
240
                    Index, WalkState->LocalVariables[Index].Object));
241
 
242
            /* Detach object (if present) and remove a reference */
243
 
244
            AcpiNsDetachObject (&WalkState->LocalVariables[Index]);
245
        }
246
    }
247
 
248
    /* Detach the arguments */
249
 
250
    for (Index = 0; Index < ACPI_METHOD_NUM_ARGS; Index++)
251
    {
252
        if (WalkState->Arguments[Index].Object)
253
        {
254
            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%u=%p\n",
255
                    Index, WalkState->Arguments[Index].Object));
256
 
257
            /* Detach object (if present) and remove a reference */
258
 
259
            AcpiNsDetachObject (&WalkState->Arguments[Index]);
260
        }
261
    }
262
 
263
    return_VOID;
264
}
265
 
266
 
267
/*******************************************************************************
268
 *
269
 * FUNCTION:    AcpiDsMethodDataInitArgs
270
 *
271
 * PARAMETERS:  *Params         - Pointer to a parameter list for the method
272
 *              MaxParamCount   - The arg count for this method
273
 *              WalkState       - Current walk state object
274
 *
275
 * RETURN:      Status
276
 *
277
 * DESCRIPTION: Initialize arguments for a method.  The parameter list is a list
278
 *              of ACPI operand objects, either null terminated or whose length
279
 *              is defined by MaxParamCount.
280
 *
281
 ******************************************************************************/
282
 
283
ACPI_STATUS
284
AcpiDsMethodDataInitArgs (
285
    ACPI_OPERAND_OBJECT     **Params,
286
    UINT32                  MaxParamCount,
287
    ACPI_WALK_STATE         *WalkState)
288
{
289
    ACPI_STATUS             Status;
290
    UINT32                  Index = 0;
291
 
292
 
293
    ACPI_FUNCTION_TRACE_PTR (DsMethodDataInitArgs, Params);
294
 
295
 
296
    if (!Params)
297
    {
298
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n"));
299
        return_ACPI_STATUS (AE_OK);
300
    }
301
 
302
    /* Copy passed parameters into the new method stack frame */
303
 
304
    while ((Index < ACPI_METHOD_NUM_ARGS) &&
305
           (Index < MaxParamCount)        &&
306
            Params[Index])
307
    {
308
        /*
309
         * A valid parameter.
310
         * Store the argument in the method/walk descriptor.
311
         * Do not copy the arg in order to implement call by reference
312
         */
313
        Status = AcpiDsMethodDataSetValue (ACPI_REFCLASS_ARG, Index,
314
                    Params[Index], WalkState);
315
        if (ACPI_FAILURE (Status))
316
        {
317
            return_ACPI_STATUS (Status);
318
        }
319
 
320
        Index++;
321
    }
322
 
323
    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%u args passed to method\n", Index));
324
    return_ACPI_STATUS (AE_OK);
325
}
326
 
327
 
328
/*******************************************************************************
329
 *
330
 * FUNCTION:    AcpiDsMethodDataGetNode
331
 *
332
 * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
333
 *                                    ACPI_REFCLASS_ARG
334
 *              Index               - Which Local or Arg whose type to get
335
 *              WalkState           - Current walk state object
336
 *              Node                - Where the node is returned.
337
 *
338
 * RETURN:      Status and node
339
 *
340
 * DESCRIPTION: Get the Node associated with a local or arg.
341
 *
342
 ******************************************************************************/
343
 
344
ACPI_STATUS
345
AcpiDsMethodDataGetNode (
346
    UINT8                   Type,
347
    UINT32                  Index,
348
    ACPI_WALK_STATE         *WalkState,
349
    ACPI_NAMESPACE_NODE     **Node)
350
{
351
    ACPI_FUNCTION_TRACE (DsMethodDataGetNode);
352
 
353
 
354
    /*
355
     * Method Locals and Arguments are supported
356
     */
357
    switch (Type)
358
    {
359
    case ACPI_REFCLASS_LOCAL:
360
 
361
        if (Index > ACPI_METHOD_MAX_LOCAL)
362
        {
363
            ACPI_ERROR ((AE_INFO,
364
                "Local index %u is invalid (max %u)",
365
                Index, ACPI_METHOD_MAX_LOCAL));
366
            return_ACPI_STATUS (AE_AML_INVALID_INDEX);
367
        }
368
 
369
        /* Return a pointer to the pseudo-node */
370
 
371
        *Node = &WalkState->LocalVariables[Index];
372
        break;
373
 
374
    case ACPI_REFCLASS_ARG:
375
 
376
        if (Index > ACPI_METHOD_MAX_ARG)
377
        {
378
            ACPI_ERROR ((AE_INFO,
379
                "Arg index %u is invalid (max %u)",
380
                Index, ACPI_METHOD_MAX_ARG));
381
            return_ACPI_STATUS (AE_AML_INVALID_INDEX);
382
        }
383
 
384
        /* Return a pointer to the pseudo-node */
385
 
386
        *Node = &WalkState->Arguments[Index];
387
        break;
388
 
389
    default:
390
        ACPI_ERROR ((AE_INFO, "Type %u is invalid", Type));
391
        return_ACPI_STATUS (AE_TYPE);
392
    }
393
 
394
    return_ACPI_STATUS (AE_OK);
395
}
396
 
397
 
398
/*******************************************************************************
399
 *
400
 * FUNCTION:    AcpiDsMethodDataSetValue
401
 *
402
 * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
403
 *                                    ACPI_REFCLASS_ARG
404
 *              Index               - Which Local or Arg to get
405
 *              Object              - Object to be inserted into the stack entry
406
 *              WalkState           - Current walk state object
407
 *
408
 * RETURN:      Status
409
 *
410
 * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index.
411
 *              Note: There is no "implicit conversion" for locals.
412
 *
413
 ******************************************************************************/
414
 
415
static ACPI_STATUS
416
AcpiDsMethodDataSetValue (
417
    UINT8                   Type,
418
    UINT32                  Index,
419
    ACPI_OPERAND_OBJECT     *Object,
420
    ACPI_WALK_STATE         *WalkState)
421
{
422
    ACPI_STATUS             Status;
423
    ACPI_NAMESPACE_NODE     *Node;
424
 
425
 
426
    ACPI_FUNCTION_TRACE (DsMethodDataSetValue);
427
 
428
 
429
    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
430
        "NewObj %p Type %2.2X, Refs=%u [%s]\n", Object,
431
        Type, Object->Common.ReferenceCount,
432
        AcpiUtGetTypeName (Object->Common.Type)));
433
 
434
    /* Get the namespace node for the arg/local */
435
 
436
    Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
437
    if (ACPI_FAILURE (Status))
438
    {
439
        return_ACPI_STATUS (Status);
440
    }
441
 
442
    /*
443
     * Increment ref count so object can't be deleted while installed.
444
     * NOTE: We do not copy the object in order to preserve the call by
445
     * reference semantics of ACPI Control Method invocation.
446
     * (See ACPI Specification 2.0C)
447
     */
448
    AcpiUtAddReference (Object);
449
 
450
    /* Install the object */
451
 
452
    Node->Object = Object;
453
    return_ACPI_STATUS (Status);
454
}
455
 
456
 
457
/*******************************************************************************
458
 *
459
 * FUNCTION:    AcpiDsMethodDataGetValue
460
 *
461
 * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
462
 *                                    ACPI_REFCLASS_ARG
463
 *              Index               - Which localVar or argument to get
464
 *              WalkState           - Current walk state object
465
 *              DestDesc            - Where Arg or Local value is returned
466
 *
467
 * RETURN:      Status
468
 *
469
 * DESCRIPTION: Retrieve value of selected Arg or Local for this method
470
 *              Used only in AcpiExResolveToValue().
471
 *
472
 ******************************************************************************/
473
 
474
ACPI_STATUS
475
AcpiDsMethodDataGetValue (
476
    UINT8                   Type,
477
    UINT32                  Index,
478
    ACPI_WALK_STATE         *WalkState,
479
    ACPI_OPERAND_OBJECT     **DestDesc)
480
{
481
    ACPI_STATUS             Status;
482
    ACPI_NAMESPACE_NODE     *Node;
483
    ACPI_OPERAND_OBJECT     *Object;
484
 
485
 
486
    ACPI_FUNCTION_TRACE (DsMethodDataGetValue);
487
 
488
 
489
    /* Validate the object descriptor */
490
 
491
    if (!DestDesc)
492
    {
493
        ACPI_ERROR ((AE_INFO, "Null object descriptor pointer"));
494
        return_ACPI_STATUS (AE_BAD_PARAMETER);
495
    }
496
 
497
    /* Get the namespace node for the arg/local */
498
 
499
    Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
500
    if (ACPI_FAILURE (Status))
501
    {
502
        return_ACPI_STATUS (Status);
503
    }
504
 
505
    /* Get the object from the node */
506
 
507
    Object = Node->Object;
508
 
509
    /* Examine the returned object, it must be valid. */
510
 
511
    if (!Object)
512
    {
513
        /*
514
         * Index points to uninitialized object.
515
         * This means that either 1) The expected argument was
516
         * not passed to the method, or 2) A local variable
517
         * was referenced by the method (via the ASL)
518
         * before it was initialized.  Either case is an error.
519
         */
520
 
521
        /* If slack enabled, init the LocalX/ArgX to an Integer of value zero */
522
 
523
        if (AcpiGbl_EnableInterpreterSlack)
524
        {
525
            Object = AcpiUtCreateIntegerObject ((UINT64) 0);
526
            if (!Object)
527
            {
528
                return_ACPI_STATUS (AE_NO_MEMORY);
529
            }
530
 
531
            Node->Object = Object;
532
        }
533
 
534
        /* Otherwise, return the error */
535
 
536
        else switch (Type)
537
        {
538
        case ACPI_REFCLASS_ARG:
539
 
540
            ACPI_ERROR ((AE_INFO,
541
                "Uninitialized Arg[%u] at node %p",
542
                Index, Node));
543
 
544
            return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
545
 
546
        case ACPI_REFCLASS_LOCAL:
547
 
548
            /*
549
             * No error message for this case, will be trapped again later to
550
             * detect and ignore cases of Store(LocalX,LocalX)
551
             */
552
            return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL);
553
 
554
        default:
555
 
556
            ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: 0x%X", Type));
557
            return_ACPI_STATUS (AE_AML_INTERNAL);
558
        }
559
    }
560
 
561
    /*
562
     * The Index points to an initialized and valid object.
563
     * Return an additional reference to the object
564
     */
565
    *DestDesc = Object;
566
    AcpiUtAddReference (Object);
567
 
568
    return_ACPI_STATUS (AE_OK);
569
}
570
 
571
 
572
/*******************************************************************************
573
 *
574
 * FUNCTION:    AcpiDsMethodDataDeleteValue
575
 *
576
 * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
577
 *                                    ACPI_REFCLASS_ARG
578
 *              Index               - Which localVar or argument to delete
579
 *              WalkState           - Current walk state object
580
 *
581
 * RETURN:      None
582
 *
583
 * DESCRIPTION: Delete the entry at Opcode:Index.  Inserts
584
 *              a null into the stack slot after the object is deleted.
585
 *
586
 ******************************************************************************/
587
 
588
static void
589
AcpiDsMethodDataDeleteValue (
590
    UINT8                   Type,
591
    UINT32                  Index,
592
    ACPI_WALK_STATE         *WalkState)
593
{
594
    ACPI_STATUS             Status;
595
    ACPI_NAMESPACE_NODE     *Node;
596
    ACPI_OPERAND_OBJECT     *Object;
597
 
598
 
599
    ACPI_FUNCTION_TRACE (DsMethodDataDeleteValue);
600
 
601
 
602
    /* Get the namespace node for the arg/local */
603
 
604
    Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
605
    if (ACPI_FAILURE (Status))
606
    {
607
        return_VOID;
608
    }
609
 
610
    /* Get the associated object */
611
 
612
    Object = AcpiNsGetAttachedObject (Node);
613
 
614
    /*
615
     * Undefine the Arg or Local by setting its descriptor
616
     * pointer to NULL. Locals/Args can contain both
617
     * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
618
     */
619
    Node->Object = NULL;
620
 
621
    if ((Object) &&
622
        (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_OPERAND))
623
    {
624
        /*
625
         * There is a valid object.
626
         * Decrement the reference count by one to balance the
627
         * increment when the object was stored.
628
         */
629
        AcpiUtRemoveReference (Object);
630
    }
631
 
632
    return_VOID;
633
}
634
 
635
 
636
/*******************************************************************************
637
 *
638
 * FUNCTION:    AcpiDsStoreObjectToLocal
639
 *
640
 * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
641
 *                                    ACPI_REFCLASS_ARG
642
 *              Index               - Which Local or Arg to set
643
 *              ObjDesc             - Value to be stored
644
 *              WalkState           - Current walk state
645
 *
646
 * RETURN:      Status
647
 *
648
 * DESCRIPTION: Store a value in an Arg or Local.  The ObjDesc is installed
649
 *              as the new value for the Arg or Local and the reference count
650
 *              for ObjDesc is incremented.
651
 *
652
 ******************************************************************************/
653
 
654
ACPI_STATUS
655
AcpiDsStoreObjectToLocal (
656
    UINT8                   Type,
657
    UINT32                  Index,
658
    ACPI_OPERAND_OBJECT     *ObjDesc,
659
    ACPI_WALK_STATE         *WalkState)
660
{
661
    ACPI_STATUS             Status;
662
    ACPI_NAMESPACE_NODE     *Node;
663
    ACPI_OPERAND_OBJECT     *CurrentObjDesc;
664
    ACPI_OPERAND_OBJECT     *NewObjDesc;
665
 
666
 
667
    ACPI_FUNCTION_TRACE (DsStoreObjectToLocal);
668
    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Type=%2.2X Index=%u Obj=%p\n",
669
        Type, Index, ObjDesc));
670
 
671
    /* Parameter validation */
672
 
673
    if (!ObjDesc)
674
    {
675
        return_ACPI_STATUS (AE_BAD_PARAMETER);
676
    }
677
 
678
    /* Get the namespace node for the arg/local */
679
 
680
    Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
681
    if (ACPI_FAILURE (Status))
682
    {
683
        return_ACPI_STATUS (Status);
684
    }
685
 
686
    CurrentObjDesc = AcpiNsGetAttachedObject (Node);
687
    if (CurrentObjDesc == ObjDesc)
688
    {
689
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n",
690
            ObjDesc));
691
        return_ACPI_STATUS (Status);
692
    }
693
 
694
    /*
695
     * If the reference count on the object is more than one, we must
696
     * take a copy of the object before we store.  A reference count
697
     * of exactly 1 means that the object was just created during the
698
     * evaluation of an expression, and we can safely use it since it
699
     * is not used anywhere else.
700
     */
701
    NewObjDesc = ObjDesc;
702
    if (ObjDesc->Common.ReferenceCount > 1)
703
    {
704
        Status = AcpiUtCopyIobjectToIobject (ObjDesc, &NewObjDesc, WalkState);
705
        if (ACPI_FAILURE (Status))
706
        {
707
            return_ACPI_STATUS (Status);
708
        }
709
    }
710
 
711
    /*
712
     * If there is an object already in this slot, we either
713
     * have to delete it, or if this is an argument and there
714
     * is an object reference stored there, we have to do
715
     * an indirect store!
716
     */
717
    if (CurrentObjDesc)
718
    {
719
        /*
720
         * Check for an indirect store if an argument
721
         * contains an object reference (stored as an Node).
722
         * We don't allow this automatic dereferencing for
723
         * locals, since a store to a local should overwrite
724
         * anything there, including an object reference.
725
         *
726
         * If both Arg0 and Local0 contain RefOf (Local4):
727
         *
728
         * Store (1, Arg0)             - Causes indirect store to local4
729
         * Store (1, Local0)           - Stores 1 in local0, overwriting
730
         *                                  the reference to local4
731
         * Store (1, DeRefof (Local0)) - Causes indirect store to local4
732
         *
733
         * Weird, but true.
734
         */
735
        if (Type == ACPI_REFCLASS_ARG)
736
        {
737
            /*
738
             * If we have a valid reference object that came from RefOf(),
739
             * do the indirect store
740
             */
741
            if ((ACPI_GET_DESCRIPTOR_TYPE (CurrentObjDesc) == ACPI_DESC_TYPE_OPERAND) &&
742
                (CurrentObjDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
743
                (CurrentObjDesc->Reference.Class == ACPI_REFCLASS_REFOF))
744
            {
745
                ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
746
                        "Arg (%p) is an ObjRef(Node), storing in node %p\n",
747
                        NewObjDesc, CurrentObjDesc));
748
 
749
                /*
750
                 * Store this object to the Node (perform the indirect store)
751
                 * NOTE: No implicit conversion is performed, as per the ACPI
752
                 * specification rules on storing to Locals/Args.
753
                 */
754
                Status = AcpiExStoreObjectToNode (NewObjDesc,
755
                            CurrentObjDesc->Reference.Object, WalkState,
756
                            ACPI_NO_IMPLICIT_CONVERSION);
757
 
758
                /* Remove local reference if we copied the object above */
759
 
760
                if (NewObjDesc != ObjDesc)
761
                {
762
                    AcpiUtRemoveReference (NewObjDesc);
763
                }
764
                return_ACPI_STATUS (Status);
765
            }
766
        }
767
 
768
        /* Delete the existing object before storing the new one */
769
 
770
        AcpiDsMethodDataDeleteValue (Type, Index, WalkState);
771
    }
772
 
773
    /*
774
     * Install the Obj descriptor (*NewObjDesc) into
775
     * the descriptor for the Arg or Local.
776
     * (increments the object reference count by one)
777
     */
778
    Status = AcpiDsMethodDataSetValue (Type, Index, NewObjDesc, WalkState);
779
 
780
    /* Remove local reference if we copied the object above */
781
 
782
    if (NewObjDesc != ObjDesc)
783
    {
784
        AcpiUtRemoveReference (NewObjDesc);
785
    }
786
 
787
    return_ACPI_STATUS (Status);
788
}
789
 
790
 
791
#ifdef ACPI_OBSOLETE_FUNCTIONS
792
/*******************************************************************************
793
 *
794
 * FUNCTION:    AcpiDsMethodDataGetType
795
 *
796
 * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
797
 *              Index               - Which Local or Arg whose type to get
798
 *              WalkState           - Current walk state object
799
 *
800
 * RETURN:      Data type of current value of the selected Arg or Local
801
 *
802
 * DESCRIPTION: Get the type of the object stored in the Local or Arg
803
 *
804
 ******************************************************************************/
805
 
806
ACPI_OBJECT_TYPE
807
AcpiDsMethodDataGetType (
808
    UINT16                  Opcode,
809
    UINT32                  Index,
810
    ACPI_WALK_STATE         *WalkState)
811
{
812
    ACPI_STATUS             Status;
813
    ACPI_NAMESPACE_NODE     *Node;
814
    ACPI_OPERAND_OBJECT     *Object;
815
 
816
 
817
    ACPI_FUNCTION_TRACE (DsMethodDataGetType);
818
 
819
 
820
    /* Get the namespace node for the arg/local */
821
 
822
    Status = AcpiDsMethodDataGetNode (Opcode, Index, WalkState, &Node);
823
    if (ACPI_FAILURE (Status))
824
    {
825
        return_VALUE ((ACPI_TYPE_NOT_FOUND));
826
    }
827
 
828
    /* Get the object */
829
 
830
    Object = AcpiNsGetAttachedObject (Node);
831
    if (!Object)
832
    {
833
        /* Uninitialized local/arg, return TYPE_ANY */
834
 
835
        return_VALUE (ACPI_TYPE_ANY);
836
    }
837
 
838
    /* Get the object type */
839
 
840
    return_VALUE (Object->Type);
841
}
842
#endif
843