Home | History | Annotate | Line # | Download | only in dispatcher
dswexec.c revision 1.3
      1 /******************************************************************************
      2  *
      3  * Module Name: dswexec - Dispatcher method execution callbacks;
      4  *                        dispatch to interpreter.
      5  *
      6  *****************************************************************************/
      7 
      8 /*
      9  * Copyright (C) 2000 - 2023, Intel Corp.
     10  * All rights reserved.
     11  *
     12  * Redistribution and use in source and binary forms, with or without
     13  * modification, are permitted provided that the following conditions
     14  * are met:
     15  * 1. Redistributions of source code must retain the above copyright
     16  *    notice, this list of conditions, and the following disclaimer,
     17  *    without modification.
     18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     19  *    substantially similar to the "NO WARRANTY" disclaimer below
     20  *    ("Disclaimer") and any redistribution must be conditioned upon
     21  *    including a substantially similar Disclaimer requirement for further
     22  *    binary redistribution.
     23  * 3. Neither the names of the above-listed copyright holders nor the names
     24  *    of any contributors may be used to endorse or promote products derived
     25  *    from this software without specific prior written permission.
     26  *
     27  * Alternatively, this software may be distributed under the terms of the
     28  * GNU General Public License ("GPL") version 2 as published by the Free
     29  * Software Foundation.
     30  *
     31  * NO WARRANTY
     32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     42  * POSSIBILITY OF SUCH DAMAGES.
     43  */
     44 
     45 #include "acpi.h"
     46 #include "accommon.h"
     47 #include "acparser.h"
     48 #include "amlcode.h"
     49 #include "acdispat.h"
     50 #include "acinterp.h"
     51 #include "acnamesp.h"
     52 #include "acdebug.h"
     53 #ifdef ACPI_EXEC_APP
     54 #include "aecommon.h"
     55 #endif
     56 
     57 #define _COMPONENT          ACPI_DISPATCHER
     58         ACPI_MODULE_NAME    ("dswexec")
     59 
     60 /*
     61  * Dispatch table for opcode classes
     62  */
     63 static ACPI_EXECUTE_OP      AcpiGbl_OpTypeDispatch [] =
     64 {
     65     AcpiExOpcode_0A_0T_1R,
     66     AcpiExOpcode_1A_0T_0R,
     67     AcpiExOpcode_1A_0T_1R,
     68     NULL,   /* Was: AcpiExOpcode_1A_0T_0R (Was for Load operator) */
     69     AcpiExOpcode_1A_1T_1R,
     70     AcpiExOpcode_2A_0T_0R,
     71     AcpiExOpcode_2A_0T_1R,
     72     AcpiExOpcode_2A_1T_1R,
     73     AcpiExOpcode_2A_2T_1R,
     74     AcpiExOpcode_3A_0T_0R,
     75     AcpiExOpcode_3A_1T_1R,
     76     AcpiExOpcode_6A_0T_1R
     77 };
     78 
     79 
     80 /*****************************************************************************
     81  *
     82  * FUNCTION:    AcpiDsGetPredicateValue
     83  *
     84  * PARAMETERS:  WalkState       - Current state of the parse tree walk
     85  *              ResultObj       - if non-zero, pop result from result stack
     86  *
     87  * RETURN:      Status
     88  *
     89  * DESCRIPTION: Get the result of a predicate evaluation
     90  *
     91  ****************************************************************************/
     92 
     93 ACPI_STATUS
     94 AcpiDsGetPredicateValue (
     95     ACPI_WALK_STATE         *WalkState,
     96     ACPI_OPERAND_OBJECT     *ResultObj)
     97 {
     98     ACPI_STATUS             Status = AE_OK;
     99     ACPI_OPERAND_OBJECT     *ObjDesc;
    100     ACPI_OPERAND_OBJECT     *LocalObjDesc = NULL;
    101 
    102 
    103     ACPI_FUNCTION_TRACE_PTR (DsGetPredicateValue, WalkState);
    104 
    105 
    106     WalkState->ControlState->Common.State = 0;
    107 
    108     if (ResultObj)
    109     {
    110         Status = AcpiDsResultPop (&ObjDesc, WalkState);
    111         if (ACPI_FAILURE (Status))
    112         {
    113             ACPI_EXCEPTION ((AE_INFO, Status,
    114                 "Could not get result from predicate evaluation"));
    115 
    116             return_ACPI_STATUS (Status);
    117         }
    118     }
    119     else
    120     {
    121         Status = AcpiDsCreateOperand (WalkState, WalkState->Op, 0);
    122         if (ACPI_FAILURE (Status))
    123         {
    124             return_ACPI_STATUS (Status);
    125         }
    126 
    127         Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
    128         if (ACPI_FAILURE (Status))
    129         {
    130             return_ACPI_STATUS (Status);
    131         }
    132 
    133         ObjDesc = WalkState->Operands [0];
    134     }
    135 
    136     if (!ObjDesc)
    137     {
    138         ACPI_ERROR ((AE_INFO,
    139             "No predicate ObjDesc=%p State=%p",
    140             ObjDesc, WalkState));
    141 
    142         return_ACPI_STATUS (AE_AML_NO_OPERAND);
    143     }
    144 
    145     /*
    146      * Result of predicate evaluation must be an Integer
    147      * object. Implicitly convert the argument if necessary.
    148      */
    149     Status = AcpiExConvertToInteger (ObjDesc, &LocalObjDesc,
    150         ACPI_IMPLICIT_CONVERSION);
    151     if (ACPI_FAILURE (Status))
    152     {
    153         goto Cleanup;
    154     }
    155 
    156     if (LocalObjDesc->Common.Type != ACPI_TYPE_INTEGER)
    157     {
    158         ACPI_ERROR ((AE_INFO,
    159             "Bad predicate (not an integer) ObjDesc=%p State=%p Type=0x%X",
    160             ObjDesc, WalkState, ObjDesc->Common.Type));
    161 
    162         Status = AE_AML_OPERAND_TYPE;
    163         goto Cleanup;
    164     }
    165 
    166     /* Truncate the predicate to 32-bits if necessary */
    167 
    168     (void) AcpiExTruncateFor32bitTable (LocalObjDesc);
    169 
    170     /*
    171      * Save the result of the predicate evaluation on
    172      * the control stack
    173      */
    174     if (LocalObjDesc->Integer.Value)
    175     {
    176         WalkState->ControlState->Common.Value = TRUE;
    177     }
    178     else
    179     {
    180         /*
    181          * Predicate is FALSE, we will just toss the
    182          * rest of the package
    183          */
    184         WalkState->ControlState->Common.Value = FALSE;
    185         Status = AE_CTRL_FALSE;
    186     }
    187 
    188     /* Predicate can be used for an implicit return value */
    189 
    190     (void) AcpiDsDoImplicitReturn (LocalObjDesc, WalkState, TRUE);
    191 
    192 
    193 Cleanup:
    194 
    195     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
    196         "Completed a predicate eval=%X Op=%p\n",
    197         WalkState->ControlState->Common.Value, WalkState->Op));
    198 
    199     /* Break to debugger to display result */
    200 
    201     AcpiDbDisplayResultObject (LocalObjDesc, WalkState);
    202 
    203     /*
    204      * Delete the predicate result object (we know that
    205      * we don't need it anymore)
    206      */
    207     if (LocalObjDesc != ObjDesc)
    208     {
    209         AcpiUtRemoveReference (LocalObjDesc);
    210     }
    211     AcpiUtRemoveReference (ObjDesc);
    212 
    213     WalkState->ControlState->Common.State = ACPI_CONTROL_NORMAL;
    214     return_ACPI_STATUS (Status);
    215 }
    216 
    217 
    218 /*****************************************************************************
    219  *
    220  * FUNCTION:    AcpiDsExecBeginOp
    221  *
    222  * PARAMETERS:  WalkState       - Current state of the parse tree walk
    223  *              OutOp           - Where to return op if a new one is created
    224  *
    225  * RETURN:      Status
    226  *
    227  * DESCRIPTION: Descending callback used during the execution of control
    228  *              methods. This is where most operators and operands are
    229  *              dispatched to the interpreter.
    230  *
    231  ****************************************************************************/
    232 
    233 ACPI_STATUS
    234 AcpiDsExecBeginOp (
    235     ACPI_WALK_STATE         *WalkState,
    236     ACPI_PARSE_OBJECT       **OutOp)
    237 {
    238     ACPI_PARSE_OBJECT       *Op;
    239     ACPI_STATUS             Status = AE_OK;
    240     UINT32                  OpcodeClass;
    241 
    242 
    243     ACPI_FUNCTION_TRACE_PTR (DsExecBeginOp, WalkState);
    244 
    245 
    246     Op = WalkState->Op;
    247     if (!Op)
    248     {
    249         Status = AcpiDsLoad2BeginOp (WalkState, OutOp);
    250         if (ACPI_FAILURE (Status))
    251         {
    252             goto ErrorExit;
    253         }
    254 
    255         Op = *OutOp;
    256         WalkState->Op = Op;
    257         WalkState->Opcode = Op->Common.AmlOpcode;
    258         WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    259 
    260         if (AcpiNsOpensScope (WalkState->OpInfo->ObjectType))
    261         {
    262             ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
    263                 "(%s) Popping scope for Op %p\n",
    264                 AcpiUtGetTypeName (WalkState->OpInfo->ObjectType), Op));
    265 
    266             Status = AcpiDsScopeStackPop (WalkState);
    267             if (ACPI_FAILURE (Status))
    268             {
    269                 goto ErrorExit;
    270             }
    271         }
    272     }
    273 
    274     if (Op == WalkState->Origin)
    275     {
    276         if (OutOp)
    277         {
    278             *OutOp = Op;
    279         }
    280 
    281         return_ACPI_STATUS (AE_OK);
    282     }
    283 
    284     /*
    285      * If the previous opcode was a conditional, this opcode
    286      * must be the beginning of the associated predicate.
    287      * Save this knowledge in the current scope descriptor
    288      */
    289     if ((WalkState->ControlState) &&
    290         (WalkState->ControlState->Common.State ==
    291             ACPI_CONTROL_CONDITIONAL_EXECUTING))
    292     {
    293         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
    294             "Exec predicate Op=%p State=%p\n",
    295             Op, WalkState));
    296 
    297         WalkState->ControlState->Common.State =
    298             ACPI_CONTROL_PREDICATE_EXECUTING;
    299 
    300         /* Save start of predicate */
    301 
    302         WalkState->ControlState->Control.PredicateOp = Op;
    303     }
    304 
    305 
    306     OpcodeClass = WalkState->OpInfo->Class;
    307 
    308     /* We want to send namepaths to the load code */
    309 
    310     if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
    311     {
    312         OpcodeClass = AML_CLASS_NAMED_OBJECT;
    313     }
    314 
    315     /*
    316      * Handle the opcode based upon the opcode type
    317      */
    318     switch (OpcodeClass)
    319     {
    320     case AML_CLASS_CONTROL:
    321 
    322         Status = AcpiDsExecBeginControlOp (WalkState, Op);
    323         break;
    324 
    325     case AML_CLASS_NAMED_OBJECT:
    326 
    327         if (WalkState->WalkType & ACPI_WALK_METHOD)
    328         {
    329             /*
    330              * Found a named object declaration during method execution;
    331              * we must enter this object into the namespace. The created
    332              * object is temporary and will be deleted upon completion of
    333              * the execution of this method.
    334              *
    335              * Note 10/2010: Except for the Scope() op. This opcode does
    336              * not actually create a new object, it refers to an existing
    337              * object. However, for Scope(), we want to indeed open a
    338              * new scope.
    339              */
    340             if (Op->Common.AmlOpcode != AML_SCOPE_OP)
    341             {
    342                 Status = AcpiDsLoad2BeginOp (WalkState, NULL);
    343             }
    344             else
    345             {
    346                 Status = AcpiDsScopeStackPush (
    347                     Op->Named.Node, Op->Named.Node->Type, WalkState);
    348                 if (ACPI_FAILURE (Status))
    349                 {
    350                     return_ACPI_STATUS (Status);
    351                 }
    352             }
    353         }
    354         break;
    355 
    356     case AML_CLASS_EXECUTE:
    357     case AML_CLASS_CREATE:
    358 
    359         break;
    360 
    361     default:
    362 
    363         break;
    364     }
    365 
    366     /* Nothing to do here during method execution */
    367 
    368     return_ACPI_STATUS (Status);
    369 
    370 
    371 ErrorExit:
    372     Status = AcpiDsMethodError (Status, WalkState);
    373     return_ACPI_STATUS (Status);
    374 }
    375 
    376 
    377 /*****************************************************************************
    378  *
    379  * FUNCTION:    AcpiDsExecEndOp
    380  *
    381  * PARAMETERS:  WalkState       - Current state of the parse tree walk
    382  *
    383  * RETURN:      Status
    384  *
    385  * DESCRIPTION: Ascending callback used during the execution of control
    386  *              methods. The only thing we really need to do here is to
    387  *              notice the beginning of IF, ELSE, and WHILE blocks.
    388  *
    389  ****************************************************************************/
    390 
    391 ACPI_STATUS
    392 AcpiDsExecEndOp (
    393     ACPI_WALK_STATE         *WalkState)
    394 {
    395     ACPI_PARSE_OBJECT       *Op;
    396     ACPI_STATUS             Status = AE_OK;
    397     UINT32                  OpType;
    398     UINT32                  OpClass;
    399     ACPI_PARSE_OBJECT       *NextOp;
    400     ACPI_PARSE_OBJECT       *FirstArg;
    401 #ifdef ACPI_EXEC_APP
    402     char                    *Namepath;
    403     ACPI_OPERAND_OBJECT     *ObjDesc;
    404 #endif
    405 
    406     ACPI_FUNCTION_TRACE_PTR (DsExecEndOp, WalkState);
    407 
    408 
    409     Op = WalkState->Op;
    410     OpType = WalkState->OpInfo->Type;
    411     OpClass = WalkState->OpInfo->Class;
    412 
    413     if (OpClass == AML_CLASS_UNKNOWN)
    414     {
    415         ACPI_ERROR ((AE_INFO, "Unknown opcode 0x%X", Op->Common.AmlOpcode));
    416         return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
    417     }
    418 
    419     FirstArg = Op->Common.Value.Arg;
    420 
    421     /* Init the walk state */
    422 
    423     WalkState->NumOperands = 0;
    424     WalkState->OperandIndex = 0;
    425     WalkState->ReturnDesc = NULL;
    426     WalkState->ResultObj = NULL;
    427 
    428     /* Call debugger for single step support (DEBUG build only) */
    429 
    430     Status = AcpiDbSingleStep (WalkState, Op, OpClass);
    431     if (ACPI_FAILURE (Status))
    432     {
    433         return_ACPI_STATUS (Status);
    434     }
    435 
    436     /* Decode the Opcode Class */
    437 
    438     switch (OpClass)
    439     {
    440     case AML_CLASS_ARGUMENT:    /* Constants, literals, etc. */
    441 
    442         if (WalkState->Opcode == AML_INT_NAMEPATH_OP)
    443         {
    444             Status = AcpiDsEvaluateNamePath (WalkState);
    445             if (ACPI_FAILURE (Status))
    446             {
    447                 goto Cleanup;
    448             }
    449         }
    450         break;
    451 
    452     case AML_CLASS_EXECUTE:     /* Most operators with arguments */
    453 
    454         /* Build resolved operand stack */
    455 
    456         Status = AcpiDsCreateOperands (WalkState, FirstArg);
    457         if (ACPI_FAILURE (Status))
    458         {
    459             goto Cleanup;
    460         }
    461 
    462         /*
    463          * All opcodes require operand resolution, with the only exceptions
    464          * being the ObjectType and SizeOf operators as well as opcodes that
    465          * take no arguments.
    466          */
    467         if (!(WalkState->OpInfo->Flags & AML_NO_OPERAND_RESOLVE) &&
    468             (WalkState->OpInfo->Flags & AML_HAS_ARGS))
    469         {
    470             /* Resolve all operands */
    471 
    472             Status = AcpiExResolveOperands (WalkState->Opcode,
    473                 &(WalkState->Operands [WalkState->NumOperands -1]),
    474                 WalkState);
    475         }
    476 
    477         if (ACPI_SUCCESS (Status))
    478         {
    479             /*
    480              * Dispatch the request to the appropriate interpreter handler
    481              * routine. There is one routine per opcode "type" based upon the
    482              * number of opcode arguments and return type.
    483              */
    484             Status = AcpiGbl_OpTypeDispatch[OpType] (WalkState);
    485         }
    486         else
    487         {
    488             /*
    489              * Treat constructs of the form "Store(LocalX,LocalX)" as noops when the
    490              * Local is uninitialized.
    491              */
    492             if  ((Status == AE_AML_UNINITIALIZED_LOCAL) &&
    493                 (WalkState->Opcode == AML_STORE_OP) &&
    494                 (WalkState->Operands[0]->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
    495                 (WalkState->Operands[1]->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
    496                 (WalkState->Operands[0]->Reference.Class ==
    497                  WalkState->Operands[1]->Reference.Class) &&
    498                 (WalkState->Operands[0]->Reference.Value ==
    499                  WalkState->Operands[1]->Reference.Value))
    500             {
    501                 Status = AE_OK;
    502             }
    503             else
    504             {
    505                 ACPI_EXCEPTION ((AE_INFO, Status,
    506                     "While resolving operands for [%s]",
    507                     AcpiPsGetOpcodeName (WalkState->Opcode)));
    508             }
    509         }
    510 
    511         /* Always delete the argument objects and clear the operand stack */
    512 
    513         AcpiDsClearOperands (WalkState);
    514 
    515         /*
    516          * If a result object was returned from above, push it on the
    517          * current result stack
    518          */
    519         if (ACPI_SUCCESS (Status) &&
    520             WalkState->ResultObj)
    521         {
    522             Status = AcpiDsResultPush (WalkState->ResultObj, WalkState);
    523         }
    524         break;
    525 
    526     default:
    527 
    528         switch (OpType)
    529         {
    530         case AML_TYPE_CONTROL:    /* Type 1 opcode, IF/ELSE/WHILE/NOOP */
    531 
    532             /* 1 Operand, 0 ExternalResult, 0 InternalResult */
    533 
    534             Status = AcpiDsExecEndControlOp (WalkState, Op);
    535 
    536             break;
    537 
    538         case AML_TYPE_METHOD_CALL:
    539             /*
    540              * If the method is referenced from within a package
    541              * declaration, it is not a invocation of the method, just
    542              * a reference to it.
    543              */
    544             if ((Op->Asl.Parent) &&
    545                ((Op->Asl.Parent->Asl.AmlOpcode == AML_PACKAGE_OP) ||
    546                 (Op->Asl.Parent->Asl.AmlOpcode == AML_VARIABLE_PACKAGE_OP)))
    547             {
    548                 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
    549                     "Method Reference in a Package, Op=%p\n", Op));
    550 
    551                 Op->Common.Node = (ACPI_NAMESPACE_NODE *)
    552                     Op->Asl.Value.Arg->Asl.Node;
    553                 AcpiUtAddReference (Op->Asl.Value.Arg->Asl.Node->Object);
    554                 return_ACPI_STATUS (AE_OK);
    555             }
    556 
    557             ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
    558                 "Method invocation, Op=%p\n", Op));
    559 
    560             /*
    561              * (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains
    562              * the method Node pointer
    563              */
    564             /* NextOp points to the op that holds the method name */
    565 
    566             NextOp = FirstArg;
    567 
    568             /* NextOp points to first argument op */
    569 
    570             NextOp = NextOp->Common.Next;
    571 
    572             /*
    573              * Get the method's arguments and put them on the operand stack
    574              */
    575             Status = AcpiDsCreateOperands (WalkState, NextOp);
    576             if (ACPI_FAILURE (Status))
    577             {
    578                 break;
    579             }
    580 
    581             /*
    582              * Since the operands will be passed to another control method,
    583              * we must resolve all local references here (Local variables,
    584              * arguments to *this* method, etc.)
    585              */
    586             Status = AcpiDsResolveOperands (WalkState);
    587             if (ACPI_FAILURE (Status))
    588             {
    589                 /* On error, clear all resolved operands */
    590 
    591                 AcpiDsClearOperands (WalkState);
    592                 break;
    593             }
    594 
    595             /*
    596              * Tell the walk loop to preempt this running method and
    597              * execute the new method
    598              */
    599             Status = AE_CTRL_TRANSFER;
    600 
    601             /*
    602              * Return now; we don't want to disturb anything,
    603              * especially the operand count!
    604              */
    605             return_ACPI_STATUS (Status);
    606 
    607         case AML_TYPE_CREATE_FIELD:
    608 
    609             ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
    610                 "Executing CreateField Buffer/Index Op=%p\n", Op));
    611 
    612             Status = AcpiDsLoad2EndOp (WalkState);
    613             if (ACPI_FAILURE (Status))
    614             {
    615                 break;
    616             }
    617 
    618             Status = AcpiDsEvalBufferFieldOperands (WalkState, Op);
    619             if (ACPI_FAILURE (Status))
    620             {
    621                 break;
    622             }
    623 
    624 #ifdef ACPI_EXEC_APP
    625             /*
    626              * AcpiExec support for namespace initialization file (initialize
    627              * BufferFields in this code.)
    628              */
    629             Namepath = AcpiNsGetExternalPathname (Op->Common.Node);
    630             Status = AeLookupInitFileEntry (Namepath, &ObjDesc);
    631             if (ACPI_SUCCESS (Status))
    632             {
    633                 Status = AcpiExWriteDataToField (ObjDesc, Op->Common.Node->Object, NULL);
    634                 if (ACPI_FAILURE (Status))
    635                 {
    636                     ACPI_EXCEPTION ((AE_INFO, Status, "While writing to buffer field"));
    637                 }
    638             }
    639             ACPI_FREE (Namepath);
    640             Status = AE_OK;
    641 #endif
    642             break;
    643 
    644 
    645         case AML_TYPE_CREATE_OBJECT:
    646 
    647             ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
    648                 "Executing CreateObject (Buffer/Package) Op=%p Child=%p ParentOpcode=%4.4X\n",
    649                 Op, Op->Named.Value.Arg, Op->Common.Parent->Common.AmlOpcode));
    650 
    651             switch (Op->Common.Parent->Common.AmlOpcode)
    652             {
    653             case AML_NAME_OP:
    654                 /*
    655                  * Put the Node on the object stack (Contains the ACPI Name
    656                  * of this object)
    657                  */
    658                 WalkState->Operands[0] = (void *)
    659                     Op->Common.Parent->Common.Node;
    660                 WalkState->NumOperands = 1;
    661 
    662                 Status = AcpiDsCreateNode (WalkState,
    663                     Op->Common.Parent->Common.Node, Op->Common.Parent);
    664                 if (ACPI_FAILURE (Status))
    665                 {
    666                     break;
    667                 }
    668 
    669                 ACPI_FALLTHROUGH;
    670 
    671             case AML_INT_EVAL_SUBTREE_OP:
    672 
    673                 Status = AcpiDsEvalDataObjectOperands (WalkState, Op,
    674                     AcpiNsGetAttachedObject (Op->Common.Parent->Common.Node));
    675                 break;
    676 
    677             default:
    678 
    679                 Status = AcpiDsEvalDataObjectOperands (WalkState, Op, NULL);
    680                 break;
    681             }
    682 
    683             /*
    684              * If a result object was returned from above, push it on the
    685              * current result stack
    686              */
    687             if (WalkState->ResultObj)
    688             {
    689                 Status = AcpiDsResultPush (WalkState->ResultObj, WalkState);
    690             }
    691             break;
    692 
    693         case AML_TYPE_NAMED_FIELD:
    694         case AML_TYPE_NAMED_COMPLEX:
    695         case AML_TYPE_NAMED_SIMPLE:
    696         case AML_TYPE_NAMED_NO_OBJ:
    697 
    698             Status = AcpiDsLoad2EndOp (WalkState);
    699             if (ACPI_FAILURE (Status))
    700             {
    701                 break;
    702             }
    703 
    704             if (Op->Common.AmlOpcode == AML_REGION_OP)
    705             {
    706                 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
    707                     "Executing OpRegion Address/Length Op=%p\n", Op));
    708 
    709                 Status = AcpiDsEvalRegionOperands (WalkState, Op);
    710                 if (ACPI_FAILURE (Status))
    711                 {
    712                     break;
    713                 }
    714             }
    715             else if (Op->Common.AmlOpcode == AML_DATA_REGION_OP)
    716             {
    717                 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
    718                     "Executing DataTableRegion Strings Op=%p\n", Op));
    719 
    720                 Status = AcpiDsEvalTableRegionOperands (WalkState, Op);
    721                 if (ACPI_FAILURE (Status))
    722                 {
    723                     break;
    724                 }
    725             }
    726             else if (Op->Common.AmlOpcode == AML_BANK_FIELD_OP)
    727             {
    728                 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
    729                     "Executing BankField Op=%p\n", Op));
    730 
    731                 Status = AcpiDsEvalBankFieldOperands (WalkState, Op);
    732                 if (ACPI_FAILURE (Status))
    733                 {
    734                     break;
    735                 }
    736             }
    737             break;
    738 
    739         case AML_TYPE_UNDEFINED:
    740 
    741             ACPI_ERROR ((AE_INFO,
    742                 "Undefined opcode type Op=%p", Op));
    743             return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
    744 
    745         case AML_TYPE_BOGUS:
    746 
    747             ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
    748                 "Internal opcode=%X type Op=%p\n",
    749                 WalkState->Opcode, Op));
    750             break;
    751 
    752         default:
    753 
    754             ACPI_ERROR ((AE_INFO,
    755                 "Unimplemented opcode, class=0x%X "
    756                 "type=0x%X Opcode=0x%X Op=%p",
    757                 OpClass, OpType, Op->Common.AmlOpcode, Op));
    758 
    759             Status = AE_NOT_IMPLEMENTED;
    760             break;
    761         }
    762     }
    763 
    764     /*
    765      * ACPI 2.0 support for 64-bit integers: Truncate numeric
    766      * result value if we are executing from a 32-bit ACPI table
    767      */
    768     (void) AcpiExTruncateFor32bitTable (WalkState->ResultObj);
    769 
    770     /*
    771      * Check if we just completed the evaluation of a
    772      * conditional predicate
    773      */
    774     if ((ACPI_SUCCESS (Status)) &&
    775         (WalkState->ControlState) &&
    776         (WalkState->ControlState->Common.State ==
    777             ACPI_CONTROL_PREDICATE_EXECUTING) &&
    778         (WalkState->ControlState->Control.PredicateOp == Op))
    779     {
    780         Status = AcpiDsGetPredicateValue (WalkState, WalkState->ResultObj);
    781         WalkState->ResultObj = NULL;
    782     }
    783 
    784 
    785 Cleanup:
    786 
    787     if (WalkState->ResultObj)
    788     {
    789         /* Break to debugger to display result */
    790 
    791         AcpiDbDisplayResultObject (WalkState->ResultObj,WalkState);
    792 
    793         /*
    794          * Delete the result op if and only if:
    795          * Parent will not use the result -- such as any
    796          * non-nested type2 op in a method (parent will be method)
    797          */
    798         AcpiDsDeleteResultIfNotUsed (Op, WalkState->ResultObj, WalkState);
    799     }
    800 
    801 #ifdef _UNDER_DEVELOPMENT
    802 
    803     if (WalkState->ParserState.Aml == WalkState->ParserState.AmlEnd)
    804     {
    805         AcpiDbMethodEnd (WalkState);
    806     }
    807 #endif
    808 
    809     /* Invoke exception handler on error */
    810 
    811     if (ACPI_FAILURE (Status))
    812     {
    813         Status = AcpiDsMethodError (Status, WalkState);
    814     }
    815 
    816     /* Always clear the object stack */
    817 
    818     WalkState->NumOperands = 0;
    819     return_ACPI_STATUS (Status);
    820 }
    821