1/******************************************************************************
2 *
3 * Module Name: dsobject - Dispatcher object management routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2013, 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#define __DSOBJECT_C__
45
46#include <contrib/dev/acpica/include/acpi.h>
47#include <contrib/dev/acpica/include/accommon.h>
48#include <contrib/dev/acpica/include/acparser.h>
49#include <contrib/dev/acpica/include/amlcode.h>
50#include <contrib/dev/acpica/include/acdispat.h>
51#include <contrib/dev/acpica/include/acnamesp.h>
52#include <contrib/dev/acpica/include/acinterp.h>
53
54#define _COMPONENT          ACPI_DISPATCHER
55        ACPI_MODULE_NAME    ("dsobject")
56
57/* Local prototypes */
58
59static ACPI_STATUS
60AcpiDsBuildInternalObject (
61    ACPI_WALK_STATE         *WalkState,
62    ACPI_PARSE_OBJECT       *Op,
63    ACPI_OPERAND_OBJECT     **ObjDescPtr);
64
65
66#ifndef ACPI_NO_METHOD_EXECUTION
67/*******************************************************************************
68 *
69 * FUNCTION:    AcpiDsBuildInternalObject
70 *
71 * PARAMETERS:  WalkState       - Current walk state
72 *              Op              - Parser object to be translated
73 *              ObjDescPtr      - Where the ACPI internal object is returned
74 *
75 * RETURN:      Status
76 *
77 * DESCRIPTION: Translate a parser Op object to the equivalent namespace object
78 *              Simple objects are any objects other than a package object!
79 *
80 ******************************************************************************/
81
82static ACPI_STATUS
83AcpiDsBuildInternalObject (
84    ACPI_WALK_STATE         *WalkState,
85    ACPI_PARSE_OBJECT       *Op,
86    ACPI_OPERAND_OBJECT     **ObjDescPtr)
87{
88    ACPI_OPERAND_OBJECT     *ObjDesc;
89    ACPI_STATUS             Status;
90    ACPI_OBJECT_TYPE        Type;
91
92
93    ACPI_FUNCTION_TRACE (DsBuildInternalObject);
94
95
96    *ObjDescPtr = NULL;
97    if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
98    {
99        /*
100         * This is a named object reference. If this name was
101         * previously looked up in the namespace, it was stored in this op.
102         * Otherwise, go ahead and look it up now
103         */
104        if (!Op->Common.Node)
105        {
106            Status = AcpiNsLookup (WalkState->ScopeInfo,
107                        Op->Common.Value.String,
108                        ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
109                        ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL,
110                        ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &(Op->Common.Node)));
111            if (ACPI_FAILURE (Status))
112            {
113                /* Check if we are resolving a named reference within a package */
114
115                if ((Status == AE_NOT_FOUND) && (AcpiGbl_EnableInterpreterSlack) &&
116
117                    ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
118                     (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)))
119                {
120                    /*
121                     * We didn't find the target and we are populating elements
122                     * of a package - ignore if slack enabled. Some ASL code
123                     * contains dangling invalid references in packages and
124                     * expects that no exception will be issued. Leave the
125                     * element as a null element. It cannot be used, but it
126                     * can be overwritten by subsequent ASL code - this is
127                     * typically the case.
128                     */
129                    ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
130                        "Ignoring unresolved reference in package [%4.4s]\n",
131                        WalkState->ScopeInfo->Scope.Node->Name.Ascii));
132
133                    return_ACPI_STATUS (AE_OK);
134                }
135                else
136                {
137                    ACPI_ERROR_NAMESPACE (Op->Common.Value.String, Status);
138                }
139
140                return_ACPI_STATUS (Status);
141            }
142        }
143
144        /* Special object resolution for elements of a package */
145
146        if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
147            (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
148        {
149            /*
150             * Attempt to resolve the node to a value before we insert it into
151             * the package. If this is a reference to a common data type,
152             * resolve it immediately. According to the ACPI spec, package
153             * elements can only be "data objects" or method references.
154             * Attempt to resolve to an Integer, Buffer, String or Package.
155             * If cannot, return the named reference (for things like Devices,
156             * Methods, etc.) Buffer Fields and Fields will resolve to simple
157             * objects (int/buf/str/pkg).
158             *
159             * NOTE: References to things like Devices, Methods, Mutexes, etc.
160             * will remain as named references. This behavior is not described
161             * in the ACPI spec, but it appears to be an oversight.
162             */
163            ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Op->Common.Node);
164
165            Status = AcpiExResolveNodeToValue (
166                        ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc),
167                        WalkState);
168            if (ACPI_FAILURE (Status))
169            {
170                return_ACPI_STATUS (Status);
171            }
172
173            /*
174             * Special handling for Alias objects. We need to setup the type
175             * and the Op->Common.Node to point to the Alias target. Note,
176             * Alias has at most one level of indirection internally.
177             */
178            Type = Op->Common.Node->Type;
179            if (Type == ACPI_TYPE_LOCAL_ALIAS)
180            {
181                Type = ObjDesc->Common.Type;
182                Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
183                    Op->Common.Node->Object);
184            }
185
186            switch (Type)
187            {
188            /*
189             * For these types, we need the actual node, not the subobject.
190             * However, the subobject did not get an extra reference count above.
191             *
192             * TBD: should ExResolveNodeToValue be changed to fix this?
193             */
194            case ACPI_TYPE_DEVICE:
195            case ACPI_TYPE_THERMAL:
196
197                AcpiUtAddReference (Op->Common.Node->Object);
198
199                /*lint -fallthrough */
200            /*
201             * For these types, we need the actual node, not the subobject.
202             * The subobject got an extra reference count in ExResolveNodeToValue.
203             */
204            case ACPI_TYPE_MUTEX:
205            case ACPI_TYPE_METHOD:
206            case ACPI_TYPE_POWER:
207            case ACPI_TYPE_PROCESSOR:
208            case ACPI_TYPE_EVENT:
209            case ACPI_TYPE_REGION:
210
211                /* We will create a reference object for these types below */
212                break;
213
214            default:
215                /*
216                 * All other types - the node was resolved to an actual
217                 * object, we are done.
218                 */
219                goto Exit;
220            }
221        }
222    }
223
224    /* Create and init a new internal ACPI object */
225
226    ObjDesc = AcpiUtCreateInternalObject (
227                (AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode))->ObjectType);
228    if (!ObjDesc)
229    {
230        return_ACPI_STATUS (AE_NO_MEMORY);
231    }
232
233    Status = AcpiDsInitObjectFromOp (WalkState, Op, Op->Common.AmlOpcode,
234                &ObjDesc);
235    if (ACPI_FAILURE (Status))
236    {
237        AcpiUtRemoveReference (ObjDesc);
238        return_ACPI_STATUS (Status);
239    }
240
241Exit:
242    *ObjDescPtr = ObjDesc;
243    return_ACPI_STATUS (Status);
244}
245
246
247/*******************************************************************************
248 *
249 * FUNCTION:    AcpiDsBuildInternalBufferObj
250 *
251 * PARAMETERS:  WalkState       - Current walk state
252 *              Op              - Parser object to be translated
253 *              BufferLength    - Length of the buffer
254 *              ObjDescPtr      - Where the ACPI internal object is returned
255 *
256 * RETURN:      Status
257 *
258 * DESCRIPTION: Translate a parser Op package object to the equivalent
259 *              namespace object
260 *
261 ******************************************************************************/
262
263ACPI_STATUS
264AcpiDsBuildInternalBufferObj (
265    ACPI_WALK_STATE         *WalkState,
266    ACPI_PARSE_OBJECT       *Op,
267    UINT32                  BufferLength,
268    ACPI_OPERAND_OBJECT     **ObjDescPtr)
269{
270    ACPI_PARSE_OBJECT       *Arg;
271    ACPI_OPERAND_OBJECT     *ObjDesc;
272    ACPI_PARSE_OBJECT       *ByteList;
273    UINT32                  ByteListLength = 0;
274
275
276    ACPI_FUNCTION_TRACE (DsBuildInternalBufferObj);
277
278
279    /*
280     * If we are evaluating a Named buffer object "Name (xxxx, Buffer)".
281     * The buffer object already exists (from the NS node), otherwise it must
282     * be created.
283     */
284    ObjDesc = *ObjDescPtr;
285    if (!ObjDesc)
286    {
287        /* Create a new buffer object */
288
289        ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER);
290        *ObjDescPtr = ObjDesc;
291        if (!ObjDesc)
292        {
293            return_ACPI_STATUS (AE_NO_MEMORY);
294        }
295    }
296
297    /*
298     * Second arg is the buffer data (optional) ByteList can be either
299     * individual bytes or a string initializer. In either case, a
300     * ByteList appears in the AML.
301     */
302    Arg = Op->Common.Value.Arg;         /* skip first arg */
303
304    ByteList = Arg->Named.Next;
305    if (ByteList)
306    {
307        if (ByteList->Common.AmlOpcode != AML_INT_BYTELIST_OP)
308        {
309            ACPI_ERROR ((AE_INFO,
310                "Expecting bytelist, found AML opcode 0x%X in op %p",
311                ByteList->Common.AmlOpcode, ByteList));
312
313            AcpiUtRemoveReference (ObjDesc);
314            return (AE_TYPE);
315        }
316
317        ByteListLength = (UINT32) ByteList->Common.Value.Integer;
318    }
319
320    /*
321     * The buffer length (number of bytes) will be the larger of:
322     * 1) The specified buffer length and
323     * 2) The length of the initializer byte list
324     */
325    ObjDesc->Buffer.Length = BufferLength;
326    if (ByteListLength > BufferLength)
327    {
328        ObjDesc->Buffer.Length = ByteListLength;
329    }
330
331    /* Allocate the buffer */
332
333    if (ObjDesc->Buffer.Length == 0)
334    {
335        ObjDesc->Buffer.Pointer = NULL;
336        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
337            "Buffer defined with zero length in AML, creating\n"));
338    }
339    else
340    {
341        ObjDesc->Buffer.Pointer = ACPI_ALLOCATE_ZEROED (
342                                        ObjDesc->Buffer.Length);
343        if (!ObjDesc->Buffer.Pointer)
344        {
345            AcpiUtDeleteObjectDesc (ObjDesc);
346            return_ACPI_STATUS (AE_NO_MEMORY);
347        }
348
349        /* Initialize buffer from the ByteList (if present) */
350
351        if (ByteList)
352        {
353            ACPI_MEMCPY (ObjDesc->Buffer.Pointer, ByteList->Named.Data,
354                         ByteListLength);
355        }
356    }
357
358    ObjDesc->Buffer.Flags |= AOPOBJ_DATA_VALID;
359    Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc);
360    return_ACPI_STATUS (AE_OK);
361}
362
363
364/*******************************************************************************
365 *
366 * FUNCTION:    AcpiDsBuildInternalPackageObj
367 *
368 * PARAMETERS:  WalkState       - Current walk state
369 *              Op              - Parser object to be translated
370 *              ElementCount    - Number of elements in the package - this is
371 *                                the NumElements argument to Package()
372 *              ObjDescPtr      - Where the ACPI internal object is returned
373 *
374 * RETURN:      Status
375 *
376 * DESCRIPTION: Translate a parser Op package object to the equivalent
377 *              namespace object
378 *
379 * NOTE: The number of elements in the package will be always be the NumElements
380 * count, regardless of the number of elements in the package list. If
381 * NumElements is smaller, only that many package list elements are used.
382 * if NumElements is larger, the Package object is padded out with
383 * objects of type Uninitialized (as per ACPI spec.)
384 *
385 * Even though the ASL compilers do not allow NumElements to be smaller
386 * than the Package list length (for the fixed length package opcode), some
387 * BIOS code modifies the AML on the fly to adjust the NumElements, and
388 * this code compensates for that. This also provides compatibility with
389 * other AML interpreters.
390 *
391 ******************************************************************************/
392
393ACPI_STATUS
394AcpiDsBuildInternalPackageObj (
395    ACPI_WALK_STATE         *WalkState,
396    ACPI_PARSE_OBJECT       *Op,
397    UINT32                  ElementCount,
398    ACPI_OPERAND_OBJECT     **ObjDescPtr)
399{
400    ACPI_PARSE_OBJECT       *Arg;
401    ACPI_PARSE_OBJECT       *Parent;
402    ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
403    ACPI_STATUS             Status = AE_OK;
404    UINT32                  i;
405    UINT16                  Index;
406    UINT16                  ReferenceCount;
407
408
409    ACPI_FUNCTION_TRACE (DsBuildInternalPackageObj);
410
411
412    /* Find the parent of a possibly nested package */
413
414    Parent = Op->Common.Parent;
415    while ((Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
416           (Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
417    {
418        Parent = Parent->Common.Parent;
419    }
420
421    /*
422     * If we are evaluating a Named package object "Name (xxxx, Package)",
423     * the package object already exists, otherwise it must be created.
424     */
425    ObjDesc = *ObjDescPtr;
426    if (!ObjDesc)
427    {
428        ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE);
429        *ObjDescPtr = ObjDesc;
430        if (!ObjDesc)
431        {
432            return_ACPI_STATUS (AE_NO_MEMORY);
433        }
434
435        ObjDesc->Package.Node = Parent->Common.Node;
436    }
437
438    /*
439     * Allocate the element array (array of pointers to the individual
440     * objects) based on the NumElements parameter. Add an extra pointer slot
441     * so that the list is always null terminated.
442     */
443    ObjDesc->Package.Elements = ACPI_ALLOCATE_ZEROED (
444        ((ACPI_SIZE) ElementCount + 1) * sizeof (void *));
445
446    if (!ObjDesc->Package.Elements)
447    {
448        AcpiUtDeleteObjectDesc (ObjDesc);
449        return_ACPI_STATUS (AE_NO_MEMORY);
450    }
451
452    ObjDesc->Package.Count = ElementCount;
453
454    /*
455     * Initialize the elements of the package, up to the NumElements count.
456     * Package is automatically padded with uninitialized (NULL) elements
457     * if NumElements is greater than the package list length. Likewise,
458     * Package is truncated if NumElements is less than the list length.
459     */
460    Arg = Op->Common.Value.Arg;
461    Arg = Arg->Common.Next;
462    for (i = 0; Arg && (i < ElementCount); i++)
463    {
464        if (Arg->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP)
465        {
466            if (Arg->Common.Node->Type == ACPI_TYPE_METHOD)
467            {
468                /*
469                 * A method reference "looks" to the parser to be a method
470                 * invocation, so we special case it here
471                 */
472                Arg->Common.AmlOpcode = AML_INT_NAMEPATH_OP;
473                Status = AcpiDsBuildInternalObject (WalkState, Arg,
474                            &ObjDesc->Package.Elements[i]);
475            }
476            else
477            {
478                /* This package element is already built, just get it */
479
480                ObjDesc->Package.Elements[i] =
481                    ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node);
482            }
483        }
484        else
485        {
486            Status = AcpiDsBuildInternalObject (WalkState, Arg,
487                        &ObjDesc->Package.Elements[i]);
488        }
489
490        if (*ObjDescPtr)
491        {
492            /* Existing package, get existing reference count */
493
494            ReferenceCount = (*ObjDescPtr)->Common.ReferenceCount;
495            if (ReferenceCount > 1)
496            {
497                /* Make new element ref count match original ref count */
498
499                for (Index = 0; Index < (ReferenceCount - 1); Index++)
500                {
501                    AcpiUtAddReference ((ObjDesc->Package.Elements[i]));
502                }
503            }
504        }
505
506        Arg = Arg->Common.Next;
507    }
508
509    /* Check for match between NumElements and actual length of PackageList */
510
511    if (Arg)
512    {
513        /*
514         * NumElements was exhausted, but there are remaining elements in the
515         * PackageList. Truncate the package to NumElements.
516         *
517         * Note: technically, this is an error, from ACPI spec: "It is an error
518         * for NumElements to be less than the number of elements in the
519         * PackageList". However, we just print a message and
520         * no exception is returned. This provides Windows compatibility. Some
521         * BIOSs will alter the NumElements on the fly, creating this type
522         * of ill-formed package object.
523         */
524        while (Arg)
525        {
526            /*
527             * We must delete any package elements that were created earlier
528             * and are not going to be used because of the package truncation.
529             */
530            if (Arg->Common.Node)
531            {
532                AcpiUtRemoveReference (
533                    ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node));
534                Arg->Common.Node = NULL;
535            }
536
537            /* Find out how many elements there really are */
538
539            i++;
540            Arg = Arg->Common.Next;
541        }
542
543        ACPI_INFO ((AE_INFO,
544            "Actual Package length (%u) is larger than NumElements field (%u), truncated",
545            i, ElementCount));
546    }
547    else if (i < ElementCount)
548    {
549        /*
550         * Arg list (elements) was exhausted, but we did not reach NumElements count.
551         * Note: this is not an error, the package is padded out with NULLs.
552         */
553        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
554            "Package List length (%u) smaller than NumElements 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 (WalkState, Op->Common.Value.Arg,
611                &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 (ACPI_NAMESPACE_NODE,
684                                        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 (ACPI_NAMESPACE_NODE,
694                                        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) ACPI_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