167754Smsmith/******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: dswexec - Dispatcher method execution callbacks;
467754Smsmith *                        dispatch to interpreter.
567754Smsmith *
667754Smsmith *****************************************************************************/
767754Smsmith
8316303Sjkim/******************************************************************************
9316303Sjkim *
10316303Sjkim * 1. Copyright Notice
11316303Sjkim *
12316303Sjkim * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
1370243Smsmith * All rights reserved.
1467754Smsmith *
15316303Sjkim * 2. License
16316303Sjkim *
17316303Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property
18316303Sjkim * rights. You may have additional license terms from the party that provided
19316303Sjkim * you this software, covering your right to use that party's intellectual
20316303Sjkim * property rights.
21316303Sjkim *
22316303Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23316303Sjkim * copy of the source code appearing in this file ("Covered Code") an
24316303Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25316303Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy,
26316303Sjkim * make derivatives, distribute, use and display any portion of the Covered
27316303Sjkim * Code in any form, with the right to sublicense such rights; and
28316303Sjkim *
29316303Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30316303Sjkim * license (with the right to sublicense), under only those claims of Intel
31316303Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell,
32316303Sjkim * offer to sell, and import the Covered Code and derivative works thereof
33316303Sjkim * solely to the minimum extent necessary to exercise the above copyright
34316303Sjkim * license, and in no event shall the patent license extend to any additions
35316303Sjkim * to or modifications of the Original Intel Code. No other license or right
36316303Sjkim * is granted directly or by implication, estoppel or otherwise;
37316303Sjkim *
38316303Sjkim * The above copyright and patent license is granted only if the following
39316303Sjkim * conditions are met:
40316303Sjkim *
41316303Sjkim * 3. Conditions
42316303Sjkim *
43316303Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44316303Sjkim * Redistribution of source code of any substantial portion of the Covered
45316303Sjkim * Code or modification with rights to further distribute source must include
46316303Sjkim * the above Copyright Notice, the above License, this list of Conditions,
47316303Sjkim * and the following Disclaimer and Export Compliance provision. In addition,
48316303Sjkim * Licensee must cause all Covered Code to which Licensee contributes to
49316303Sjkim * contain a file documenting the changes Licensee made to create that Covered
50316303Sjkim * Code and the date of any change. Licensee must include in that file the
51316303Sjkim * documentation of any changes made by any predecessor Licensee. Licensee
52316303Sjkim * must include a prominent statement that the modification is derived,
53316303Sjkim * directly or indirectly, from Original Intel Code.
54316303Sjkim *
55316303Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56316303Sjkim * Redistribution of source code of any substantial portion of the Covered
57316303Sjkim * Code or modification without rights to further distribute source must
58316303Sjkim * include the following Disclaimer and Export Compliance provision in the
59316303Sjkim * documentation and/or other materials provided with distribution. In
60316303Sjkim * addition, Licensee may not authorize further sublicense of source of any
61316303Sjkim * portion of the Covered Code, and must include terms to the effect that the
62316303Sjkim * license from Licensee to its licensee is limited to the intellectual
63316303Sjkim * property embodied in the software Licensee provides to its licensee, and
64316303Sjkim * not to intellectual property embodied in modifications its licensee may
65316303Sjkim * make.
66316303Sjkim *
67316303Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any
68316303Sjkim * substantial portion of the Covered Code or modification must reproduce the
69316303Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance
70316303Sjkim * provision in the documentation and/or other materials provided with the
71316303Sjkim * distribution.
72316303Sjkim *
73316303Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original
74316303Sjkim * Intel Code.
75316303Sjkim *
76316303Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77316303Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or
78316303Sjkim * other dealings in products derived from or relating to the Covered Code
79316303Sjkim * without prior written authorization from Intel.
80316303Sjkim *
81316303Sjkim * 4. Disclaimer and Export Compliance
82316303Sjkim *
83316303Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84316303Sjkim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85316303Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
86316303Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
87316303Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
88316303Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89316303Sjkim * PARTICULAR PURPOSE.
90316303Sjkim *
91316303Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92316303Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93316303Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94316303Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95316303Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96316303Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
97316303Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98316303Sjkim * LIMITED REMEDY.
99316303Sjkim *
100316303Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this
101316303Sjkim * software or system incorporating such software without first obtaining any
102316303Sjkim * required license or other approval from the U. S. Department of Commerce or
103316303Sjkim * any other agency or department of the United States Government. In the
104316303Sjkim * event Licensee exports any such software from the United States or
105316303Sjkim * re-exports any such software from a foreign destination, Licensee shall
106316303Sjkim * ensure that the distribution and export/re-export of the software is in
107316303Sjkim * compliance with all laws, regulations, orders, or other restrictions of the
108316303Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109316303Sjkim * any of its subsidiaries will export/re-export any technical data, process,
110316303Sjkim * software, or service, directly or indirectly, to any country for which the
111316303Sjkim * United States government or any agency thereof requires an export license,
112316303Sjkim * other governmental approval, or letter of assurance, without first obtaining
113316303Sjkim * such license, approval or letter.
114316303Sjkim *
115316303Sjkim *****************************************************************************
116316303Sjkim *
117316303Sjkim * Alternatively, you may choose to be licensed under the terms of the
118316303Sjkim * following license:
119316303Sjkim *
120217365Sjkim * Redistribution and use in source and binary forms, with or without
121217365Sjkim * modification, are permitted provided that the following conditions
122217365Sjkim * are met:
123217365Sjkim * 1. Redistributions of source code must retain the above copyright
124217365Sjkim *    notice, this list of conditions, and the following disclaimer,
125217365Sjkim *    without modification.
126217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
127217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
128217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
129217365Sjkim *    including a substantially similar Disclaimer requirement for further
130217365Sjkim *    binary redistribution.
131217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
132217365Sjkim *    of any contributors may be used to endorse or promote products derived
133217365Sjkim *    from this software without specific prior written permission.
13467754Smsmith *
135316303Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
136316303Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
137316303Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
138316303Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
139316303Sjkim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
140316303Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
141316303Sjkim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
142316303Sjkim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
143316303Sjkim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144316303Sjkim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
145316303Sjkim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
146316303Sjkim *
147316303Sjkim * Alternatively, you may choose to be licensed under the terms of the
148217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
149217365Sjkim * Software Foundation.
15067754Smsmith *
151316303Sjkim *****************************************************************************/
15267754Smsmith
153193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
154193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
155193341Sjkim#include <contrib/dev/acpica/include/acparser.h>
156193341Sjkim#include <contrib/dev/acpica/include/amlcode.h>
157193341Sjkim#include <contrib/dev/acpica/include/acdispat.h>
158193341Sjkim#include <contrib/dev/acpica/include/acinterp.h>
159193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
160193341Sjkim#include <contrib/dev/acpica/include/acdebug.h>
16167754Smsmith
16267754Smsmith
16377424Smsmith#define _COMPONENT          ACPI_DISPATCHER
16491116Smsmith        ACPI_MODULE_NAME    ("dswexec")
16567754Smsmith
16685756Smsmith/*
16787031Smsmith * Dispatch table for opcode classes
16885756Smsmith */
169167802Sjkimstatic ACPI_EXECUTE_OP      AcpiGbl_OpTypeDispatch [] =
170167802Sjkim{
171167802Sjkim    AcpiExOpcode_0A_0T_1R,
172167802Sjkim    AcpiExOpcode_1A_0T_0R,
173167802Sjkim    AcpiExOpcode_1A_0T_1R,
174167802Sjkim    AcpiExOpcode_1A_1T_0R,
175167802Sjkim    AcpiExOpcode_1A_1T_1R,
176167802Sjkim    AcpiExOpcode_2A_0T_0R,
177167802Sjkim    AcpiExOpcode_2A_0T_1R,
178167802Sjkim    AcpiExOpcode_2A_1T_1R,
179167802Sjkim    AcpiExOpcode_2A_2T_1R,
180167802Sjkim    AcpiExOpcode_3A_0T_0R,
181167802Sjkim    AcpiExOpcode_3A_1T_1R,
182167802Sjkim    AcpiExOpcode_6A_0T_1R
183167802Sjkim};
18467754Smsmith
185151937Sjkim
18667754Smsmith/*****************************************************************************
18767754Smsmith *
18867754Smsmith * FUNCTION:    AcpiDsGetPredicateValue
18967754Smsmith *
19067754Smsmith * PARAMETERS:  WalkState       - Current state of the parse tree walk
191151937Sjkim *              ResultObj       - if non-zero, pop result from result stack
19267754Smsmith *
19367754Smsmith * RETURN:      Status
19467754Smsmith *
19571867Smsmith * DESCRIPTION: Get the result of a predicate evaluation
19667754Smsmith *
19767754Smsmith ****************************************************************************/
19867754Smsmith
19967754SmsmithACPI_STATUS
20067754SmsmithAcpiDsGetPredicateValue (
20167754Smsmith    ACPI_WALK_STATE         *WalkState,
20291116Smsmith    ACPI_OPERAND_OBJECT     *ResultObj)
20367754Smsmith{
20467754Smsmith    ACPI_STATUS             Status = AE_OK;
20567754Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
206151937Sjkim    ACPI_OPERAND_OBJECT     *LocalObjDesc = NULL;
20767754Smsmith
20867754Smsmith
209167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsGetPredicateValue, WalkState);
21067754Smsmith
21167754Smsmith
21267754Smsmith    WalkState->ControlState->Common.State = 0;
21367754Smsmith
21491116Smsmith    if (ResultObj)
21567754Smsmith    {
21669746Smsmith        Status = AcpiDsResultPop (&ObjDesc, WalkState);
21767754Smsmith        if (ACPI_FAILURE (Status))
21867754Smsmith        {
219167802Sjkim            ACPI_EXCEPTION ((AE_INFO, Status,
220167802Sjkim                "Could not get result from predicate evaluation"));
22169450Smsmith
22267754Smsmith            return_ACPI_STATUS (Status);
22367754Smsmith        }
22467754Smsmith    }
22567754Smsmith    else
22667754Smsmith    {
22784491Smsmith        Status = AcpiDsCreateOperand (WalkState, WalkState->Op, 0);
22867754Smsmith        if (ACPI_FAILURE (Status))
22967754Smsmith        {
23067754Smsmith            return_ACPI_STATUS (Status);
23167754Smsmith        }
23267754Smsmith
23377424Smsmith        Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
23467754Smsmith        if (ACPI_FAILURE (Status))
23567754Smsmith        {
23667754Smsmith            return_ACPI_STATUS (Status);
23767754Smsmith        }
23867754Smsmith
23967754Smsmith        ObjDesc = WalkState->Operands [0];
24067754Smsmith    }
24167754Smsmith
24267754Smsmith    if (!ObjDesc)
24367754Smsmith    {
244167802Sjkim        ACPI_ERROR ((AE_INFO,
245167802Sjkim            "No predicate ObjDesc=%p State=%p",
24667754Smsmith            ObjDesc, WalkState));
24767754Smsmith
24867754Smsmith        return_ACPI_STATUS (AE_AML_NO_OPERAND);
24967754Smsmith    }
25067754Smsmith
25169450Smsmith    /*
252151937Sjkim     * Result of predicate evaluation must be an Integer
253151937Sjkim     * object. Implicitly convert the argument if necessary.
25467754Smsmith     */
255316303Sjkim    Status = AcpiExConvertToInteger (ObjDesc, &LocalObjDesc,
256327557Sjkim        ACPI_IMPLICIT_CONVERSION);
257151937Sjkim    if (ACPI_FAILURE (Status))
25867754Smsmith    {
259151937Sjkim        goto Cleanup;
260151937Sjkim    }
261151937Sjkim
262193267Sjkim    if (LocalObjDesc->Common.Type != ACPI_TYPE_INTEGER)
263151937Sjkim    {
264167802Sjkim        ACPI_ERROR ((AE_INFO,
265204773Sjkim            "Bad predicate (not an integer) ObjDesc=%p State=%p Type=0x%X",
266193267Sjkim            ObjDesc, WalkState, ObjDesc->Common.Type));
26767754Smsmith
26867754Smsmith        Status = AE_AML_OPERAND_TYPE;
26967754Smsmith        goto Cleanup;
27067754Smsmith    }
27167754Smsmith
27271867Smsmith    /* Truncate the predicate to 32-bits if necessary */
27369450Smsmith
274245582Sjkim    (void) AcpiExTruncateFor32bitTable (LocalObjDesc);
27569450Smsmith
27669450Smsmith    /*
27767754Smsmith     * Save the result of the predicate evaluation on
27869450Smsmith     * the control stack
27967754Smsmith     */
280151937Sjkim    if (LocalObjDesc->Integer.Value)
28167754Smsmith    {
28267754Smsmith        WalkState->ControlState->Common.Value = TRUE;
28367754Smsmith    }
28467754Smsmith    else
28567754Smsmith    {
28669450Smsmith        /*
28767754Smsmith         * Predicate is FALSE, we will just toss the
28869450Smsmith         * rest of the package
28967754Smsmith         */
29067754Smsmith        WalkState->ControlState->Common.Value = FALSE;
29167754Smsmith        Status = AE_CTRL_FALSE;
29267754Smsmith    }
29367754Smsmith
294193267Sjkim    /* Predicate can be used for an implicit return value */
29567754Smsmith
296193267Sjkim    (void) AcpiDsDoImplicitReturn (LocalObjDesc, WalkState, TRUE);
297193267Sjkim
298193267Sjkim
29967754SmsmithCleanup:
30067754Smsmith
301298714Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
302298714Sjkim        "Completed a predicate eval=%X Op=%p\n",
30384491Smsmith        WalkState->ControlState->Common.Value, WalkState->Op));
30467754Smsmith
305298714Sjkim    /* Break to debugger to display result */
30667754Smsmith
307298714Sjkim    AcpiDbDisplayResultObject (LocalObjDesc, WalkState);
30867754Smsmith
30969450Smsmith    /*
31067754Smsmith     * Delete the predicate result object (we know that
31167754Smsmith     * we don't need it anymore)
31267754Smsmith     */
313151937Sjkim    if (LocalObjDesc != ObjDesc)
314151937Sjkim    {
315151937Sjkim        AcpiUtRemoveReference (LocalObjDesc);
316151937Sjkim    }
31777424Smsmith    AcpiUtRemoveReference (ObjDesc);
31867754Smsmith
31991116Smsmith    WalkState->ControlState->Common.State = ACPI_CONTROL_NORMAL;
32067754Smsmith    return_ACPI_STATUS (Status);
32167754Smsmith}
32267754Smsmith
32367754Smsmith
32467754Smsmith/*****************************************************************************
32567754Smsmith *
32667754Smsmith * FUNCTION:    AcpiDsExecBeginOp
32767754Smsmith *
32867754Smsmith * PARAMETERS:  WalkState       - Current state of the parse tree walk
329151937Sjkim *              OutOp           - Where to return op if a new one is created
33067754Smsmith *
33167754Smsmith * RETURN:      Status
33267754Smsmith *
33367754Smsmith * DESCRIPTION: Descending callback used during the execution of control
334241973Sjkim *              methods. This is where most operators and operands are
33567754Smsmith *              dispatched to the interpreter.
33667754Smsmith *
33767754Smsmith ****************************************************************************/
33867754Smsmith
33967754SmsmithACPI_STATUS
34067754SmsmithAcpiDsExecBeginOp (
34167754Smsmith    ACPI_WALK_STATE         *WalkState,
34267754Smsmith    ACPI_PARSE_OBJECT       **OutOp)
34367754Smsmith{
34484491Smsmith    ACPI_PARSE_OBJECT       *Op;
34567754Smsmith    ACPI_STATUS             Status = AE_OK;
34685756Smsmith    UINT32                  OpcodeClass;
34767754Smsmith
34867754Smsmith
349167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsExecBeginOp, WalkState);
35067754Smsmith
35167754Smsmith
35284491Smsmith    Op = WalkState->Op;
35367754Smsmith    if (!Op)
35467754Smsmith    {
35584491Smsmith        Status = AcpiDsLoad2BeginOp (WalkState, OutOp);
35667754Smsmith        if (ACPI_FAILURE (Status))
35767754Smsmith        {
358167802Sjkim            goto ErrorExit;
35967754Smsmith        }
36067754Smsmith
36167754Smsmith        Op = *OutOp;
36284491Smsmith        WalkState->Op = Op;
36399679Siwasaki        WalkState->Opcode = Op->Common.AmlOpcode;
36499679Siwasaki        WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
36591116Smsmith
36691116Smsmith        if (AcpiNsOpensScope (WalkState->OpInfo->ObjectType))
36791116Smsmith        {
368151937Sjkim            ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
369151937Sjkim                "(%s) Popping scope for Op %p\n",
37091116Smsmith                AcpiUtGetTypeName (WalkState->OpInfo->ObjectType), Op));
37199679Siwasaki
37299679Siwasaki            Status = AcpiDsScopeStackPop (WalkState);
37399679Siwasaki            if (ACPI_FAILURE (Status))
37499679Siwasaki            {
375167802Sjkim                goto ErrorExit;
37699679Siwasaki            }
37791116Smsmith        }
37867754Smsmith    }
37967754Smsmith
38067754Smsmith    if (Op == WalkState->Origin)
38167754Smsmith    {
38267754Smsmith        if (OutOp)
38367754Smsmith        {
38467754Smsmith            *OutOp = Op;
38567754Smsmith        }
38667754Smsmith
38767754Smsmith        return_ACPI_STATUS (AE_OK);
38867754Smsmith    }
38967754Smsmith
39067754Smsmith    /*
39167754Smsmith     * If the previous opcode was a conditional, this opcode
39267754Smsmith     * must be the beginning of the associated predicate.
39367754Smsmith     * Save this knowledge in the current scope descriptor
39467754Smsmith     */
39567754Smsmith    if ((WalkState->ControlState) &&
39667754Smsmith        (WalkState->ControlState->Common.State ==
39791116Smsmith            ACPI_CONTROL_CONDITIONAL_EXECUTING))
39867754Smsmith    {
399298714Sjkim        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
400298714Sjkim            "Exec predicate Op=%p State=%p\n",
401298714Sjkim            Op, WalkState));
40267754Smsmith
403298714Sjkim        WalkState->ControlState->Common.State =
404298714Sjkim            ACPI_CONTROL_PREDICATE_EXECUTING;
40567754Smsmith
40667754Smsmith        /* Save start of predicate */
40767754Smsmith
40867754Smsmith        WalkState->ControlState->Control.PredicateOp = Op;
40967754Smsmith    }
41067754Smsmith
41167754Smsmith
41285756Smsmith    OpcodeClass = WalkState->OpInfo->Class;
41367754Smsmith
41467754Smsmith    /* We want to send namepaths to the load code */
41567754Smsmith
41699679Siwasaki    if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
41767754Smsmith    {
41885756Smsmith        OpcodeClass = AML_CLASS_NAMED_OBJECT;
41967754Smsmith    }
42067754Smsmith
42167754Smsmith    /*
42267754Smsmith     * Handle the opcode based upon the opcode type
42367754Smsmith     */
42483174Smsmith    switch (OpcodeClass)
42567754Smsmith    {
42685756Smsmith    case AML_CLASS_CONTROL:
42767754Smsmith
42867754Smsmith        Status = AcpiDsExecBeginControlOp (WalkState, Op);
42967754Smsmith        break;
43067754Smsmith
43185756Smsmith    case AML_CLASS_NAMED_OBJECT:
43267754Smsmith
433167802Sjkim        if (WalkState->WalkType & ACPI_WALK_METHOD)
43467754Smsmith        {
43567754Smsmith            /*
436151937Sjkim             * Found a named object declaration during method execution;
437241973Sjkim             * we must enter this object into the namespace. The created
438151937Sjkim             * object is temporary and will be deleted upon completion of
439151937Sjkim             * the execution of this method.
440216471Sjkim             *
441216471Sjkim             * Note 10/2010: Except for the Scope() op. This opcode does
442216471Sjkim             * not actually create a new object, it refers to an existing
443216471Sjkim             * object. However, for Scope(), we want to indeed open a
444216471Sjkim             * new scope.
44567754Smsmith             */
446216471Sjkim            if (Op->Common.AmlOpcode != AML_SCOPE_OP)
447216471Sjkim            {
448216471Sjkim                Status = AcpiDsLoad2BeginOp (WalkState, NULL);
449216471Sjkim            }
450216471Sjkim            else
451216471Sjkim            {
452298714Sjkim                Status = AcpiDsScopeStackPush (
453298714Sjkim                    Op->Named.Node, Op->Named.Node->Type, WalkState);
454216471Sjkim                if (ACPI_FAILURE (Status))
455216471Sjkim                {
456216471Sjkim                    return_ACPI_STATUS (Status);
457216471Sjkim                }
458216471Sjkim            }
45967754Smsmith        }
46067754Smsmith        break;
46167754Smsmith
46285756Smsmith    case AML_CLASS_EXECUTE:
46385756Smsmith    case AML_CLASS_CREATE:
46469746Smsmith
46569746Smsmith        break;
46669746Smsmith
467250838Sjkim    default:
46869746Smsmith
46967754Smsmith        break;
47067754Smsmith    }
47167754Smsmith
47267754Smsmith    /* Nothing to do here during method execution */
47367754Smsmith
47467754Smsmith    return_ACPI_STATUS (Status);
475167802Sjkim
476167802Sjkim
477167802SjkimErrorExit:
478167802Sjkim    Status = AcpiDsMethodError (Status, WalkState);
479167802Sjkim    return_ACPI_STATUS (Status);
48067754Smsmith}
48167754Smsmith
48267754Smsmith
48367754Smsmith/*****************************************************************************
48467754Smsmith *
48567754Smsmith * FUNCTION:    AcpiDsExecEndOp
48667754Smsmith *
48767754Smsmith * PARAMETERS:  WalkState       - Current state of the parse tree walk
48867754Smsmith *
48967754Smsmith * RETURN:      Status
49067754Smsmith *
49167754Smsmith * DESCRIPTION: Ascending callback used during the execution of control
492241973Sjkim *              methods. The only thing we really need to do here is to
49367754Smsmith *              notice the beginning of IF, ELSE, and WHILE blocks.
49467754Smsmith *
49567754Smsmith ****************************************************************************/
49667754Smsmith
49767754SmsmithACPI_STATUS
49867754SmsmithAcpiDsExecEndOp (
49984491Smsmith    ACPI_WALK_STATE         *WalkState)
50067754Smsmith{
50184491Smsmith    ACPI_PARSE_OBJECT       *Op;
50267754Smsmith    ACPI_STATUS             Status = AE_OK;
50385756Smsmith    UINT32                  OpType;
50485756Smsmith    UINT32                  OpClass;
50567754Smsmith    ACPI_PARSE_OBJECT       *NextOp;
50667754Smsmith    ACPI_PARSE_OBJECT       *FirstArg;
50767754Smsmith
50867754Smsmith
509167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsExecEndOp, WalkState);
51067754Smsmith
51167754Smsmith
512298714Sjkim    Op = WalkState->Op;
513298714Sjkim    OpType = WalkState->OpInfo->Type;
51485756Smsmith    OpClass = WalkState->OpInfo->Class;
51567754Smsmith
51685756Smsmith    if (OpClass == AML_CLASS_UNKNOWN)
51767754Smsmith    {
518204773Sjkim        ACPI_ERROR ((AE_INFO, "Unknown opcode 0x%X", Op->Common.AmlOpcode));
51967754Smsmith        return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
52067754Smsmith    }
52167754Smsmith
52299679Siwasaki    FirstArg = Op->Common.Value.Arg;
52367754Smsmith
52467754Smsmith    /* Init the walk state */
52567754Smsmith
52667754Smsmith    WalkState->NumOperands = 0;
527167802Sjkim    WalkState->OperandIndex = 0;
52867754Smsmith    WalkState->ReturnDesc = NULL;
52984491Smsmith    WalkState->ResultObj = NULL;
53067754Smsmith
53167754Smsmith    /* Call debugger for single step support (DEBUG build only) */
53267754Smsmith
533298714Sjkim    Status = AcpiDbSingleStep (WalkState, Op, OpClass);
534298714Sjkim    if (ACPI_FAILURE (Status))
535298714Sjkim    {
536298714Sjkim        return_ACPI_STATUS (Status);
537298714Sjkim    }
53867754Smsmith
53987031Smsmith    /* Decode the Opcode Class */
54067754Smsmith
54185756Smsmith    switch (OpClass)
54267754Smsmith    {
543167802Sjkim    case AML_CLASS_ARGUMENT:    /* Constants, literals, etc. */
544167802Sjkim
545167802Sjkim        if (WalkState->Opcode == AML_INT_NAMEPATH_OP)
546167802Sjkim        {
547167802Sjkim            Status = AcpiDsEvaluateNamePath (WalkState);
548167802Sjkim            if (ACPI_FAILURE (Status))
549167802Sjkim            {
550167802Sjkim                goto Cleanup;
551167802Sjkim            }
552167802Sjkim        }
55367754Smsmith        break;
55467754Smsmith
555167802Sjkim    case AML_CLASS_EXECUTE:     /* Most operators with arguments */
55667754Smsmith
55769746Smsmith        /* Build resolved operand stack */
55869746Smsmith
55967754Smsmith        Status = AcpiDsCreateOperands (WalkState, FirstArg);
56067754Smsmith        if (ACPI_FAILURE (Status))
56167754Smsmith        {
56267754Smsmith            goto Cleanup;
56367754Smsmith        }
56467754Smsmith
565151937Sjkim        /*
566151937Sjkim         * All opcodes require operand resolution, with the only exceptions
567151937Sjkim         * being the ObjectType and SizeOf operators.
568151937Sjkim         */
569151937Sjkim        if (!(WalkState->OpInfo->Flags & AML_NO_OPERAND_RESOLVE))
570151937Sjkim        {
571151937Sjkim            /* Resolve all operands */
57283174Smsmith
573151937Sjkim            Status = AcpiExResolveOperands (WalkState->Opcode,
574298714Sjkim                &(WalkState->Operands [WalkState->NumOperands -1]),
575298714Sjkim                WalkState);
576151937Sjkim        }
577151937Sjkim
57887031Smsmith        if (ACPI_SUCCESS (Status))
57983174Smsmith        {
58083174Smsmith            /*
58187031Smsmith             * Dispatch the request to the appropriate interpreter handler
582241973Sjkim             * routine. There is one routine per opcode "type" based upon the
58387031Smsmith             * number of opcode arguments and return type.
58483174Smsmith             */
585138287Smarks            Status = AcpiGbl_OpTypeDispatch[OpType] (WalkState);
58683174Smsmith        }
58787031Smsmith        else
58887031Smsmith        {
589123315Snjl            /*
590123315Snjl             * Treat constructs of the form "Store(LocalX,LocalX)" as noops when the
591123315Snjl             * Local is uninitialized.
592123315Snjl             */
593123315Snjl            if  ((Status == AE_AML_UNINITIALIZED_LOCAL) &&
594123315Snjl                (WalkState->Opcode == AML_STORE_OP) &&
595123315Snjl                (WalkState->Operands[0]->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
596123315Snjl                (WalkState->Operands[1]->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
597193267Sjkim                (WalkState->Operands[0]->Reference.Class ==
598193267Sjkim                 WalkState->Operands[1]->Reference.Class) &&
599193267Sjkim                (WalkState->Operands[0]->Reference.Value ==
600193267Sjkim                 WalkState->Operands[1]->Reference.Value))
601123315Snjl            {
602123315Snjl                Status = AE_OK;
603123315Snjl            }
604123315Snjl            else
605123315Snjl            {
606167802Sjkim                ACPI_EXCEPTION ((AE_INFO, Status,
607167802Sjkim                    "While resolving operands for [%s]",
608167802Sjkim                    AcpiPsGetOpcodeName (WalkState->Opcode)));
609123315Snjl            }
61087031Smsmith        }
61183174Smsmith
61287031Smsmith        /* Always delete the argument objects and clear the operand stack */
61383174Smsmith
614107325Siwasaki        AcpiDsClearOperands (WalkState);
61583174Smsmith
61669746Smsmith        /*
61769746Smsmith         * If a result object was returned from above, push it on the
61869746Smsmith         * current result stack
61969746Smsmith         */
62069746Smsmith        if (ACPI_SUCCESS (Status) &&
62184491Smsmith            WalkState->ResultObj)
62269746Smsmith        {
62384491Smsmith            Status = AcpiDsResultPush (WalkState->ResultObj, WalkState);
62469746Smsmith        }
62567754Smsmith        break;
62667754Smsmith
62785756Smsmith    default:
62867754Smsmith
62985756Smsmith        switch (OpType)
63085756Smsmith        {
63185756Smsmith        case AML_TYPE_CONTROL:    /* Type 1 opcode, IF/ELSE/WHILE/NOOP */
63267754Smsmith
63385756Smsmith            /* 1 Operand, 0 ExternalResult, 0 InternalResult */
63467754Smsmith
63585756Smsmith            Status = AcpiDsExecEndControlOp (WalkState, Op);
636151937Sjkim
63785756Smsmith            break;
63867754Smsmith
63985756Smsmith        case AML_TYPE_METHOD_CALL:
640151937Sjkim            /*
641151937Sjkim             * If the method is referenced from within a package
642151937Sjkim             * declaration, it is not a invocation of the method, just
643151937Sjkim             * a reference to it.
644151937Sjkim             */
645151937Sjkim            if ((Op->Asl.Parent) &&
646151937Sjkim               ((Op->Asl.Parent->Asl.AmlOpcode == AML_PACKAGE_OP) ||
647316303Sjkim                (Op->Asl.Parent->Asl.AmlOpcode == AML_VARIABLE_PACKAGE_OP)))
648151937Sjkim            {
649151937Sjkim                ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
650151937Sjkim                    "Method Reference in a Package, Op=%p\n", Op));
651167802Sjkim
652298714Sjkim                Op->Common.Node = (ACPI_NAMESPACE_NODE *)
653298714Sjkim                    Op->Asl.Value.Arg->Asl.Node;
654151937Sjkim                AcpiUtAddReference (Op->Asl.Value.Arg->Asl.Node->Object);
655151937Sjkim                return_ACPI_STATUS (AE_OK);
656151937Sjkim            }
657151937Sjkim
658272444Sjkim            ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
659272444Sjkim                "Method invocation, Op=%p\n", Op));
66067754Smsmith
66185756Smsmith            /*
662151937Sjkim             * (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains
66385756Smsmith             * the method Node pointer
66485756Smsmith             */
66585756Smsmith            /* NextOp points to the op that holds the method name */
66667754Smsmith
66785756Smsmith            NextOp = FirstArg;
66867754Smsmith
66985756Smsmith            /* NextOp points to first argument op */
67067754Smsmith
67199679Siwasaki            NextOp = NextOp->Common.Next;
67267754Smsmith
67385756Smsmith            /*
67485756Smsmith             * Get the method's arguments and put them on the operand stack
67585756Smsmith             */
67685756Smsmith            Status = AcpiDsCreateOperands (WalkState, NextOp);
67785756Smsmith            if (ACPI_FAILURE (Status))
67885756Smsmith            {
67985756Smsmith                break;
68085756Smsmith            }
68167754Smsmith
68285756Smsmith            /*
68391116Smsmith             * Since the operands will be passed to another control method,
68491116Smsmith             * we must resolve all local references here (Local variables,
68587031Smsmith             * arguments to *this* method, etc.)
68685756Smsmith             */
68785756Smsmith            Status = AcpiDsResolveOperands (WalkState);
68885756Smsmith            if (ACPI_FAILURE (Status))
68985756Smsmith            {
690107325Siwasaki                /* On error, clear all resolved operands */
691107325Siwasaki
692107325Siwasaki                AcpiDsClearOperands (WalkState);
69385756Smsmith                break;
69485756Smsmith            }
69567754Smsmith
69685756Smsmith            /*
69785756Smsmith             * Tell the walk loop to preempt this running method and
69885756Smsmith             * execute the new method
69985756Smsmith             */
70085756Smsmith            Status = AE_CTRL_TRANSFER;
70167754Smsmith
70285756Smsmith            /*
70385756Smsmith             * Return now; we don't want to disturb anything,
70485756Smsmith             * especially the operand count!
70585756Smsmith             */
70685756Smsmith            return_ACPI_STATUS (Status);
70767754Smsmith
70885756Smsmith        case AML_TYPE_CREATE_FIELD:
70967754Smsmith
71085756Smsmith            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
71185756Smsmith                "Executing CreateField Buffer/Index Op=%p\n", Op));
71267754Smsmith
71385756Smsmith            Status = AcpiDsLoad2EndOp (WalkState);
71485756Smsmith            if (ACPI_FAILURE (Status))
71585756Smsmith            {
71685756Smsmith                break;
71785756Smsmith            }
71867754Smsmith
71985756Smsmith            Status = AcpiDsEvalBufferFieldOperands (WalkState, Op);
72067754Smsmith            break;
72167754Smsmith
72267754Smsmith
72399146Siwasaki        case AML_TYPE_CREATE_OBJECT:
72499146Siwasaki
72599146Siwasaki            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
726322877Sjkim                "Executing CreateObject (Buffer/Package) Op=%p AMLPtr=%p\n",
727322877Sjkim                Op, Op->Named.Data));
72899146Siwasaki
72999679Siwasaki            switch (Op->Common.Parent->Common.AmlOpcode)
73099146Siwasaki            {
73199146Siwasaki            case AML_NAME_OP:
73299146Siwasaki                /*
733151937Sjkim                 * Put the Node on the object stack (Contains the ACPI Name
734151937Sjkim                 * of this object)
73599146Siwasaki                 */
736298714Sjkim                WalkState->Operands[0] = (void *)
737298714Sjkim                    Op->Common.Parent->Common.Node;
73899146Siwasaki                WalkState->NumOperands = 1;
73999146Siwasaki
740151937Sjkim                Status = AcpiDsCreateNode (WalkState,
741298714Sjkim                    Op->Common.Parent->Common.Node, Op->Common.Parent);
74299146Siwasaki                if (ACPI_FAILURE (Status))
74399146Siwasaki                {
74499146Siwasaki                    break;
74599146Siwasaki                }
74699146Siwasaki
74799146Siwasaki                /* Fall through */
74899679Siwasaki                /*lint -fallthrough */
74999146Siwasaki
75099146Siwasaki            case AML_INT_EVAL_SUBTREE_OP:
75199146Siwasaki
752102550Siwasaki                Status = AcpiDsEvalDataObjectOperands (WalkState, Op,
753298714Sjkim                    AcpiNsGetAttachedObject (Op->Common.Parent->Common.Node));
75499146Siwasaki                break;
75599146Siwasaki
75699146Siwasaki            default:
75799146Siwasaki
75899146Siwasaki                Status = AcpiDsEvalDataObjectOperands (WalkState, Op, NULL);
75999146Siwasaki                break;
76099146Siwasaki            }
76199146Siwasaki
76299146Siwasaki            /*
76399146Siwasaki             * If a result object was returned from above, push it on the
76499146Siwasaki             * current result stack
76599146Siwasaki             */
766151937Sjkim            if (WalkState->ResultObj)
76799146Siwasaki            {
76899146Siwasaki                Status = AcpiDsResultPush (WalkState->ResultObj, WalkState);
76999146Siwasaki            }
77099146Siwasaki            break;
77199146Siwasaki
77285756Smsmith        case AML_TYPE_NAMED_FIELD:
77385756Smsmith        case AML_TYPE_NAMED_COMPLEX:
77485756Smsmith        case AML_TYPE_NAMED_SIMPLE:
77591116Smsmith        case AML_TYPE_NAMED_NO_OBJ:
77667754Smsmith
77785756Smsmith            Status = AcpiDsLoad2EndOp (WalkState);
77869746Smsmith            if (ACPI_FAILURE (Status))
77969746Smsmith            {
78069746Smsmith                break;
78169746Smsmith            }
78267754Smsmith
78399679Siwasaki            if (Op->Common.AmlOpcode == AML_REGION_OP)
78485756Smsmith            {
78585756Smsmith                ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
78685756Smsmith                    "Executing OpRegion Address/Length Op=%p\n", Op));
78785756Smsmith
78885756Smsmith                Status = AcpiDsEvalRegionOperands (WalkState, Op);
78985756Smsmith                if (ACPI_FAILURE (Status))
79085756Smsmith                {
79185756Smsmith                    break;
79285756Smsmith                }
79385756Smsmith            }
794193267Sjkim            else if (Op->Common.AmlOpcode == AML_DATA_REGION_OP)
795193267Sjkim            {
796193267Sjkim                ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
797193267Sjkim                    "Executing DataTableRegion Strings Op=%p\n", Op));
798193267Sjkim
799193267Sjkim                Status = AcpiDsEvalTableRegionOperands (WalkState, Op);
800193267Sjkim                if (ACPI_FAILURE (Status))
801193267Sjkim                {
802193267Sjkim                    break;
803193267Sjkim                }
804193267Sjkim            }
805193267Sjkim            else if (Op->Common.AmlOpcode == AML_BANK_FIELD_OP)
806193267Sjkim            {
807193267Sjkim                ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
808193267Sjkim                    "Executing BankField Op=%p\n", Op));
809193267Sjkim
810193267Sjkim                Status = AcpiDsEvalBankFieldOperands (WalkState, Op);
811193267Sjkim                if (ACPI_FAILURE (Status))
812193267Sjkim                {
813193267Sjkim                    break;
814193267Sjkim                }
815193267Sjkim            }
81667754Smsmith            break;
81767754Smsmith
81885756Smsmith        case AML_TYPE_UNDEFINED:
81967754Smsmith
820167802Sjkim            ACPI_ERROR ((AE_INFO,
821167802Sjkim                "Undefined opcode type Op=%p", Op));
82285756Smsmith            return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
82367754Smsmith
82485756Smsmith        case AML_TYPE_BOGUS:
82587031Smsmith
82691116Smsmith            ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
82787031Smsmith                "Internal opcode=%X type Op=%p\n",
82885756Smsmith                WalkState->Opcode, Op));
82967754Smsmith            break;
83067754Smsmith
83167754Smsmith        default:
83267754Smsmith
833167802Sjkim            ACPI_ERROR ((AE_INFO,
834298714Sjkim                "Unimplemented opcode, class=0x%X "
835298714Sjkim                "type=0x%X Opcode=0x%X Op=%p",
83699679Siwasaki                OpClass, OpType, Op->Common.AmlOpcode, Op));
83785756Smsmith
83885756Smsmith            Status = AE_NOT_IMPLEMENTED;
83967754Smsmith            break;
84067754Smsmith        }
84167754Smsmith    }
84267754Smsmith
84367754Smsmith    /*
84491116Smsmith     * ACPI 2.0 support for 64-bit integers: Truncate numeric
84587031Smsmith     * result value if we are executing from a 32-bit ACPI table
84669450Smsmith     */
847245582Sjkim    (void) AcpiExTruncateFor32bitTable (WalkState->ResultObj);
84869450Smsmith
84969450Smsmith    /*
85067754Smsmith     * Check if we just completed the evaluation of a
85167754Smsmith     * conditional predicate
85267754Smsmith     */
853138287Smarks    if ((ACPI_SUCCESS (Status)) &&
854138287Smarks        (WalkState->ControlState) &&
85567754Smsmith        (WalkState->ControlState->Common.State ==
85691116Smsmith            ACPI_CONTROL_PREDICATE_EXECUTING) &&
85767754Smsmith        (WalkState->ControlState->Control.PredicateOp == Op))
85867754Smsmith    {
85991116Smsmith        Status = AcpiDsGetPredicateValue (WalkState, WalkState->ResultObj);
86084491Smsmith        WalkState->ResultObj = NULL;
86167754Smsmith    }
86267754Smsmith
86367754Smsmith
86467754SmsmithCleanup:
865138287Smarks
86684491Smsmith    if (WalkState->ResultObj)
86767754Smsmith    {
86867754Smsmith        /* Break to debugger to display result */
86967754Smsmith
870298714Sjkim        AcpiDbDisplayResultObject (WalkState->ResultObj,WalkState);
87167754Smsmith
87267754Smsmith        /*
87367754Smsmith         * Delete the result op if and only if:
87467754Smsmith         * Parent will not use the result -- such as any
87567754Smsmith         * non-nested type2 op in a method (parent will be method)
87667754Smsmith         */
87784491Smsmith        AcpiDsDeleteResultIfNotUsed (Op, WalkState->ResultObj, WalkState);
87867754Smsmith    }
87967754Smsmith
880117521Snjl#ifdef _UNDER_DEVELOPMENT
881114237Snjl
882114237Snjl    if (WalkState->ParserState.Aml == WalkState->ParserState.AmlEnd)
883114237Snjl    {
884114237Snjl        AcpiDbMethodEnd (WalkState);
885114237Snjl    }
886114237Snjl#endif
887114237Snjl
888167802Sjkim    /* Invoke exception handler on error */
88967754Smsmith
890117521Snjl    if (ACPI_FAILURE (Status))
891117521Snjl    {
892167802Sjkim        Status = AcpiDsMethodError (Status, WalkState);
893117521Snjl    }
894117521Snjl
895167802Sjkim    /* Always clear the object stack */
896167802Sjkim
897167802Sjkim    WalkState->NumOperands = 0;
89867754Smsmith    return_ACPI_STATUS (Status);
89967754Smsmith}
900