1 /******************************************************************************
   2  *
   3  * Module Name: dsopcode - Dispatcher support for regions and fields
   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 __DSOPCODE_C__
  45 
  46 #include "acpi.h"
  47 #include "accommon.h"
  48 #include "acparser.h"
  49 #include "amlcode.h"
  50 #include "acdispat.h"
  51 #include "acinterp.h"
  52 #include "acnamesp.h"
  53 #include "acevents.h"
  54 #include "actables.h"
  55 
  56 #define _COMPONENT          ACPI_DISPATCHER
  57         ACPI_MODULE_NAME    ("dsopcode")
  58 
  59 /* Local prototypes */
  60 
  61 static ACPI_STATUS
  62 AcpiDsInitBufferField (
  63     UINT16                  AmlOpcode,
  64     ACPI_OPERAND_OBJECT     *ObjDesc,
  65     ACPI_OPERAND_OBJECT     *BufferDesc,
  66     ACPI_OPERAND_OBJECT     *OffsetDesc,
  67     ACPI_OPERAND_OBJECT     *LengthDesc,
  68     ACPI_OPERAND_OBJECT     *ResultDesc);
  69 
  70 
  71 /*******************************************************************************
  72  *
  73  * FUNCTION:    AcpiDsInitializeRegion
  74  *
  75  * PARAMETERS:  ObjHandle       - Region namespace node
  76  *
  77  * RETURN:      Status
  78  *
  79  * DESCRIPTION: Front end to EvInitializeRegion
  80  *
  81  ******************************************************************************/
  82 
  83 ACPI_STATUS
  84 AcpiDsInitializeRegion (
  85     ACPI_HANDLE             ObjHandle)
  86 {
  87     ACPI_OPERAND_OBJECT     *ObjDesc;
  88     ACPI_STATUS             Status;
  89 
  90 
  91     ObjDesc = AcpiNsGetAttachedObject (ObjHandle);
  92 
  93     /* Namespace is NOT locked */
  94 
  95     Status = AcpiEvInitializeRegion (ObjDesc, FALSE);
  96     return (Status);
  97 }
  98 
  99 
 100 /*******************************************************************************
 101  *
 102  * FUNCTION:    AcpiDsInitBufferField
 103  *
 104  * PARAMETERS:  AmlOpcode       - CreateXxxField
 105  *              ObjDesc         - BufferField object
 106  *              BufferDesc      - Host Buffer
 107  *              OffsetDesc      - Offset into buffer
 108  *              LengthDesc      - Length of field (CREATE_FIELD_OP only)
 109  *              ResultDesc      - Where to store the result
 110  *
 111  * RETURN:      Status
 112  *
 113  * DESCRIPTION: Perform actual initialization of a buffer field
 114  *
 115  ******************************************************************************/
 116 
 117 static ACPI_STATUS
 118 AcpiDsInitBufferField (
 119     UINT16                  AmlOpcode,
 120     ACPI_OPERAND_OBJECT     *ObjDesc,
 121     ACPI_OPERAND_OBJECT     *BufferDesc,
 122     ACPI_OPERAND_OBJECT     *OffsetDesc,
 123     ACPI_OPERAND_OBJECT     *LengthDesc,
 124     ACPI_OPERAND_OBJECT     *ResultDesc)
 125 {
 126     UINT32                  Offset;
 127     UINT32                  BitOffset;
 128     UINT32                  BitCount;
 129     UINT8                   FieldFlags;
 130     ACPI_STATUS             Status;
 131 
 132 
 133     ACPI_FUNCTION_TRACE_PTR (DsInitBufferField, ObjDesc);
 134 
 135 
 136     /* Host object must be a Buffer */
 137 
 138     if (BufferDesc->Common.Type != ACPI_TYPE_BUFFER)
 139     {
 140         ACPI_ERROR ((AE_INFO,
 141             "Target of Create Field is not a Buffer object - %s",
 142             AcpiUtGetObjectTypeName (BufferDesc)));
 143 
 144         Status = AE_AML_OPERAND_TYPE;
 145         goto Cleanup;
 146     }
 147 
 148     /*
 149      * The last parameter to all of these opcodes (ResultDesc) started
 150      * out as a NameString, and should therefore now be a NS node
 151      * after resolution in AcpiExResolveOperands().
 152      */
 153     if (ACPI_GET_DESCRIPTOR_TYPE (ResultDesc) != ACPI_DESC_TYPE_NAMED)
 154     {
 155         ACPI_ERROR ((AE_INFO,
 156             "(%s) destination not a NS Node [%s]",
 157             AcpiPsGetOpcodeName (AmlOpcode),
 158             AcpiUtGetDescriptorName (ResultDesc)));
 159 
 160         Status = AE_AML_OPERAND_TYPE;
 161         goto Cleanup;
 162     }
 163 
 164     Offset = (UINT32) OffsetDesc->Integer.Value;
 165 
 166     /*
 167      * Setup the Bit offsets and counts, according to the opcode
 168      */
 169     switch (AmlOpcode)
 170     {
 171     case AML_CREATE_FIELD_OP:
 172 
 173         /* Offset is in bits, count is in bits */
 174 
 175         FieldFlags = AML_FIELD_ACCESS_BYTE;
 176         BitOffset  = Offset;
 177         BitCount   = (UINT32) LengthDesc->Integer.Value;
 178 
 179         /* Must have a valid (>0) bit count */
 180 
 181         if (BitCount == 0)
 182         {
 183             ACPI_ERROR ((AE_INFO,
 184                 "Attempt to CreateField of length zero"));
 185             Status = AE_AML_OPERAND_VALUE;
 186             goto Cleanup;
 187         }
 188         break;
 189 
 190     case AML_CREATE_BIT_FIELD_OP:
 191 
 192         /* Offset is in bits, Field is one bit */
 193 
 194         BitOffset  = Offset;
 195         BitCount   = 1;
 196         FieldFlags = AML_FIELD_ACCESS_BYTE;
 197         break;
 198 
 199     case AML_CREATE_BYTE_FIELD_OP:
 200 
 201         /* Offset is in bytes, field is one byte */
 202 
 203         BitOffset  = 8 * Offset;
 204         BitCount   = 8;
 205         FieldFlags = AML_FIELD_ACCESS_BYTE;
 206         break;
 207 
 208     case AML_CREATE_WORD_FIELD_OP:
 209 
 210         /* Offset is in bytes, field is one word */
 211 
 212         BitOffset  = 8 * Offset;
 213         BitCount   = 16;
 214         FieldFlags = AML_FIELD_ACCESS_WORD;
 215         break;
 216 
 217     case AML_CREATE_DWORD_FIELD_OP:
 218 
 219         /* Offset is in bytes, field is one dword */
 220 
 221         BitOffset  = 8 * Offset;
 222         BitCount   = 32;
 223         FieldFlags = AML_FIELD_ACCESS_DWORD;
 224         break;
 225 
 226     case AML_CREATE_QWORD_FIELD_OP:
 227 
 228         /* Offset is in bytes, field is one qword */
 229 
 230         BitOffset  = 8 * Offset;
 231         BitCount   = 64;
 232         FieldFlags = AML_FIELD_ACCESS_QWORD;
 233         break;
 234 
 235     default:
 236 
 237         ACPI_ERROR ((AE_INFO,
 238             "Unknown field creation opcode 0x%02X",
 239             AmlOpcode));
 240         Status = AE_AML_BAD_OPCODE;
 241         goto Cleanup;
 242     }
 243 
 244     /* Entire field must fit within the current length of the buffer */
 245 
 246     if ((BitOffset + BitCount) >
 247         (8 * (UINT32) BufferDesc->Buffer.Length))
 248     {
 249         ACPI_ERROR ((AE_INFO,
 250             "Field [%4.4s] at %u exceeds Buffer [%4.4s] size %u (bits)",
 251             AcpiUtGetNodeName (ResultDesc),
 252             BitOffset + BitCount,
 253             AcpiUtGetNodeName (BufferDesc->Buffer.Node),
 254             8 * (UINT32) BufferDesc->Buffer.Length));
 255         Status = AE_AML_BUFFER_LIMIT;
 256         goto Cleanup;
 257     }
 258 
 259     /*
 260      * Initialize areas of the field object that are common to all fields
 261      * For FieldFlags, use LOCK_RULE = 0 (NO_LOCK),
 262      * UPDATE_RULE = 0 (UPDATE_PRESERVE)
 263      */
 264     Status = AcpiExPrepCommonFieldObject (ObjDesc, FieldFlags, 0,
 265                                             BitOffset, BitCount);
 266     if (ACPI_FAILURE (Status))
 267     {
 268         goto Cleanup;
 269     }
 270 
 271     ObjDesc->BufferField.BufferObj = BufferDesc;
 272 
 273     /* Reference count for BufferDesc inherits ObjDesc count */
 274 
 275     BufferDesc->Common.ReferenceCount = (UINT16)
 276         (BufferDesc->Common.ReferenceCount + ObjDesc->Common.ReferenceCount);
 277 
 278 
 279 Cleanup:
 280 
 281     /* Always delete the operands */
 282 
 283     AcpiUtRemoveReference (OffsetDesc);
 284     AcpiUtRemoveReference (BufferDesc);
 285 
 286     if (AmlOpcode == AML_CREATE_FIELD_OP)
 287     {
 288         AcpiUtRemoveReference (LengthDesc);
 289     }
 290 
 291     /* On failure, delete the result descriptor */
 292 
 293     if (ACPI_FAILURE (Status))
 294     {
 295         AcpiUtRemoveReference (ResultDesc);     /* Result descriptor */
 296     }
 297     else
 298     {
 299         /* Now the address and length are valid for this BufferField */
 300 
 301         ObjDesc->BufferField.Flags |= AOPOBJ_DATA_VALID;
 302     }
 303 
 304     return_ACPI_STATUS (Status);
 305 }
 306 
 307 
 308 /*******************************************************************************
 309  *
 310  * FUNCTION:    AcpiDsEvalBufferFieldOperands
 311  *
 312  * PARAMETERS:  WalkState       - Current walk
 313  *              Op              - A valid BufferField Op object
 314  *
 315  * RETURN:      Status
 316  *
 317  * DESCRIPTION: Get BufferField Buffer and Index
 318  *              Called from AcpiDsExecEndOp during BufferField parse tree walk
 319  *
 320  ******************************************************************************/
 321 
 322 ACPI_STATUS
 323 AcpiDsEvalBufferFieldOperands (
 324     ACPI_WALK_STATE         *WalkState,
 325     ACPI_PARSE_OBJECT       *Op)
 326 {
 327     ACPI_STATUS             Status;
 328     ACPI_OPERAND_OBJECT     *ObjDesc;
 329     ACPI_NAMESPACE_NODE     *Node;
 330     ACPI_PARSE_OBJECT       *NextOp;
 331 
 332 
 333     ACPI_FUNCTION_TRACE_PTR (DsEvalBufferFieldOperands, Op);
 334 
 335 
 336     /*
 337      * This is where we evaluate the address and length fields of the
 338      * CreateXxxField declaration
 339      */
 340     Node =  Op->Common.Node;
 341 
 342     /* NextOp points to the op that holds the Buffer */
 343 
 344     NextOp = Op->Common.Value.Arg;
 345 
 346     /* Evaluate/create the address and length operands */
 347 
 348     Status = AcpiDsCreateOperands (WalkState, NextOp);
 349     if (ACPI_FAILURE (Status))
 350     {
 351         return_ACPI_STATUS (Status);
 352     }
 353 
 354     ObjDesc = AcpiNsGetAttachedObject (Node);
 355     if (!ObjDesc)
 356     {
 357         return_ACPI_STATUS (AE_NOT_EXIST);
 358     }
 359 
 360     /* Resolve the operands */
 361 
 362     Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
 363                     ACPI_WALK_OPERANDS, WalkState);
 364     if (ACPI_FAILURE (Status))
 365     {
 366         ACPI_ERROR ((AE_INFO, "(%s) bad operand(s), status 0x%X",
 367             AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status));
 368 
 369         return_ACPI_STATUS (Status);
 370     }
 371 
 372     /* Initialize the Buffer Field */
 373 
 374     if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
 375     {
 376         /* NOTE: Slightly different operands for this opcode */
 377 
 378         Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
 379                     WalkState->Operands[0], WalkState->Operands[1],
 380                     WalkState->Operands[2], WalkState->Operands[3]);
 381     }
 382     else
 383     {
 384         /* All other, CreateXxxField opcodes */
 385 
 386         Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
 387                     WalkState->Operands[0], WalkState->Operands[1],
 388                                       NULL, WalkState->Operands[2]);
 389     }
 390 
 391     return_ACPI_STATUS (Status);
 392 }
 393 
 394 
 395 /*******************************************************************************
 396  *
 397  * FUNCTION:    AcpiDsEvalRegionOperands
 398  *
 399  * PARAMETERS:  WalkState       - Current walk
 400  *              Op              - A valid region Op object
 401  *
 402  * RETURN:      Status
 403  *
 404  * DESCRIPTION: Get region address and length
 405  *              Called from AcpiDsExecEndOp during OpRegion parse tree walk
 406  *
 407  ******************************************************************************/
 408 
 409 ACPI_STATUS
 410 AcpiDsEvalRegionOperands (
 411     ACPI_WALK_STATE         *WalkState,
 412     ACPI_PARSE_OBJECT       *Op)
 413 {
 414     ACPI_STATUS             Status;
 415     ACPI_OPERAND_OBJECT     *ObjDesc;
 416     ACPI_OPERAND_OBJECT     *OperandDesc;
 417     ACPI_NAMESPACE_NODE     *Node;
 418     ACPI_PARSE_OBJECT       *NextOp;
 419 
 420 
 421     ACPI_FUNCTION_TRACE_PTR (DsEvalRegionOperands, Op);
 422 
 423 
 424     /*
 425      * This is where we evaluate the address and length fields of the
 426      * OpRegion declaration
 427      */
 428     Node =  Op->Common.Node;
 429 
 430     /* NextOp points to the op that holds the SpaceID */
 431 
 432     NextOp = Op->Common.Value.Arg;
 433 
 434     /* NextOp points to address op */
 435 
 436     NextOp = NextOp->Common.Next;
 437 
 438     /* Evaluate/create the address and length operands */
 439 
 440     Status = AcpiDsCreateOperands (WalkState, NextOp);
 441     if (ACPI_FAILURE (Status))
 442     {
 443         return_ACPI_STATUS (Status);
 444     }
 445 
 446     /* Resolve the length and address operands to numbers */
 447 
 448     Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
 449                 ACPI_WALK_OPERANDS, WalkState);
 450     if (ACPI_FAILURE (Status))
 451     {
 452         return_ACPI_STATUS (Status);
 453     }
 454 
 455     ObjDesc = AcpiNsGetAttachedObject (Node);
 456     if (!ObjDesc)
 457     {
 458         return_ACPI_STATUS (AE_NOT_EXIST);
 459     }
 460 
 461     /*
 462      * Get the length operand and save it
 463      * (at Top of stack)
 464      */
 465     OperandDesc = WalkState->Operands[WalkState->NumOperands - 1];
 466 
 467     ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value;
 468     AcpiUtRemoveReference (OperandDesc);
 469 
 470     /*
 471      * Get the address and save it
 472      * (at top of stack - 1)
 473      */
 474     OperandDesc = WalkState->Operands[WalkState->NumOperands - 2];
 475 
 476     ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS)
 477                                 OperandDesc->Integer.Value;
 478     AcpiUtRemoveReference (OperandDesc);
 479 
 480     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
 481         ObjDesc,
 482         ACPI_FORMAT_NATIVE_UINT (ObjDesc->Region.Address),
 483         ObjDesc->Region.Length));
 484 
 485     /* Now the address and length are valid for this opregion */
 486 
 487     ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
 488 
 489     return_ACPI_STATUS (Status);
 490 }
 491 
 492 
 493 /*******************************************************************************
 494  *
 495  * FUNCTION:    AcpiDsEvalTableRegionOperands
 496  *
 497  * PARAMETERS:  WalkState       - Current walk
 498  *              Op              - A valid region Op object
 499  *
 500  * RETURN:      Status
 501  *
 502  * DESCRIPTION: Get region address and length.
 503  *              Called from AcpiDsExecEndOp during DataTableRegion parse
 504  *              tree walk.
 505  *
 506  ******************************************************************************/
 507 
 508 ACPI_STATUS
 509 AcpiDsEvalTableRegionOperands (
 510     ACPI_WALK_STATE         *WalkState,
 511     ACPI_PARSE_OBJECT       *Op)
 512 {
 513     ACPI_STATUS             Status;
 514     ACPI_OPERAND_OBJECT     *ObjDesc;
 515     ACPI_OPERAND_OBJECT     **Operand;
 516     ACPI_NAMESPACE_NODE     *Node;
 517     ACPI_PARSE_OBJECT       *NextOp;
 518     UINT32                  TableIndex;
 519     ACPI_TABLE_HEADER       *Table;
 520 
 521 
 522     ACPI_FUNCTION_TRACE_PTR (DsEvalTableRegionOperands, Op);
 523 
 524 
 525     /*
 526      * This is where we evaluate the Signature string, OemId string,
 527      * and OemTableId string of the Data Table Region declaration
 528      */
 529     Node =  Op->Common.Node;
 530 
 531     /* NextOp points to Signature string op */
 532 
 533     NextOp = Op->Common.Value.Arg;
 534 
 535     /*
 536      * Evaluate/create the Signature string, OemId string,
 537      * and OemTableId string operands
 538      */
 539     Status = AcpiDsCreateOperands (WalkState, NextOp);
 540     if (ACPI_FAILURE (Status))
 541     {
 542         return_ACPI_STATUS (Status);
 543     }
 544 
 545     /*
 546      * Resolve the Signature string, OemId string,
 547      * and OemTableId string operands
 548      */
 549     Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
 550                 ACPI_WALK_OPERANDS, WalkState);
 551     if (ACPI_FAILURE (Status))
 552     {
 553         return_ACPI_STATUS (Status);
 554     }
 555 
 556     Operand = &WalkState->Operands[0];
 557 
 558     /* Find the ACPI table */
 559 
 560     Status = AcpiTbFindTable (Operand[0]->String.Pointer,
 561                 Operand[1]->String.Pointer, Operand[2]->String.Pointer,
 562                 &TableIndex);
 563     if (ACPI_FAILURE (Status))
 564     {
 565         return_ACPI_STATUS (Status);
 566     }
 567 
 568     AcpiUtRemoveReference (Operand[0]);
 569     AcpiUtRemoveReference (Operand[1]);
 570     AcpiUtRemoveReference (Operand[2]);
 571 
 572     Status = AcpiGetTableByIndex (TableIndex, &Table);
 573     if (ACPI_FAILURE (Status))
 574     {
 575         return_ACPI_STATUS (Status);
 576     }
 577 
 578     ObjDesc = AcpiNsGetAttachedObject (Node);
 579     if (!ObjDesc)
 580     {
 581         return_ACPI_STATUS (AE_NOT_EXIST);
 582     }
 583 
 584     ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS) ACPI_TO_INTEGER (Table);
 585     ObjDesc->Region.Length = Table->Length;
 586 
 587     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
 588         ObjDesc,
 589         ACPI_FORMAT_NATIVE_UINT (ObjDesc->Region.Address),
 590         ObjDesc->Region.Length));
 591 
 592     /* Now the address and length are valid for this opregion */
 593 
 594     ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
 595 
 596     return_ACPI_STATUS (Status);
 597 }
 598 
 599 
 600 /*******************************************************************************
 601  *
 602  * FUNCTION:    AcpiDsEvalDataObjectOperands
 603  *
 604  * PARAMETERS:  WalkState       - Current walk
 605  *              Op              - A valid DataObject Op object
 606  *              ObjDesc         - DataObject
 607  *
 608  * RETURN:      Status
 609  *
 610  * DESCRIPTION: Get the operands and complete the following data object types:
 611  *              Buffer, Package.
 612  *
 613  ******************************************************************************/
 614 
 615 ACPI_STATUS
 616 AcpiDsEvalDataObjectOperands (
 617     ACPI_WALK_STATE         *WalkState,
 618     ACPI_PARSE_OBJECT       *Op,
 619     ACPI_OPERAND_OBJECT     *ObjDesc)
 620 {
 621     ACPI_STATUS             Status;
 622     ACPI_OPERAND_OBJECT     *ArgDesc;
 623     UINT32                  Length;
 624 
 625 
 626     ACPI_FUNCTION_TRACE (DsEvalDataObjectOperands);
 627 
 628 
 629     /* The first operand (for all of these data objects) is the length */
 630 
 631     /*
 632      * Set proper index into operand stack for AcpiDsObjStackPush
 633      * invoked inside AcpiDsCreateOperand.
 634      */
 635     WalkState->OperandIndex = WalkState->NumOperands;
 636 
 637     Status = AcpiDsCreateOperand (WalkState, Op->Common.Value.Arg, 1);
 638     if (ACPI_FAILURE (Status))
 639     {
 640         return_ACPI_STATUS (Status);
 641     }
 642 
 643     Status = AcpiExResolveOperands (WalkState->Opcode,
 644                     &(WalkState->Operands [WalkState->NumOperands -1]),
 645                     WalkState);
 646     if (ACPI_FAILURE (Status))
 647     {
 648         return_ACPI_STATUS (Status);
 649     }
 650 
 651     /* Extract length operand */
 652 
 653     ArgDesc = WalkState->Operands [WalkState->NumOperands - 1];
 654     Length = (UINT32) ArgDesc->Integer.Value;
 655 
 656     /* Cleanup for length operand */
 657 
 658     Status = AcpiDsObjStackPop (1, WalkState);
 659     if (ACPI_FAILURE (Status))
 660     {
 661         return_ACPI_STATUS (Status);
 662     }
 663 
 664     AcpiUtRemoveReference (ArgDesc);
 665 
 666     /*
 667      * Create the actual data object
 668      */
 669     switch (Op->Common.AmlOpcode)
 670     {
 671     case AML_BUFFER_OP:
 672 
 673         Status = AcpiDsBuildInternalBufferObj (WalkState, Op, Length, &ObjDesc);
 674         break;
 675 
 676     case AML_PACKAGE_OP:
 677     case AML_VAR_PACKAGE_OP:
 678 
 679         Status = AcpiDsBuildInternalPackageObj (WalkState, Op, Length, &ObjDesc);
 680         break;
 681 
 682     default:
 683 
 684         return_ACPI_STATUS (AE_AML_BAD_OPCODE);
 685     }
 686 
 687     if (ACPI_SUCCESS (Status))
 688     {
 689         /*
 690          * Return the object in the WalkState, unless the parent is a package -
 691          * in this case, the return object will be stored in the parse tree
 692          * for the package.
 693          */
 694         if ((!Op->Common.Parent) ||
 695             ((Op->Common.Parent->Common.AmlOpcode != AML_PACKAGE_OP) &&
 696              (Op->Common.Parent->Common.AmlOpcode != AML_VAR_PACKAGE_OP) &&
 697              (Op->Common.Parent->Common.AmlOpcode != AML_NAME_OP)))
 698         {
 699             WalkState->ResultObj = ObjDesc;
 700         }
 701     }
 702 
 703     return_ACPI_STATUS (Status);
 704 }
 705 
 706 
 707 /*******************************************************************************
 708  *
 709  * FUNCTION:    AcpiDsEvalBankFieldOperands
 710  *
 711  * PARAMETERS:  WalkState       - Current walk
 712  *              Op              - A valid BankField Op object
 713  *
 714  * RETURN:      Status
 715  *
 716  * DESCRIPTION: Get BankField BankValue
 717  *              Called from AcpiDsExecEndOp during BankField parse tree walk
 718  *
 719  ******************************************************************************/
 720 
 721 ACPI_STATUS
 722 AcpiDsEvalBankFieldOperands (
 723     ACPI_WALK_STATE         *WalkState,
 724     ACPI_PARSE_OBJECT       *Op)
 725 {
 726     ACPI_STATUS             Status;
 727     ACPI_OPERAND_OBJECT     *ObjDesc;
 728     ACPI_OPERAND_OBJECT     *OperandDesc;
 729     ACPI_NAMESPACE_NODE     *Node;
 730     ACPI_PARSE_OBJECT       *NextOp;
 731     ACPI_PARSE_OBJECT       *Arg;
 732 
 733 
 734     ACPI_FUNCTION_TRACE_PTR (DsEvalBankFieldOperands, Op);
 735 
 736 
 737     /*
 738      * This is where we evaluate the BankValue field of the
 739      * BankField declaration
 740      */
 741 
 742     /* NextOp points to the op that holds the Region */
 743 
 744     NextOp = Op->Common.Value.Arg;
 745 
 746     /* NextOp points to the op that holds the Bank Register */
 747 
 748     NextOp = NextOp->Common.Next;
 749 
 750     /* NextOp points to the op that holds the Bank Value */
 751 
 752     NextOp = NextOp->Common.Next;
 753 
 754     /*
 755      * Set proper index into operand stack for AcpiDsObjStackPush
 756      * invoked inside AcpiDsCreateOperand.
 757      *
 758      * We use WalkState->Operands[0] to store the evaluated BankValue
 759      */
 760     WalkState->OperandIndex = 0;
 761 
 762     Status = AcpiDsCreateOperand (WalkState, NextOp, 0);
 763     if (ACPI_FAILURE (Status))
 764     {
 765         return_ACPI_STATUS (Status);
 766     }
 767 
 768     Status = AcpiExResolveToValue (&WalkState->Operands[0], WalkState);
 769     if (ACPI_FAILURE (Status))
 770     {
 771         return_ACPI_STATUS (Status);
 772     }
 773 
 774     ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS,
 775         AcpiPsGetOpcodeName (Op->Common.AmlOpcode), 1);
 776     /*
 777      * Get the BankValue operand and save it
 778      * (at Top of stack)
 779      */
 780     OperandDesc = WalkState->Operands[0];
 781 
 782     /* Arg points to the start Bank Field */
 783 
 784     Arg = AcpiPsGetArg (Op, 4);
 785     while (Arg)
 786     {
 787         /* Ignore OFFSET and ACCESSAS terms here */
 788 
 789         if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
 790         {
 791             Node = Arg->Common.Node;
 792 
 793             ObjDesc = AcpiNsGetAttachedObject (Node);
 794             if (!ObjDesc)
 795             {
 796                 return_ACPI_STATUS (AE_NOT_EXIST);
 797             }
 798 
 799             ObjDesc->BankField.Value = (UINT32) OperandDesc->Integer.Value;
 800         }
 801 
 802         /* Move to next field in the list */
 803 
 804         Arg = Arg->Common.Next;
 805     }
 806 
 807     AcpiUtRemoveReference (OperandDesc);
 808     return_ACPI_STATUS (Status);
 809 }