xref: /netbsd-src/sys/external/bsd/acpica/dist/dispatcher/dsutils.c (revision 2c7d7e3ca2e4f0b675c6c58e614f6aede66c678e)
128c506b8Sjruoho /*******************************************************************************
228c506b8Sjruoho  *
328c506b8Sjruoho  * Module Name: dsutils - Dispatcher utilities
428c506b8Sjruoho  *
528c506b8Sjruoho  ******************************************************************************/
628c506b8Sjruoho 
7124f4c82Sjruoho /*
8*2c7d7e3cSchristos  * Copyright (C) 2000 - 2023, Intel Corp.
928c506b8Sjruoho  * All rights reserved.
1028c506b8Sjruoho  *
11124f4c82Sjruoho  * Redistribution and use in source and binary forms, with or without
12124f4c82Sjruoho  * modification, are permitted provided that the following conditions
13124f4c82Sjruoho  * are met:
14124f4c82Sjruoho  * 1. Redistributions of source code must retain the above copyright
15124f4c82Sjruoho  *    notice, this list of conditions, and the following disclaimer,
16124f4c82Sjruoho  *    without modification.
17124f4c82Sjruoho  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18124f4c82Sjruoho  *    substantially similar to the "NO WARRANTY" disclaimer below
19124f4c82Sjruoho  *    ("Disclaimer") and any redistribution must be conditioned upon
20124f4c82Sjruoho  *    including a substantially similar Disclaimer requirement for further
21124f4c82Sjruoho  *    binary redistribution.
22124f4c82Sjruoho  * 3. Neither the names of the above-listed copyright holders nor the names
23124f4c82Sjruoho  *    of any contributors may be used to endorse or promote products derived
24124f4c82Sjruoho  *    from this software without specific prior written permission.
2528c506b8Sjruoho  *
26124f4c82Sjruoho  * Alternatively, this software may be distributed under the terms of the
27124f4c82Sjruoho  * GNU General Public License ("GPL") version 2 as published by the Free
28124f4c82Sjruoho  * Software Foundation.
2928c506b8Sjruoho  *
30124f4c82Sjruoho  * NO WARRANTY
31124f4c82Sjruoho  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32124f4c82Sjruoho  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3398244dcfSchristos  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34124f4c82Sjruoho  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35124f4c82Sjruoho  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36124f4c82Sjruoho  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37124f4c82Sjruoho  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38124f4c82Sjruoho  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39124f4c82Sjruoho  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40124f4c82Sjruoho  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41124f4c82Sjruoho  * POSSIBILITY OF SUCH DAMAGES.
42124f4c82Sjruoho  */
4328c506b8Sjruoho 
4428c506b8Sjruoho #include "acpi.h"
4528c506b8Sjruoho #include "accommon.h"
4628c506b8Sjruoho #include "acparser.h"
4728c506b8Sjruoho #include "amlcode.h"
4828c506b8Sjruoho #include "acdispat.h"
4928c506b8Sjruoho #include "acinterp.h"
5028c506b8Sjruoho #include "acnamesp.h"
5128c506b8Sjruoho #include "acdebug.h"
5228c506b8Sjruoho 
5328c506b8Sjruoho #define _COMPONENT          ACPI_DISPATCHER
5428c506b8Sjruoho         ACPI_MODULE_NAME    ("dsutils")
5528c506b8Sjruoho 
5628c506b8Sjruoho 
5728c506b8Sjruoho /*******************************************************************************
5828c506b8Sjruoho  *
5928c506b8Sjruoho  * FUNCTION:    AcpiDsClearImplicitReturn
6028c506b8Sjruoho  *
6128c506b8Sjruoho  * PARAMETERS:  WalkState           - Current State
6228c506b8Sjruoho  *
6328c506b8Sjruoho  * RETURN:      None.
6428c506b8Sjruoho  *
6528c506b8Sjruoho  * DESCRIPTION: Clear and remove a reference on an implicit return value. Used
6628c506b8Sjruoho  *              to delete "stale" return values (if enabled, the return value
6728c506b8Sjruoho  *              from every operator is saved at least momentarily, in case the
6828c506b8Sjruoho  *              parent method exits.)
6928c506b8Sjruoho  *
7028c506b8Sjruoho  ******************************************************************************/
7128c506b8Sjruoho 
7228c506b8Sjruoho void
AcpiDsClearImplicitReturn(ACPI_WALK_STATE * WalkState)7328c506b8Sjruoho AcpiDsClearImplicitReturn (
7428c506b8Sjruoho     ACPI_WALK_STATE         *WalkState)
7528c506b8Sjruoho {
7628c506b8Sjruoho     ACPI_FUNCTION_NAME (DsClearImplicitReturn);
7728c506b8Sjruoho 
7828c506b8Sjruoho 
7928c506b8Sjruoho     /*
8028c506b8Sjruoho      * Slack must be enabled for this feature
8128c506b8Sjruoho      */
8228c506b8Sjruoho     if (!AcpiGbl_EnableInterpreterSlack)
8328c506b8Sjruoho     {
8428c506b8Sjruoho         return;
8528c506b8Sjruoho     }
8628c506b8Sjruoho 
8728c506b8Sjruoho     if (WalkState->ImplicitReturnObj)
8828c506b8Sjruoho     {
8928c506b8Sjruoho         /*
9028c506b8Sjruoho          * Delete any "stale" implicit return. However, in
9128c506b8Sjruoho          * complex statements, the implicit return value can be
9228c506b8Sjruoho          * bubbled up several levels.
9328c506b8Sjruoho          */
9428c506b8Sjruoho         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
9528c506b8Sjruoho             "Removing reference on stale implicit return obj %p\n",
9628c506b8Sjruoho             WalkState->ImplicitReturnObj));
9728c506b8Sjruoho 
9828c506b8Sjruoho         AcpiUtRemoveReference (WalkState->ImplicitReturnObj);
9928c506b8Sjruoho         WalkState->ImplicitReturnObj = NULL;
10028c506b8Sjruoho     }
10128c506b8Sjruoho }
10228c506b8Sjruoho 
10328c506b8Sjruoho 
10428c506b8Sjruoho /*******************************************************************************
10528c506b8Sjruoho  *
10628c506b8Sjruoho  * FUNCTION:    AcpiDsDoImplicitReturn
10728c506b8Sjruoho  *
10828c506b8Sjruoho  * PARAMETERS:  ReturnDesc          - The return value
10928c506b8Sjruoho  *              WalkState           - Current State
11028c506b8Sjruoho  *              AddReference        - True if a reference should be added to the
11128c506b8Sjruoho  *                                    return object
11228c506b8Sjruoho  *
11328c506b8Sjruoho  * RETURN:      TRUE if implicit return enabled, FALSE otherwise
11428c506b8Sjruoho  *
11528c506b8Sjruoho  * DESCRIPTION: Implements the optional "implicit return".  We save the result
11628c506b8Sjruoho  *              of every ASL operator and control method invocation in case the
11728c506b8Sjruoho  *              parent method exit. Before storing a new return value, we
11828c506b8Sjruoho  *              delete the previous return value.
11928c506b8Sjruoho  *
12028c506b8Sjruoho  ******************************************************************************/
12128c506b8Sjruoho 
12228c506b8Sjruoho BOOLEAN
AcpiDsDoImplicitReturn(ACPI_OPERAND_OBJECT * ReturnDesc,ACPI_WALK_STATE * WalkState,BOOLEAN AddReference)12328c506b8Sjruoho AcpiDsDoImplicitReturn (
12428c506b8Sjruoho     ACPI_OPERAND_OBJECT     *ReturnDesc,
12528c506b8Sjruoho     ACPI_WALK_STATE         *WalkState,
12628c506b8Sjruoho     BOOLEAN                 AddReference)
12728c506b8Sjruoho {
12828c506b8Sjruoho     ACPI_FUNCTION_NAME (DsDoImplicitReturn);
12928c506b8Sjruoho 
13028c506b8Sjruoho 
13128c506b8Sjruoho     /*
13228c506b8Sjruoho      * Slack must be enabled for this feature, and we must
13328c506b8Sjruoho      * have a valid return object
13428c506b8Sjruoho      */
13528c506b8Sjruoho     if ((!AcpiGbl_EnableInterpreterSlack) ||
13628c506b8Sjruoho         (!ReturnDesc))
13728c506b8Sjruoho     {
13828c506b8Sjruoho         return (FALSE);
13928c506b8Sjruoho     }
14028c506b8Sjruoho 
14128c506b8Sjruoho     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
14228c506b8Sjruoho         "Result %p will be implicitly returned; Prev=%p\n",
14328c506b8Sjruoho         ReturnDesc,
14428c506b8Sjruoho         WalkState->ImplicitReturnObj));
14528c506b8Sjruoho 
14628c506b8Sjruoho     /*
14728c506b8Sjruoho      * Delete any "stale" implicit return value first. However, in
14828c506b8Sjruoho      * complex statements, the implicit return value can be
14928c506b8Sjruoho      * bubbled up several levels, so we don't clear the value if it
15028c506b8Sjruoho      * is the same as the ReturnDesc.
15128c506b8Sjruoho      */
15228c506b8Sjruoho     if (WalkState->ImplicitReturnObj)
15328c506b8Sjruoho     {
15428c506b8Sjruoho         if (WalkState->ImplicitReturnObj == ReturnDesc)
15528c506b8Sjruoho         {
15628c506b8Sjruoho             return (TRUE);
15728c506b8Sjruoho         }
15828c506b8Sjruoho         AcpiDsClearImplicitReturn (WalkState);
15928c506b8Sjruoho     }
16028c506b8Sjruoho 
16128c506b8Sjruoho     /* Save the implicit return value, add a reference if requested */
16228c506b8Sjruoho 
16328c506b8Sjruoho     WalkState->ImplicitReturnObj = ReturnDesc;
16428c506b8Sjruoho     if (AddReference)
16528c506b8Sjruoho     {
16628c506b8Sjruoho         AcpiUtAddReference (ReturnDesc);
16728c506b8Sjruoho     }
16828c506b8Sjruoho 
16928c506b8Sjruoho     return (TRUE);
17028c506b8Sjruoho }
17128c506b8Sjruoho 
17228c506b8Sjruoho 
17328c506b8Sjruoho /*******************************************************************************
17428c506b8Sjruoho  *
17528c506b8Sjruoho  * FUNCTION:    AcpiDsIsResultUsed
17628c506b8Sjruoho  *
17728c506b8Sjruoho  * PARAMETERS:  Op                  - Current Op
17828c506b8Sjruoho  *              WalkState           - Current State
17928c506b8Sjruoho  *
18028c506b8Sjruoho  * RETURN:      TRUE if result is used, FALSE otherwise
18128c506b8Sjruoho  *
18228c506b8Sjruoho  * DESCRIPTION: Check if a result object will be used by the parent
18328c506b8Sjruoho  *
18428c506b8Sjruoho  ******************************************************************************/
18528c506b8Sjruoho 
18628c506b8Sjruoho BOOLEAN
AcpiDsIsResultUsed(ACPI_PARSE_OBJECT * Op,ACPI_WALK_STATE * WalkState)18728c506b8Sjruoho AcpiDsIsResultUsed (
18828c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
18928c506b8Sjruoho     ACPI_WALK_STATE         *WalkState)
19028c506b8Sjruoho {
19128c506b8Sjruoho     const ACPI_OPCODE_INFO  *ParentInfo;
19228c506b8Sjruoho 
19328c506b8Sjruoho     ACPI_FUNCTION_TRACE_PTR (DsIsResultUsed, Op);
19428c506b8Sjruoho 
19528c506b8Sjruoho 
19628c506b8Sjruoho     /* Must have both an Op and a Result Object */
19728c506b8Sjruoho 
19828c506b8Sjruoho     if (!Op)
19928c506b8Sjruoho     {
20028c506b8Sjruoho         ACPI_ERROR ((AE_INFO, "Null Op"));
20128c506b8Sjruoho         return_UINT8 (TRUE);
20228c506b8Sjruoho     }
20328c506b8Sjruoho 
20428c506b8Sjruoho     /*
20528c506b8Sjruoho      * We know that this operator is not a
20628c506b8Sjruoho      * Return() operator (would not come here.) The following code is the
20728c506b8Sjruoho      * optional support for a so-called "implicit return". Some AML code
20828c506b8Sjruoho      * assumes that the last value of the method is "implicitly" returned
20928c506b8Sjruoho      * to the caller. Just save the last result as the return value.
21028c506b8Sjruoho      * NOTE: this is optional because the ASL language does not actually
21128c506b8Sjruoho      * support this behavior.
21228c506b8Sjruoho      */
21328c506b8Sjruoho     (void) AcpiDsDoImplicitReturn (WalkState->ResultObj, WalkState, TRUE);
21428c506b8Sjruoho 
21528c506b8Sjruoho     /*
21628c506b8Sjruoho      * Now determine if the parent will use the result
21728c506b8Sjruoho      *
21828c506b8Sjruoho      * If there is no parent, or the parent is a ScopeOp, we are executing
21928c506b8Sjruoho      * at the method level. An executing method typically has no parent,
22028c506b8Sjruoho      * since each method is parsed separately. A method invoked externally
22128c506b8Sjruoho      * via ExecuteControlMethod has a ScopeOp as the parent.
22228c506b8Sjruoho      */
22328c506b8Sjruoho     if ((!Op->Common.Parent) ||
22428c506b8Sjruoho         (Op->Common.Parent->Common.AmlOpcode == AML_SCOPE_OP))
22528c506b8Sjruoho     {
22628c506b8Sjruoho         /* No parent, the return value cannot possibly be used */
22728c506b8Sjruoho 
22828c506b8Sjruoho         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
22928c506b8Sjruoho             "At Method level, result of [%s] not used\n",
23028c506b8Sjruoho             AcpiPsGetOpcodeName (Op->Common.AmlOpcode)));
23128c506b8Sjruoho         return_UINT8 (FALSE);
23228c506b8Sjruoho     }
23328c506b8Sjruoho 
23428c506b8Sjruoho     /* Get info on the parent. The RootOp is AML_SCOPE */
23528c506b8Sjruoho 
23628c506b8Sjruoho     ParentInfo = AcpiPsGetOpcodeInfo (Op->Common.Parent->Common.AmlOpcode);
23728c506b8Sjruoho     if (ParentInfo->Class == AML_CLASS_UNKNOWN)
23828c506b8Sjruoho     {
23928c506b8Sjruoho         ACPI_ERROR ((AE_INFO,
24028c506b8Sjruoho             "Unknown parent opcode Op=%p", Op));
24128c506b8Sjruoho         return_UINT8 (FALSE);
24228c506b8Sjruoho     }
24328c506b8Sjruoho 
24428c506b8Sjruoho     /*
24528c506b8Sjruoho      * Decide what to do with the result based on the parent. If
24628c506b8Sjruoho      * the parent opcode will not use the result, delete the object.
24728c506b8Sjruoho      * Otherwise leave it as is, it will be deleted when it is used
24828c506b8Sjruoho      * as an operand later.
24928c506b8Sjruoho      */
25028c506b8Sjruoho     switch (ParentInfo->Class)
25128c506b8Sjruoho     {
25228c506b8Sjruoho     case AML_CLASS_CONTROL:
25328c506b8Sjruoho 
25428c506b8Sjruoho         switch (Op->Common.Parent->Common.AmlOpcode)
25528c506b8Sjruoho         {
25628c506b8Sjruoho         case AML_RETURN_OP:
25728c506b8Sjruoho 
25828c506b8Sjruoho             /* Never delete the return value associated with a return opcode */
25928c506b8Sjruoho 
26028c506b8Sjruoho             goto ResultUsed;
26128c506b8Sjruoho 
26228c506b8Sjruoho         case AML_IF_OP:
26328c506b8Sjruoho         case AML_WHILE_OP:
26428c506b8Sjruoho             /*
26528c506b8Sjruoho              * If we are executing the predicate AND this is the predicate op,
26628c506b8Sjruoho              * we will use the return value
26728c506b8Sjruoho              */
26881bd9c9cSchristos             if ((WalkState->ControlState->Common.State ==
26981bd9c9cSchristos                     ACPI_CONTROL_PREDICATE_EXECUTING) &&
27028c506b8Sjruoho                 (WalkState->ControlState->Control.PredicateOp == Op))
27128c506b8Sjruoho             {
27228c506b8Sjruoho                 goto ResultUsed;
27328c506b8Sjruoho             }
27428c506b8Sjruoho             break;
27528c506b8Sjruoho 
27628c506b8Sjruoho         default:
277ff4a156dSchristos 
27828c506b8Sjruoho             /* Ignore other control opcodes */
279ff4a156dSchristos 
28028c506b8Sjruoho             break;
28128c506b8Sjruoho         }
28228c506b8Sjruoho 
28328c506b8Sjruoho         /* The general control opcode returns no result */
28428c506b8Sjruoho 
28528c506b8Sjruoho         goto ResultNotUsed;
28628c506b8Sjruoho 
28728c506b8Sjruoho     case AML_CLASS_CREATE:
28828c506b8Sjruoho         /*
28928c506b8Sjruoho          * These opcodes allow TermArg(s) as operands and therefore
29028c506b8Sjruoho          * the operands can be method calls. The result is used.
29128c506b8Sjruoho          */
29228c506b8Sjruoho         goto ResultUsed;
29328c506b8Sjruoho 
29428c506b8Sjruoho     case AML_CLASS_NAMED_OBJECT:
29528c506b8Sjruoho 
29628c506b8Sjruoho         if ((Op->Common.Parent->Common.AmlOpcode == AML_REGION_OP)       ||
29728c506b8Sjruoho             (Op->Common.Parent->Common.AmlOpcode == AML_DATA_REGION_OP)  ||
29828c506b8Sjruoho             (Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP)      ||
29928c506b8Sjruoho             (Op->Common.Parent->Common.AmlOpcode == AML_BUFFER_OP)       ||
3008f1e17bdSchristos             (Op->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP) ||
30128c506b8Sjruoho             (Op->Common.Parent->Common.AmlOpcode == AML_INT_EVAL_SUBTREE_OP) ||
30228c506b8Sjruoho             (Op->Common.Parent->Common.AmlOpcode == AML_BANK_FIELD_OP))
30328c506b8Sjruoho         {
30428c506b8Sjruoho             /*
30528c506b8Sjruoho              * These opcodes allow TermArg(s) as operands and therefore
30628c506b8Sjruoho              * the operands can be method calls. The result is used.
30728c506b8Sjruoho              */
30828c506b8Sjruoho             goto ResultUsed;
30928c506b8Sjruoho         }
31028c506b8Sjruoho 
31128c506b8Sjruoho         goto ResultNotUsed;
31228c506b8Sjruoho 
31328c506b8Sjruoho     default:
31428c506b8Sjruoho         /*
31528c506b8Sjruoho          * In all other cases. the parent will actually use the return
31628c506b8Sjruoho          * object, so keep it.
31728c506b8Sjruoho          */
31828c506b8Sjruoho         goto ResultUsed;
31928c506b8Sjruoho     }
32028c506b8Sjruoho 
32128c506b8Sjruoho 
32228c506b8Sjruoho ResultUsed:
32328c506b8Sjruoho     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
32428c506b8Sjruoho         "Result of [%s] used by Parent [%s] Op=%p\n",
32528c506b8Sjruoho         AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
32628c506b8Sjruoho         AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op));
32728c506b8Sjruoho 
32828c506b8Sjruoho     return_UINT8 (TRUE);
32928c506b8Sjruoho 
33028c506b8Sjruoho 
33128c506b8Sjruoho ResultNotUsed:
33228c506b8Sjruoho     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
33328c506b8Sjruoho         "Result of [%s] not used by Parent [%s] Op=%p\n",
33428c506b8Sjruoho         AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
33528c506b8Sjruoho         AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op));
33628c506b8Sjruoho 
33728c506b8Sjruoho     return_UINT8 (FALSE);
33828c506b8Sjruoho }
33928c506b8Sjruoho 
34028c506b8Sjruoho 
34128c506b8Sjruoho /*******************************************************************************
34228c506b8Sjruoho  *
34328c506b8Sjruoho  * FUNCTION:    AcpiDsDeleteResultIfNotUsed
34428c506b8Sjruoho  *
34528c506b8Sjruoho  * PARAMETERS:  Op              - Current parse Op
34628c506b8Sjruoho  *              ResultObj       - Result of the operation
34728c506b8Sjruoho  *              WalkState       - Current state
34828c506b8Sjruoho  *
34928c506b8Sjruoho  * RETURN:      Status
35028c506b8Sjruoho  *
35128c506b8Sjruoho  * DESCRIPTION: Used after interpretation of an opcode. If there is an internal
35228c506b8Sjruoho  *              result descriptor, check if the parent opcode will actually use
35328c506b8Sjruoho  *              this result. If not, delete the result now so that it will
35428c506b8Sjruoho  *              not become orphaned.
35528c506b8Sjruoho  *
35628c506b8Sjruoho  ******************************************************************************/
35728c506b8Sjruoho 
35828c506b8Sjruoho void
AcpiDsDeleteResultIfNotUsed(ACPI_PARSE_OBJECT * Op,ACPI_OPERAND_OBJECT * ResultObj,ACPI_WALK_STATE * WalkState)35928c506b8Sjruoho AcpiDsDeleteResultIfNotUsed (
36028c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
36128c506b8Sjruoho     ACPI_OPERAND_OBJECT     *ResultObj,
36228c506b8Sjruoho     ACPI_WALK_STATE         *WalkState)
36328c506b8Sjruoho {
36428c506b8Sjruoho     ACPI_OPERAND_OBJECT     *ObjDesc;
36528c506b8Sjruoho     ACPI_STATUS             Status;
36628c506b8Sjruoho 
36728c506b8Sjruoho 
36828c506b8Sjruoho     ACPI_FUNCTION_TRACE_PTR (DsDeleteResultIfNotUsed, ResultObj);
36928c506b8Sjruoho 
37028c506b8Sjruoho 
37128c506b8Sjruoho     if (!Op)
37228c506b8Sjruoho     {
37328c506b8Sjruoho         ACPI_ERROR ((AE_INFO, "Null Op"));
37428c506b8Sjruoho         return_VOID;
37528c506b8Sjruoho     }
37628c506b8Sjruoho 
37728c506b8Sjruoho     if (!ResultObj)
37828c506b8Sjruoho     {
37928c506b8Sjruoho         return_VOID;
38028c506b8Sjruoho     }
38128c506b8Sjruoho 
38228c506b8Sjruoho     if (!AcpiDsIsResultUsed (Op, WalkState))
38328c506b8Sjruoho     {
38428c506b8Sjruoho         /* Must pop the result stack (ObjDesc should be equal to ResultObj) */
38528c506b8Sjruoho 
38628c506b8Sjruoho         Status = AcpiDsResultPop (&ObjDesc, WalkState);
38728c506b8Sjruoho         if (ACPI_SUCCESS (Status))
38828c506b8Sjruoho         {
38928c506b8Sjruoho             AcpiUtRemoveReference (ResultObj);
39028c506b8Sjruoho         }
39128c506b8Sjruoho     }
39228c506b8Sjruoho 
39328c506b8Sjruoho     return_VOID;
39428c506b8Sjruoho }
39528c506b8Sjruoho 
39628c506b8Sjruoho 
39728c506b8Sjruoho /*******************************************************************************
39828c506b8Sjruoho  *
39928c506b8Sjruoho  * FUNCTION:    AcpiDsResolveOperands
40028c506b8Sjruoho  *
40128c506b8Sjruoho  * PARAMETERS:  WalkState           - Current walk state with operands on stack
40228c506b8Sjruoho  *
40328c506b8Sjruoho  * RETURN:      Status
40428c506b8Sjruoho  *
40528c506b8Sjruoho  * DESCRIPTION: Resolve all operands to their values. Used to prepare
40628c506b8Sjruoho  *              arguments to a control method invocation (a call from one
40728c506b8Sjruoho  *              method to another.)
40828c506b8Sjruoho  *
40928c506b8Sjruoho  ******************************************************************************/
41028c506b8Sjruoho 
41128c506b8Sjruoho ACPI_STATUS
AcpiDsResolveOperands(ACPI_WALK_STATE * WalkState)41228c506b8Sjruoho AcpiDsResolveOperands (
41328c506b8Sjruoho     ACPI_WALK_STATE         *WalkState)
41428c506b8Sjruoho {
41528c506b8Sjruoho     UINT32                  i;
41628c506b8Sjruoho     ACPI_STATUS             Status = AE_OK;
41728c506b8Sjruoho 
41828c506b8Sjruoho 
41928c506b8Sjruoho     ACPI_FUNCTION_TRACE_PTR (DsResolveOperands, WalkState);
42028c506b8Sjruoho 
42128c506b8Sjruoho 
42228c506b8Sjruoho     /*
42328c506b8Sjruoho      * Attempt to resolve each of the valid operands
42428c506b8Sjruoho      * Method arguments are passed by reference, not by value. This means
42528c506b8Sjruoho      * that the actual objects are passed, not copies of the objects.
42628c506b8Sjruoho      */
42728c506b8Sjruoho     for (i = 0; i < WalkState->NumOperands; i++)
42828c506b8Sjruoho     {
42928c506b8Sjruoho         Status = AcpiExResolveToValue (&WalkState->Operands[i], WalkState);
43028c506b8Sjruoho         if (ACPI_FAILURE (Status))
43128c506b8Sjruoho         {
43228c506b8Sjruoho             break;
43328c506b8Sjruoho         }
43428c506b8Sjruoho     }
43528c506b8Sjruoho 
43628c506b8Sjruoho     return_ACPI_STATUS (Status);
43728c506b8Sjruoho }
43828c506b8Sjruoho 
43928c506b8Sjruoho 
44028c506b8Sjruoho /*******************************************************************************
44128c506b8Sjruoho  *
44228c506b8Sjruoho  * FUNCTION:    AcpiDsClearOperands
44328c506b8Sjruoho  *
44428c506b8Sjruoho  * PARAMETERS:  WalkState           - Current walk state with operands on stack
44528c506b8Sjruoho  *
44628c506b8Sjruoho  * RETURN:      None
44728c506b8Sjruoho  *
44828c506b8Sjruoho  * DESCRIPTION: Clear all operands on the current walk state operand stack.
44928c506b8Sjruoho  *
45028c506b8Sjruoho  ******************************************************************************/
45128c506b8Sjruoho 
45228c506b8Sjruoho void
AcpiDsClearOperands(ACPI_WALK_STATE * WalkState)45328c506b8Sjruoho AcpiDsClearOperands (
45428c506b8Sjruoho     ACPI_WALK_STATE         *WalkState)
45528c506b8Sjruoho {
45628c506b8Sjruoho     UINT32                  i;
45728c506b8Sjruoho 
45828c506b8Sjruoho 
45928c506b8Sjruoho     ACPI_FUNCTION_TRACE_PTR (DsClearOperands, WalkState);
46028c506b8Sjruoho 
46128c506b8Sjruoho 
46228c506b8Sjruoho     /* Remove a reference on each operand on the stack */
46328c506b8Sjruoho 
46428c506b8Sjruoho     for (i = 0; i < WalkState->NumOperands; i++)
46528c506b8Sjruoho     {
46628c506b8Sjruoho         /*
46728c506b8Sjruoho          * Remove a reference to all operands, including both
46828c506b8Sjruoho          * "Arguments" and "Targets".
46928c506b8Sjruoho          */
47028c506b8Sjruoho         AcpiUtRemoveReference (WalkState->Operands[i]);
47128c506b8Sjruoho         WalkState->Operands[i] = NULL;
47228c506b8Sjruoho     }
47328c506b8Sjruoho 
47428c506b8Sjruoho     WalkState->NumOperands = 0;
47528c506b8Sjruoho     return_VOID;
47628c506b8Sjruoho }
47728c506b8Sjruoho 
47828c506b8Sjruoho 
47928c506b8Sjruoho /*******************************************************************************
48028c506b8Sjruoho  *
48128c506b8Sjruoho  * FUNCTION:    AcpiDsCreateOperand
48228c506b8Sjruoho  *
48328c506b8Sjruoho  * PARAMETERS:  WalkState       - Current walk state
48428c506b8Sjruoho  *              Arg             - Parse object for the argument
48528c506b8Sjruoho  *              ArgIndex        - Which argument (zero based)
48628c506b8Sjruoho  *
48728c506b8Sjruoho  * RETURN:      Status
48828c506b8Sjruoho  *
48928c506b8Sjruoho  * DESCRIPTION: Translate a parse tree object that is an argument to an AML
49028c506b8Sjruoho  *              opcode to the equivalent interpreter object. This may include
49128c506b8Sjruoho  *              looking up a name or entering a new name into the internal
49228c506b8Sjruoho  *              namespace.
49328c506b8Sjruoho  *
49428c506b8Sjruoho  ******************************************************************************/
49528c506b8Sjruoho 
49628c506b8Sjruoho ACPI_STATUS
AcpiDsCreateOperand(ACPI_WALK_STATE * WalkState,ACPI_PARSE_OBJECT * Arg,UINT32 ArgIndex)49728c506b8Sjruoho AcpiDsCreateOperand (
49828c506b8Sjruoho     ACPI_WALK_STATE         *WalkState,
49928c506b8Sjruoho     ACPI_PARSE_OBJECT       *Arg,
50028c506b8Sjruoho     UINT32                  ArgIndex)
50128c506b8Sjruoho {
50228c506b8Sjruoho     ACPI_STATUS             Status = AE_OK;
50328c506b8Sjruoho     char                    *NameString;
50428c506b8Sjruoho     UINT32                  NameLength;
50528c506b8Sjruoho     ACPI_OPERAND_OBJECT     *ObjDesc;
50628c506b8Sjruoho     ACPI_PARSE_OBJECT       *ParentOp;
50728c506b8Sjruoho     UINT16                  Opcode;
50828c506b8Sjruoho     ACPI_INTERPRETER_MODE   InterpreterMode;
50928c506b8Sjruoho     const ACPI_OPCODE_INFO  *OpInfo;
51028c506b8Sjruoho 
51128c506b8Sjruoho 
51228c506b8Sjruoho     ACPI_FUNCTION_TRACE_PTR (DsCreateOperand, Arg);
51328c506b8Sjruoho 
51428c506b8Sjruoho 
51528c506b8Sjruoho     /* A valid name must be looked up in the namespace */
51628c506b8Sjruoho 
51728c506b8Sjruoho     if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
51828c506b8Sjruoho         (Arg->Common.Value.String) &&
51928c506b8Sjruoho         !(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))
52028c506b8Sjruoho     {
52128c506b8Sjruoho         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", Arg));
52228c506b8Sjruoho 
52328c506b8Sjruoho         /* Get the entire name string from the AML stream */
52428c506b8Sjruoho 
52581bd9c9cSchristos         Status = AcpiExGetNameString (ACPI_TYPE_ANY,
52681bd9c9cSchristos             Arg->Common.Value.Buffer, &NameString, &NameLength);
52728c506b8Sjruoho 
52828c506b8Sjruoho         if (ACPI_FAILURE (Status))
52928c506b8Sjruoho         {
53028c506b8Sjruoho             return_ACPI_STATUS (Status);
53128c506b8Sjruoho         }
53228c506b8Sjruoho 
53328c506b8Sjruoho         /* All prefixes have been handled, and the name is in NameString */
53428c506b8Sjruoho 
53528c506b8Sjruoho         /*
53628c506b8Sjruoho          * Special handling for BufferField declarations. This is a deferred
53728c506b8Sjruoho          * opcode that unfortunately defines the field name as the last
53828c506b8Sjruoho          * parameter instead of the first. We get here when we are performing
53928c506b8Sjruoho          * the deferred execution, so the actual name of the field is already
54028c506b8Sjruoho          * in the namespace. We don't want to attempt to look it up again
54128c506b8Sjruoho          * because we may be executing in a different scope than where the
54228c506b8Sjruoho          * actual opcode exists.
54328c506b8Sjruoho          */
54428c506b8Sjruoho         if ((WalkState->DeferredNode) &&
54528c506b8Sjruoho             (WalkState->DeferredNode->Type == ACPI_TYPE_BUFFER_FIELD) &&
54681bd9c9cSchristos             (ArgIndex == (UINT32)
54781bd9c9cSchristos                 ((WalkState->Opcode == AML_CREATE_FIELD_OP) ? 3 : 2)))
54828c506b8Sjruoho         {
54928c506b8Sjruoho             ObjDesc = ACPI_CAST_PTR (
55028c506b8Sjruoho                 ACPI_OPERAND_OBJECT, WalkState->DeferredNode);
55128c506b8Sjruoho             Status = AE_OK;
55228c506b8Sjruoho         }
55328c506b8Sjruoho         else    /* All other opcodes */
55428c506b8Sjruoho         {
55528c506b8Sjruoho             /*
55628c506b8Sjruoho              * Differentiate between a namespace "create" operation
55728c506b8Sjruoho              * versus a "lookup" operation (IMODE_LOAD_PASS2 vs.
55828c506b8Sjruoho              * IMODE_EXECUTE) in order to support the creation of
55928c506b8Sjruoho              * namespace objects during the execution of control methods.
56028c506b8Sjruoho              */
56128c506b8Sjruoho             ParentOp = Arg->Common.Parent;
56228c506b8Sjruoho             OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode);
56381bd9c9cSchristos 
56428c506b8Sjruoho             if ((OpInfo->Flags & AML_NSNODE) &&
56528c506b8Sjruoho                 (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) &&
56628c506b8Sjruoho                 (ParentOp->Common.AmlOpcode != AML_REGION_OP) &&
56728c506b8Sjruoho                 (ParentOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP))
56828c506b8Sjruoho             {
56928c506b8Sjruoho                 /* Enter name into namespace if not found */
57028c506b8Sjruoho 
57128c506b8Sjruoho                 InterpreterMode = ACPI_IMODE_LOAD_PASS2;
57228c506b8Sjruoho             }
57328c506b8Sjruoho             else
57428c506b8Sjruoho             {
57528c506b8Sjruoho                 /* Return a failure if name not found */
57628c506b8Sjruoho 
57728c506b8Sjruoho                 InterpreterMode = ACPI_IMODE_EXECUTE;
57828c506b8Sjruoho             }
57928c506b8Sjruoho 
58028c506b8Sjruoho             Status = AcpiNsLookup (WalkState->ScopeInfo, NameString,
58128c506b8Sjruoho                 ACPI_TYPE_ANY, InterpreterMode,
58281bd9c9cSchristos                 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, WalkState,
58328c506b8Sjruoho                 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc));
58428c506b8Sjruoho             /*
58528c506b8Sjruoho              * The only case where we pass through (ignore) a NOT_FOUND
58628c506b8Sjruoho              * error is for the CondRefOf opcode.
58728c506b8Sjruoho              */
58828c506b8Sjruoho             if (Status == AE_NOT_FOUND)
58928c506b8Sjruoho             {
5908f1e17bdSchristos                 if (ParentOp->Common.AmlOpcode == AML_CONDITIONAL_REF_OF_OP)
59128c506b8Sjruoho                 {
59228c506b8Sjruoho                     /*
59328c506b8Sjruoho                      * For the Conditional Reference op, it's OK if
59428c506b8Sjruoho                      * the name is not found;  We just need a way to
59528c506b8Sjruoho                      * indicate this to the interpreter, set the
59628c506b8Sjruoho                      * object to the root
59728c506b8Sjruoho                      */
59828c506b8Sjruoho                     ObjDesc = ACPI_CAST_PTR (
59928c506b8Sjruoho                         ACPI_OPERAND_OBJECT, AcpiGbl_RootNode);
60028c506b8Sjruoho                     Status = AE_OK;
60128c506b8Sjruoho                 }
602679c17fdSchristos                 else if (ParentOp->Common.AmlOpcode == AML_EXTERNAL_OP)
603679c17fdSchristos                 {
60472abab0cSchristos                     /*
60572abab0cSchristos                      * This opcode should never appear here. It is used only
60672abab0cSchristos                      * by AML disassemblers and is surrounded by an If(0)
60772abab0cSchristos                      * by the ASL compiler.
60872abab0cSchristos                      *
60972abab0cSchristos                      * Therefore, if we see it here, it is a serious error.
61072abab0cSchristos                      */
61172abab0cSchristos                     Status = AE_AML_BAD_OPCODE;
612dd6caf1eSchristos                 }
61328c506b8Sjruoho                 else
61428c506b8Sjruoho                 {
61528c506b8Sjruoho                     /*
61628c506b8Sjruoho                      * We just plain didn't find it -- which is a
61728c506b8Sjruoho                      * very serious error at this point
61828c506b8Sjruoho                      */
61928c506b8Sjruoho                     Status = AE_AML_NAME_NOT_FOUND;
62028c506b8Sjruoho                 }
62128c506b8Sjruoho             }
62228c506b8Sjruoho 
62328c506b8Sjruoho             if (ACPI_FAILURE (Status))
62428c506b8Sjruoho             {
62525666a51Schristos                 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
62625666a51Schristos                     NameString, Status);
62728c506b8Sjruoho             }
62828c506b8Sjruoho         }
62928c506b8Sjruoho 
63028c506b8Sjruoho         /* Free the namestring created above */
63128c506b8Sjruoho 
63228c506b8Sjruoho         ACPI_FREE (NameString);
63328c506b8Sjruoho 
63428c506b8Sjruoho         /* Check status from the lookup */
63528c506b8Sjruoho 
63628c506b8Sjruoho         if (ACPI_FAILURE (Status))
63728c506b8Sjruoho         {
63828c506b8Sjruoho             return_ACPI_STATUS (Status);
63928c506b8Sjruoho         }
64028c506b8Sjruoho 
64128c506b8Sjruoho         /* Put the resulting object onto the current object stack */
64228c506b8Sjruoho 
64328c506b8Sjruoho         Status = AcpiDsObjStackPush (ObjDesc, WalkState);
64428c506b8Sjruoho         if (ACPI_FAILURE (Status))
64528c506b8Sjruoho         {
64628c506b8Sjruoho             return_ACPI_STATUS (Status);
64728c506b8Sjruoho         }
64881bd9c9cSchristos 
64981bd9c9cSchristos         AcpiDbDisplayArgumentObject (ObjDesc, WalkState);
65028c506b8Sjruoho     }
65128c506b8Sjruoho     else
65228c506b8Sjruoho     {
65328c506b8Sjruoho         /* Check for null name case */
65428c506b8Sjruoho 
65528c506b8Sjruoho         if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
65628c506b8Sjruoho             !(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))
65728c506b8Sjruoho         {
65828c506b8Sjruoho             /*
65928c506b8Sjruoho              * If the name is null, this means that this is an
66028c506b8Sjruoho              * optional result parameter that was not specified
66128c506b8Sjruoho              * in the original ASL. Create a Zero Constant for a
66228c506b8Sjruoho              * placeholder. (Store to a constant is a Noop.)
66328c506b8Sjruoho              */
66428c506b8Sjruoho             Opcode = AML_ZERO_OP;       /* Has no arguments! */
66528c506b8Sjruoho 
66628c506b8Sjruoho             ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
66728c506b8Sjruoho                 "Null namepath: Arg=%p\n", Arg));
66828c506b8Sjruoho         }
66928c506b8Sjruoho         else
67028c506b8Sjruoho         {
67128c506b8Sjruoho             Opcode = Arg->Common.AmlOpcode;
67228c506b8Sjruoho         }
67328c506b8Sjruoho 
67428c506b8Sjruoho         /* Get the object type of the argument */
67528c506b8Sjruoho 
67628c506b8Sjruoho         OpInfo = AcpiPsGetOpcodeInfo (Opcode);
67728c506b8Sjruoho         if (OpInfo->ObjectType == ACPI_TYPE_INVALID)
67828c506b8Sjruoho         {
67928c506b8Sjruoho             return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
68028c506b8Sjruoho         }
68128c506b8Sjruoho 
68281bd9c9cSchristos         if ((OpInfo->Flags & AML_HAS_RETVAL) ||
68381bd9c9cSchristos             (Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))
68428c506b8Sjruoho         {
68528c506b8Sjruoho             /*
68628c506b8Sjruoho              * Use value that was already previously returned
68728c506b8Sjruoho              * by the evaluation of this argument
68828c506b8Sjruoho              */
68928c506b8Sjruoho             Status = AcpiDsResultPop (&ObjDesc, WalkState);
69028c506b8Sjruoho             if (ACPI_FAILURE (Status))
69128c506b8Sjruoho             {
69228c506b8Sjruoho                 /*
69328c506b8Sjruoho                  * Only error is underflow, and this indicates
69428c506b8Sjruoho                  * a missing or null operand!
69528c506b8Sjruoho                  */
69628c506b8Sjruoho                 ACPI_EXCEPTION ((AE_INFO, Status,
69728c506b8Sjruoho                     "Missing or null operand"));
69828c506b8Sjruoho                 return_ACPI_STATUS (Status);
69928c506b8Sjruoho             }
70028c506b8Sjruoho         }
70128c506b8Sjruoho         else
70228c506b8Sjruoho         {
70328c506b8Sjruoho             /* Create an ACPI_INTERNAL_OBJECT for the argument */
70428c506b8Sjruoho 
70528c506b8Sjruoho             ObjDesc = AcpiUtCreateInternalObject (OpInfo->ObjectType);
70628c506b8Sjruoho             if (!ObjDesc)
70728c506b8Sjruoho             {
70828c506b8Sjruoho                 return_ACPI_STATUS (AE_NO_MEMORY);
70928c506b8Sjruoho             }
71028c506b8Sjruoho 
71128c506b8Sjruoho             /* Initialize the new object */
71228c506b8Sjruoho 
71328c506b8Sjruoho             Status = AcpiDsInitObjectFromOp (
71428c506b8Sjruoho                 WalkState, Arg, Opcode, &ObjDesc);
71528c506b8Sjruoho             if (ACPI_FAILURE (Status))
71628c506b8Sjruoho             {
71728c506b8Sjruoho                 AcpiUtDeleteObjectDesc (ObjDesc);
71828c506b8Sjruoho                 return_ACPI_STATUS (Status);
71928c506b8Sjruoho             }
72028c506b8Sjruoho         }
72128c506b8Sjruoho 
72228c506b8Sjruoho         /* Put the operand object on the object stack */
72328c506b8Sjruoho 
72428c506b8Sjruoho         Status = AcpiDsObjStackPush (ObjDesc, WalkState);
72528c506b8Sjruoho         if (ACPI_FAILURE (Status))
72628c506b8Sjruoho         {
72728c506b8Sjruoho             return_ACPI_STATUS (Status);
72828c506b8Sjruoho         }
72928c506b8Sjruoho 
73081bd9c9cSchristos         AcpiDbDisplayArgumentObject (ObjDesc, WalkState);
73128c506b8Sjruoho     }
73228c506b8Sjruoho 
73328c506b8Sjruoho     return_ACPI_STATUS (AE_OK);
73428c506b8Sjruoho }
73528c506b8Sjruoho 
73628c506b8Sjruoho 
73728c506b8Sjruoho /*******************************************************************************
73828c506b8Sjruoho  *
73928c506b8Sjruoho  * FUNCTION:    AcpiDsCreateOperands
74028c506b8Sjruoho  *
74128c506b8Sjruoho  * PARAMETERS:  WalkState           - Current state
74228c506b8Sjruoho  *              FirstArg            - First argument of a parser argument tree
74328c506b8Sjruoho  *
74428c506b8Sjruoho  * RETURN:      Status
74528c506b8Sjruoho  *
74628c506b8Sjruoho  * DESCRIPTION: Convert an operator's arguments from a parse tree format to
74728c506b8Sjruoho  *              namespace objects and place those argument object on the object
74828c506b8Sjruoho  *              stack in preparation for evaluation by the interpreter.
74928c506b8Sjruoho  *
75028c506b8Sjruoho  ******************************************************************************/
75128c506b8Sjruoho 
75228c506b8Sjruoho ACPI_STATUS
AcpiDsCreateOperands(ACPI_WALK_STATE * WalkState,ACPI_PARSE_OBJECT * FirstArg)75328c506b8Sjruoho AcpiDsCreateOperands (
75428c506b8Sjruoho     ACPI_WALK_STATE         *WalkState,
75528c506b8Sjruoho     ACPI_PARSE_OBJECT       *FirstArg)
75628c506b8Sjruoho {
75728c506b8Sjruoho     ACPI_STATUS             Status = AE_OK;
75828c506b8Sjruoho     ACPI_PARSE_OBJECT       *Arg;
75928c506b8Sjruoho     ACPI_PARSE_OBJECT       *Arguments[ACPI_OBJ_NUM_OPERANDS];
76028c506b8Sjruoho     UINT32                  ArgCount = 0;
76128c506b8Sjruoho     UINT32                  Index = WalkState->NumOperands;
76228c506b8Sjruoho     UINT32                  i;
76328c506b8Sjruoho 
76428c506b8Sjruoho 
76528c506b8Sjruoho     ACPI_FUNCTION_TRACE_PTR (DsCreateOperands, FirstArg);
76628c506b8Sjruoho 
76728c506b8Sjruoho 
76828c506b8Sjruoho     /* Get all arguments in the list */
76928c506b8Sjruoho 
77028c506b8Sjruoho     Arg = FirstArg;
77128c506b8Sjruoho     while (Arg)
77228c506b8Sjruoho     {
77328c506b8Sjruoho         if (Index >= ACPI_OBJ_NUM_OPERANDS)
77428c506b8Sjruoho         {
77528c506b8Sjruoho             return_ACPI_STATUS (AE_BAD_DATA);
77628c506b8Sjruoho         }
77728c506b8Sjruoho 
77828c506b8Sjruoho         Arguments[Index] = Arg;
77928c506b8Sjruoho         WalkState->Operands [Index] = NULL;
78028c506b8Sjruoho 
78128c506b8Sjruoho         /* Move on to next argument, if any */
78228c506b8Sjruoho 
78328c506b8Sjruoho         Arg = Arg->Common.Next;
78428c506b8Sjruoho         ArgCount++;
78528c506b8Sjruoho         Index++;
78628c506b8Sjruoho     }
78728c506b8Sjruoho 
788ff4a156dSchristos     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
789ff4a156dSchristos         "NumOperands %d, ArgCount %d, Index %d\n",
790ff4a156dSchristos         WalkState->NumOperands, ArgCount, Index));
791ff4a156dSchristos 
792ff4a156dSchristos     /* Create the interpreter arguments, in reverse order */
793ff4a156dSchristos 
79428c506b8Sjruoho     Index--;
79528c506b8Sjruoho     for (i = 0; i < ArgCount; i++)
79628c506b8Sjruoho     {
79728c506b8Sjruoho         Arg = Arguments[Index];
79828c506b8Sjruoho         WalkState->OperandIndex = (UINT8) Index;
79928c506b8Sjruoho 
80028c506b8Sjruoho         Status = AcpiDsCreateOperand (WalkState, Arg, Index);
80128c506b8Sjruoho         if (ACPI_FAILURE (Status))
80228c506b8Sjruoho         {
80328c506b8Sjruoho             goto Cleanup;
80428c506b8Sjruoho         }
80528c506b8Sjruoho 
806ff4a156dSchristos         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
807ff4a156dSchristos             "Created Arg #%u (%p) %u args total\n",
808ff4a156dSchristos             Index, Arg, ArgCount));
80928c506b8Sjruoho         Index--;
81028c506b8Sjruoho     }
81128c506b8Sjruoho 
81228c506b8Sjruoho     return_ACPI_STATUS (Status);
81328c506b8Sjruoho 
81428c506b8Sjruoho 
81528c506b8Sjruoho Cleanup:
81628c506b8Sjruoho     /*
81728c506b8Sjruoho      * We must undo everything done above; meaning that we must
81828c506b8Sjruoho      * pop everything off of the operand stack and delete those
81928c506b8Sjruoho      * objects
82028c506b8Sjruoho      */
82128c506b8Sjruoho     AcpiDsObjStackPopAndDelete (ArgCount, WalkState);
82228c506b8Sjruoho 
82328c506b8Sjruoho     ACPI_EXCEPTION ((AE_INFO, Status, "While creating Arg %u", Index));
82428c506b8Sjruoho     return_ACPI_STATUS (Status);
82528c506b8Sjruoho }
82628c506b8Sjruoho 
82728c506b8Sjruoho 
82828c506b8Sjruoho /*****************************************************************************
82928c506b8Sjruoho  *
83028c506b8Sjruoho  * FUNCTION:    AcpiDsEvaluateNamePath
83128c506b8Sjruoho  *
83228c506b8Sjruoho  * PARAMETERS:  WalkState       - Current state of the parse tree walk,
83328c506b8Sjruoho  *                                the opcode of current operation should be
83428c506b8Sjruoho  *                                AML_INT_NAMEPATH_OP
83528c506b8Sjruoho  *
83628c506b8Sjruoho  * RETURN:      Status
83728c506b8Sjruoho  *
83828c506b8Sjruoho  * DESCRIPTION: Translate the -NamePath- parse tree object to the equivalent
83928c506b8Sjruoho  *              interpreter object, convert it to value, if needed, duplicate
84028c506b8Sjruoho  *              it, if needed, and push it onto the current result stack.
84128c506b8Sjruoho  *
84228c506b8Sjruoho  ****************************************************************************/
84328c506b8Sjruoho 
84428c506b8Sjruoho ACPI_STATUS
AcpiDsEvaluateNamePath(ACPI_WALK_STATE * WalkState)84528c506b8Sjruoho AcpiDsEvaluateNamePath (
84628c506b8Sjruoho     ACPI_WALK_STATE         *WalkState)
84728c506b8Sjruoho {
84828c506b8Sjruoho     ACPI_STATUS             Status = AE_OK;
84928c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op = WalkState->Op;
85028c506b8Sjruoho     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
85128c506b8Sjruoho     ACPI_OPERAND_OBJECT     *NewObjDesc;
85228c506b8Sjruoho     UINT8                   Type;
85328c506b8Sjruoho 
85428c506b8Sjruoho 
85528c506b8Sjruoho     ACPI_FUNCTION_TRACE_PTR (DsEvaluateNamePath, WalkState);
85628c506b8Sjruoho 
85728c506b8Sjruoho 
85828c506b8Sjruoho     if (!Op->Common.Parent)
85928c506b8Sjruoho     {
86028c506b8Sjruoho         /* This happens after certain exception processing */
86128c506b8Sjruoho 
86228c506b8Sjruoho         goto Exit;
86328c506b8Sjruoho     }
86428c506b8Sjruoho 
86528c506b8Sjruoho     if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
8668f1e17bdSchristos         (Op->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP) ||
86728c506b8Sjruoho         (Op->Common.Parent->Common.AmlOpcode == AML_REF_OF_OP))
86828c506b8Sjruoho     {
86928c506b8Sjruoho         /* TBD: Should we specify this feature as a bit of OpInfo->Flags of these opcodes? */
87028c506b8Sjruoho 
87128c506b8Sjruoho         goto Exit;
87228c506b8Sjruoho     }
87328c506b8Sjruoho 
87428c506b8Sjruoho     Status = AcpiDsCreateOperand (WalkState, Op, 0);
87528c506b8Sjruoho     if (ACPI_FAILURE (Status))
87628c506b8Sjruoho     {
87728c506b8Sjruoho         goto Exit;
87828c506b8Sjruoho     }
87928c506b8Sjruoho 
88028c506b8Sjruoho     if (Op->Common.Flags & ACPI_PARSEOP_TARGET)
88128c506b8Sjruoho     {
88228c506b8Sjruoho         NewObjDesc = *Operand;
88328c506b8Sjruoho         goto PushResult;
88428c506b8Sjruoho     }
88528c506b8Sjruoho 
88628c506b8Sjruoho     Type = (*Operand)->Common.Type;
88728c506b8Sjruoho 
88828c506b8Sjruoho     Status = AcpiExResolveToValue (Operand, WalkState);
88928c506b8Sjruoho     if (ACPI_FAILURE (Status))
89028c506b8Sjruoho     {
89128c506b8Sjruoho         goto Exit;
89228c506b8Sjruoho     }
89328c506b8Sjruoho 
89428c506b8Sjruoho     if (Type == ACPI_TYPE_INTEGER)
89528c506b8Sjruoho     {
89628c506b8Sjruoho         /* It was incremented by AcpiExResolveToValue */
89728c506b8Sjruoho 
89828c506b8Sjruoho         AcpiUtRemoveReference (*Operand);
89928c506b8Sjruoho 
90081bd9c9cSchristos         Status = AcpiUtCopyIobjectToIobject (
90181bd9c9cSchristos             *Operand, &NewObjDesc, WalkState);
90228c506b8Sjruoho         if (ACPI_FAILURE (Status))
90328c506b8Sjruoho         {
90428c506b8Sjruoho             goto Exit;
90528c506b8Sjruoho         }
90628c506b8Sjruoho     }
90728c506b8Sjruoho     else
90828c506b8Sjruoho     {
90928c506b8Sjruoho         /*
91028c506b8Sjruoho          * The object either was anew created or is
91128c506b8Sjruoho          * a Namespace node - don't decrement it.
91228c506b8Sjruoho          */
91328c506b8Sjruoho         NewObjDesc = *Operand;
91428c506b8Sjruoho     }
91528c506b8Sjruoho 
91628c506b8Sjruoho     /* Cleanup for name-path operand */
91728c506b8Sjruoho 
91828c506b8Sjruoho     Status = AcpiDsObjStackPop (1, WalkState);
91928c506b8Sjruoho     if (ACPI_FAILURE (Status))
92028c506b8Sjruoho     {
92128c506b8Sjruoho         WalkState->ResultObj = NewObjDesc;
92228c506b8Sjruoho         goto Exit;
92328c506b8Sjruoho     }
92428c506b8Sjruoho 
92528c506b8Sjruoho PushResult:
92628c506b8Sjruoho 
92728c506b8Sjruoho     WalkState->ResultObj = NewObjDesc;
92828c506b8Sjruoho 
92928c506b8Sjruoho     Status = AcpiDsResultPush (WalkState->ResultObj, WalkState);
93028c506b8Sjruoho     if (ACPI_SUCCESS (Status))
93128c506b8Sjruoho     {
93228c506b8Sjruoho         /* Force to take it from stack */
93328c506b8Sjruoho 
93428c506b8Sjruoho         Op->Common.Flags |= ACPI_PARSEOP_IN_STACK;
93528c506b8Sjruoho     }
93628c506b8Sjruoho 
93728c506b8Sjruoho Exit:
93828c506b8Sjruoho 
93928c506b8Sjruoho     return_ACPI_STATUS (Status);
94028c506b8Sjruoho }
941