Home | History | Annotate | Line # | Download | only in dispatcher
dsobject.c revision 1.1.1.5
      1 /******************************************************************************
      2  *
      3  * Module Name: dsobject - Dispatcher object management routines
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2015, 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 "acpi.h"
     45 #include "accommon.h"
     46 #include "acparser.h"
     47 #include "amlcode.h"
     48 #include "acdispat.h"
     49 #include "acnamesp.h"
     50 #include "acinterp.h"
     51 
     52 #define _COMPONENT          ACPI_DISPATCHER
     53         ACPI_MODULE_NAME    ("dsobject")
     54 
     55 /* Local prototypes */
     56 
     57 static ACPI_STATUS
     58 AcpiDsBuildInternalObject (
     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 
     80 static ACPI_STATUS
     81 AcpiDsBuildInternalObject (
     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 (WalkState, Op, Op->Common.AmlOpcode,
    232                 &ObjDesc);
    233     if (ACPI_FAILURE (Status))
    234     {
    235         AcpiUtRemoveReference (ObjDesc);
    236         return_ACPI_STATUS (Status);
    237     }
    238 
    239 Exit:
    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 
    261 ACPI_STATUS
    262 AcpiDsBuildInternalBufferObj (
    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 = ACPI_ALLOCATE_ZEROED (
    340                                         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             ACPI_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 
    391 ACPI_STATUS
    392 AcpiDsBuildInternalPackageObj (
    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 (WalkState, Arg,
    472                             &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 (WalkState, Arg,
    485                         &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 ((AE_INFO,
    542             "Actual Package length (%u) is larger than NumElements field (%u), truncated",
    543             i, ElementCount));
    544     }
    545     else if (i < ElementCount)
    546     {
    547         /*
    548          * Arg list (elements) was exhausted, but we did not reach NumElements count.
    549          * Note: this is not an error, the package is padded out with NULLs.
    550          */
    551         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    552             "Package List length (%u) smaller than NumElements count (%u), padded with null elements\n",
    553             i, ElementCount));
    554     }
    555 
    556     ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID;
    557     Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc);
    558     return_ACPI_STATUS (Status);
    559 }
    560 
    561 
    562 /*******************************************************************************
    563  *
    564  * FUNCTION:    AcpiDsCreateNode
    565  *
    566  * PARAMETERS:  WalkState       - Current walk state
    567  *              Node            - NS Node to be initialized
    568  *              Op              - Parser object to be translated
    569  *
    570  * RETURN:      Status
    571  *
    572  * DESCRIPTION: Create the object to be associated with a namespace node
    573  *
    574  ******************************************************************************/
    575 
    576 ACPI_STATUS
    577 AcpiDsCreateNode (
    578     ACPI_WALK_STATE         *WalkState,
    579     ACPI_NAMESPACE_NODE     *Node,
    580     ACPI_PARSE_OBJECT       *Op)
    581 {
    582     ACPI_STATUS             Status;
    583     ACPI_OPERAND_OBJECT     *ObjDesc;
    584 
    585 
    586     ACPI_FUNCTION_TRACE_PTR (DsCreateNode, Op);
    587 
    588 
    589     /*
    590      * Because of the execution pass through the non-control-method
    591      * parts of the table, we can arrive here twice. Only init
    592      * the named object node the first time through
    593      */
    594     if (AcpiNsGetAttachedObject (Node))
    595     {
    596         return_ACPI_STATUS (AE_OK);
    597     }
    598 
    599     if (!Op->Common.Value.Arg)
    600     {
    601         /* No arguments, there is nothing to do */
    602 
    603         return_ACPI_STATUS (AE_OK);
    604     }
    605 
    606     /* Build an internal object for the argument(s) */
    607 
    608     Status = AcpiDsBuildInternalObject (WalkState, Op->Common.Value.Arg,
    609                 &ObjDesc);
    610     if (ACPI_FAILURE (Status))
    611     {
    612         return_ACPI_STATUS (Status);
    613     }
    614 
    615     /* Re-type the object according to its argument */
    616 
    617     Node->Type = ObjDesc->Common.Type;
    618 
    619     /* Attach obj to node */
    620 
    621     Status = AcpiNsAttachObject (Node, ObjDesc, Node->Type);
    622 
    623     /* Remove local reference to the object */
    624 
    625     AcpiUtRemoveReference (ObjDesc);
    626     return_ACPI_STATUS (Status);
    627 }
    628 
    629 #endif /* ACPI_NO_METHOD_EXECUTION */
    630 
    631 
    632 /*******************************************************************************
    633  *
    634  * FUNCTION:    AcpiDsInitObjectFromOp
    635  *
    636  * PARAMETERS:  WalkState       - Current walk state
    637  *              Op              - Parser op used to init the internal object
    638  *              Opcode          - AML opcode associated with the object
    639  *              RetObjDesc      - Namespace object to be initialized
    640  *
    641  * RETURN:      Status
    642  *
    643  * DESCRIPTION: Initialize a namespace object from a parser Op and its
    644  *              associated arguments. The namespace object is a more compact
    645  *              representation of the Op and its arguments.
    646  *
    647  ******************************************************************************/
    648 
    649 ACPI_STATUS
    650 AcpiDsInitObjectFromOp (
    651     ACPI_WALK_STATE         *WalkState,
    652     ACPI_PARSE_OBJECT       *Op,
    653     UINT16                  Opcode,
    654     ACPI_OPERAND_OBJECT     **RetObjDesc)
    655 {
    656     const ACPI_OPCODE_INFO  *OpInfo;
    657     ACPI_OPERAND_OBJECT     *ObjDesc;
    658     ACPI_STATUS             Status = AE_OK;
    659 
    660 
    661     ACPI_FUNCTION_TRACE (DsInitObjectFromOp);
    662 
    663 
    664     ObjDesc = *RetObjDesc;
    665     OpInfo = AcpiPsGetOpcodeInfo (Opcode);
    666     if (OpInfo->Class == AML_CLASS_UNKNOWN)
    667     {
    668         /* Unknown opcode */
    669 
    670         return_ACPI_STATUS (AE_TYPE);
    671     }
    672 
    673     /* Perform per-object initialization */
    674 
    675     switch (ObjDesc->Common.Type)
    676     {
    677     case ACPI_TYPE_BUFFER:
    678         /*
    679          * Defer evaluation of Buffer TermArg operand
    680          */
    681         ObjDesc->Buffer.Node      = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
    682                                         WalkState->Operands[0]);
    683         ObjDesc->Buffer.AmlStart  = Op->Named.Data;
    684         ObjDesc->Buffer.AmlLength = Op->Named.Length;
    685         break;
    686 
    687     case ACPI_TYPE_PACKAGE:
    688         /*
    689          * Defer evaluation of Package TermArg operand
    690          */
    691         ObjDesc->Package.Node      = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
    692                                         WalkState->Operands[0]);
    693         ObjDesc->Package.AmlStart  = Op->Named.Data;
    694         ObjDesc->Package.AmlLength = Op->Named.Length;
    695         break;
    696 
    697     case ACPI_TYPE_INTEGER:
    698 
    699         switch (OpInfo->Type)
    700         {
    701         case AML_TYPE_CONSTANT:
    702             /*
    703              * Resolve AML Constants here - AND ONLY HERE!
    704              * All constants are integers.
    705              * We mark the integer with a flag that indicates that it started
    706              * life as a constant -- so that stores to constants will perform
    707              * as expected (noop). ZeroOp is used as a placeholder for optional
    708              * target operands.
    709              */
    710             ObjDesc->Common.Flags = AOPOBJ_AML_CONSTANT;
    711 
    712             switch (Opcode)
    713             {
    714             case AML_ZERO_OP:
    715 
    716                 ObjDesc->Integer.Value = 0;
    717                 break;
    718 
    719             case AML_ONE_OP:
    720 
    721                 ObjDesc->Integer.Value = 1;
    722                 break;
    723 
    724             case AML_ONES_OP:
    725 
    726                 ObjDesc->Integer.Value = ACPI_UINT64_MAX;
    727 
    728                 /* Truncate value if we are executing from a 32-bit ACPI table */
    729 
    730 #ifndef ACPI_NO_METHOD_EXECUTION
    731                 (void) AcpiExTruncateFor32bitTable (ObjDesc);
    732 #endif
    733                 break;
    734 
    735             case AML_REVISION_OP:
    736 
    737                 ObjDesc->Integer.Value = ACPI_CA_VERSION;
    738                 break;
    739 
    740             default:
    741 
    742                 ACPI_ERROR ((AE_INFO,
    743                     "Unknown constant opcode 0x%X", Opcode));
    744                 Status = AE_AML_OPERAND_TYPE;
    745                 break;
    746             }
    747             break;
    748 
    749         case AML_TYPE_LITERAL:
    750 
    751             ObjDesc->Integer.Value = Op->Common.Value.Integer;
    752 
    753 #ifndef ACPI_NO_METHOD_EXECUTION
    754             if (AcpiExTruncateFor32bitTable (ObjDesc))
    755             {
    756                 /* Warn if we found a 64-bit constant in a 32-bit table */
    757 
    758                 ACPI_WARNING ((AE_INFO,
    759                     "Truncated 64-bit constant found in 32-bit table: %8.8X%8.8X => %8.8X",
    760                     ACPI_FORMAT_UINT64 (Op->Common.Value.Integer),
    761                     (UINT32) ObjDesc->Integer.Value));
    762             }
    763 #endif
    764             break;
    765 
    766         default:
    767 
    768             ACPI_ERROR ((AE_INFO, "Unknown Integer type 0x%X",
    769                 OpInfo->Type));
    770             Status = AE_AML_OPERAND_TYPE;
    771             break;
    772         }
    773         break;
    774 
    775     case ACPI_TYPE_STRING:
    776 
    777         ObjDesc->String.Pointer = Op->Common.Value.String;
    778         ObjDesc->String.Length = (UINT32) ACPI_STRLEN (Op->Common.Value.String);
    779 
    780         /*
    781          * The string is contained in the ACPI table, don't ever try
    782          * to delete it
    783          */
    784         ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER;
    785         break;
    786 
    787     case ACPI_TYPE_METHOD:
    788         break;
    789 
    790     case ACPI_TYPE_LOCAL_REFERENCE:
    791 
    792         switch (OpInfo->Type)
    793         {
    794         case AML_TYPE_LOCAL_VARIABLE:
    795 
    796             /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */
    797 
    798             ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_LOCAL_OP;
    799             ObjDesc->Reference.Class = ACPI_REFCLASS_LOCAL;
    800 
    801 #ifndef ACPI_NO_METHOD_EXECUTION
    802             Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_LOCAL,
    803                         ObjDesc->Reference.Value, WalkState,
    804                         ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE,
    805                             &ObjDesc->Reference.Object));
    806 #endif
    807             break;
    808 
    809         case AML_TYPE_METHOD_ARGUMENT:
    810 
    811             /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */
    812 
    813             ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_ARG_OP;
    814             ObjDesc->Reference.Class = ACPI_REFCLASS_ARG;
    815 
    816 #ifndef ACPI_NO_METHOD_EXECUTION
    817             Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_ARG,
    818                         ObjDesc->Reference.Value, WalkState,
    819                         ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE,
    820                             &ObjDesc->Reference.Object));
    821 #endif
    822             break;
    823 
    824         default: /* Object name or Debug object */
    825 
    826             switch (Op->Common.AmlOpcode)
    827             {
    828             case AML_INT_NAMEPATH_OP:
    829 
    830                 /* Node was saved in Op */
    831 
    832                 ObjDesc->Reference.Node = Op->Common.Node;
    833                 ObjDesc->Reference.Object = Op->Common.Node->Object;
    834                 ObjDesc->Reference.Class = ACPI_REFCLASS_NAME;
    835                 break;
    836 
    837             case AML_DEBUG_OP:
    838 
    839                 ObjDesc->Reference.Class = ACPI_REFCLASS_DEBUG;
    840                 break;
    841 
    842             default:
    843 
    844                 ACPI_ERROR ((AE_INFO,
    845                     "Unimplemented reference type for AML opcode: 0x%4.4X", Opcode));
    846                 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
    847             }
    848             break;
    849         }
    850         break;
    851 
    852     default:
    853 
    854         ACPI_ERROR ((AE_INFO, "Unimplemented data type: 0x%X",
    855             ObjDesc->Common.Type));
    856 
    857         Status = AE_AML_OPERAND_TYPE;
    858         break;
    859     }
    860 
    861     return_ACPI_STATUS (Status);
    862 }
    863