1 /******************************************************************************
   2  *
   3  * Module Name: dsobject - Dispatcher object management routines
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2011, 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 "acpi.h"
  47 #include "accommon.h"
  48 #include "acparser.h"
  49 #include "amlcode.h"
  50 #include "acdispat.h"
  51 #include "acnamesp.h"
  52 #include "acinterp.h"
  53 
  54 #define _COMPONENT          ACPI_DISPATCHER
  55         ACPI_MODULE_NAME    ("dsobject")
  56 
  57 /* Local prototypes */
  58 
  59 static ACPI_STATUS
  60 AcpiDsBuildInternalObject (
  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 
  82 static ACPI_STATUS
  83 AcpiDsBuildInternalObject (
  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 
 241 Exit:
 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 
 263 ACPI_STATUS
 264 AcpiDsBuildInternalBufferObj (
 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 
 393 ACPI_STATUS
 394 AcpiDsBuildInternalPackageObj (
 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\n",
 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 
 578 ACPI_STATUS
 579 AcpiDsCreateNode (
 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 
 651 ACPI_STATUS
 652 AcpiDsInitObjectFromOp (
 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         /*
 682          * Defer evaluation of Buffer TermArg operand
 683          */
 684         ObjDesc->Buffer.Node      = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
 685                                         WalkState->Operands[0]);
 686         ObjDesc->Buffer.AmlStart  = Op->Named.Data;
 687         ObjDesc->Buffer.AmlLength = Op->Named.Length;
 688         break;
 689 
 690 
 691     case ACPI_TYPE_PACKAGE:
 692 
 693         /*
 694          * Defer evaluation of Package TermArg operand
 695          */
 696         ObjDesc->Package.Node      = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
 697                                         WalkState->Operands[0]);
 698         ObjDesc->Package.AmlStart  = Op->Named.Data;
 699         ObjDesc->Package.AmlLength = Op->Named.Length;
 700         break;
 701 
 702 
 703     case ACPI_TYPE_INTEGER:
 704 
 705         switch (OpInfo->Type)
 706         {
 707         case AML_TYPE_CONSTANT:
 708             /*
 709              * Resolve AML Constants here - AND ONLY HERE!
 710              * All constants are integers.
 711              * We mark the integer with a flag that indicates that it started
 712              * life as a constant -- so that stores to constants will perform
 713              * as expected (noop). ZeroOp is used as a placeholder for optional
 714              * target operands.
 715              */
 716             ObjDesc->Common.Flags = AOPOBJ_AML_CONSTANT;
 717 
 718             switch (Opcode)
 719             {
 720             case AML_ZERO_OP:
 721 
 722                 ObjDesc->Integer.Value = 0;
 723                 break;
 724 
 725             case AML_ONE_OP:
 726 
 727                 ObjDesc->Integer.Value = 1;
 728                 break;
 729 
 730             case AML_ONES_OP:
 731 
 732                 ObjDesc->Integer.Value = ACPI_UINT64_MAX;
 733 
 734                 /* Truncate value if we are executing from a 32-bit ACPI table */
 735 
 736 #ifndef ACPI_NO_METHOD_EXECUTION
 737                 AcpiExTruncateFor32bitTable (ObjDesc);
 738 #endif
 739                 break;
 740 
 741             case AML_REVISION_OP:
 742 
 743                 ObjDesc->Integer.Value = ACPI_CA_VERSION;
 744                 break;
 745 
 746             default:
 747 
 748                 ACPI_ERROR ((AE_INFO,
 749                     "Unknown constant opcode 0x%X", Opcode));
 750                 Status = AE_AML_OPERAND_TYPE;
 751                 break;
 752             }
 753             break;
 754 
 755 
 756         case AML_TYPE_LITERAL:
 757 
 758             ObjDesc->Integer.Value = Op->Common.Value.Integer;
 759 #ifndef ACPI_NO_METHOD_EXECUTION
 760             AcpiExTruncateFor32bitTable (ObjDesc);
 761 #endif
 762             break;
 763 
 764 
 765         default:
 766             ACPI_ERROR ((AE_INFO, "Unknown Integer type 0x%X",
 767                 OpInfo->Type));
 768             Status = AE_AML_OPERAND_TYPE;
 769             break;
 770         }
 771         break;
 772 
 773 
 774     case ACPI_TYPE_STRING:
 775 
 776         ObjDesc->String.Pointer = Op->Common.Value.String;
 777         ObjDesc->String.Length = (UINT32) ACPI_STRLEN (Op->Common.Value.String);
 778 
 779         /*
 780          * The string is contained in the ACPI table, don't ever try
 781          * to delete it
 782          */
 783         ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER;
 784         break;
 785 
 786 
 787     case ACPI_TYPE_METHOD:
 788         break;
 789 
 790 
 791     case ACPI_TYPE_LOCAL_REFERENCE:
 792 
 793         switch (OpInfo->Type)
 794         {
 795         case AML_TYPE_LOCAL_VARIABLE:
 796 
 797             /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */
 798 
 799             ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_LOCAL_OP;
 800             ObjDesc->Reference.Class = ACPI_REFCLASS_LOCAL;
 801 
 802 #ifndef ACPI_NO_METHOD_EXECUTION
 803             Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_LOCAL,
 804                         ObjDesc->Reference.Value, WalkState,
 805                         ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE,
 806                             &ObjDesc->Reference.Object));
 807 #endif
 808             break;
 809 
 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 
 855     default:
 856 
 857         ACPI_ERROR ((AE_INFO, "Unimplemented data type: 0x%X",
 858             ObjDesc->Common.Type));
 859 
 860         Status = AE_AML_OPERAND_TYPE;
 861         break;
 862     }
 863 
 864     return_ACPI_STATUS (Status);
 865 }
 866 
 867