Home | History | Annotate | Line # | Download | only in dispatcher
dsopcode.c revision 1.1.1.1
      1 /******************************************************************************
      2  *
      3  * Module Name: dsopcode - Dispatcher Op Region support and handling of
      4  *                         "control" opcodes
      5  *
      6  *****************************************************************************/
      7 
      8 /******************************************************************************
      9  *
     10  * 1. Copyright Notice
     11  *
     12  * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
     13  * All rights reserved.
     14  *
     15  * 2. License
     16  *
     17  * 2.1. This is your license from Intel Corp. under its intellectual property
     18  * rights.  You may have additional license terms from the party that provided
     19  * you this software, covering your right to use that party's intellectual
     20  * property rights.
     21  *
     22  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
     23  * copy of the source code appearing in this file ("Covered Code") an
     24  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
     25  * base code distributed originally by Intel ("Original Intel Code") to copy,
     26  * make derivatives, distribute, use and display any portion of the Covered
     27  * Code in any form, with the right to sublicense such rights; and
     28  *
     29  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
     30  * license (with the right to sublicense), under only those claims of Intel
     31  * patents that are infringed by the Original Intel Code, to make, use, sell,
     32  * offer to sell, and import the Covered Code and derivative works thereof
     33  * solely to the minimum extent necessary to exercise the above copyright
     34  * license, and in no event shall the patent license extend to any additions
     35  * to or modifications of the Original Intel Code.  No other license or right
     36  * is granted directly or by implication, estoppel or otherwise;
     37  *
     38  * The above copyright and patent license is granted only if the following
     39  * conditions are met:
     40  *
     41  * 3. Conditions
     42  *
     43  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
     44  * Redistribution of source code of any substantial portion of the Covered
     45  * Code or modification with rights to further distribute source must include
     46  * the above Copyright Notice, the above License, this list of Conditions,
     47  * and the following Disclaimer and Export Compliance provision.  In addition,
     48  * Licensee must cause all Covered Code to which Licensee contributes to
     49  * contain a file documenting the changes Licensee made to create that Covered
     50  * Code and the date of any change.  Licensee must include in that file the
     51  * documentation of any changes made by any predecessor Licensee.  Licensee
     52  * must include a prominent statement that the modification is derived,
     53  * directly or indirectly, from Original Intel Code.
     54  *
     55  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
     56  * Redistribution of source code of any substantial portion of the Covered
     57  * Code or modification without rights to further distribute source must
     58  * include the following Disclaimer and Export Compliance provision in the
     59  * documentation and/or other materials provided with distribution.  In
     60  * addition, Licensee may not authorize further sublicense of source of any
     61  * portion of the Covered Code, and must include terms to the effect that the
     62  * license from Licensee to its licensee is limited to the intellectual
     63  * property embodied in the software Licensee provides to its licensee, and
     64  * not to intellectual property embodied in modifications its licensee may
     65  * make.
     66  *
     67  * 3.3. Redistribution of Executable. Redistribution in executable form of any
     68  * substantial portion of the Covered Code or modification must reproduce the
     69  * above Copyright Notice, and the following Disclaimer and Export Compliance
     70  * provision in the documentation and/or other materials provided with the
     71  * distribution.
     72  *
     73  * 3.4. Intel retains all right, title, and interest in and to the Original
     74  * Intel Code.
     75  *
     76  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
     77  * Intel shall be used in advertising or otherwise to promote the sale, use or
     78  * other dealings in products derived from or relating to the Covered Code
     79  * without prior written authorization from Intel.
     80  *
     81  * 4. Disclaimer and Export Compliance
     82  *
     83  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
     84  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
     85  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
     86  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
     87  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
     88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
     89  * PARTICULAR PURPOSE.
     90  *
     91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
     92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
     93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
     94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
     95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
     96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
     97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
     98  * LIMITED REMEDY.
     99  *
    100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
    101  * software or system incorporating such software without first obtaining any
    102  * required license or other approval from the U. S. Department of Commerce or
    103  * any other agency or department of the United States Government.  In the
    104  * event Licensee exports any such software from the United States or
    105  * re-exports any such software from a foreign destination, Licensee shall
    106  * ensure that the distribution and export/re-export of the software is in
    107  * compliance with all laws, regulations, orders, or other restrictions of the
    108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
    109  * any of its subsidiaries will export/re-export any technical data, process,
    110  * software, or service, directly or indirectly, to any country for which the
    111  * United States government or any agency thereof requires an export license,
    112  * other governmental approval, or letter of assurance, without first obtaining
    113  * such license, approval or letter.
    114  *
    115  *****************************************************************************/
    116 
    117 #define __DSOPCODE_C__
    118 
    119 #include "acpi.h"
    120 #include "accommon.h"
    121 #include "acparser.h"
    122 #include "amlcode.h"
    123 #include "acdispat.h"
    124 #include "acinterp.h"
    125 #include "acnamesp.h"
    126 #include "acevents.h"
    127 #include "actables.h"
    128 
    129 #define _COMPONENT          ACPI_DISPATCHER
    130         ACPI_MODULE_NAME    ("dsopcode")
    131 
    132 /* Local prototypes */
    133 
    134 static ACPI_STATUS
    135 AcpiDsExecuteArguments (
    136     ACPI_NAMESPACE_NODE     *Node,
    137     ACPI_NAMESPACE_NODE     *ScopeNode,
    138     UINT32                  AmlLength,
    139     UINT8                   *AmlStart);
    140 
    141 static ACPI_STATUS
    142 AcpiDsInitBufferField (
    143     UINT16                  AmlOpcode,
    144     ACPI_OPERAND_OBJECT     *ObjDesc,
    145     ACPI_OPERAND_OBJECT     *BufferDesc,
    146     ACPI_OPERAND_OBJECT     *OffsetDesc,
    147     ACPI_OPERAND_OBJECT     *LengthDesc,
    148     ACPI_OPERAND_OBJECT     *ResultDesc);
    149 
    150 
    151 /*******************************************************************************
    152  *
    153  * FUNCTION:    AcpiDsExecuteArguments
    154  *
    155  * PARAMETERS:  Node                - Object NS node
    156  *              ScopeNode           - Parent NS node
    157  *              AmlLength           - Length of executable AML
    158  *              AmlStart            - Pointer to the AML
    159  *
    160  * RETURN:      Status.
    161  *
    162  * DESCRIPTION: Late (deferred) execution of region or field arguments
    163  *
    164  ******************************************************************************/
    165 
    166 static ACPI_STATUS
    167 AcpiDsExecuteArguments (
    168     ACPI_NAMESPACE_NODE     *Node,
    169     ACPI_NAMESPACE_NODE     *ScopeNode,
    170     UINT32                  AmlLength,
    171     UINT8                   *AmlStart)
    172 {
    173     ACPI_STATUS             Status;
    174     ACPI_PARSE_OBJECT       *Op;
    175     ACPI_WALK_STATE         *WalkState;
    176 
    177 
    178     ACPI_FUNCTION_TRACE (DsExecuteArguments);
    179 
    180 
    181     /*
    182      * Allocate a new parser op to be the root of the parsed tree
    183      */
    184     Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
    185     if (!Op)
    186     {
    187         return_ACPI_STATUS (AE_NO_MEMORY);
    188     }
    189 
    190     /* Save the Node for use in AcpiPsParseAml */
    191 
    192     Op->Common.Node = ScopeNode;
    193 
    194     /* Create and initialize a new parser state */
    195 
    196     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
    197     if (!WalkState)
    198     {
    199         Status = AE_NO_MEMORY;
    200         goto Cleanup;
    201     }
    202 
    203     Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
    204                     AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
    205     if (ACPI_FAILURE (Status))
    206     {
    207         AcpiDsDeleteWalkState (WalkState);
    208         goto Cleanup;
    209     }
    210 
    211     /* Mark this parse as a deferred opcode */
    212 
    213     WalkState->ParseFlags = ACPI_PARSE_DEFERRED_OP;
    214     WalkState->DeferredNode = Node;
    215 
    216     /* Pass1: Parse the entire declaration */
    217 
    218     Status = AcpiPsParseAml (WalkState);
    219     if (ACPI_FAILURE (Status))
    220     {
    221         goto Cleanup;
    222     }
    223 
    224     /* Get and init the Op created above */
    225 
    226     Op->Common.Node = Node;
    227     AcpiPsDeleteParseTree (Op);
    228 
    229     /* Evaluate the deferred arguments */
    230 
    231     Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
    232     if (!Op)
    233     {
    234         return_ACPI_STATUS (AE_NO_MEMORY);
    235     }
    236 
    237     Op->Common.Node = ScopeNode;
    238 
    239     /* Create and initialize a new parser state */
    240 
    241     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
    242     if (!WalkState)
    243     {
    244         Status = AE_NO_MEMORY;
    245         goto Cleanup;
    246     }
    247 
    248     /* Execute the opcode and arguments */
    249 
    250     Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
    251                     AmlLength, NULL, ACPI_IMODE_EXECUTE);
    252     if (ACPI_FAILURE (Status))
    253     {
    254         AcpiDsDeleteWalkState (WalkState);
    255         goto Cleanup;
    256     }
    257 
    258     /* Mark this execution as a deferred opcode */
    259 
    260     WalkState->DeferredNode = Node;
    261     Status = AcpiPsParseAml (WalkState);
    262 
    263 Cleanup:
    264     AcpiPsDeleteParseTree (Op);
    265     return_ACPI_STATUS (Status);
    266 }
    267 
    268 
    269 /*******************************************************************************
    270  *
    271  * FUNCTION:    AcpiDsGetBufferFieldArguments
    272  *
    273  * PARAMETERS:  ObjDesc         - A valid BufferField object
    274  *
    275  * RETURN:      Status.
    276  *
    277  * DESCRIPTION: Get BufferField Buffer and Index.  This implements the late
    278  *              evaluation of these field attributes.
    279  *
    280  ******************************************************************************/
    281 
    282 ACPI_STATUS
    283 AcpiDsGetBufferFieldArguments (
    284     ACPI_OPERAND_OBJECT     *ObjDesc)
    285 {
    286     ACPI_OPERAND_OBJECT     *ExtraDesc;
    287     ACPI_NAMESPACE_NODE     *Node;
    288     ACPI_STATUS             Status;
    289 
    290 
    291     ACPI_FUNCTION_TRACE_PTR (DsGetBufferFieldArguments, ObjDesc);
    292 
    293 
    294     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
    295     {
    296         return_ACPI_STATUS (AE_OK);
    297     }
    298 
    299     /* Get the AML pointer (method object) and BufferField node */
    300 
    301     ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
    302     Node = ObjDesc->BufferField.Node;
    303 
    304     ACPI_DEBUG_EXEC(AcpiUtDisplayInitPathname (ACPI_TYPE_BUFFER_FIELD, Node, NULL));
    305     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
    306         AcpiUtGetNodeName (Node)));
    307 
    308     /* Execute the AML code for the TermArg arguments */
    309 
    310     Status = AcpiDsExecuteArguments (Node, Node->Parent,
    311                 ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
    312     return_ACPI_STATUS (Status);
    313 }
    314 
    315 
    316 /*******************************************************************************
    317  *
    318  * FUNCTION:    AcpiDsGetBankFieldArguments
    319  *
    320  * PARAMETERS:  ObjDesc         - A valid BankField object
    321  *
    322  * RETURN:      Status.
    323  *
    324  * DESCRIPTION: Get BankField BankValue.  This implements the late
    325  *              evaluation of these field attributes.
    326  *
    327  ******************************************************************************/
    328 
    329 ACPI_STATUS
    330 AcpiDsGetBankFieldArguments (
    331     ACPI_OPERAND_OBJECT     *ObjDesc)
    332 {
    333     ACPI_OPERAND_OBJECT     *ExtraDesc;
    334     ACPI_NAMESPACE_NODE     *Node;
    335     ACPI_STATUS             Status;
    336 
    337 
    338     ACPI_FUNCTION_TRACE_PTR (DsGetBankFieldArguments, ObjDesc);
    339 
    340 
    341     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
    342     {
    343         return_ACPI_STATUS (AE_OK);
    344     }
    345 
    346     /* Get the AML pointer (method object) and BankField node */
    347 
    348     ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
    349     Node = ObjDesc->BankField.Node;
    350 
    351     ACPI_DEBUG_EXEC(AcpiUtDisplayInitPathname (ACPI_TYPE_LOCAL_BANK_FIELD, Node, NULL));
    352     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
    353         AcpiUtGetNodeName (Node)));
    354 
    355     /* Execute the AML code for the TermArg arguments */
    356 
    357     Status = AcpiDsExecuteArguments (Node, Node->Parent,
    358                 ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
    359     return_ACPI_STATUS (Status);
    360 }
    361 
    362 
    363 /*******************************************************************************
    364  *
    365  * FUNCTION:    AcpiDsGetBufferArguments
    366  *
    367  * PARAMETERS:  ObjDesc         - A valid Buffer object
    368  *
    369  * RETURN:      Status.
    370  *
    371  * DESCRIPTION: Get Buffer length and initializer byte list.  This implements
    372  *              the late evaluation of these attributes.
    373  *
    374  ******************************************************************************/
    375 
    376 ACPI_STATUS
    377 AcpiDsGetBufferArguments (
    378     ACPI_OPERAND_OBJECT     *ObjDesc)
    379 {
    380     ACPI_NAMESPACE_NODE     *Node;
    381     ACPI_STATUS             Status;
    382 
    383 
    384     ACPI_FUNCTION_TRACE_PTR (DsGetBufferArguments, ObjDesc);
    385 
    386 
    387     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
    388     {
    389         return_ACPI_STATUS (AE_OK);
    390     }
    391 
    392     /* Get the Buffer node */
    393 
    394     Node = ObjDesc->Buffer.Node;
    395     if (!Node)
    396     {
    397         ACPI_ERROR ((AE_INFO,
    398             "No pointer back to namespace node in buffer object %p", ObjDesc));
    399         return_ACPI_STATUS (AE_AML_INTERNAL);
    400     }
    401 
    402     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n"));
    403 
    404     /* Execute the AML code for the TermArg arguments */
    405 
    406     Status = AcpiDsExecuteArguments (Node, Node,
    407                 ObjDesc->Buffer.AmlLength, ObjDesc->Buffer.AmlStart);
    408     return_ACPI_STATUS (Status);
    409 }
    410 
    411 
    412 /*******************************************************************************
    413  *
    414  * FUNCTION:    AcpiDsGetPackageArguments
    415  *
    416  * PARAMETERS:  ObjDesc         - A valid Package object
    417  *
    418  * RETURN:      Status.
    419  *
    420  * DESCRIPTION: Get Package length and initializer byte list.  This implements
    421  *              the late evaluation of these attributes.
    422  *
    423  ******************************************************************************/
    424 
    425 ACPI_STATUS
    426 AcpiDsGetPackageArguments (
    427     ACPI_OPERAND_OBJECT     *ObjDesc)
    428 {
    429     ACPI_NAMESPACE_NODE     *Node;
    430     ACPI_STATUS             Status;
    431 
    432 
    433     ACPI_FUNCTION_TRACE_PTR (DsGetPackageArguments, ObjDesc);
    434 
    435 
    436     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
    437     {
    438         return_ACPI_STATUS (AE_OK);
    439     }
    440 
    441     /* Get the Package node */
    442 
    443     Node = ObjDesc->Package.Node;
    444     if (!Node)
    445     {
    446         ACPI_ERROR ((AE_INFO,
    447             "No pointer back to namespace node in package %p", ObjDesc));
    448         return_ACPI_STATUS (AE_AML_INTERNAL);
    449     }
    450 
    451     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Arg Init\n"));
    452 
    453     /* Execute the AML code for the TermArg arguments */
    454 
    455     Status = AcpiDsExecuteArguments (Node, Node,
    456                 ObjDesc->Package.AmlLength, ObjDesc->Package.AmlStart);
    457     return_ACPI_STATUS (Status);
    458 }
    459 
    460 
    461 /*****************************************************************************
    462  *
    463  * FUNCTION:    AcpiDsGetRegionArguments
    464  *
    465  * PARAMETERS:  ObjDesc         - A valid region object
    466  *
    467  * RETURN:      Status.
    468  *
    469  * DESCRIPTION: Get region address and length.  This implements the late
    470  *              evaluation of these region attributes.
    471  *
    472  ****************************************************************************/
    473 
    474 ACPI_STATUS
    475 AcpiDsGetRegionArguments (
    476     ACPI_OPERAND_OBJECT     *ObjDesc)
    477 {
    478     ACPI_NAMESPACE_NODE     *Node;
    479     ACPI_STATUS             Status;
    480     ACPI_OPERAND_OBJECT     *ExtraDesc;
    481 
    482 
    483     ACPI_FUNCTION_TRACE_PTR (DsGetRegionArguments, ObjDesc);
    484 
    485 
    486     if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID)
    487     {
    488         return_ACPI_STATUS (AE_OK);
    489     }
    490 
    491     ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
    492     if (!ExtraDesc)
    493     {
    494         return_ACPI_STATUS (AE_NOT_EXIST);
    495     }
    496 
    497     /* Get the Region node */
    498 
    499     Node = ObjDesc->Region.Node;
    500 
    501     ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_REGION, Node, NULL));
    502 
    503     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n",
    504         AcpiUtGetNodeName (Node), ExtraDesc->Extra.AmlStart));
    505 
    506     /* Execute the argument AML */
    507 
    508     Status = AcpiDsExecuteArguments (Node, Node->Parent,
    509                 ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
    510     return_ACPI_STATUS (Status);
    511 }
    512 
    513 
    514 /*******************************************************************************
    515  *
    516  * FUNCTION:    AcpiDsInitializeRegion
    517  *
    518  * PARAMETERS:  ObjHandle       - Region namespace node
    519  *
    520  * RETURN:      Status
    521  *
    522  * DESCRIPTION: Front end to EvInitializeRegion
    523  *
    524  ******************************************************************************/
    525 
    526 ACPI_STATUS
    527 AcpiDsInitializeRegion (
    528     ACPI_HANDLE             ObjHandle)
    529 {
    530     ACPI_OPERAND_OBJECT     *ObjDesc;
    531     ACPI_STATUS             Status;
    532 
    533 
    534     ObjDesc = AcpiNsGetAttachedObject (ObjHandle);
    535 
    536     /* Namespace is NOT locked */
    537 
    538     Status = AcpiEvInitializeRegion (ObjDesc, FALSE);
    539     return (Status);
    540 }
    541 
    542 
    543 /*******************************************************************************
    544  *
    545  * FUNCTION:    AcpiDsInitBufferField
    546  *
    547  * PARAMETERS:  AmlOpcode       - CreateXxxField
    548  *              ObjDesc         - BufferField object
    549  *              BufferDesc      - Host Buffer
    550  *              OffsetDesc      - Offset into buffer
    551  *              LengthDesc      - Length of field (CREATE_FIELD_OP only)
    552  *              ResultDesc      - Where to store the result
    553  *
    554  * RETURN:      Status
    555  *
    556  * DESCRIPTION: Perform actual initialization of a buffer field
    557  *
    558  ******************************************************************************/
    559 
    560 static ACPI_STATUS
    561 AcpiDsInitBufferField (
    562     UINT16                  AmlOpcode,
    563     ACPI_OPERAND_OBJECT     *ObjDesc,
    564     ACPI_OPERAND_OBJECT     *BufferDesc,
    565     ACPI_OPERAND_OBJECT     *OffsetDesc,
    566     ACPI_OPERAND_OBJECT     *LengthDesc,
    567     ACPI_OPERAND_OBJECT     *ResultDesc)
    568 {
    569     UINT32                  Offset;
    570     UINT32                  BitOffset;
    571     UINT32                  BitCount;
    572     UINT8                   FieldFlags;
    573     ACPI_STATUS             Status;
    574 
    575 
    576     ACPI_FUNCTION_TRACE_PTR (DsInitBufferField, ObjDesc);
    577 
    578 
    579     /* Host object must be a Buffer */
    580 
    581     if (BufferDesc->Common.Type != ACPI_TYPE_BUFFER)
    582     {
    583         ACPI_ERROR ((AE_INFO,
    584             "Target of Create Field is not a Buffer object - %s",
    585             AcpiUtGetObjectTypeName (BufferDesc)));
    586 
    587         Status = AE_AML_OPERAND_TYPE;
    588         goto Cleanup;
    589     }
    590 
    591     /*
    592      * The last parameter to all of these opcodes (ResultDesc) started
    593      * out as a NameString, and should therefore now be a NS node
    594      * after resolution in AcpiExResolveOperands().
    595      */
    596     if (ACPI_GET_DESCRIPTOR_TYPE (ResultDesc) != ACPI_DESC_TYPE_NAMED)
    597     {
    598         ACPI_ERROR ((AE_INFO,
    599             "(%s) destination not a NS Node [%s]",
    600             AcpiPsGetOpcodeName (AmlOpcode),
    601             AcpiUtGetDescriptorName (ResultDesc)));
    602 
    603         Status = AE_AML_OPERAND_TYPE;
    604         goto Cleanup;
    605     }
    606 
    607     Offset = (UINT32) OffsetDesc->Integer.Value;
    608 
    609     /*
    610      * Setup the Bit offsets and counts, according to the opcode
    611      */
    612     switch (AmlOpcode)
    613     {
    614     case AML_CREATE_FIELD_OP:
    615 
    616         /* Offset is in bits, count is in bits */
    617 
    618         FieldFlags = AML_FIELD_ACCESS_BYTE;
    619         BitOffset  = Offset;
    620         BitCount   = (UINT32) LengthDesc->Integer.Value;
    621 
    622         /* Must have a valid (>0) bit count */
    623 
    624         if (BitCount == 0)
    625         {
    626             ACPI_ERROR ((AE_INFO,
    627                 "Attempt to CreateField of length zero"));
    628             Status = AE_AML_OPERAND_VALUE;
    629             goto Cleanup;
    630         }
    631         break;
    632 
    633     case AML_CREATE_BIT_FIELD_OP:
    634 
    635         /* Offset is in bits, Field is one bit */
    636 
    637         BitOffset  = Offset;
    638         BitCount   = 1;
    639         FieldFlags = AML_FIELD_ACCESS_BYTE;
    640         break;
    641 
    642     case AML_CREATE_BYTE_FIELD_OP:
    643 
    644         /* Offset is in bytes, field is one byte */
    645 
    646         BitOffset  = 8 * Offset;
    647         BitCount   = 8;
    648         FieldFlags = AML_FIELD_ACCESS_BYTE;
    649         break;
    650 
    651     case AML_CREATE_WORD_FIELD_OP:
    652 
    653         /* Offset is in bytes, field is one word */
    654 
    655         BitOffset  = 8 * Offset;
    656         BitCount   = 16;
    657         FieldFlags = AML_FIELD_ACCESS_WORD;
    658         break;
    659 
    660     case AML_CREATE_DWORD_FIELD_OP:
    661 
    662         /* Offset is in bytes, field is one dword */
    663 
    664         BitOffset  = 8 * Offset;
    665         BitCount   = 32;
    666         FieldFlags = AML_FIELD_ACCESS_DWORD;
    667         break;
    668 
    669     case AML_CREATE_QWORD_FIELD_OP:
    670 
    671         /* Offset is in bytes, field is one qword */
    672 
    673         BitOffset  = 8 * Offset;
    674         BitCount   = 64;
    675         FieldFlags = AML_FIELD_ACCESS_QWORD;
    676         break;
    677 
    678     default:
    679 
    680         ACPI_ERROR ((AE_INFO,
    681             "Unknown field creation opcode 0x%02X",
    682             AmlOpcode));
    683         Status = AE_AML_BAD_OPCODE;
    684         goto Cleanup;
    685     }
    686 
    687     /* Entire field must fit within the current length of the buffer */
    688 
    689     if ((BitOffset + BitCount) >
    690         (8 * (UINT32) BufferDesc->Buffer.Length))
    691     {
    692         ACPI_ERROR ((AE_INFO,
    693             "Field [%4.4s] at %u exceeds Buffer [%4.4s] size %u (bits)",
    694             AcpiUtGetNodeName (ResultDesc),
    695             BitOffset + BitCount,
    696             AcpiUtGetNodeName (BufferDesc->Buffer.Node),
    697             8 * (UINT32) BufferDesc->Buffer.Length));
    698         Status = AE_AML_BUFFER_LIMIT;
    699         goto Cleanup;
    700     }
    701 
    702     /*
    703      * Initialize areas of the field object that are common to all fields
    704      * For FieldFlags, use LOCK_RULE = 0 (NO_LOCK),
    705      * UPDATE_RULE = 0 (UPDATE_PRESERVE)
    706      */
    707     Status = AcpiExPrepCommonFieldObject (ObjDesc, FieldFlags, 0,
    708                                             BitOffset, BitCount);
    709     if (ACPI_FAILURE (Status))
    710     {
    711         goto Cleanup;
    712     }
    713 
    714     ObjDesc->BufferField.BufferObj = BufferDesc;
    715 
    716     /* Reference count for BufferDesc inherits ObjDesc count */
    717 
    718     BufferDesc->Common.ReferenceCount = (UINT16)
    719         (BufferDesc->Common.ReferenceCount + ObjDesc->Common.ReferenceCount);
    720 
    721 
    722 Cleanup:
    723 
    724     /* Always delete the operands */
    725 
    726     AcpiUtRemoveReference (OffsetDesc);
    727     AcpiUtRemoveReference (BufferDesc);
    728 
    729     if (AmlOpcode == AML_CREATE_FIELD_OP)
    730     {
    731         AcpiUtRemoveReference (LengthDesc);
    732     }
    733 
    734     /* On failure, delete the result descriptor */
    735 
    736     if (ACPI_FAILURE (Status))
    737     {
    738         AcpiUtRemoveReference (ResultDesc);     /* Result descriptor */
    739     }
    740     else
    741     {
    742         /* Now the address and length are valid for this BufferField */
    743 
    744         ObjDesc->BufferField.Flags |= AOPOBJ_DATA_VALID;
    745     }
    746 
    747     return_ACPI_STATUS (Status);
    748 }
    749 
    750 
    751 /*******************************************************************************
    752  *
    753  * FUNCTION:    AcpiDsEvalBufferFieldOperands
    754  *
    755  * PARAMETERS:  WalkState       - Current walk
    756  *              Op              - A valid BufferField Op object
    757  *
    758  * RETURN:      Status
    759  *
    760  * DESCRIPTION: Get BufferField Buffer and Index
    761  *              Called from AcpiDsExecEndOp during BufferField parse tree walk
    762  *
    763  ******************************************************************************/
    764 
    765 ACPI_STATUS
    766 AcpiDsEvalBufferFieldOperands (
    767     ACPI_WALK_STATE         *WalkState,
    768     ACPI_PARSE_OBJECT       *Op)
    769 {
    770     ACPI_STATUS             Status;
    771     ACPI_OPERAND_OBJECT     *ObjDesc;
    772     ACPI_NAMESPACE_NODE     *Node;
    773     ACPI_PARSE_OBJECT       *NextOp;
    774 
    775 
    776     ACPI_FUNCTION_TRACE_PTR (DsEvalBufferFieldOperands, Op);
    777 
    778 
    779     /*
    780      * This is where we evaluate the address and length fields of the
    781      * CreateXxxField declaration
    782      */
    783     Node =  Op->Common.Node;
    784 
    785     /* NextOp points to the op that holds the Buffer */
    786 
    787     NextOp = Op->Common.Value.Arg;
    788 
    789     /* Evaluate/create the address and length operands */
    790 
    791     Status = AcpiDsCreateOperands (WalkState, NextOp);
    792     if (ACPI_FAILURE (Status))
    793     {
    794         return_ACPI_STATUS (Status);
    795     }
    796 
    797     ObjDesc = AcpiNsGetAttachedObject (Node);
    798     if (!ObjDesc)
    799     {
    800         return_ACPI_STATUS (AE_NOT_EXIST);
    801     }
    802 
    803     /* Resolve the operands */
    804 
    805     Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
    806                     ACPI_WALK_OPERANDS, WalkState);
    807     if (ACPI_FAILURE (Status))
    808     {
    809         ACPI_ERROR ((AE_INFO, "(%s) bad operand(s), status 0x%X",
    810             AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status));
    811 
    812         return_ACPI_STATUS (Status);
    813     }
    814 
    815     /* Initialize the Buffer Field */
    816 
    817     if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
    818     {
    819         /* NOTE: Slightly different operands for this opcode */
    820 
    821         Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
    822                     WalkState->Operands[0], WalkState->Operands[1],
    823                     WalkState->Operands[2], WalkState->Operands[3]);
    824     }
    825     else
    826     {
    827         /* All other, CreateXxxField opcodes */
    828 
    829         Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
    830                     WalkState->Operands[0], WalkState->Operands[1],
    831                                       NULL, WalkState->Operands[2]);
    832     }
    833 
    834     return_ACPI_STATUS (Status);
    835 }
    836 
    837 
    838 /*******************************************************************************
    839  *
    840  * FUNCTION:    AcpiDsEvalRegionOperands
    841  *
    842  * PARAMETERS:  WalkState       - Current walk
    843  *              Op              - A valid region Op object
    844  *
    845  * RETURN:      Status
    846  *
    847  * DESCRIPTION: Get region address and length
    848  *              Called from AcpiDsExecEndOp during OpRegion parse tree walk
    849  *
    850  ******************************************************************************/
    851 
    852 ACPI_STATUS
    853 AcpiDsEvalRegionOperands (
    854     ACPI_WALK_STATE         *WalkState,
    855     ACPI_PARSE_OBJECT       *Op)
    856 {
    857     ACPI_STATUS             Status;
    858     ACPI_OPERAND_OBJECT     *ObjDesc;
    859     ACPI_OPERAND_OBJECT     *OperandDesc;
    860     ACPI_NAMESPACE_NODE     *Node;
    861     ACPI_PARSE_OBJECT       *NextOp;
    862 
    863 
    864     ACPI_FUNCTION_TRACE_PTR (DsEvalRegionOperands, Op);
    865 
    866 
    867     /*
    868      * This is where we evaluate the address and length fields of the
    869      * OpRegion declaration
    870      */
    871     Node =  Op->Common.Node;
    872 
    873     /* NextOp points to the op that holds the SpaceID */
    874 
    875     NextOp = Op->Common.Value.Arg;
    876 
    877     /* NextOp points to address op */
    878 
    879     NextOp = NextOp->Common.Next;
    880 
    881     /* Evaluate/create the address and length operands */
    882 
    883     Status = AcpiDsCreateOperands (WalkState, NextOp);
    884     if (ACPI_FAILURE (Status))
    885     {
    886         return_ACPI_STATUS (Status);
    887     }
    888 
    889     /* Resolve the length and address operands to numbers */
    890 
    891     Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
    892                 ACPI_WALK_OPERANDS, WalkState);
    893     if (ACPI_FAILURE (Status))
    894     {
    895         return_ACPI_STATUS (Status);
    896     }
    897 
    898     ObjDesc = AcpiNsGetAttachedObject (Node);
    899     if (!ObjDesc)
    900     {
    901         return_ACPI_STATUS (AE_NOT_EXIST);
    902     }
    903 
    904     /*
    905      * Get the length operand and save it
    906      * (at Top of stack)
    907      */
    908     OperandDesc = WalkState->Operands[WalkState->NumOperands - 1];
    909 
    910     ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value;
    911     AcpiUtRemoveReference (OperandDesc);
    912 
    913     /*
    914      * Get the address and save it
    915      * (at top of stack - 1)
    916      */
    917     OperandDesc = WalkState->Operands[WalkState->NumOperands - 2];
    918 
    919     ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS)
    920                                 OperandDesc->Integer.Value;
    921     AcpiUtRemoveReference (OperandDesc);
    922 
    923     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
    924         ObjDesc,
    925         ACPI_FORMAT_NATIVE_UINT (ObjDesc->Region.Address),
    926         ObjDesc->Region.Length));
    927 
    928     /* Now the address and length are valid for this opregion */
    929 
    930     ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
    931 
    932     return_ACPI_STATUS (Status);
    933 }
    934 
    935 
    936 /*******************************************************************************
    937  *
    938  * FUNCTION:    AcpiDsEvalTableRegionOperands
    939  *
    940  * PARAMETERS:  WalkState       - Current walk
    941  *              Op              - A valid region Op object
    942  *
    943  * RETURN:      Status
    944  *
    945  * DESCRIPTION: Get region address and length
    946  *              Called from AcpiDsExecEndOp during DataTableRegion parse tree walk
    947  *
    948  ******************************************************************************/
    949 
    950 ACPI_STATUS
    951 AcpiDsEvalTableRegionOperands (
    952     ACPI_WALK_STATE         *WalkState,
    953     ACPI_PARSE_OBJECT       *Op)
    954 {
    955     ACPI_STATUS             Status;
    956     ACPI_OPERAND_OBJECT     *ObjDesc;
    957     ACPI_OPERAND_OBJECT     **Operand;
    958     ACPI_NAMESPACE_NODE     *Node;
    959     ACPI_PARSE_OBJECT       *NextOp;
    960     UINT32                  TableIndex;
    961     ACPI_TABLE_HEADER       *Table;
    962 
    963 
    964     ACPI_FUNCTION_TRACE_PTR (DsEvalTableRegionOperands, Op);
    965 
    966 
    967     /*
    968      * This is where we evaluate the SignatureString and OemIDString
    969      * and OemTableIDString of the DataTableRegion declaration
    970      */
    971     Node =  Op->Common.Node;
    972 
    973     /* NextOp points to SignatureString op */
    974 
    975     NextOp = Op->Common.Value.Arg;
    976 
    977     /*
    978      * Evaluate/create the SignatureString and OemIDString
    979      * and OemTableIDString operands
    980      */
    981     Status = AcpiDsCreateOperands (WalkState, NextOp);
    982     if (ACPI_FAILURE (Status))
    983     {
    984         return_ACPI_STATUS (Status);
    985     }
    986 
    987     /*
    988      * Resolve the SignatureString and OemIDString
    989      * and OemTableIDString operands
    990      */
    991     Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
    992                 ACPI_WALK_OPERANDS, WalkState);
    993     if (ACPI_FAILURE (Status))
    994     {
    995         return_ACPI_STATUS (Status);
    996     }
    997 
    998     Operand = &WalkState->Operands[0];
    999 
   1000     /* Find the ACPI table */
   1001 
   1002     Status = AcpiTbFindTable (Operand[0]->String.Pointer,
   1003                 Operand[1]->String.Pointer, Operand[2]->String.Pointer,
   1004                 &TableIndex);
   1005     if (ACPI_FAILURE (Status))
   1006     {
   1007         return_ACPI_STATUS (Status);
   1008     }
   1009 
   1010     AcpiUtRemoveReference (Operand[0]);
   1011     AcpiUtRemoveReference (Operand[1]);
   1012     AcpiUtRemoveReference (Operand[2]);
   1013 
   1014     Status = AcpiGetTableByIndex (TableIndex, &Table);
   1015     if (ACPI_FAILURE (Status))
   1016     {
   1017         return_ACPI_STATUS (Status);
   1018     }
   1019 
   1020     ObjDesc = AcpiNsGetAttachedObject (Node);
   1021     if (!ObjDesc)
   1022     {
   1023         return_ACPI_STATUS (AE_NOT_EXIST);
   1024     }
   1025 
   1026     ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS) ACPI_TO_INTEGER (Table);
   1027     ObjDesc->Region.Length = Table->Length;
   1028 
   1029     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
   1030         ObjDesc,
   1031         ACPI_FORMAT_NATIVE_UINT (ObjDesc->Region.Address),
   1032         ObjDesc->Region.Length));
   1033 
   1034     /* Now the address and length are valid for this opregion */
   1035 
   1036     ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
   1037 
   1038     return_ACPI_STATUS (Status);
   1039 }
   1040 
   1041 
   1042 /*******************************************************************************
   1043  *
   1044  * FUNCTION:    AcpiDsEvalDataObjectOperands
   1045  *
   1046  * PARAMETERS:  WalkState       - Current walk
   1047  *              Op              - A valid DataObject Op object
   1048  *              ObjDesc         - DataObject
   1049  *
   1050  * RETURN:      Status
   1051  *
   1052  * DESCRIPTION: Get the operands and complete the following data object types:
   1053  *              Buffer, Package.
   1054  *
   1055  ******************************************************************************/
   1056 
   1057 ACPI_STATUS
   1058 AcpiDsEvalDataObjectOperands (
   1059     ACPI_WALK_STATE         *WalkState,
   1060     ACPI_PARSE_OBJECT       *Op,
   1061     ACPI_OPERAND_OBJECT     *ObjDesc)
   1062 {
   1063     ACPI_STATUS             Status;
   1064     ACPI_OPERAND_OBJECT     *ArgDesc;
   1065     UINT32                  Length;
   1066 
   1067 
   1068     ACPI_FUNCTION_TRACE (DsEvalDataObjectOperands);
   1069 
   1070 
   1071     /* The first operand (for all of these data objects) is the length */
   1072 
   1073     /*
   1074      * Set proper index into operand stack for AcpiDsObjStackPush
   1075      * invoked inside AcpiDsCreateOperand.
   1076      */
   1077     WalkState->OperandIndex = WalkState->NumOperands;
   1078 
   1079     Status = AcpiDsCreateOperand (WalkState, Op->Common.Value.Arg, 1);
   1080     if (ACPI_FAILURE (Status))
   1081     {
   1082         return_ACPI_STATUS (Status);
   1083     }
   1084 
   1085     Status = AcpiExResolveOperands (WalkState->Opcode,
   1086                     &(WalkState->Operands [WalkState->NumOperands -1]),
   1087                     WalkState);
   1088     if (ACPI_FAILURE (Status))
   1089     {
   1090         return_ACPI_STATUS (Status);
   1091     }
   1092 
   1093     /* Extract length operand */
   1094 
   1095     ArgDesc = WalkState->Operands [WalkState->NumOperands - 1];
   1096     Length = (UINT32) ArgDesc->Integer.Value;
   1097 
   1098     /* Cleanup for length operand */
   1099 
   1100     Status = AcpiDsObjStackPop (1, WalkState);
   1101     if (ACPI_FAILURE (Status))
   1102     {
   1103         return_ACPI_STATUS (Status);
   1104     }
   1105 
   1106     AcpiUtRemoveReference (ArgDesc);
   1107 
   1108     /*
   1109      * Create the actual data object
   1110      */
   1111     switch (Op->Common.AmlOpcode)
   1112     {
   1113     case AML_BUFFER_OP:
   1114 
   1115         Status = AcpiDsBuildInternalBufferObj (WalkState, Op, Length, &ObjDesc);
   1116         break;
   1117 
   1118     case AML_PACKAGE_OP:
   1119     case AML_VAR_PACKAGE_OP:
   1120 
   1121         Status = AcpiDsBuildInternalPackageObj (WalkState, Op, Length, &ObjDesc);
   1122         break;
   1123 
   1124     default:
   1125         return_ACPI_STATUS (AE_AML_BAD_OPCODE);
   1126     }
   1127 
   1128     if (ACPI_SUCCESS (Status))
   1129     {
   1130         /*
   1131          * Return the object in the WalkState, unless the parent is a package -
   1132          * in this case, the return object will be stored in the parse tree
   1133          * for the package.
   1134          */
   1135         if ((!Op->Common.Parent) ||
   1136             ((Op->Common.Parent->Common.AmlOpcode != AML_PACKAGE_OP) &&
   1137              (Op->Common.Parent->Common.AmlOpcode != AML_VAR_PACKAGE_OP) &&
   1138              (Op->Common.Parent->Common.AmlOpcode != AML_NAME_OP)))
   1139         {
   1140             WalkState->ResultObj = ObjDesc;
   1141         }
   1142     }
   1143 
   1144     return_ACPI_STATUS (Status);
   1145 }
   1146 
   1147 
   1148 /*******************************************************************************
   1149  *
   1150  * FUNCTION:    AcpiDsEvalBankFieldOperands
   1151  *
   1152  * PARAMETERS:  WalkState       - Current walk
   1153  *              Op              - A valid BankField Op object
   1154  *
   1155  * RETURN:      Status
   1156  *
   1157  * DESCRIPTION: Get BankField BankValue
   1158  *              Called from AcpiDsExecEndOp during BankField parse tree walk
   1159  *
   1160  ******************************************************************************/
   1161 
   1162 ACPI_STATUS
   1163 AcpiDsEvalBankFieldOperands (
   1164     ACPI_WALK_STATE         *WalkState,
   1165     ACPI_PARSE_OBJECT       *Op)
   1166 {
   1167     ACPI_STATUS             Status;
   1168     ACPI_OPERAND_OBJECT     *ObjDesc;
   1169     ACPI_OPERAND_OBJECT     *OperandDesc;
   1170     ACPI_NAMESPACE_NODE     *Node;
   1171     ACPI_PARSE_OBJECT       *NextOp;
   1172     ACPI_PARSE_OBJECT       *Arg;
   1173 
   1174 
   1175     ACPI_FUNCTION_TRACE_PTR (DsEvalBankFieldOperands, Op);
   1176 
   1177 
   1178     /*
   1179      * This is where we evaluate the BankValue field of the
   1180      * BankField declaration
   1181      */
   1182 
   1183     /* NextOp points to the op that holds the Region */
   1184 
   1185     NextOp = Op->Common.Value.Arg;
   1186 
   1187     /* NextOp points to the op that holds the Bank Register */
   1188 
   1189     NextOp = NextOp->Common.Next;
   1190 
   1191     /* NextOp points to the op that holds the Bank Value */
   1192 
   1193     NextOp = NextOp->Common.Next;
   1194 
   1195     /*
   1196      * Set proper index into operand stack for AcpiDsObjStackPush
   1197      * invoked inside AcpiDsCreateOperand.
   1198      *
   1199      * We use WalkState->Operands[0] to store the evaluated BankValue
   1200      */
   1201     WalkState->OperandIndex = 0;
   1202 
   1203     Status = AcpiDsCreateOperand (WalkState, NextOp, 0);
   1204     if (ACPI_FAILURE (Status))
   1205     {
   1206         return_ACPI_STATUS (Status);
   1207     }
   1208 
   1209     Status = AcpiExResolveToValue (&WalkState->Operands[0], WalkState);
   1210     if (ACPI_FAILURE (Status))
   1211     {
   1212         return_ACPI_STATUS (Status);
   1213     }
   1214 
   1215     ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS,
   1216         AcpiPsGetOpcodeName (Op->Common.AmlOpcode), 1);
   1217     /*
   1218      * Get the BankValue operand and save it
   1219      * (at Top of stack)
   1220      */
   1221     OperandDesc = WalkState->Operands[0];
   1222 
   1223     /* Arg points to the start Bank Field */
   1224 
   1225     Arg = AcpiPsGetArg (Op, 4);
   1226     while (Arg)
   1227     {
   1228         /* Ignore OFFSET and ACCESSAS terms here */
   1229 
   1230         if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
   1231         {
   1232             Node = Arg->Common.Node;
   1233 
   1234             ObjDesc = AcpiNsGetAttachedObject (Node);
   1235             if (!ObjDesc)
   1236             {
   1237                 return_ACPI_STATUS (AE_NOT_EXIST);
   1238             }
   1239 
   1240             ObjDesc->BankField.Value = (UINT32) OperandDesc->Integer.Value;
   1241         }
   1242 
   1243         /* Move to next field in the list */
   1244 
   1245         Arg = Arg->Common.Next;
   1246     }
   1247 
   1248     AcpiUtRemoveReference (OperandDesc);
   1249     return_ACPI_STATUS (Status);
   1250 }
   1251 
   1252 
   1253 /*******************************************************************************
   1254  *
   1255  * FUNCTION:    AcpiDsExecBeginControlOp
   1256  *
   1257  * PARAMETERS:  WalkList        - The list that owns the walk stack
   1258  *              Op              - The control Op
   1259  *
   1260  * RETURN:      Status
   1261  *
   1262  * DESCRIPTION: Handles all control ops encountered during control method
   1263  *              execution.
   1264  *
   1265  ******************************************************************************/
   1266 
   1267 ACPI_STATUS
   1268 AcpiDsExecBeginControlOp (
   1269     ACPI_WALK_STATE         *WalkState,
   1270     ACPI_PARSE_OBJECT       *Op)
   1271 {
   1272     ACPI_STATUS             Status = AE_OK;
   1273     ACPI_GENERIC_STATE      *ControlState;
   1274 
   1275 
   1276     ACPI_FUNCTION_NAME (DsExecBeginControlOp);
   1277 
   1278 
   1279     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", Op,
   1280         Op->Common.AmlOpcode, WalkState));
   1281 
   1282     switch (Op->Common.AmlOpcode)
   1283     {
   1284     case AML_WHILE_OP:
   1285 
   1286         /*
   1287          * If this is an additional iteration of a while loop, continue.
   1288          * There is no need to allocate a new control state.
   1289          */
   1290         if (WalkState->ControlState)
   1291         {
   1292             if (WalkState->ControlState->Control.AmlPredicateStart ==
   1293                 (WalkState->ParserState.Aml - 1))
   1294             {
   1295                 /* Reset the state to start-of-loop */
   1296 
   1297                 WalkState->ControlState->Common.State = ACPI_CONTROL_CONDITIONAL_EXECUTING;
   1298                 break;
   1299             }
   1300         }
   1301 
   1302         /*lint -fallthrough */
   1303 
   1304     case AML_IF_OP:
   1305 
   1306         /*
   1307          * IF/WHILE: Create a new control state to manage these
   1308          * constructs. We need to manage these as a stack, in order
   1309          * to handle nesting.
   1310          */
   1311         ControlState = AcpiUtCreateControlState ();
   1312         if (!ControlState)
   1313         {
   1314             Status = AE_NO_MEMORY;
   1315             break;
   1316         }
   1317         /*
   1318          * Save a pointer to the predicate for multiple executions
   1319          * of a loop
   1320          */
   1321         ControlState->Control.AmlPredicateStart = WalkState->ParserState.Aml - 1;
   1322         ControlState->Control.PackageEnd = WalkState->ParserState.PkgEnd;
   1323         ControlState->Control.Opcode = Op->Common.AmlOpcode;
   1324 
   1325 
   1326         /* Push the control state on this walk's control stack */
   1327 
   1328         AcpiUtPushGenericState (&WalkState->ControlState, ControlState);
   1329         break;
   1330 
   1331     case AML_ELSE_OP:
   1332 
   1333         /* Predicate is in the state object */
   1334         /* If predicate is true, the IF was executed, ignore ELSE part */
   1335 
   1336         if (WalkState->LastPredicate)
   1337         {
   1338             Status = AE_CTRL_TRUE;
   1339         }
   1340 
   1341         break;
   1342 
   1343     case AML_RETURN_OP:
   1344 
   1345         break;
   1346 
   1347     default:
   1348         break;
   1349     }
   1350 
   1351     return (Status);
   1352 }
   1353 
   1354 
   1355 /*******************************************************************************
   1356  *
   1357  * FUNCTION:    AcpiDsExecEndControlOp
   1358  *
   1359  * PARAMETERS:  WalkList        - The list that owns the walk stack
   1360  *              Op              - The control Op
   1361  *
   1362  * RETURN:      Status
   1363  *
   1364  * DESCRIPTION: Handles all control ops encountered during control method
   1365  *              execution.
   1366  *
   1367  ******************************************************************************/
   1368 
   1369 ACPI_STATUS
   1370 AcpiDsExecEndControlOp (
   1371     ACPI_WALK_STATE         *WalkState,
   1372     ACPI_PARSE_OBJECT       *Op)
   1373 {
   1374     ACPI_STATUS             Status = AE_OK;
   1375     ACPI_GENERIC_STATE      *ControlState;
   1376 
   1377 
   1378     ACPI_FUNCTION_NAME (DsExecEndControlOp);
   1379 
   1380 
   1381     switch (Op->Common.AmlOpcode)
   1382     {
   1383     case AML_IF_OP:
   1384 
   1385         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", Op));
   1386 
   1387         /*
   1388          * Save the result of the predicate in case there is an
   1389          * ELSE to come
   1390          */
   1391         WalkState->LastPredicate =
   1392             (BOOLEAN) WalkState->ControlState->Common.Value;
   1393 
   1394         /*
   1395          * Pop the control state that was created at the start
   1396          * of the IF and free it
   1397          */
   1398         ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
   1399         AcpiUtDeleteGenericState (ControlState);
   1400         break;
   1401 
   1402 
   1403     case AML_ELSE_OP:
   1404 
   1405         break;
   1406 
   1407 
   1408     case AML_WHILE_OP:
   1409 
   1410         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", Op));
   1411 
   1412         ControlState = WalkState->ControlState;
   1413         if (ControlState->Common.Value)
   1414         {
   1415             /* Predicate was true, the body of the loop was just executed */
   1416 
   1417             /*
   1418              * This loop counter mechanism allows the interpreter to escape
   1419              * possibly infinite loops. This can occur in poorly written AML
   1420              * when the hardware does not respond within a while loop and the
   1421              * loop does not implement a timeout.
   1422              */
   1423             ControlState->Control.LoopCount++;
   1424             if (ControlState->Control.LoopCount > ACPI_MAX_LOOP_ITERATIONS)
   1425             {
   1426                 Status = AE_AML_INFINITE_LOOP;
   1427                 break;
   1428             }
   1429 
   1430             /*
   1431              * Go back and evaluate the predicate and maybe execute the loop
   1432              * another time
   1433              */
   1434             Status = AE_CTRL_PENDING;
   1435             WalkState->AmlLastWhile = ControlState->Control.AmlPredicateStart;
   1436             break;
   1437         }
   1438 
   1439         /* Predicate was false, terminate this while loop */
   1440 
   1441         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
   1442             "[WHILE_OP] termination! Op=%p\n",Op));
   1443 
   1444         /* Pop this control state and free it */
   1445 
   1446         ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
   1447         AcpiUtDeleteGenericState (ControlState);
   1448         break;
   1449 
   1450 
   1451     case AML_RETURN_OP:
   1452 
   1453         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
   1454             "[RETURN_OP] Op=%p Arg=%p\n",Op, Op->Common.Value.Arg));
   1455 
   1456         /*
   1457          * One optional operand -- the return value
   1458          * It can be either an immediate operand or a result that
   1459          * has been bubbled up the tree
   1460          */
   1461         if (Op->Common.Value.Arg)
   1462         {
   1463             /* Since we have a real Return(), delete any implicit return */
   1464 
   1465             AcpiDsClearImplicitReturn (WalkState);
   1466 
   1467             /* Return statement has an immediate operand */
   1468 
   1469             Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg);
   1470             if (ACPI_FAILURE (Status))
   1471             {
   1472                 return (Status);
   1473             }
   1474 
   1475             /*
   1476              * If value being returned is a Reference (such as
   1477              * an arg or local), resolve it now because it may
   1478              * cease to exist at the end of the method.
   1479              */
   1480             Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
   1481             if (ACPI_FAILURE (Status))
   1482             {
   1483                 return (Status);
   1484             }
   1485 
   1486             /*
   1487              * Get the return value and save as the last result
   1488              * value.  This is the only place where WalkState->ReturnDesc
   1489              * is set to anything other than zero!
   1490              */
   1491             WalkState->ReturnDesc = WalkState->Operands[0];
   1492         }
   1493         else if (WalkState->ResultCount)
   1494         {
   1495             /* Since we have a real Return(), delete any implicit return */
   1496 
   1497             AcpiDsClearImplicitReturn (WalkState);
   1498 
   1499             /*
   1500              * The return value has come from a previous calculation.
   1501              *
   1502              * If value being returned is a Reference (such as
   1503              * an arg or local), resolve it now because it may
   1504              * cease to exist at the end of the method.
   1505              *
   1506              * Allow references created by the Index operator to return unchanged.
   1507              */
   1508             if ((ACPI_GET_DESCRIPTOR_TYPE (WalkState->Results->Results.ObjDesc[0]) == ACPI_DESC_TYPE_OPERAND) &&
   1509                 ((WalkState->Results->Results.ObjDesc [0])->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
   1510                 ((WalkState->Results->Results.ObjDesc [0])->Reference.Class != ACPI_REFCLASS_INDEX))
   1511             {
   1512                 Status = AcpiExResolveToValue (&WalkState->Results->Results.ObjDesc [0], WalkState);
   1513                 if (ACPI_FAILURE (Status))
   1514                 {
   1515                     return (Status);
   1516                 }
   1517             }
   1518 
   1519             WalkState->ReturnDesc = WalkState->Results->Results.ObjDesc [0];
   1520         }
   1521         else
   1522         {
   1523             /* No return operand */
   1524 
   1525             if (WalkState->NumOperands)
   1526             {
   1527                 AcpiUtRemoveReference (WalkState->Operands [0]);
   1528             }
   1529 
   1530             WalkState->Operands [0]     = NULL;
   1531             WalkState->NumOperands      = 0;
   1532             WalkState->ReturnDesc       = NULL;
   1533         }
   1534 
   1535 
   1536         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
   1537             "Completed RETURN_OP State=%p, RetVal=%p\n",
   1538             WalkState, WalkState->ReturnDesc));
   1539 
   1540         /* End the control method execution right now */
   1541 
   1542         Status = AE_CTRL_TERMINATE;
   1543         break;
   1544 
   1545 
   1546     case AML_NOOP_OP:
   1547 
   1548         /* Just do nothing! */
   1549         break;
   1550 
   1551 
   1552     case AML_BREAK_POINT_OP:
   1553 
   1554         /*
   1555          * Set the single-step flag. This will cause the debugger (if present)
   1556          * to break to the console within the AML debugger at the start of the
   1557          * next AML instruction.
   1558          */
   1559         ACPI_DEBUGGER_EXEC (
   1560             AcpiGbl_CmSingleStep = TRUE);
   1561         ACPI_DEBUGGER_EXEC (
   1562             AcpiOsPrintf ("**break** Executed AML BreakPoint opcode\n"));
   1563 
   1564         /* Call to the OSL in case OS wants a piece of the action */
   1565 
   1566         Status = AcpiOsSignal (ACPI_SIGNAL_BREAKPOINT,
   1567                     "Executed AML Breakpoint opcode");
   1568         break;
   1569 
   1570 
   1571     case AML_BREAK_OP:
   1572     case AML_CONTINUE_OP: /* ACPI 2.0 */
   1573 
   1574 
   1575         /* Pop and delete control states until we find a while */
   1576 
   1577         while (WalkState->ControlState &&
   1578                 (WalkState->ControlState->Control.Opcode != AML_WHILE_OP))
   1579         {
   1580             ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
   1581             AcpiUtDeleteGenericState (ControlState);
   1582         }
   1583 
   1584         /* No while found? */
   1585 
   1586         if (!WalkState->ControlState)
   1587         {
   1588             return (AE_AML_NO_WHILE);
   1589         }
   1590 
   1591         /* Was: WalkState->AmlLastWhile = WalkState->ControlState->Control.AmlPredicateStart; */
   1592 
   1593         WalkState->AmlLastWhile = WalkState->ControlState->Control.PackageEnd;
   1594 
   1595         /* Return status depending on opcode */
   1596 
   1597         if (Op->Common.AmlOpcode == AML_BREAK_OP)
   1598         {
   1599             Status = AE_CTRL_BREAK;
   1600         }
   1601         else
   1602         {
   1603             Status = AE_CTRL_CONTINUE;
   1604         }
   1605         break;
   1606 
   1607 
   1608     default:
   1609 
   1610         ACPI_ERROR ((AE_INFO, "Unknown control opcode=0x%X Op=%p",
   1611             Op->Common.AmlOpcode, Op));
   1612 
   1613         Status = AE_AML_BAD_OPCODE;
   1614         break;
   1615     }
   1616 
   1617     return (Status);
   1618 }
   1619 
   1620