1
2/******************************************************************************
3 *
4 * Module Name: exstore - AML Interpreter object store support
5 *
6 *****************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999 - 2009, 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 __EXSTORE_C__
118
119#include "acpi.h"
120#include "accommon.h"
121#include "acdispat.h"
122#include "acinterp.h"
123#include "amlcode.h"
124#include "acnamesp.h"
125
126
127#define _COMPONENT          ACPI_EXECUTER
128        ACPI_MODULE_NAME    ("exstore")
129
130/* Local prototypes */
131
132static void
133AcpiExDoDebugObject (
134    ACPI_OPERAND_OBJECT     *SourceDesc,
135    UINT32                  Level,
136    UINT32                  Index);
137
138static ACPI_STATUS
139AcpiExStoreObjectToIndex (
140    ACPI_OPERAND_OBJECT     *ValDesc,
141    ACPI_OPERAND_OBJECT     *DestDesc,
142    ACPI_WALK_STATE         *WalkState);
143
144
145/*******************************************************************************
146 *
147 * FUNCTION:    AcpiExDoDebugObject
148 *
149 * PARAMETERS:  SourceDesc          - Value to be stored
150 *              Level               - Indentation level (used for packages)
151 *              Index               - Current package element, zero if not pkg
152 *
153 * RETURN:      None
154 *
155 * DESCRIPTION: Handles stores to the Debug Object.
156 *
157 ******************************************************************************/
158
159static void
160AcpiExDoDebugObject (
161    ACPI_OPERAND_OBJECT     *SourceDesc,
162    UINT32                  Level,
163    UINT32                  Index)
164{
165    UINT32                  i;
166
167
168    ACPI_FUNCTION_TRACE_PTR (ExDoDebugObject, SourceDesc);
169
170
171    /* Print line header as long as we are not in the middle of an object display */
172
173    if (!((Level > 0) && Index == 0))
174    {
175        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s",
176            Level, " "));
177    }
178
179    /* Display index for package output only */
180
181    if (Index > 0)
182    {
183       ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
184           "(%.2u) ", Index -1));
185    }
186
187    if (!SourceDesc)
188    {
189        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[Null Object]\n"));
190        return_VOID;
191    }
192
193    if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_OPERAND)
194    {
195        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s ",
196            AcpiUtGetObjectTypeName (SourceDesc)));
197
198        if (!AcpiUtValidInternalObject (SourceDesc))
199        {
200           ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
201               "%p, Invalid Internal Object!\n", SourceDesc));
202           return_VOID;
203        }
204    }
205    else if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED)
206    {
207        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s: %p\n",
208            AcpiUtGetTypeName (((ACPI_NAMESPACE_NODE *) SourceDesc)->Type),
209            SourceDesc));
210        return_VOID;
211    }
212    else
213    {
214        return_VOID;
215    }
216
217    /* SourceDesc is of type ACPI_DESC_TYPE_OPERAND */
218
219    switch (SourceDesc->Common.Type)
220    {
221    case ACPI_TYPE_INTEGER:
222
223        /* Output correct integer width */
224
225        if (AcpiGbl_IntegerByteWidth == 4)
226        {
227            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X\n",
228                (UINT32) SourceDesc->Integer.Value));
229        }
230        else
231        {
232            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X%8.8X\n",
233                ACPI_FORMAT_UINT64 (SourceDesc->Integer.Value)));
234        }
235        break;
236
237    case ACPI_TYPE_BUFFER:
238
239        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X]\n",
240            (UINT32) SourceDesc->Buffer.Length));
241        ACPI_DUMP_BUFFER (SourceDesc->Buffer.Pointer,
242            (SourceDesc->Buffer.Length < 256) ? SourceDesc->Buffer.Length : 256);
243        break;
244
245    case ACPI_TYPE_STRING:
246
247        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] \"%s\"\n",
248            SourceDesc->String.Length, SourceDesc->String.Pointer));
249        break;
250
251    case ACPI_TYPE_PACKAGE:
252
253        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[Contains 0x%.2X Elements]\n",
254            SourceDesc->Package.Count));
255
256        /* Output the entire contents of the package */
257
258        for (i = 0; i < SourceDesc->Package.Count; i++)
259        {
260            AcpiExDoDebugObject (SourceDesc->Package.Elements[i],
261                Level+4, i+1);
262        }
263        break;
264
265    case ACPI_TYPE_LOCAL_REFERENCE:
266
267        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[%s] ",
268            AcpiUtGetReferenceName (SourceDesc)));
269
270        /* Decode the reference */
271
272        switch (SourceDesc->Reference.Class)
273        {
274        case ACPI_REFCLASS_INDEX:
275
276            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%X\n",
277                SourceDesc->Reference.Value));
278            break;
279
280        case ACPI_REFCLASS_TABLE:
281
282            /* Case for DdbHandle */
283
284            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Table Index 0x%X\n",
285                SourceDesc->Reference.Value));
286            return;
287
288        default:
289            break;
290        }
291
292        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "  "));
293
294        /* Check for valid node first, then valid object */
295
296        if (SourceDesc->Reference.Node)
297        {
298            if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Node) !=
299                    ACPI_DESC_TYPE_NAMED)
300            {
301                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
302                    " %p - Not a valid namespace node\n",
303                    SourceDesc->Reference.Node));
304            }
305            else
306            {
307                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Node %p [%4.4s] ",
308                    SourceDesc->Reference.Node, (SourceDesc->Reference.Node)->Name.Ascii));
309
310                switch ((SourceDesc->Reference.Node)->Type)
311                {
312                /* These types have no attached object */
313
314                case ACPI_TYPE_DEVICE:
315                    AcpiOsPrintf ("Device\n");
316                    break;
317
318                case ACPI_TYPE_THERMAL:
319                    AcpiOsPrintf ("Thermal Zone\n");
320                    break;
321
322                default:
323                    AcpiExDoDebugObject ((SourceDesc->Reference.Node)->Object,
324                        Level+4, 0);
325                    break;
326                }
327            }
328        }
329        else if (SourceDesc->Reference.Object)
330        {
331            if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Object) ==
332                    ACPI_DESC_TYPE_NAMED)
333            {
334                AcpiExDoDebugObject (((ACPI_NAMESPACE_NODE *)
335                    SourceDesc->Reference.Object)->Object,
336                    Level+4, 0);
337            }
338            else
339            {
340                AcpiExDoDebugObject (SourceDesc->Reference.Object, Level+4, 0);
341            }
342        }
343        break;
344
345    default:
346
347        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%p\n",
348            SourceDesc));
349        break;
350    }
351
352    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n"));
353    return_VOID;
354}
355
356
357/*******************************************************************************
358 *
359 * FUNCTION:    AcpiExStore
360 *
361 * PARAMETERS:  *SourceDesc         - Value to be stored
362 *              *DestDesc           - Where to store it.  Must be an NS node
363 *                                    or an ACPI_OPERAND_OBJECT of type
364 *                                    Reference;
365 *              WalkState           - Current walk state
366 *
367 * RETURN:      Status
368 *
369 * DESCRIPTION: Store the value described by SourceDesc into the location
370 *              described by DestDesc.  Called by various interpreter
371 *              functions to store the result of an operation into
372 *              the destination operand -- not just simply the actual "Store"
373 *              ASL operator.
374 *
375 ******************************************************************************/
376
377ACPI_STATUS
378AcpiExStore (
379    ACPI_OPERAND_OBJECT     *SourceDesc,
380    ACPI_OPERAND_OBJECT     *DestDesc,
381    ACPI_WALK_STATE         *WalkState)
382{
383    ACPI_STATUS             Status = AE_OK;
384    ACPI_OPERAND_OBJECT     *RefDesc = DestDesc;
385
386
387    ACPI_FUNCTION_TRACE_PTR (ExStore, DestDesc);
388
389
390    /* Validate parameters */
391
392    if (!SourceDesc || !DestDesc)
393    {
394        ACPI_ERROR ((AE_INFO, "Null parameter"));
395        return_ACPI_STATUS (AE_AML_NO_OPERAND);
396    }
397
398    /* DestDesc can be either a namespace node or an ACPI object */
399
400    if (ACPI_GET_DESCRIPTOR_TYPE (DestDesc) == ACPI_DESC_TYPE_NAMED)
401    {
402        /*
403         * Dest is a namespace node,
404         * Storing an object into a Named node.
405         */
406        Status = AcpiExStoreObjectToNode (SourceDesc,
407                    (ACPI_NAMESPACE_NODE *) DestDesc, WalkState,
408                    ACPI_IMPLICIT_CONVERSION);
409
410        return_ACPI_STATUS (Status);
411    }
412
413    /* Destination object must be a Reference or a Constant object */
414
415    switch (DestDesc->Common.Type)
416    {
417    case ACPI_TYPE_LOCAL_REFERENCE:
418        break;
419
420    case ACPI_TYPE_INTEGER:
421
422        /* Allow stores to Constants -- a Noop as per ACPI spec */
423
424        if (DestDesc->Common.Flags & AOPOBJ_AML_CONSTANT)
425        {
426            return_ACPI_STATUS (AE_OK);
427        }
428
429        /*lint -fallthrough */
430
431    default:
432
433        /* Destination is not a Reference object */
434
435        ACPI_ERROR ((AE_INFO,
436            "Target is not a Reference or Constant object - %s [%p]",
437            AcpiUtGetObjectTypeName (DestDesc), DestDesc));
438
439        return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
440    }
441
442    /*
443     * Examine the Reference class. These cases are handled:
444     *
445     * 1) Store to Name (Change the object associated with a name)
446     * 2) Store to an indexed area of a Buffer or Package
447     * 3) Store to a Method Local or Arg
448     * 4) Store to the debug object
449     */
450    switch (RefDesc->Reference.Class)
451    {
452    case ACPI_REFCLASS_REFOF:
453
454        /* Storing an object into a Name "container" */
455
456        Status = AcpiExStoreObjectToNode (SourceDesc,
457                    RefDesc->Reference.Object,
458                    WalkState, ACPI_IMPLICIT_CONVERSION);
459        break;
460
461
462    case ACPI_REFCLASS_INDEX:
463
464        /* Storing to an Index (pointer into a packager or buffer) */
465
466        Status = AcpiExStoreObjectToIndex (SourceDesc, RefDesc, WalkState);
467        break;
468
469
470    case ACPI_REFCLASS_LOCAL:
471    case ACPI_REFCLASS_ARG:
472
473        /* Store to a method local/arg  */
474
475        Status = AcpiDsStoreObjectToLocal (RefDesc->Reference.Class,
476                    RefDesc->Reference.Value, SourceDesc, WalkState);
477        break;
478
479
480    case ACPI_REFCLASS_DEBUG:
481
482        /*
483         * Storing to the Debug object causes the value stored to be
484         * displayed and otherwise has no effect -- see ACPI Specification
485         */
486        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
487            "**** Write to Debug Object: Object %p %s ****:\n\n",
488            SourceDesc, AcpiUtGetObjectTypeName (SourceDesc)));
489
490        AcpiExDoDebugObject (SourceDesc, 0, 0);
491        break;
492
493
494    default:
495
496        ACPI_ERROR ((AE_INFO, "Unknown Reference Class %2.2X",
497            RefDesc->Reference.Class));
498        ACPI_DUMP_ENTRY (RefDesc, ACPI_LV_INFO);
499
500        Status = AE_AML_INTERNAL;
501        break;
502    }
503
504    return_ACPI_STATUS (Status);
505}
506
507
508/*******************************************************************************
509 *
510 * FUNCTION:    AcpiExStoreObjectToIndex
511 *
512 * PARAMETERS:  *SourceDesc             - Value to be stored
513 *              *DestDesc               - Named object to receive the value
514 *              WalkState               - Current walk state
515 *
516 * RETURN:      Status
517 *
518 * DESCRIPTION: Store the object to indexed Buffer or Package element
519 *
520 ******************************************************************************/
521
522static ACPI_STATUS
523AcpiExStoreObjectToIndex (
524    ACPI_OPERAND_OBJECT     *SourceDesc,
525    ACPI_OPERAND_OBJECT     *IndexDesc,
526    ACPI_WALK_STATE         *WalkState)
527{
528    ACPI_STATUS             Status = AE_OK;
529    ACPI_OPERAND_OBJECT     *ObjDesc;
530    ACPI_OPERAND_OBJECT     *NewDesc;
531    UINT8                   Value = 0;
532    UINT32                  i;
533
534
535    ACPI_FUNCTION_TRACE (ExStoreObjectToIndex);
536
537
538    /*
539     * Destination must be a reference pointer, and
540     * must point to either a buffer or a package
541     */
542    switch (IndexDesc->Reference.TargetType)
543    {
544    case ACPI_TYPE_PACKAGE:
545        /*
546         * Storing to a package element. Copy the object and replace
547         * any existing object with the new object. No implicit
548         * conversion is performed.
549         *
550         * The object at *(IndexDesc->Reference.Where) is the
551         * element within the package that is to be modified.
552         * The parent package object is at IndexDesc->Reference.Object
553         */
554        ObjDesc = *(IndexDesc->Reference.Where);
555
556        if (SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE &&
557            SourceDesc->Reference.Class == ACPI_REFCLASS_TABLE)
558        {
559            /* This is a DDBHandle, just add a reference to it */
560
561            AcpiUtAddReference (SourceDesc);
562            NewDesc = SourceDesc;
563        }
564        else
565        {
566            /* Normal object, copy it */
567
568            Status = AcpiUtCopyIobjectToIobject (SourceDesc, &NewDesc, WalkState);
569            if (ACPI_FAILURE (Status))
570            {
571                return_ACPI_STATUS (Status);
572            }
573        }
574
575        if (ObjDesc)
576        {
577            /* Decrement reference count by the ref count of the parent package */
578
579            for (i = 0;
580                 i < ((ACPI_OPERAND_OBJECT *)
581                        IndexDesc->Reference.Object)->Common.ReferenceCount;
582                 i++)
583            {
584                AcpiUtRemoveReference (ObjDesc);
585            }
586        }
587
588        *(IndexDesc->Reference.Where) = NewDesc;
589
590        /* Increment ref count by the ref count of the parent package-1 */
591
592        for (i = 1;
593             i < ((ACPI_OPERAND_OBJECT *)
594                    IndexDesc->Reference.Object)->Common.ReferenceCount;
595             i++)
596        {
597            AcpiUtAddReference (NewDesc);
598        }
599
600        break;
601
602
603    case ACPI_TYPE_BUFFER_FIELD:
604
605        /*
606         * Store into a Buffer or String (not actually a real BufferField)
607         * at a location defined by an Index.
608         *
609         * The first 8-bit element of the source object is written to the
610         * 8-bit Buffer location defined by the Index destination object,
611         * according to the ACPI 2.0 specification.
612         */
613
614        /*
615         * Make sure the target is a Buffer or String. An error should
616         * not happen here, since the ReferenceObject was constructed
617         * by the INDEX_OP code.
618         */
619        ObjDesc = IndexDesc->Reference.Object;
620        if ((ObjDesc->Common.Type != ACPI_TYPE_BUFFER) &&
621            (ObjDesc->Common.Type != ACPI_TYPE_STRING))
622        {
623            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
624        }
625
626        /*
627         * The assignment of the individual elements will be slightly
628         * different for each source type.
629         */
630        switch (SourceDesc->Common.Type)
631        {
632        case ACPI_TYPE_INTEGER:
633
634            /* Use the least-significant byte of the integer */
635
636            Value = (UINT8) (SourceDesc->Integer.Value);
637            break;
638
639        case ACPI_TYPE_BUFFER:
640        case ACPI_TYPE_STRING:
641
642            /* Note: Takes advantage of common string/buffer fields */
643
644            Value = SourceDesc->Buffer.Pointer[0];
645            break;
646
647        default:
648
649            /* All other types are invalid */
650
651            ACPI_ERROR ((AE_INFO,
652                "Source must be Integer/Buffer/String type, not %s",
653                AcpiUtGetObjectTypeName (SourceDesc)));
654            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
655        }
656
657        /* Store the source value into the target buffer byte */
658
659        ObjDesc->Buffer.Pointer[IndexDesc->Reference.Value] = Value;
660        break;
661
662
663    default:
664        ACPI_ERROR ((AE_INFO,
665            "Target is not a Package or BufferField"));
666        Status = AE_AML_OPERAND_TYPE;
667        break;
668    }
669
670    return_ACPI_STATUS (Status);
671}
672
673
674/*******************************************************************************
675 *
676 * FUNCTION:    AcpiExStoreObjectToNode
677 *
678 * PARAMETERS:  SourceDesc              - Value to be stored
679 *              Node                    - Named object to receive the value
680 *              WalkState               - Current walk state
681 *              ImplicitConversion      - Perform implicit conversion (yes/no)
682 *
683 * RETURN:      Status
684 *
685 * DESCRIPTION: Store the object to the named object.
686 *
687 *              The Assignment of an object to a named object is handled here
688 *              The value passed in will replace the current value (if any)
689 *              with the input value.
690 *
691 *              When storing into an object the data is converted to the
692 *              target object type then stored in the object.  This means
693 *              that the target object type (for an initialized target) will
694 *              not be changed by a store operation.
695 *
696 *              Assumes parameters are already validated.
697 *
698 ******************************************************************************/
699
700ACPI_STATUS
701AcpiExStoreObjectToNode (
702    ACPI_OPERAND_OBJECT     *SourceDesc,
703    ACPI_NAMESPACE_NODE     *Node,
704    ACPI_WALK_STATE         *WalkState,
705    UINT8                   ImplicitConversion)
706{
707    ACPI_STATUS             Status = AE_OK;
708    ACPI_OPERAND_OBJECT     *TargetDesc;
709    ACPI_OPERAND_OBJECT     *NewDesc;
710    ACPI_OBJECT_TYPE        TargetType;
711
712
713    ACPI_FUNCTION_TRACE_PTR (ExStoreObjectToNode, SourceDesc);
714
715
716    /* Get current type of the node, and object attached to Node */
717
718    TargetType = AcpiNsGetType (Node);
719    TargetDesc = AcpiNsGetAttachedObject (Node);
720
721    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n",
722        SourceDesc, AcpiUtGetObjectTypeName (SourceDesc),
723              Node, AcpiUtGetTypeName (TargetType)));
724
725    /*
726     * Resolve the source object to an actual value
727     * (If it is a reference object)
728     */
729    Status = AcpiExResolveObject (&SourceDesc, TargetType, WalkState);
730    if (ACPI_FAILURE (Status))
731    {
732        return_ACPI_STATUS (Status);
733    }
734
735    /* If no implicit conversion, drop into the default case below */
736
737    if ((!ImplicitConversion) ||
738          ((WalkState->Opcode == AML_COPY_OP) &&
739           (TargetType != ACPI_TYPE_LOCAL_REGION_FIELD) &&
740           (TargetType != ACPI_TYPE_LOCAL_BANK_FIELD) &&
741           (TargetType != ACPI_TYPE_LOCAL_INDEX_FIELD)))
742    {
743        /*
744         * Force execution of default (no implicit conversion). Note:
745         * CopyObject does not perform an implicit conversion, as per the ACPI
746         * spec -- except in case of region/bank/index fields -- because these
747         * objects must retain their original type permanently.
748         */
749        TargetType = ACPI_TYPE_ANY;
750    }
751
752    /* Do the actual store operation */
753
754    switch (TargetType)
755    {
756    case ACPI_TYPE_BUFFER_FIELD:
757    case ACPI_TYPE_LOCAL_REGION_FIELD:
758    case ACPI_TYPE_LOCAL_BANK_FIELD:
759    case ACPI_TYPE_LOCAL_INDEX_FIELD:
760
761        /* For fields, copy the source data to the target field. */
762
763        Status = AcpiExWriteDataToField (SourceDesc, TargetDesc,
764                    &WalkState->ResultObj);
765        break;
766
767
768    case ACPI_TYPE_INTEGER:
769    case ACPI_TYPE_STRING:
770    case ACPI_TYPE_BUFFER:
771
772        /*
773         * These target types are all of type Integer/String/Buffer, and
774         * therefore support implicit conversion before the store.
775         *
776         * Copy and/or convert the source object to a new target object
777         */
778        Status = AcpiExStoreObjectToObject (SourceDesc, TargetDesc,
779                    &NewDesc, WalkState);
780        if (ACPI_FAILURE (Status))
781        {
782            return_ACPI_STATUS (Status);
783        }
784
785        if (NewDesc != TargetDesc)
786        {
787            /*
788             * Store the new NewDesc as the new value of the Name, and set
789             * the Name's type to that of the value being stored in it.
790             * SourceDesc reference count is incremented by AttachObject.
791             *
792             * Note: This may change the type of the node if an explicit store
793             * has been performed such that the node/object type has been
794             * changed.
795             */
796            Status = AcpiNsAttachObject (Node, NewDesc, NewDesc->Common.Type);
797
798            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
799                "Store %s into %s via Convert/Attach\n",
800                AcpiUtGetObjectTypeName (SourceDesc),
801                AcpiUtGetObjectTypeName (NewDesc)));
802        }
803        break;
804
805
806    default:
807
808        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
809            "Storing %s (%p) directly into node (%p) with no implicit conversion\n",
810            AcpiUtGetObjectTypeName (SourceDesc), SourceDesc, Node));
811
812        /* No conversions for all other types.  Just attach the source object */
813
814        Status = AcpiNsAttachObject (Node, SourceDesc,
815                    SourceDesc->Common.Type);
816        break;
817    }
818
819    return_ACPI_STATUS (Status);
820}
821
822
823