167754Smsmith/******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: dswexec - Dispatcher method execution callbacks;
467754Smsmith *                        dispatch to interpreter.
567754Smsmith *
667754Smsmith *****************************************************************************/
767754Smsmith
8217365Sjkim/*
9281075Sdim * Copyright (C) 2000 - 2015, Intel Corp.
1070243Smsmith * All rights reserved.
1167754Smsmith *
12217365Sjkim * Redistribution and use in source and binary forms, with or without
13217365Sjkim * modification, are permitted provided that the following conditions
14217365Sjkim * are met:
15217365Sjkim * 1. Redistributions of source code must retain the above copyright
16217365Sjkim *    notice, this list of conditions, and the following disclaimer,
17217365Sjkim *    without modification.
18217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
20217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
21217365Sjkim *    including a substantially similar Disclaimer requirement for further
22217365Sjkim *    binary redistribution.
23217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
24217365Sjkim *    of any contributors may be used to endorse or promote products derived
25217365Sjkim *    from this software without specific prior written permission.
2667754Smsmith *
27217365Sjkim * Alternatively, this software may be distributed under the terms of the
28217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
29217365Sjkim * Software Foundation.
3067754Smsmith *
31217365Sjkim * NO WARRANTY
32217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
43217365Sjkim */
4467754Smsmith
45193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
46193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
47193341Sjkim#include <contrib/dev/acpica/include/acparser.h>
48193341Sjkim#include <contrib/dev/acpica/include/amlcode.h>
49193341Sjkim#include <contrib/dev/acpica/include/acdispat.h>
50193341Sjkim#include <contrib/dev/acpica/include/acinterp.h>
51193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
52193341Sjkim#include <contrib/dev/acpica/include/acdebug.h>
5367754Smsmith
5467754Smsmith
5577424Smsmith#define _COMPONENT          ACPI_DISPATCHER
5691116Smsmith        ACPI_MODULE_NAME    ("dswexec")
5767754Smsmith
5885756Smsmith/*
5987031Smsmith * Dispatch table for opcode classes
6085756Smsmith */
61167802Sjkimstatic ACPI_EXECUTE_OP      AcpiGbl_OpTypeDispatch [] =
62167802Sjkim{
63167802Sjkim    AcpiExOpcode_0A_0T_1R,
64167802Sjkim    AcpiExOpcode_1A_0T_0R,
65167802Sjkim    AcpiExOpcode_1A_0T_1R,
66167802Sjkim    AcpiExOpcode_1A_1T_0R,
67167802Sjkim    AcpiExOpcode_1A_1T_1R,
68167802Sjkim    AcpiExOpcode_2A_0T_0R,
69167802Sjkim    AcpiExOpcode_2A_0T_1R,
70167802Sjkim    AcpiExOpcode_2A_1T_1R,
71167802Sjkim    AcpiExOpcode_2A_2T_1R,
72167802Sjkim    AcpiExOpcode_3A_0T_0R,
73167802Sjkim    AcpiExOpcode_3A_1T_1R,
74167802Sjkim    AcpiExOpcode_6A_0T_1R
75167802Sjkim};
7667754Smsmith
77151937Sjkim
7867754Smsmith/*****************************************************************************
7967754Smsmith *
8067754Smsmith * FUNCTION:    AcpiDsGetPredicateValue
8167754Smsmith *
8267754Smsmith * PARAMETERS:  WalkState       - Current state of the parse tree walk
83151937Sjkim *              ResultObj       - if non-zero, pop result from result stack
8467754Smsmith *
8567754Smsmith * RETURN:      Status
8667754Smsmith *
8771867Smsmith * DESCRIPTION: Get the result of a predicate evaluation
8867754Smsmith *
8967754Smsmith ****************************************************************************/
9067754Smsmith
9167754SmsmithACPI_STATUS
9267754SmsmithAcpiDsGetPredicateValue (
9367754Smsmith    ACPI_WALK_STATE         *WalkState,
9491116Smsmith    ACPI_OPERAND_OBJECT     *ResultObj)
9567754Smsmith{
9667754Smsmith    ACPI_STATUS             Status = AE_OK;
9767754Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
98151937Sjkim    ACPI_OPERAND_OBJECT     *LocalObjDesc = NULL;
9967754Smsmith
10067754Smsmith
101167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsGetPredicateValue, WalkState);
10267754Smsmith
10367754Smsmith
10467754Smsmith    WalkState->ControlState->Common.State = 0;
10567754Smsmith
10691116Smsmith    if (ResultObj)
10767754Smsmith    {
10869746Smsmith        Status = AcpiDsResultPop (&ObjDesc, WalkState);
10967754Smsmith        if (ACPI_FAILURE (Status))
11067754Smsmith        {
111167802Sjkim            ACPI_EXCEPTION ((AE_INFO, Status,
112167802Sjkim                "Could not get result from predicate evaluation"));
11369450Smsmith
11467754Smsmith            return_ACPI_STATUS (Status);
11567754Smsmith        }
11667754Smsmith    }
11767754Smsmith    else
11867754Smsmith    {
11984491Smsmith        Status = AcpiDsCreateOperand (WalkState, WalkState->Op, 0);
12067754Smsmith        if (ACPI_FAILURE (Status))
12167754Smsmith        {
12267754Smsmith            return_ACPI_STATUS (Status);
12367754Smsmith        }
12467754Smsmith
12577424Smsmith        Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
12667754Smsmith        if (ACPI_FAILURE (Status))
12767754Smsmith        {
12867754Smsmith            return_ACPI_STATUS (Status);
12967754Smsmith        }
13067754Smsmith
13167754Smsmith        ObjDesc = WalkState->Operands [0];
13267754Smsmith    }
13367754Smsmith
13467754Smsmith    if (!ObjDesc)
13567754Smsmith    {
136167802Sjkim        ACPI_ERROR ((AE_INFO,
137167802Sjkim            "No predicate ObjDesc=%p State=%p",
13867754Smsmith            ObjDesc, WalkState));
13967754Smsmith
14067754Smsmith        return_ACPI_STATUS (AE_AML_NO_OPERAND);
14167754Smsmith    }
14267754Smsmith
14369450Smsmith    /*
144151937Sjkim     * Result of predicate evaluation must be an Integer
145151937Sjkim     * object. Implicitly convert the argument if necessary.
14667754Smsmith     */
147151937Sjkim    Status = AcpiExConvertToInteger (ObjDesc, &LocalObjDesc, 16);
148151937Sjkim    if (ACPI_FAILURE (Status))
14967754Smsmith    {
150151937Sjkim        goto Cleanup;
151151937Sjkim    }
152151937Sjkim
153193267Sjkim    if (LocalObjDesc->Common.Type != ACPI_TYPE_INTEGER)
154151937Sjkim    {
155167802Sjkim        ACPI_ERROR ((AE_INFO,
156204773Sjkim            "Bad predicate (not an integer) ObjDesc=%p State=%p Type=0x%X",
157193267Sjkim            ObjDesc, WalkState, ObjDesc->Common.Type));
15867754Smsmith
15967754Smsmith        Status = AE_AML_OPERAND_TYPE;
16067754Smsmith        goto Cleanup;
16167754Smsmith    }
16267754Smsmith
16371867Smsmith    /* Truncate the predicate to 32-bits if necessary */
16469450Smsmith
165245582Sjkim    (void) AcpiExTruncateFor32bitTable (LocalObjDesc);
16669450Smsmith
16769450Smsmith    /*
16867754Smsmith     * Save the result of the predicate evaluation on
16969450Smsmith     * the control stack
17067754Smsmith     */
171151937Sjkim    if (LocalObjDesc->Integer.Value)
17267754Smsmith    {
17367754Smsmith        WalkState->ControlState->Common.Value = TRUE;
17467754Smsmith    }
17567754Smsmith    else
17667754Smsmith    {
17769450Smsmith        /*
17867754Smsmith         * Predicate is FALSE, we will just toss the
17969450Smsmith         * rest of the package
18067754Smsmith         */
18167754Smsmith        WalkState->ControlState->Common.Value = FALSE;
18267754Smsmith        Status = AE_CTRL_FALSE;
18367754Smsmith    }
18467754Smsmith
185193267Sjkim    /* Predicate can be used for an implicit return value */
18667754Smsmith
187193267Sjkim    (void) AcpiDsDoImplicitReturn (LocalObjDesc, WalkState, TRUE);
188193267Sjkim
189193267Sjkim
19067754SmsmithCleanup:
19167754Smsmith
19287031Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n",
19384491Smsmith        WalkState->ControlState->Common.Value, WalkState->Op));
19467754Smsmith
19567754Smsmith     /* Break to debugger to display result */
19667754Smsmith
197151937Sjkim    ACPI_DEBUGGER_EXEC (AcpiDbDisplayResultObject (LocalObjDesc, WalkState));
19867754Smsmith
19969450Smsmith    /*
20067754Smsmith     * Delete the predicate result object (we know that
20167754Smsmith     * we don't need it anymore)
20267754Smsmith     */
203151937Sjkim    if (LocalObjDesc != ObjDesc)
204151937Sjkim    {
205151937Sjkim        AcpiUtRemoveReference (LocalObjDesc);
206151937Sjkim    }
20777424Smsmith    AcpiUtRemoveReference (ObjDesc);
20867754Smsmith
20991116Smsmith    WalkState->ControlState->Common.State = ACPI_CONTROL_NORMAL;
21067754Smsmith    return_ACPI_STATUS (Status);
21167754Smsmith}
21267754Smsmith
21367754Smsmith
21467754Smsmith/*****************************************************************************
21567754Smsmith *
21667754Smsmith * FUNCTION:    AcpiDsExecBeginOp
21767754Smsmith *
21867754Smsmith * PARAMETERS:  WalkState       - Current state of the parse tree walk
219151937Sjkim *              OutOp           - Where to return op if a new one is created
22067754Smsmith *
22167754Smsmith * RETURN:      Status
22267754Smsmith *
22367754Smsmith * DESCRIPTION: Descending callback used during the execution of control
224241973Sjkim *              methods. This is where most operators and operands are
22567754Smsmith *              dispatched to the interpreter.
22667754Smsmith *
22767754Smsmith ****************************************************************************/
22867754Smsmith
22967754SmsmithACPI_STATUS
23067754SmsmithAcpiDsExecBeginOp (
23167754Smsmith    ACPI_WALK_STATE         *WalkState,
23267754Smsmith    ACPI_PARSE_OBJECT       **OutOp)
23367754Smsmith{
23484491Smsmith    ACPI_PARSE_OBJECT       *Op;
23567754Smsmith    ACPI_STATUS             Status = AE_OK;
23685756Smsmith    UINT32                  OpcodeClass;
23767754Smsmith
23867754Smsmith
239167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsExecBeginOp, WalkState);
24067754Smsmith
24167754Smsmith
24284491Smsmith    Op = WalkState->Op;
24367754Smsmith    if (!Op)
24467754Smsmith    {
24584491Smsmith        Status = AcpiDsLoad2BeginOp (WalkState, OutOp);
24667754Smsmith        if (ACPI_FAILURE (Status))
24767754Smsmith        {
248167802Sjkim            goto ErrorExit;
24967754Smsmith        }
25067754Smsmith
25167754Smsmith        Op = *OutOp;
25284491Smsmith        WalkState->Op = Op;
25399679Siwasaki        WalkState->Opcode = Op->Common.AmlOpcode;
25499679Siwasaki        WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
25591116Smsmith
25691116Smsmith        if (AcpiNsOpensScope (WalkState->OpInfo->ObjectType))
25791116Smsmith        {
258151937Sjkim            ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
259151937Sjkim                "(%s) Popping scope for Op %p\n",
26091116Smsmith                AcpiUtGetTypeName (WalkState->OpInfo->ObjectType), Op));
26199679Siwasaki
26299679Siwasaki            Status = AcpiDsScopeStackPop (WalkState);
26399679Siwasaki            if (ACPI_FAILURE (Status))
26499679Siwasaki            {
265167802Sjkim                goto ErrorExit;
26699679Siwasaki            }
26791116Smsmith        }
26867754Smsmith    }
26967754Smsmith
27067754Smsmith    if (Op == WalkState->Origin)
27167754Smsmith    {
27267754Smsmith        if (OutOp)
27367754Smsmith        {
27467754Smsmith            *OutOp = Op;
27567754Smsmith        }
27667754Smsmith
27767754Smsmith        return_ACPI_STATUS (AE_OK);
27867754Smsmith    }
27967754Smsmith
28067754Smsmith    /*
28167754Smsmith     * If the previous opcode was a conditional, this opcode
28267754Smsmith     * must be the beginning of the associated predicate.
28367754Smsmith     * Save this knowledge in the current scope descriptor
28467754Smsmith     */
28567754Smsmith    if ((WalkState->ControlState) &&
28667754Smsmith        (WalkState->ControlState->Common.State ==
28791116Smsmith            ACPI_CONTROL_CONDITIONAL_EXECUTING))
28867754Smsmith    {
28985756Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Exec predicate Op=%p State=%p\n",
29067754Smsmith                        Op, WalkState));
29167754Smsmith
29291116Smsmith        WalkState->ControlState->Common.State = ACPI_CONTROL_PREDICATE_EXECUTING;
29367754Smsmith
29467754Smsmith        /* Save start of predicate */
29567754Smsmith
29667754Smsmith        WalkState->ControlState->Control.PredicateOp = Op;
29767754Smsmith    }
29867754Smsmith
29967754Smsmith
30085756Smsmith    OpcodeClass = WalkState->OpInfo->Class;
30167754Smsmith
30267754Smsmith    /* We want to send namepaths to the load code */
30367754Smsmith
30499679Siwasaki    if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
30567754Smsmith    {
30685756Smsmith        OpcodeClass = AML_CLASS_NAMED_OBJECT;
30767754Smsmith    }
30867754Smsmith
30967754Smsmith    /*
31067754Smsmith     * Handle the opcode based upon the opcode type
31167754Smsmith     */
31283174Smsmith    switch (OpcodeClass)
31367754Smsmith    {
31485756Smsmith    case AML_CLASS_CONTROL:
31567754Smsmith
31667754Smsmith        Status = AcpiDsExecBeginControlOp (WalkState, Op);
31767754Smsmith        break;
31867754Smsmith
31985756Smsmith    case AML_CLASS_NAMED_OBJECT:
32067754Smsmith
321167802Sjkim        if (WalkState->WalkType & ACPI_WALK_METHOD)
32267754Smsmith        {
32367754Smsmith            /*
324151937Sjkim             * Found a named object declaration during method execution;
325241973Sjkim             * we must enter this object into the namespace. The created
326151937Sjkim             * object is temporary and will be deleted upon completion of
327151937Sjkim             * the execution of this method.
328216471Sjkim             *
329216471Sjkim             * Note 10/2010: Except for the Scope() op. This opcode does
330216471Sjkim             * not actually create a new object, it refers to an existing
331216471Sjkim             * object. However, for Scope(), we want to indeed open a
332216471Sjkim             * new scope.
33367754Smsmith             */
334216471Sjkim            if (Op->Common.AmlOpcode != AML_SCOPE_OP)
335216471Sjkim            {
336216471Sjkim                Status = AcpiDsLoad2BeginOp (WalkState, NULL);
337216471Sjkim            }
338216471Sjkim            else
339216471Sjkim            {
340216471Sjkim                Status = AcpiDsScopeStackPush (Op->Named.Node,
341216471Sjkim                            Op->Named.Node->Type, WalkState);
342216471Sjkim                if (ACPI_FAILURE (Status))
343216471Sjkim                {
344216471Sjkim                    return_ACPI_STATUS (Status);
345216471Sjkim                }
346216471Sjkim            }
34767754Smsmith        }
34867754Smsmith        break;
34967754Smsmith
35085756Smsmith    case AML_CLASS_EXECUTE:
35185756Smsmith    case AML_CLASS_CREATE:
35269746Smsmith
35369746Smsmith        break;
35469746Smsmith
355250838Sjkim    default:
35669746Smsmith
35767754Smsmith        break;
35867754Smsmith    }
35967754Smsmith
36067754Smsmith    /* Nothing to do here during method execution */
36167754Smsmith
36267754Smsmith    return_ACPI_STATUS (Status);
363167802Sjkim
364167802Sjkim
365167802SjkimErrorExit:
366167802Sjkim    Status = AcpiDsMethodError (Status, WalkState);
367167802Sjkim    return_ACPI_STATUS (Status);
36867754Smsmith}
36967754Smsmith
37067754Smsmith
37167754Smsmith/*****************************************************************************
37267754Smsmith *
37367754Smsmith * FUNCTION:    AcpiDsExecEndOp
37467754Smsmith *
37567754Smsmith * PARAMETERS:  WalkState       - Current state of the parse tree walk
37667754Smsmith *
37767754Smsmith * RETURN:      Status
37867754Smsmith *
37967754Smsmith * DESCRIPTION: Ascending callback used during the execution of control
380241973Sjkim *              methods. The only thing we really need to do here is to
38167754Smsmith *              notice the beginning of IF, ELSE, and WHILE blocks.
38267754Smsmith *
38367754Smsmith ****************************************************************************/
38467754Smsmith
38567754SmsmithACPI_STATUS
38667754SmsmithAcpiDsExecEndOp (
38784491Smsmith    ACPI_WALK_STATE         *WalkState)
38867754Smsmith{
38984491Smsmith    ACPI_PARSE_OBJECT       *Op;
39067754Smsmith    ACPI_STATUS             Status = AE_OK;
39185756Smsmith    UINT32                  OpType;
39285756Smsmith    UINT32                  OpClass;
39367754Smsmith    ACPI_PARSE_OBJECT       *NextOp;
39467754Smsmith    ACPI_PARSE_OBJECT       *FirstArg;
39567754Smsmith
39667754Smsmith
397167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsExecEndOp, WalkState);
39867754Smsmith
39967754Smsmith
40085756Smsmith    Op      = WalkState->Op;
40185756Smsmith    OpType  = WalkState->OpInfo->Type;
40285756Smsmith    OpClass = WalkState->OpInfo->Class;
40367754Smsmith
40485756Smsmith    if (OpClass == AML_CLASS_UNKNOWN)
40567754Smsmith    {
406204773Sjkim        ACPI_ERROR ((AE_INFO, "Unknown opcode 0x%X", Op->Common.AmlOpcode));
40767754Smsmith        return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
40867754Smsmith    }
40967754Smsmith
41099679Siwasaki    FirstArg = Op->Common.Value.Arg;
41167754Smsmith
41267754Smsmith    /* Init the walk state */
41367754Smsmith
41467754Smsmith    WalkState->NumOperands = 0;
415167802Sjkim    WalkState->OperandIndex = 0;
41667754Smsmith    WalkState->ReturnDesc = NULL;
41784491Smsmith    WalkState->ResultObj = NULL;
41867754Smsmith
41967754Smsmith    /* Call debugger for single step support (DEBUG build only) */
42067754Smsmith
42191116Smsmith    ACPI_DEBUGGER_EXEC (Status = AcpiDbSingleStep (WalkState, Op, OpClass));
42291116Smsmith    ACPI_DEBUGGER_EXEC (if (ACPI_FAILURE (Status)) {return_ACPI_STATUS (Status);});
42367754Smsmith
42487031Smsmith    /* Decode the Opcode Class */
42567754Smsmith
42685756Smsmith    switch (OpClass)
42767754Smsmith    {
428167802Sjkim    case AML_CLASS_ARGUMENT:    /* Constants, literals, etc. */
429167802Sjkim
430167802Sjkim        if (WalkState->Opcode == AML_INT_NAMEPATH_OP)
431167802Sjkim        {
432167802Sjkim            Status = AcpiDsEvaluateNamePath (WalkState);
433167802Sjkim            if (ACPI_FAILURE (Status))
434167802Sjkim            {
435167802Sjkim                goto Cleanup;
436167802Sjkim            }
437167802Sjkim        }
43867754Smsmith        break;
43967754Smsmith
440167802Sjkim    case AML_CLASS_EXECUTE:     /* Most operators with arguments */
44167754Smsmith
44269746Smsmith        /* Build resolved operand stack */
44369746Smsmith
44467754Smsmith        Status = AcpiDsCreateOperands (WalkState, FirstArg);
44567754Smsmith        if (ACPI_FAILURE (Status))
44667754Smsmith        {
44767754Smsmith            goto Cleanup;
44867754Smsmith        }
44967754Smsmith
450151937Sjkim        /*
451151937Sjkim         * All opcodes require operand resolution, with the only exceptions
452151937Sjkim         * being the ObjectType and SizeOf operators.
453151937Sjkim         */
454151937Sjkim        if (!(WalkState->OpInfo->Flags & AML_NO_OPERAND_RESOLVE))
455151937Sjkim        {
456151937Sjkim            /* Resolve all operands */
45783174Smsmith
458151937Sjkim            Status = AcpiExResolveOperands (WalkState->Opcode,
45987031Smsmith                        &(WalkState->Operands [WalkState->NumOperands -1]),
46083174Smsmith                        WalkState);
461151937Sjkim        }
462151937Sjkim
46387031Smsmith        if (ACPI_SUCCESS (Status))
46483174Smsmith        {
46583174Smsmith            /*
46687031Smsmith             * Dispatch the request to the appropriate interpreter handler
467241973Sjkim             * routine. There is one routine per opcode "type" based upon the
46887031Smsmith             * number of opcode arguments and return type.
46983174Smsmith             */
470138287Smarks            Status = AcpiGbl_OpTypeDispatch[OpType] (WalkState);
47183174Smsmith        }
47287031Smsmith        else
47387031Smsmith        {
474123315Snjl            /*
475123315Snjl             * Treat constructs of the form "Store(LocalX,LocalX)" as noops when the
476123315Snjl             * Local is uninitialized.
477123315Snjl             */
478123315Snjl            if  ((Status == AE_AML_UNINITIALIZED_LOCAL) &&
479123315Snjl                (WalkState->Opcode == AML_STORE_OP) &&
480123315Snjl                (WalkState->Operands[0]->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
481123315Snjl                (WalkState->Operands[1]->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
482193267Sjkim                (WalkState->Operands[0]->Reference.Class ==
483193267Sjkim                 WalkState->Operands[1]->Reference.Class) &&
484193267Sjkim                (WalkState->Operands[0]->Reference.Value ==
485193267Sjkim                 WalkState->Operands[1]->Reference.Value))
486123315Snjl            {
487123315Snjl                Status = AE_OK;
488123315Snjl            }
489123315Snjl            else
490123315Snjl            {
491167802Sjkim                ACPI_EXCEPTION ((AE_INFO, Status,
492167802Sjkim                    "While resolving operands for [%s]",
493167802Sjkim                    AcpiPsGetOpcodeName (WalkState->Opcode)));
494123315Snjl            }
49587031Smsmith        }
49683174Smsmith
49787031Smsmith        /* Always delete the argument objects and clear the operand stack */
49883174Smsmith
499107325Siwasaki        AcpiDsClearOperands (WalkState);
50083174Smsmith
50169746Smsmith        /*
50269746Smsmith         * If a result object was returned from above, push it on the
50369746Smsmith         * current result stack
50469746Smsmith         */
50569746Smsmith        if (ACPI_SUCCESS (Status) &&
50684491Smsmith            WalkState->ResultObj)
50769746Smsmith        {
50884491Smsmith            Status = AcpiDsResultPush (WalkState->ResultObj, WalkState);
50969746Smsmith        }
51067754Smsmith        break;
51167754Smsmith
51285756Smsmith    default:
51367754Smsmith
51485756Smsmith        switch (OpType)
51585756Smsmith        {
51685756Smsmith        case AML_TYPE_CONTROL:    /* Type 1 opcode, IF/ELSE/WHILE/NOOP */
51767754Smsmith
51885756Smsmith            /* 1 Operand, 0 ExternalResult, 0 InternalResult */
51967754Smsmith
52085756Smsmith            Status = AcpiDsExecEndControlOp (WalkState, Op);
521151937Sjkim
52285756Smsmith            break;
52367754Smsmith
52485756Smsmith        case AML_TYPE_METHOD_CALL:
525151937Sjkim            /*
526151937Sjkim             * If the method is referenced from within a package
527151937Sjkim             * declaration, it is not a invocation of the method, just
528151937Sjkim             * a reference to it.
529151937Sjkim             */
530151937Sjkim            if ((Op->Asl.Parent) &&
531151937Sjkim               ((Op->Asl.Parent->Asl.AmlOpcode == AML_PACKAGE_OP) ||
532151937Sjkim                (Op->Asl.Parent->Asl.AmlOpcode == AML_VAR_PACKAGE_OP)))
533151937Sjkim            {
534151937Sjkim                ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
535151937Sjkim                    "Method Reference in a Package, Op=%p\n", Op));
536167802Sjkim
537193267Sjkim                Op->Common.Node = (ACPI_NAMESPACE_NODE *) Op->Asl.Value.Arg->Asl.Node;
538151937Sjkim                AcpiUtAddReference (Op->Asl.Value.Arg->Asl.Node->Object);
539151937Sjkim                return_ACPI_STATUS (AE_OK);
540151937Sjkim            }
541151937Sjkim
542281075Sdim            ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
543281075Sdim                "Method invocation, Op=%p\n", Op));
54467754Smsmith
54585756Smsmith            /*
546151937Sjkim             * (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains
54785756Smsmith             * the method Node pointer
54885756Smsmith             */
54985756Smsmith            /* NextOp points to the op that holds the method name */
55067754Smsmith
55185756Smsmith            NextOp = FirstArg;
55267754Smsmith
55385756Smsmith            /* NextOp points to first argument op */
55467754Smsmith
55599679Siwasaki            NextOp = NextOp->Common.Next;
55667754Smsmith
55785756Smsmith            /*
55885756Smsmith             * Get the method's arguments and put them on the operand stack
55985756Smsmith             */
56085756Smsmith            Status = AcpiDsCreateOperands (WalkState, NextOp);
56185756Smsmith            if (ACPI_FAILURE (Status))
56285756Smsmith            {
56385756Smsmith                break;
56485756Smsmith            }
56567754Smsmith
56685756Smsmith            /*
56791116Smsmith             * Since the operands will be passed to another control method,
56891116Smsmith             * we must resolve all local references here (Local variables,
56987031Smsmith             * arguments to *this* method, etc.)
57085756Smsmith             */
57185756Smsmith            Status = AcpiDsResolveOperands (WalkState);
57285756Smsmith            if (ACPI_FAILURE (Status))
57385756Smsmith            {
574107325Siwasaki                /* On error, clear all resolved operands */
575107325Siwasaki
576107325Siwasaki                AcpiDsClearOperands (WalkState);
57785756Smsmith                break;
57885756Smsmith            }
57967754Smsmith
58085756Smsmith            /*
58185756Smsmith             * Tell the walk loop to preempt this running method and
58285756Smsmith             * execute the new method
58385756Smsmith             */
58485756Smsmith            Status = AE_CTRL_TRANSFER;
58567754Smsmith
58685756Smsmith            /*
58785756Smsmith             * Return now; we don't want to disturb anything,
58885756Smsmith             * especially the operand count!
58985756Smsmith             */
59085756Smsmith            return_ACPI_STATUS (Status);
59167754Smsmith
59285756Smsmith        case AML_TYPE_CREATE_FIELD:
59367754Smsmith
59485756Smsmith            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
59585756Smsmith                "Executing CreateField Buffer/Index Op=%p\n", Op));
59667754Smsmith
59785756Smsmith            Status = AcpiDsLoad2EndOp (WalkState);
59885756Smsmith            if (ACPI_FAILURE (Status))
59985756Smsmith            {
60085756Smsmith                break;
60185756Smsmith            }
60267754Smsmith
60385756Smsmith            Status = AcpiDsEvalBufferFieldOperands (WalkState, Op);
60467754Smsmith            break;
60567754Smsmith
60667754Smsmith
60799146Siwasaki        case AML_TYPE_CREATE_OBJECT:
60899146Siwasaki
60999146Siwasaki            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
61099146Siwasaki                "Executing CreateObject (Buffer/Package) Op=%p\n", Op));
61199146Siwasaki
61299679Siwasaki            switch (Op->Common.Parent->Common.AmlOpcode)
61399146Siwasaki            {
61499146Siwasaki            case AML_NAME_OP:
61599146Siwasaki                /*
616151937Sjkim                 * Put the Node on the object stack (Contains the ACPI Name
617151937Sjkim                 * of this object)
61899146Siwasaki                 */
61999679Siwasaki                WalkState->Operands[0] = (void *) Op->Common.Parent->Common.Node;
62099146Siwasaki                WalkState->NumOperands = 1;
62199146Siwasaki
622151937Sjkim                Status = AcpiDsCreateNode (WalkState,
623151937Sjkim                            Op->Common.Parent->Common.Node,
624151937Sjkim                            Op->Common.Parent);
62599146Siwasaki                if (ACPI_FAILURE (Status))
62699146Siwasaki                {
62799146Siwasaki                    break;
62899146Siwasaki                }
62999146Siwasaki
63099146Siwasaki                /* Fall through */
63199679Siwasaki                /*lint -fallthrough */
63299146Siwasaki
63399146Siwasaki            case AML_INT_EVAL_SUBTREE_OP:
63499146Siwasaki
635102550Siwasaki                Status = AcpiDsEvalDataObjectOperands (WalkState, Op,
636151937Sjkim                            AcpiNsGetAttachedObject (Op->Common.Parent->Common.Node));
63799146Siwasaki                break;
63899146Siwasaki
63999146Siwasaki            default:
64099146Siwasaki
64199146Siwasaki                Status = AcpiDsEvalDataObjectOperands (WalkState, Op, NULL);
64299146Siwasaki                break;
64399146Siwasaki            }
64499146Siwasaki
64599146Siwasaki            /*
64699146Siwasaki             * If a result object was returned from above, push it on the
64799146Siwasaki             * current result stack
64899146Siwasaki             */
649151937Sjkim            if (WalkState->ResultObj)
65099146Siwasaki            {
65199146Siwasaki                Status = AcpiDsResultPush (WalkState->ResultObj, WalkState);
65299146Siwasaki            }
65399146Siwasaki            break;
65499146Siwasaki
65585756Smsmith        case AML_TYPE_NAMED_FIELD:
65685756Smsmith        case AML_TYPE_NAMED_COMPLEX:
65785756Smsmith        case AML_TYPE_NAMED_SIMPLE:
65891116Smsmith        case AML_TYPE_NAMED_NO_OBJ:
65967754Smsmith
66085756Smsmith            Status = AcpiDsLoad2EndOp (WalkState);
66169746Smsmith            if (ACPI_FAILURE (Status))
66269746Smsmith            {
66369746Smsmith                break;
66469746Smsmith            }
66567754Smsmith
66699679Siwasaki            if (Op->Common.AmlOpcode == AML_REGION_OP)
66785756Smsmith            {
66885756Smsmith                ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
66985756Smsmith                    "Executing OpRegion Address/Length Op=%p\n", Op));
67085756Smsmith
67185756Smsmith                Status = AcpiDsEvalRegionOperands (WalkState, Op);
67285756Smsmith                if (ACPI_FAILURE (Status))
67385756Smsmith                {
67485756Smsmith                    break;
67585756Smsmith                }
67685756Smsmith            }
677193267Sjkim            else if (Op->Common.AmlOpcode == AML_DATA_REGION_OP)
678193267Sjkim            {
679193267Sjkim                ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
680193267Sjkim                    "Executing DataTableRegion Strings Op=%p\n", Op));
681193267Sjkim
682193267Sjkim                Status = AcpiDsEvalTableRegionOperands (WalkState, Op);
683193267Sjkim                if (ACPI_FAILURE (Status))
684193267Sjkim                {
685193267Sjkim                    break;
686193267Sjkim                }
687193267Sjkim            }
688193267Sjkim            else if (Op->Common.AmlOpcode == AML_BANK_FIELD_OP)
689193267Sjkim            {
690193267Sjkim                ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
691193267Sjkim                    "Executing BankField Op=%p\n", Op));
692193267Sjkim
693193267Sjkim                Status = AcpiDsEvalBankFieldOperands (WalkState, Op);
694193267Sjkim                if (ACPI_FAILURE (Status))
695193267Sjkim                {
696193267Sjkim                    break;
697193267Sjkim                }
698193267Sjkim            }
69967754Smsmith            break;
70067754Smsmith
70185756Smsmith        case AML_TYPE_UNDEFINED:
70267754Smsmith
703167802Sjkim            ACPI_ERROR ((AE_INFO,
704167802Sjkim                "Undefined opcode type Op=%p", Op));
70585756Smsmith            return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
70667754Smsmith
70785756Smsmith        case AML_TYPE_BOGUS:
70887031Smsmith
70991116Smsmith            ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
71087031Smsmith                "Internal opcode=%X type Op=%p\n",
71185756Smsmith                WalkState->Opcode, Op));
71267754Smsmith            break;
71367754Smsmith
71467754Smsmith        default:
71567754Smsmith
716167802Sjkim            ACPI_ERROR ((AE_INFO,
717249112Sjkim                "Unimplemented opcode, class=0x%X type=0x%X Opcode=0x%X Op=%p",
71899679Siwasaki                OpClass, OpType, Op->Common.AmlOpcode, Op));
71985756Smsmith
72085756Smsmith            Status = AE_NOT_IMPLEMENTED;
72167754Smsmith            break;
72267754Smsmith        }
72367754Smsmith    }
72467754Smsmith
72567754Smsmith    /*
72691116Smsmith     * ACPI 2.0 support for 64-bit integers: Truncate numeric
72787031Smsmith     * result value if we are executing from a 32-bit ACPI table
72869450Smsmith     */
729245582Sjkim    (void) AcpiExTruncateFor32bitTable (WalkState->ResultObj);
73069450Smsmith
73169450Smsmith    /*
73267754Smsmith     * Check if we just completed the evaluation of a
73367754Smsmith     * conditional predicate
73467754Smsmith     */
735138287Smarks    if ((ACPI_SUCCESS (Status)) &&
736138287Smarks        (WalkState->ControlState) &&
73767754Smsmith        (WalkState->ControlState->Common.State ==
73891116Smsmith            ACPI_CONTROL_PREDICATE_EXECUTING) &&
73967754Smsmith        (WalkState->ControlState->Control.PredicateOp == Op))
74067754Smsmith    {
74191116Smsmith        Status = AcpiDsGetPredicateValue (WalkState, WalkState->ResultObj);
74284491Smsmith        WalkState->ResultObj = NULL;
74367754Smsmith    }
74467754Smsmith
74567754Smsmith
74667754SmsmithCleanup:
747138287Smarks
74884491Smsmith    if (WalkState->ResultObj)
74967754Smsmith    {
75067754Smsmith        /* Break to debugger to display result */
75167754Smsmith
752151937Sjkim        ACPI_DEBUGGER_EXEC (AcpiDbDisplayResultObject (WalkState->ResultObj,
753151937Sjkim                                WalkState));
75467754Smsmith
75567754Smsmith        /*
75667754Smsmith         * Delete the result op if and only if:
75767754Smsmith         * Parent will not use the result -- such as any
75867754Smsmith         * non-nested type2 op in a method (parent will be method)
75967754Smsmith         */
76084491Smsmith        AcpiDsDeleteResultIfNotUsed (Op, WalkState->ResultObj, WalkState);
76167754Smsmith    }
76267754Smsmith
763117521Snjl#ifdef _UNDER_DEVELOPMENT
764114237Snjl
765114237Snjl    if (WalkState->ParserState.Aml == WalkState->ParserState.AmlEnd)
766114237Snjl    {
767114237Snjl        AcpiDbMethodEnd (WalkState);
768114237Snjl    }
769114237Snjl#endif
770114237Snjl
771167802Sjkim    /* Invoke exception handler on error */
77267754Smsmith
773117521Snjl    if (ACPI_FAILURE (Status))
774117521Snjl    {
775167802Sjkim        Status = AcpiDsMethodError (Status, WalkState);
776117521Snjl    }
777117521Snjl
778167802Sjkim    /* Always clear the object stack */
779167802Sjkim
780167802Sjkim    WalkState->NumOperands = 0;
78167754Smsmith    return_ACPI_STATUS (Status);
78267754Smsmith}
783