dsobject.c revision 306536
1/******************************************************************************
2 *
3 * Module Name: dsobject - Dispatcher object management routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2016, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions, and the following disclaimer,
16 *    without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 *    substantially similar to the "NO WARRANTY" disclaimer below
19 *    ("Disclaimer") and any redistribution must be conditioned upon
20 *    including a substantially similar Disclaimer requirement for further
21 *    binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 *    of any contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <contrib/dev/acpica/include/acpi.h>
45#include <contrib/dev/acpica/include/accommon.h>
46#include <contrib/dev/acpica/include/acparser.h>
47#include <contrib/dev/acpica/include/amlcode.h>
48#include <contrib/dev/acpica/include/acdispat.h>
49#include <contrib/dev/acpica/include/acnamesp.h>
50#include <contrib/dev/acpica/include/acinterp.h>
51
52#define _COMPONENT          ACPI_DISPATCHER
53        ACPI_MODULE_NAME    ("dsobject")
54
55/* Local prototypes */
56
57static ACPI_STATUS
58AcpiDsBuildInternalObject (
59    ACPI_WALK_STATE         *WalkState,
60    ACPI_PARSE_OBJECT       *Op,
61    ACPI_OPERAND_OBJECT     **ObjDescPtr);
62
63
64#ifndef ACPI_NO_METHOD_EXECUTION
65/*******************************************************************************
66 *
67 * FUNCTION:    AcpiDsBuildInternalObject
68 *
69 * PARAMETERS:  WalkState       - Current walk state
70 *              Op              - Parser object to be translated
71 *              ObjDescPtr      - Where the ACPI internal object is returned
72 *
73 * RETURN:      Status
74 *
75 * DESCRIPTION: Translate a parser Op object to the equivalent namespace object
76 *              Simple objects are any objects other than a package object!
77 *
78 ******************************************************************************/
79
80static ACPI_STATUS
81AcpiDsBuildInternalObject (
82    ACPI_WALK_STATE         *WalkState,
83    ACPI_PARSE_OBJECT       *Op,
84    ACPI_OPERAND_OBJECT     **ObjDescPtr)
85{
86    ACPI_OPERAND_OBJECT     *ObjDesc;
87    ACPI_STATUS             Status;
88    ACPI_OBJECT_TYPE        Type;
89
90
91    ACPI_FUNCTION_TRACE (DsBuildInternalObject);
92
93
94    *ObjDescPtr = NULL;
95    if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
96    {
97        /*
98         * This is a named object reference. If this name was
99         * previously looked up in the namespace, it was stored in this op.
100         * Otherwise, go ahead and look it up now
101         */
102        if (!Op->Common.Node)
103        {
104            Status = AcpiNsLookup (WalkState->ScopeInfo,
105                Op->Common.Value.String,
106                ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
107                ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL,
108                ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &(Op->Common.Node)));
109            if (ACPI_FAILURE (Status))
110            {
111                /* Check if we are resolving a named reference within a package */
112
113                if ((Status == AE_NOT_FOUND) && (AcpiGbl_EnableInterpreterSlack) &&
114
115                    ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
116                     (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)))
117                {
118                    /*
119                     * We didn't find the target and we are populating elements
120                     * of a package - ignore if slack enabled. Some ASL code
121                     * contains dangling invalid references in packages and
122                     * expects that no exception will be issued. Leave the
123                     * element as a null element. It cannot be used, but it
124                     * can be overwritten by subsequent ASL code - this is
125                     * typically the case.
126                     */
127                    ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
128                        "Ignoring unresolved reference in package [%4.4s]\n",
129                        WalkState->ScopeInfo->Scope.Node->Name.Ascii));
130
131                    return_ACPI_STATUS (AE_OK);
132                }
133                else
134                {
135                    ACPI_ERROR_NAMESPACE (Op->Common.Value.String, Status);
136                }
137
138                return_ACPI_STATUS (Status);
139            }
140        }
141
142        /* Special object resolution for elements of a package */
143
144        if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
145            (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
146        {
147            /*
148             * Attempt to resolve the node to a value before we insert it into
149             * the package. If this is a reference to a common data type,
150             * resolve it immediately. According to the ACPI spec, package
151             * elements can only be "data objects" or method references.
152             * Attempt to resolve to an Integer, Buffer, String or Package.
153             * If cannot, return the named reference (for things like Devices,
154             * Methods, etc.) Buffer Fields and Fields will resolve to simple
155             * objects (int/buf/str/pkg).
156             *
157             * NOTE: References to things like Devices, Methods, Mutexes, etc.
158             * will remain as named references. This behavior is not described
159             * in the ACPI spec, but it appears to be an oversight.
160             */
161            ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Op->Common.Node);
162
163            Status = AcpiExResolveNodeToValue (
164                ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc),
165                WalkState);
166            if (ACPI_FAILURE (Status))
167            {
168                return_ACPI_STATUS (Status);
169            }
170
171            /*
172             * Special handling for Alias objects. We need to setup the type
173             * and the Op->Common.Node to point to the Alias target. Note,
174             * Alias has at most one level of indirection internally.
175             */
176            Type = Op->Common.Node->Type;
177            if (Type == ACPI_TYPE_LOCAL_ALIAS)
178            {
179                Type = ObjDesc->Common.Type;
180                Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
181                    Op->Common.Node->Object);
182            }
183
184            switch (Type)
185            {
186            /*
187             * For these types, we need the actual node, not the subobject.
188             * However, the subobject did not get an extra reference count above.
189             *
190             * TBD: should ExResolveNodeToValue be changed to fix this?
191             */
192            case ACPI_TYPE_DEVICE:
193            case ACPI_TYPE_THERMAL:
194
195                AcpiUtAddReference (Op->Common.Node->Object);
196
197                /*lint -fallthrough */
198            /*
199             * For these types, we need the actual node, not the subobject.
200             * The subobject got an extra reference count in ExResolveNodeToValue.
201             */
202            case ACPI_TYPE_MUTEX:
203            case ACPI_TYPE_METHOD:
204            case ACPI_TYPE_POWER:
205            case ACPI_TYPE_PROCESSOR:
206            case ACPI_TYPE_EVENT:
207            case ACPI_TYPE_REGION:
208
209                /* We will create a reference object for these types below */
210                break;
211
212            default:
213                /*
214                 * All other types - the node was resolved to an actual
215                 * object, we are done.
216                 */
217                goto Exit;
218            }
219        }
220    }
221
222    /* Create and init a new internal ACPI object */
223
224    ObjDesc = AcpiUtCreateInternalObject (
225        (AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode))->ObjectType);
226    if (!ObjDesc)
227    {
228        return_ACPI_STATUS (AE_NO_MEMORY);
229    }
230
231    Status = AcpiDsInitObjectFromOp (
232        WalkState, Op, Op->Common.AmlOpcode, &ObjDesc);
233    if (ACPI_FAILURE (Status))
234    {
235        AcpiUtRemoveReference (ObjDesc);
236        return_ACPI_STATUS (Status);
237    }
238
239Exit:
240    *ObjDescPtr = ObjDesc;
241    return_ACPI_STATUS (Status);
242}
243
244
245/*******************************************************************************
246 *
247 * FUNCTION:    AcpiDsBuildInternalBufferObj
248 *
249 * PARAMETERS:  WalkState       - Current walk state
250 *              Op              - Parser object to be translated
251 *              BufferLength    - Length of the buffer
252 *              ObjDescPtr      - Where the ACPI internal object is returned
253 *
254 * RETURN:      Status
255 *
256 * DESCRIPTION: Translate a parser Op package object to the equivalent
257 *              namespace object
258 *
259 ******************************************************************************/
260
261ACPI_STATUS
262AcpiDsBuildInternalBufferObj (
263    ACPI_WALK_STATE         *WalkState,
264    ACPI_PARSE_OBJECT       *Op,
265    UINT32                  BufferLength,
266    ACPI_OPERAND_OBJECT     **ObjDescPtr)
267{
268    ACPI_PARSE_OBJECT       *Arg;
269    ACPI_OPERAND_OBJECT     *ObjDesc;
270    ACPI_PARSE_OBJECT       *ByteList;
271    UINT32                  ByteListLength = 0;
272
273
274    ACPI_FUNCTION_TRACE (DsBuildInternalBufferObj);
275
276
277    /*
278     * If we are evaluating a Named buffer object "Name (xxxx, Buffer)".
279     * The buffer object already exists (from the NS node), otherwise it must
280     * be created.
281     */
282    ObjDesc = *ObjDescPtr;
283    if (!ObjDesc)
284    {
285        /* Create a new buffer object */
286
287        ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER);
288        *ObjDescPtr = ObjDesc;
289        if (!ObjDesc)
290        {
291            return_ACPI_STATUS (AE_NO_MEMORY);
292        }
293    }
294
295    /*
296     * Second arg is the buffer data (optional) ByteList can be either
297     * individual bytes or a string initializer. In either case, a
298     * ByteList appears in the AML.
299     */
300    Arg = Op->Common.Value.Arg;         /* skip first arg */
301
302    ByteList = Arg->Named.Next;
303    if (ByteList)
304    {
305        if (ByteList->Common.AmlOpcode != AML_INT_BYTELIST_OP)
306        {
307            ACPI_ERROR ((AE_INFO,
308                "Expecting bytelist, found AML opcode 0x%X in op %p",
309                ByteList->Common.AmlOpcode, ByteList));
310
311            AcpiUtRemoveReference (ObjDesc);
312            return (AE_TYPE);
313        }
314
315        ByteListLength = (UINT32) ByteList->Common.Value.Integer;
316    }
317
318    /*
319     * The buffer length (number of bytes) will be the larger of:
320     * 1) The specified buffer length and
321     * 2) The length of the initializer byte list
322     */
323    ObjDesc->Buffer.Length = BufferLength;
324    if (ByteListLength > BufferLength)
325    {
326        ObjDesc->Buffer.Length = ByteListLength;
327    }
328
329    /* Allocate the buffer */
330
331    if (ObjDesc->Buffer.Length == 0)
332    {
333        ObjDesc->Buffer.Pointer = NULL;
334        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
335            "Buffer defined with zero length in AML, creating\n"));
336    }
337    else
338    {
339        ObjDesc->Buffer.Pointer =
340            ACPI_ALLOCATE_ZEROED (ObjDesc->Buffer.Length);
341        if (!ObjDesc->Buffer.Pointer)
342        {
343            AcpiUtDeleteObjectDesc (ObjDesc);
344            return_ACPI_STATUS (AE_NO_MEMORY);
345        }
346
347        /* Initialize buffer from the ByteList (if present) */
348
349        if (ByteList)
350        {
351            memcpy (ObjDesc->Buffer.Pointer, ByteList->Named.Data,
352                ByteListLength);
353        }
354    }
355
356    ObjDesc->Buffer.Flags |= AOPOBJ_DATA_VALID;
357    Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc);
358    return_ACPI_STATUS (AE_OK);
359}
360
361
362/*******************************************************************************
363 *
364 * FUNCTION:    AcpiDsBuildInternalPackageObj
365 *
366 * PARAMETERS:  WalkState       - Current walk state
367 *              Op              - Parser object to be translated
368 *              ElementCount    - Number of elements in the package - this is
369 *                                the NumElements argument to Package()
370 *              ObjDescPtr      - Where the ACPI internal object is returned
371 *
372 * RETURN:      Status
373 *
374 * DESCRIPTION: Translate a parser Op package object to the equivalent
375 *              namespace object
376 *
377 * NOTE: The number of elements in the package will be always be the NumElements
378 * count, regardless of the number of elements in the package list. If
379 * NumElements is smaller, only that many package list elements are used.
380 * if NumElements is larger, the Package object is padded out with
381 * objects of type Uninitialized (as per ACPI spec.)
382 *
383 * Even though the ASL compilers do not allow NumElements to be smaller
384 * than the Package list length (for the fixed length package opcode), some
385 * BIOS code modifies the AML on the fly to adjust the NumElements, and
386 * this code compensates for that. This also provides compatibility with
387 * other AML interpreters.
388 *
389 ******************************************************************************/
390
391ACPI_STATUS
392AcpiDsBuildInternalPackageObj (
393    ACPI_WALK_STATE         *WalkState,
394    ACPI_PARSE_OBJECT       *Op,
395    UINT32                  ElementCount,
396    ACPI_OPERAND_OBJECT     **ObjDescPtr)
397{
398    ACPI_PARSE_OBJECT       *Arg;
399    ACPI_PARSE_OBJECT       *Parent;
400    ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
401    ACPI_STATUS             Status = AE_OK;
402    UINT32                  i;
403    UINT16                  Index;
404    UINT16                  ReferenceCount;
405
406
407    ACPI_FUNCTION_TRACE (DsBuildInternalPackageObj);
408
409
410    /* Find the parent of a possibly nested package */
411
412    Parent = Op->Common.Parent;
413    while ((Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
414           (Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
415    {
416        Parent = Parent->Common.Parent;
417    }
418
419    /*
420     * If we are evaluating a Named package object "Name (xxxx, Package)",
421     * the package object already exists, otherwise it must be created.
422     */
423    ObjDesc = *ObjDescPtr;
424    if (!ObjDesc)
425    {
426        ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE);
427        *ObjDescPtr = ObjDesc;
428        if (!ObjDesc)
429        {
430            return_ACPI_STATUS (AE_NO_MEMORY);
431        }
432
433        ObjDesc->Package.Node = Parent->Common.Node;
434    }
435
436    /*
437     * Allocate the element array (array of pointers to the individual
438     * objects) based on the NumElements parameter. Add an extra pointer slot
439     * so that the list is always null terminated.
440     */
441    ObjDesc->Package.Elements = ACPI_ALLOCATE_ZEROED (
442        ((ACPI_SIZE) ElementCount + 1) * sizeof (void *));
443
444    if (!ObjDesc->Package.Elements)
445    {
446        AcpiUtDeleteObjectDesc (ObjDesc);
447        return_ACPI_STATUS (AE_NO_MEMORY);
448    }
449
450    ObjDesc->Package.Count = ElementCount;
451
452    /*
453     * Initialize the elements of the package, up to the NumElements count.
454     * Package is automatically padded with uninitialized (NULL) elements
455     * if NumElements is greater than the package list length. Likewise,
456     * Package is truncated if NumElements is less than the list length.
457     */
458    Arg = Op->Common.Value.Arg;
459    Arg = Arg->Common.Next;
460    for (i = 0; Arg && (i < ElementCount); i++)
461    {
462        if (Arg->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP)
463        {
464            if (Arg->Common.Node->Type == ACPI_TYPE_METHOD)
465            {
466                /*
467                 * A method reference "looks" to the parser to be a method
468                 * invocation, so we special case it here
469                 */
470                Arg->Common.AmlOpcode = AML_INT_NAMEPATH_OP;
471                Status = AcpiDsBuildInternalObject (
472                    WalkState, Arg, &ObjDesc->Package.Elements[i]);
473            }
474            else
475            {
476                /* This package element is already built, just get it */
477
478                ObjDesc->Package.Elements[i] =
479                    ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node);
480            }
481        }
482        else
483        {
484            Status = AcpiDsBuildInternalObject (
485                WalkState, Arg, &ObjDesc->Package.Elements[i]);
486        }
487
488        if (*ObjDescPtr)
489        {
490            /* Existing package, get existing reference count */
491
492            ReferenceCount = (*ObjDescPtr)->Common.ReferenceCount;
493            if (ReferenceCount > 1)
494            {
495                /* Make new element ref count match original ref count */
496
497                for (Index = 0; Index < (ReferenceCount - 1); Index++)
498                {
499                    AcpiUtAddReference ((ObjDesc->Package.Elements[i]));
500                }
501            }
502        }
503
504        Arg = Arg->Common.Next;
505    }
506
507    /* Check for match between NumElements and actual length of PackageList */
508
509    if (Arg)
510    {
511        /*
512         * NumElements was exhausted, but there are remaining elements in the
513         * PackageList. Truncate the package to NumElements.
514         *
515         * Note: technically, this is an error, from ACPI spec: "It is an error
516         * for NumElements to be less than the number of elements in the
517         * PackageList". However, we just print a message and
518         * no exception is returned. This provides Windows compatibility. Some
519         * BIOSs will alter the NumElements on the fly, creating this type
520         * of ill-formed package object.
521         */
522        while (Arg)
523        {
524            /*
525             * We must delete any package elements that were created earlier
526             * and are not going to be used because of the package truncation.
527             */
528            if (Arg->Common.Node)
529            {
530                AcpiUtRemoveReference (
531                    ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node));
532                Arg->Common.Node = NULL;
533            }
534
535            /* Find out how many elements there really are */
536
537            i++;
538            Arg = Arg->Common.Next;
539        }
540
541        ACPI_INFO ((
542            "Actual Package length (%u) is larger than "
543            "NumElements field (%u), truncated",
544            i, ElementCount));
545    }
546    else if (i < ElementCount)
547    {
548        /*
549         * Arg list (elements) was exhausted, but we did not reach NumElements count.
550         * Note: this is not an error, the package is padded out with NULLs.
551         */
552        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
553            "Package List length (%u) smaller than NumElements "
554            "count (%u), padded with null elements\n",
555            i, ElementCount));
556    }
557
558    ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID;
559    Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc);
560    return_ACPI_STATUS (Status);
561}
562
563
564/*******************************************************************************
565 *
566 * FUNCTION:    AcpiDsCreateNode
567 *
568 * PARAMETERS:  WalkState       - Current walk state
569 *              Node            - NS Node to be initialized
570 *              Op              - Parser object to be translated
571 *
572 * RETURN:      Status
573 *
574 * DESCRIPTION: Create the object to be associated with a namespace node
575 *
576 ******************************************************************************/
577
578ACPI_STATUS
579AcpiDsCreateNode (
580    ACPI_WALK_STATE         *WalkState,
581    ACPI_NAMESPACE_NODE     *Node,
582    ACPI_PARSE_OBJECT       *Op)
583{
584    ACPI_STATUS             Status;
585    ACPI_OPERAND_OBJECT     *ObjDesc;
586
587
588    ACPI_FUNCTION_TRACE_PTR (DsCreateNode, Op);
589
590
591    /*
592     * Because of the execution pass through the non-control-method
593     * parts of the table, we can arrive here twice. Only init
594     * the named object node the first time through
595     */
596    if (AcpiNsGetAttachedObject (Node))
597    {
598        return_ACPI_STATUS (AE_OK);
599    }
600
601    if (!Op->Common.Value.Arg)
602    {
603        /* No arguments, there is nothing to do */
604
605        return_ACPI_STATUS (AE_OK);
606    }
607
608    /* Build an internal object for the argument(s) */
609
610    Status = AcpiDsBuildInternalObject (
611        WalkState, Op->Common.Value.Arg, &ObjDesc);
612    if (ACPI_FAILURE (Status))
613    {
614        return_ACPI_STATUS (Status);
615    }
616
617    /* Re-type the object according to its argument */
618
619    Node->Type = ObjDesc->Common.Type;
620
621    /* Attach obj to node */
622
623    Status = AcpiNsAttachObject (Node, ObjDesc, Node->Type);
624
625    /* Remove local reference to the object */
626
627    AcpiUtRemoveReference (ObjDesc);
628    return_ACPI_STATUS (Status);
629}
630
631#endif /* ACPI_NO_METHOD_EXECUTION */
632
633
634/*******************************************************************************
635 *
636 * FUNCTION:    AcpiDsInitObjectFromOp
637 *
638 * PARAMETERS:  WalkState       - Current walk state
639 *              Op              - Parser op used to init the internal object
640 *              Opcode          - AML opcode associated with the object
641 *              RetObjDesc      - Namespace object to be initialized
642 *
643 * RETURN:      Status
644 *
645 * DESCRIPTION: Initialize a namespace object from a parser Op and its
646 *              associated arguments. The namespace object is a more compact
647 *              representation of the Op and its arguments.
648 *
649 ******************************************************************************/
650
651ACPI_STATUS
652AcpiDsInitObjectFromOp (
653    ACPI_WALK_STATE         *WalkState,
654    ACPI_PARSE_OBJECT       *Op,
655    UINT16                  Opcode,
656    ACPI_OPERAND_OBJECT     **RetObjDesc)
657{
658    const ACPI_OPCODE_INFO  *OpInfo;
659    ACPI_OPERAND_OBJECT     *ObjDesc;
660    ACPI_STATUS             Status = AE_OK;
661
662
663    ACPI_FUNCTION_TRACE (DsInitObjectFromOp);
664
665
666    ObjDesc = *RetObjDesc;
667    OpInfo = AcpiPsGetOpcodeInfo (Opcode);
668    if (OpInfo->Class == AML_CLASS_UNKNOWN)
669    {
670        /* Unknown opcode */
671
672        return_ACPI_STATUS (AE_TYPE);
673    }
674
675    /* Perform per-object initialization */
676
677    switch (ObjDesc->Common.Type)
678    {
679    case ACPI_TYPE_BUFFER:
680        /*
681         * Defer evaluation of Buffer TermArg operand
682         */
683        ObjDesc->Buffer.Node = ACPI_CAST_PTR (
684            ACPI_NAMESPACE_NODE, WalkState->Operands[0]);
685        ObjDesc->Buffer.AmlStart = Op->Named.Data;
686        ObjDesc->Buffer.AmlLength = Op->Named.Length;
687        break;
688
689    case ACPI_TYPE_PACKAGE:
690        /*
691         * Defer evaluation of Package TermArg operand
692         */
693        ObjDesc->Package.Node = ACPI_CAST_PTR (
694            ACPI_NAMESPACE_NODE, WalkState->Operands[0]);
695        ObjDesc->Package.AmlStart = Op->Named.Data;
696        ObjDesc->Package.AmlLength = Op->Named.Length;
697        break;
698
699    case ACPI_TYPE_INTEGER:
700
701        switch (OpInfo->Type)
702        {
703        case AML_TYPE_CONSTANT:
704            /*
705             * Resolve AML Constants here - AND ONLY HERE!
706             * All constants are integers.
707             * We mark the integer with a flag that indicates that it started
708             * life as a constant -- so that stores to constants will perform
709             * as expected (noop). ZeroOp is used as a placeholder for optional
710             * target operands.
711             */
712            ObjDesc->Common.Flags = AOPOBJ_AML_CONSTANT;
713
714            switch (Opcode)
715            {
716            case AML_ZERO_OP:
717
718                ObjDesc->Integer.Value = 0;
719                break;
720
721            case AML_ONE_OP:
722
723                ObjDesc->Integer.Value = 1;
724                break;
725
726            case AML_ONES_OP:
727
728                ObjDesc->Integer.Value = ACPI_UINT64_MAX;
729
730                /* Truncate value if we are executing from a 32-bit ACPI table */
731
732#ifndef ACPI_NO_METHOD_EXECUTION
733                (void) AcpiExTruncateFor32bitTable (ObjDesc);
734#endif
735                break;
736
737            case AML_REVISION_OP:
738
739                ObjDesc->Integer.Value = ACPI_CA_VERSION;
740                break;
741
742            default:
743
744                ACPI_ERROR ((AE_INFO,
745                    "Unknown constant opcode 0x%X", Opcode));
746                Status = AE_AML_OPERAND_TYPE;
747                break;
748            }
749            break;
750
751        case AML_TYPE_LITERAL:
752
753            ObjDesc->Integer.Value = Op->Common.Value.Integer;
754
755#ifndef ACPI_NO_METHOD_EXECUTION
756            if (AcpiExTruncateFor32bitTable (ObjDesc))
757            {
758                /* Warn if we found a 64-bit constant in a 32-bit table */
759
760                ACPI_WARNING ((AE_INFO,
761                    "Truncated 64-bit constant found in 32-bit table: %8.8X%8.8X => %8.8X",
762                    ACPI_FORMAT_UINT64 (Op->Common.Value.Integer),
763                    (UINT32) ObjDesc->Integer.Value));
764            }
765#endif
766            break;
767
768        default:
769
770            ACPI_ERROR ((AE_INFO, "Unknown Integer type 0x%X",
771                OpInfo->Type));
772            Status = AE_AML_OPERAND_TYPE;
773            break;
774        }
775        break;
776
777    case ACPI_TYPE_STRING:
778
779        ObjDesc->String.Pointer = Op->Common.Value.String;
780        ObjDesc->String.Length = (UINT32) strlen (Op->Common.Value.String);
781
782        /*
783         * The string is contained in the ACPI table, don't ever try
784         * to delete it
785         */
786        ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER;
787        break;
788
789    case ACPI_TYPE_METHOD:
790        break;
791
792    case ACPI_TYPE_LOCAL_REFERENCE:
793
794        switch (OpInfo->Type)
795        {
796        case AML_TYPE_LOCAL_VARIABLE:
797
798            /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */
799
800            ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_LOCAL_OP;
801            ObjDesc->Reference.Class = ACPI_REFCLASS_LOCAL;
802
803#ifndef ACPI_NO_METHOD_EXECUTION
804            Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_LOCAL,
805                ObjDesc->Reference.Value, WalkState,
806                ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE,
807                    &ObjDesc->Reference.Object));
808#endif
809            break;
810
811        case AML_TYPE_METHOD_ARGUMENT:
812
813            /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */
814
815            ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_ARG_OP;
816            ObjDesc->Reference.Class = ACPI_REFCLASS_ARG;
817
818#ifndef ACPI_NO_METHOD_EXECUTION
819            Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_ARG,
820                ObjDesc->Reference.Value, WalkState,
821                ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE,
822                    &ObjDesc->Reference.Object));
823#endif
824            break;
825
826        default: /* Object name or Debug object */
827
828            switch (Op->Common.AmlOpcode)
829            {
830            case AML_INT_NAMEPATH_OP:
831
832                /* Node was saved in Op */
833
834                ObjDesc->Reference.Node = Op->Common.Node;
835                ObjDesc->Reference.Object = Op->Common.Node->Object;
836                ObjDesc->Reference.Class = ACPI_REFCLASS_NAME;
837                break;
838
839            case AML_DEBUG_OP:
840
841                ObjDesc->Reference.Class = ACPI_REFCLASS_DEBUG;
842                break;
843
844            default:
845
846                ACPI_ERROR ((AE_INFO,
847                    "Unimplemented reference type for AML opcode: 0x%4.4X", Opcode));
848                return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
849            }
850            break;
851        }
852        break;
853
854    default:
855
856        ACPI_ERROR ((AE_INFO, "Unimplemented data type: 0x%X",
857            ObjDesc->Common.Type));
858
859        Status = AE_AML_OPERAND_TYPE;
860        break;
861    }
862
863    return_ACPI_STATUS (Status);
864}
865