Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:02

0001 /*******************************************************************************
0002  *
0003  * Module Name: dsutils - Dispatcher utilities
0004  *
0005  ******************************************************************************/
0006 
0007 /******************************************************************************
0008  *
0009  * 1. Copyright Notice
0010  *
0011  * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
0012  * All rights reserved.
0013  *
0014  * 2. License
0015  *
0016  * 2.1. This is your license from Intel Corp. under its intellectual property
0017  * rights. You may have additional license terms from the party that provided
0018  * you this software, covering your right to use that party's intellectual
0019  * property rights.
0020  *
0021  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
0022  * copy of the source code appearing in this file ("Covered Code") an
0023  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
0024  * base code distributed originally by Intel ("Original Intel Code") to copy,
0025  * make derivatives, distribute, use and display any portion of the Covered
0026  * Code in any form, with the right to sublicense such rights; and
0027  *
0028  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
0029  * license (with the right to sublicense), under only those claims of Intel
0030  * patents that are infringed by the Original Intel Code, to make, use, sell,
0031  * offer to sell, and import the Covered Code and derivative works thereof
0032  * solely to the minimum extent necessary to exercise the above copyright
0033  * license, and in no event shall the patent license extend to any additions
0034  * to or modifications of the Original Intel Code. No other license or right
0035  * is granted directly or by implication, estoppel or otherwise;
0036  *
0037  * The above copyright and patent license is granted only if the following
0038  * conditions are met:
0039  *
0040  * 3. Conditions
0041  *
0042  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
0043  * Redistribution of source code of any substantial portion of the Covered
0044  * Code or modification with rights to further distribute source must include
0045  * the above Copyright Notice, the above License, this list of Conditions,
0046  * and the following Disclaimer and Export Compliance provision. In addition,
0047  * Licensee must cause all Covered Code to which Licensee contributes to
0048  * contain a file documenting the changes Licensee made to create that Covered
0049  * Code and the date of any change. Licensee must include in that file the
0050  * documentation of any changes made by any predecessor Licensee. Licensee
0051  * must include a prominent statement that the modification is derived,
0052  * directly or indirectly, from Original Intel Code.
0053  *
0054  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
0055  * Redistribution of source code of any substantial portion of the Covered
0056  * Code or modification without rights to further distribute source must
0057  * include the following Disclaimer and Export Compliance provision in the
0058  * documentation and/or other materials provided with distribution. In
0059  * addition, Licensee may not authorize further sublicense of source of any
0060  * portion of the Covered Code, and must include terms to the effect that the
0061  * license from Licensee to its licensee is limited to the intellectual
0062  * property embodied in the software Licensee provides to its licensee, and
0063  * not to intellectual property embodied in modifications its licensee may
0064  * make.
0065  *
0066  * 3.3. Redistribution of Executable. Redistribution in executable form of any
0067  * substantial portion of the Covered Code or modification must reproduce the
0068  * above Copyright Notice, and the following Disclaimer and Export Compliance
0069  * provision in the documentation and/or other materials provided with the
0070  * distribution.
0071  *
0072  * 3.4. Intel retains all right, title, and interest in and to the Original
0073  * Intel Code.
0074  *
0075  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
0076  * Intel shall be used in advertising or otherwise to promote the sale, use or
0077  * other dealings in products derived from or relating to the Covered Code
0078  * without prior written authorization from Intel.
0079  *
0080  * 4. Disclaimer and Export Compliance
0081  *
0082  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
0083  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
0084  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
0085  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
0086  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
0087  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
0088  * PARTICULAR PURPOSE.
0089  *
0090  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
0091  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
0092  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
0093  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
0094  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
0095  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
0096  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
0097  * LIMITED REMEDY.
0098  *
0099  * 4.3. Licensee shall not export, either directly or indirectly, any of this
0100  * software or system incorporating such software without first obtaining any
0101  * required license or other approval from the U. S. Department of Commerce or
0102  * any other agency or department of the United States Government. In the
0103  * event Licensee exports any such software from the United States or
0104  * re-exports any such software from a foreign destination, Licensee shall
0105  * ensure that the distribution and export/re-export of the software is in
0106  * compliance with all laws, regulations, orders, or other restrictions of the
0107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
0108  * any of its subsidiaries will export/re-export any technical data, process,
0109  * software, or service, directly or indirectly, to any country for which the
0110  * United States government or any agency thereof requires an export license,
0111  * other governmental approval, or letter of assurance, without first obtaining
0112  * such license, approval or letter.
0113  *
0114  *****************************************************************************
0115  *
0116  * Alternatively, you may choose to be licensed under the terms of the
0117  * following license:
0118  *
0119  * Redistribution and use in source and binary forms, with or without
0120  * modification, are permitted provided that the following conditions
0121  * are met:
0122  * 1. Redistributions of source code must retain the above copyright
0123  *    notice, this list of conditions, and the following disclaimer,
0124  *    without modification.
0125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
0126  *    substantially similar to the "NO WARRANTY" disclaimer below
0127  *    ("Disclaimer") and any redistribution must be conditioned upon
0128  *    including a substantially similar Disclaimer requirement for further
0129  *    binary redistribution.
0130  * 3. Neither the names of the above-listed copyright holders nor the names
0131  *    of any contributors may be used to endorse or promote products derived
0132  *    from this software without specific prior written permission.
0133  *
0134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0145  *
0146  * Alternatively, you may choose to be licensed under the terms of the
0147  * GNU General Public License ("GPL") version 2 as published by the Free
0148  * Software Foundation.
0149  *
0150  *****************************************************************************/
0151 
0152 #include "acpi.h"
0153 #include "accommon.h"
0154 #include "acparser.h"
0155 #include "amlcode.h"
0156 #include "acdispat.h"
0157 #include "acinterp.h"
0158 #include "acnamesp.h"
0159 #include "acdebug.h"
0160 
0161 #define _COMPONENT          ACPI_DISPATCHER
0162         ACPI_MODULE_NAME    ("dsutils")
0163 
0164 
0165 /*******************************************************************************
0166  *
0167  * FUNCTION:    AcpiDsClearImplicitReturn
0168  *
0169  * PARAMETERS:  WalkState           - Current State
0170  *
0171  * RETURN:      None.
0172  *
0173  * DESCRIPTION: Clear and remove a reference on an implicit return value. Used
0174  *              to delete "stale" return values (if enabled, the return value
0175  *              from every operator is saved at least momentarily, in case the
0176  *              parent method exits.)
0177  *
0178  ******************************************************************************/
0179 
0180 void
0181 AcpiDsClearImplicitReturn (
0182     ACPI_WALK_STATE         *WalkState)
0183 {
0184     ACPI_FUNCTION_NAME (DsClearImplicitReturn);
0185 
0186 
0187     /*
0188      * Slack must be enabled for this feature
0189      */
0190     if (!AcpiGbl_EnableInterpreterSlack)
0191     {
0192         return;
0193     }
0194 
0195     if (WalkState->ImplicitReturnObj)
0196     {
0197         /*
0198          * Delete any "stale" implicit return. However, in
0199          * complex statements, the implicit return value can be
0200          * bubbled up several levels.
0201          */
0202         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
0203             "Removing reference on stale implicit return obj %p\n",
0204             WalkState->ImplicitReturnObj));
0205 
0206         AcpiUtRemoveReference (WalkState->ImplicitReturnObj);
0207         WalkState->ImplicitReturnObj = NULL;
0208     }
0209 }
0210 
0211 
0212 /*******************************************************************************
0213  *
0214  * FUNCTION:    AcpiDsDoImplicitReturn
0215  *
0216  * PARAMETERS:  ReturnDesc          - The return value
0217  *              WalkState           - Current State
0218  *              AddReference        - True if a reference should be added to the
0219  *                                    return object
0220  *
0221  * RETURN:      TRUE if implicit return enabled, FALSE otherwise
0222  *
0223  * DESCRIPTION: Implements the optional "implicit return".  We save the result
0224  *              of every ASL operator and control method invocation in case the
0225  *              parent method exit. Before storing a new return value, we
0226  *              delete the previous return value.
0227  *
0228  ******************************************************************************/
0229 
0230 BOOLEAN
0231 AcpiDsDoImplicitReturn (
0232     ACPI_OPERAND_OBJECT     *ReturnDesc,
0233     ACPI_WALK_STATE         *WalkState,
0234     BOOLEAN                 AddReference)
0235 {
0236     ACPI_FUNCTION_NAME (DsDoImplicitReturn);
0237 
0238 
0239     /*
0240      * Slack must be enabled for this feature, and we must
0241      * have a valid return object
0242      */
0243     if ((!AcpiGbl_EnableInterpreterSlack) ||
0244         (!ReturnDesc))
0245     {
0246         return (FALSE);
0247     }
0248 
0249     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
0250         "Result %p will be implicitly returned; Prev=%p\n",
0251         ReturnDesc,
0252         WalkState->ImplicitReturnObj));
0253 
0254     /*
0255      * Delete any "stale" implicit return value first. However, in
0256      * complex statements, the implicit return value can be
0257      * bubbled up several levels, so we don't clear the value if it
0258      * is the same as the ReturnDesc.
0259      */
0260     if (WalkState->ImplicitReturnObj)
0261     {
0262         if (WalkState->ImplicitReturnObj == ReturnDesc)
0263         {
0264             return (TRUE);
0265         }
0266         AcpiDsClearImplicitReturn (WalkState);
0267     }
0268 
0269     /* Save the implicit return value, add a reference if requested */
0270 
0271     WalkState->ImplicitReturnObj = ReturnDesc;
0272     if (AddReference)
0273     {
0274         AcpiUtAddReference (ReturnDesc);
0275     }
0276 
0277     return (TRUE);
0278 }
0279 
0280 
0281 /*******************************************************************************
0282  *
0283  * FUNCTION:    AcpiDsIsResultUsed
0284  *
0285  * PARAMETERS:  Op                  - Current Op
0286  *              WalkState           - Current State
0287  *
0288  * RETURN:      TRUE if result is used, FALSE otherwise
0289  *
0290  * DESCRIPTION: Check if a result object will be used by the parent
0291  *
0292  ******************************************************************************/
0293 
0294 BOOLEAN
0295 AcpiDsIsResultUsed (
0296     ACPI_PARSE_OBJECT       *Op,
0297     ACPI_WALK_STATE         *WalkState)
0298 {
0299     const ACPI_OPCODE_INFO  *ParentInfo;
0300 
0301     ACPI_FUNCTION_TRACE_PTR (DsIsResultUsed, Op);
0302 
0303 
0304     /* Must have both an Op and a Result Object */
0305 
0306     if (!Op)
0307     {
0308         ACPI_ERROR ((AE_INFO, "Null Op"));
0309         return_UINT8 (TRUE);
0310     }
0311 
0312     /*
0313      * We know that this operator is not a
0314      * Return() operator (would not come here.) The following code is the
0315      * optional support for a so-called "implicit return". Some AML code
0316      * assumes that the last value of the method is "implicitly" returned
0317      * to the caller. Just save the last result as the return value.
0318      * NOTE: this is optional because the ASL language does not actually
0319      * support this behavior.
0320      */
0321     (void) AcpiDsDoImplicitReturn (WalkState->ResultObj, WalkState, TRUE);
0322 
0323     /*
0324      * Now determine if the parent will use the result
0325      *
0326      * If there is no parent, or the parent is a ScopeOp, we are executing
0327      * at the method level. An executing method typically has no parent,
0328      * since each method is parsed separately. A method invoked externally
0329      * via ExecuteControlMethod has a ScopeOp as the parent.
0330      */
0331     if ((!Op->Common.Parent) ||
0332         (Op->Common.Parent->Common.AmlOpcode == AML_SCOPE_OP))
0333     {
0334         /* No parent, the return value cannot possibly be used */
0335 
0336         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
0337             "At Method level, result of [%s] not used\n",
0338             AcpiPsGetOpcodeName (Op->Common.AmlOpcode)));
0339         return_UINT8 (FALSE);
0340     }
0341 
0342     /* Get info on the parent. The RootOp is AML_SCOPE */
0343 
0344     ParentInfo = AcpiPsGetOpcodeInfo (Op->Common.Parent->Common.AmlOpcode);
0345     if (ParentInfo->Class == AML_CLASS_UNKNOWN)
0346     {
0347         ACPI_ERROR ((AE_INFO,
0348             "Unknown parent opcode Op=%p", Op));
0349         return_UINT8 (FALSE);
0350     }
0351 
0352     /*
0353      * Decide what to do with the result based on the parent. If
0354      * the parent opcode will not use the result, delete the object.
0355      * Otherwise leave it as is, it will be deleted when it is used
0356      * as an operand later.
0357      */
0358     switch (ParentInfo->Class)
0359     {
0360     case AML_CLASS_CONTROL:
0361 
0362         switch (Op->Common.Parent->Common.AmlOpcode)
0363         {
0364         case AML_RETURN_OP:
0365 
0366             /* Never delete the return value associated with a return opcode */
0367 
0368             goto ResultUsed;
0369 
0370         case AML_IF_OP:
0371         case AML_WHILE_OP:
0372             /*
0373              * If we are executing the predicate AND this is the predicate op,
0374              * we will use the return value
0375              */
0376             if ((WalkState->ControlState->Common.State ==
0377                     ACPI_CONTROL_PREDICATE_EXECUTING) &&
0378                 (WalkState->ControlState->Control.PredicateOp == Op))
0379             {
0380                 goto ResultUsed;
0381             }
0382             break;
0383 
0384         default:
0385 
0386             /* Ignore other control opcodes */
0387 
0388             break;
0389         }
0390 
0391         /* The general control opcode returns no result */
0392 
0393         goto ResultNotUsed;
0394 
0395     case AML_CLASS_CREATE:
0396         /*
0397          * These opcodes allow TermArg(s) as operands and therefore
0398          * the operands can be method calls. The result is used.
0399          */
0400         goto ResultUsed;
0401 
0402     case AML_CLASS_NAMED_OBJECT:
0403 
0404         if ((Op->Common.Parent->Common.AmlOpcode == AML_REGION_OP)       ||
0405             (Op->Common.Parent->Common.AmlOpcode == AML_DATA_REGION_OP)  ||
0406             (Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP)      ||
0407             (Op->Common.Parent->Common.AmlOpcode == AML_BUFFER_OP)       ||
0408             (Op->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP) ||
0409             (Op->Common.Parent->Common.AmlOpcode == AML_INT_EVAL_SUBTREE_OP) ||
0410             (Op->Common.Parent->Common.AmlOpcode == AML_BANK_FIELD_OP))
0411         {
0412             /*
0413              * These opcodes allow TermArg(s) as operands and therefore
0414              * the operands can be method calls. The result is used.
0415              */
0416             goto ResultUsed;
0417         }
0418 
0419         goto ResultNotUsed;
0420 
0421     default:
0422         /*
0423          * In all other cases. the parent will actually use the return
0424          * object, so keep it.
0425          */
0426         goto ResultUsed;
0427     }
0428 
0429 
0430 ResultUsed:
0431     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
0432         "Result of [%s] used by Parent [%s] Op=%p\n",
0433         AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
0434         AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op));
0435 
0436     return_UINT8 (TRUE);
0437 
0438 
0439 ResultNotUsed:
0440     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
0441         "Result of [%s] not used by Parent [%s] Op=%p\n",
0442         AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
0443         AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op));
0444 
0445     return_UINT8 (FALSE);
0446 }
0447 
0448 
0449 /*******************************************************************************
0450  *
0451  * FUNCTION:    AcpiDsDeleteResultIfNotUsed
0452  *
0453  * PARAMETERS:  Op              - Current parse Op
0454  *              ResultObj       - Result of the operation
0455  *              WalkState       - Current state
0456  *
0457  * RETURN:      Status
0458  *
0459  * DESCRIPTION: Used after interpretation of an opcode. If there is an internal
0460  *              result descriptor, check if the parent opcode will actually use
0461  *              this result. If not, delete the result now so that it will
0462  *              not become orphaned.
0463  *
0464  ******************************************************************************/
0465 
0466 void
0467 AcpiDsDeleteResultIfNotUsed (
0468     ACPI_PARSE_OBJECT       *Op,
0469     ACPI_OPERAND_OBJECT     *ResultObj,
0470     ACPI_WALK_STATE         *WalkState)
0471 {
0472     ACPI_OPERAND_OBJECT     *ObjDesc;
0473     ACPI_STATUS             Status;
0474 
0475 
0476     ACPI_FUNCTION_TRACE_PTR (DsDeleteResultIfNotUsed, ResultObj);
0477 
0478 
0479     if (!Op)
0480     {
0481         ACPI_ERROR ((AE_INFO, "Null Op"));
0482         return_VOID;
0483     }
0484 
0485     if (!ResultObj)
0486     {
0487         return_VOID;
0488     }
0489 
0490     if (!AcpiDsIsResultUsed (Op, WalkState))
0491     {
0492         /* Must pop the result stack (ObjDesc should be equal to ResultObj) */
0493 
0494         Status = AcpiDsResultPop (&ObjDesc, WalkState);
0495         if (ACPI_SUCCESS (Status))
0496         {
0497             AcpiUtRemoveReference (ResultObj);
0498         }
0499     }
0500 
0501     return_VOID;
0502 }
0503 
0504 
0505 /*******************************************************************************
0506  *
0507  * FUNCTION:    AcpiDsResolveOperands
0508  *
0509  * PARAMETERS:  WalkState           - Current walk state with operands on stack
0510  *
0511  * RETURN:      Status
0512  *
0513  * DESCRIPTION: Resolve all operands to their values. Used to prepare
0514  *              arguments to a control method invocation (a call from one
0515  *              method to another.)
0516  *
0517  ******************************************************************************/
0518 
0519 ACPI_STATUS
0520 AcpiDsResolveOperands (
0521     ACPI_WALK_STATE         *WalkState)
0522 {
0523     UINT32                  i;
0524     ACPI_STATUS             Status = AE_OK;
0525 
0526 
0527     ACPI_FUNCTION_TRACE_PTR (DsResolveOperands, WalkState);
0528 
0529 
0530     /*
0531      * Attempt to resolve each of the valid operands
0532      * Method arguments are passed by reference, not by value. This means
0533      * that the actual objects are passed, not copies of the objects.
0534      */
0535     for (i = 0; i < WalkState->NumOperands; i++)
0536     {
0537         Status = AcpiExResolveToValue (&WalkState->Operands[i], WalkState);
0538         if (ACPI_FAILURE (Status))
0539         {
0540             break;
0541         }
0542     }
0543 
0544     return_ACPI_STATUS (Status);
0545 }
0546 
0547 
0548 /*******************************************************************************
0549  *
0550  * FUNCTION:    AcpiDsClearOperands
0551  *
0552  * PARAMETERS:  WalkState           - Current walk state with operands on stack
0553  *
0554  * RETURN:      None
0555  *
0556  * DESCRIPTION: Clear all operands on the current walk state operand stack.
0557  *
0558  ******************************************************************************/
0559 
0560 void
0561 AcpiDsClearOperands (
0562     ACPI_WALK_STATE         *WalkState)
0563 {
0564     UINT32                  i;
0565 
0566 
0567     ACPI_FUNCTION_TRACE_PTR (DsClearOperands, WalkState);
0568 
0569 
0570     /* Remove a reference on each operand on the stack */
0571 
0572     for (i = 0; i < WalkState->NumOperands; i++)
0573     {
0574         /*
0575          * Remove a reference to all operands, including both
0576          * "Arguments" and "Targets".
0577          */
0578         AcpiUtRemoveReference (WalkState->Operands[i]);
0579         WalkState->Operands[i] = NULL;
0580     }
0581 
0582     WalkState->NumOperands = 0;
0583     return_VOID;
0584 }
0585 
0586 
0587 /*******************************************************************************
0588  *
0589  * FUNCTION:    AcpiDsCreateOperand
0590  *
0591  * PARAMETERS:  WalkState       - Current walk state
0592  *              Arg             - Parse object for the argument
0593  *              ArgIndex        - Which argument (zero based)
0594  *
0595  * RETURN:      Status
0596  *
0597  * DESCRIPTION: Translate a parse tree object that is an argument to an AML
0598  *              opcode to the equivalent interpreter object. This may include
0599  *              looking up a name or entering a new name into the internal
0600  *              namespace.
0601  *
0602  ******************************************************************************/
0603 
0604 ACPI_STATUS
0605 AcpiDsCreateOperand (
0606     ACPI_WALK_STATE         *WalkState,
0607     ACPI_PARSE_OBJECT       *Arg,
0608     UINT32                  ArgIndex)
0609 {
0610     ACPI_STATUS             Status = AE_OK;
0611     char                    *NameString;
0612     UINT32                  NameLength;
0613     ACPI_OPERAND_OBJECT     *ObjDesc;
0614     ACPI_PARSE_OBJECT       *ParentOp;
0615     UINT16                  Opcode;
0616     ACPI_INTERPRETER_MODE   InterpreterMode;
0617     const ACPI_OPCODE_INFO  *OpInfo;
0618 
0619 
0620     ACPI_FUNCTION_TRACE_PTR (DsCreateOperand, Arg);
0621 
0622 
0623     /* A valid name must be looked up in the namespace */
0624 
0625     if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
0626         (Arg->Common.Value.String) &&
0627         !(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))
0628     {
0629         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", Arg));
0630 
0631         /* Get the entire name string from the AML stream */
0632 
0633         Status = AcpiExGetNameString (ACPI_TYPE_ANY,
0634             Arg->Common.Value.Buffer, &NameString, &NameLength);
0635 
0636         if (ACPI_FAILURE (Status))
0637         {
0638             return_ACPI_STATUS (Status);
0639         }
0640 
0641         /* All prefixes have been handled, and the name is in NameString */
0642 
0643         /*
0644          * Special handling for BufferField declarations. This is a deferred
0645          * opcode that unfortunately defines the field name as the last
0646          * parameter instead of the first. We get here when we are performing
0647          * the deferred execution, so the actual name of the field is already
0648          * in the namespace. We don't want to attempt to look it up again
0649          * because we may be executing in a different scope than where the
0650          * actual opcode exists.
0651          */
0652         if ((WalkState->DeferredNode) &&
0653             (WalkState->DeferredNode->Type == ACPI_TYPE_BUFFER_FIELD) &&
0654             (ArgIndex == (UINT32)
0655                 ((WalkState->Opcode == AML_CREATE_FIELD_OP) ? 3 : 2)))
0656         {
0657             ObjDesc = ACPI_CAST_PTR (
0658                 ACPI_OPERAND_OBJECT, WalkState->DeferredNode);
0659             Status = AE_OK;
0660         }
0661         else    /* All other opcodes */
0662         {
0663             /*
0664              * Differentiate between a namespace "create" operation
0665              * versus a "lookup" operation (IMODE_LOAD_PASS2 vs.
0666              * IMODE_EXECUTE) in order to support the creation of
0667              * namespace objects during the execution of control methods.
0668              */
0669             ParentOp = Arg->Common.Parent;
0670             OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode);
0671 
0672             if ((OpInfo->Flags & AML_NSNODE) &&
0673                 (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) &&
0674                 (ParentOp->Common.AmlOpcode != AML_REGION_OP) &&
0675                 (ParentOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP))
0676             {
0677                 /* Enter name into namespace if not found */
0678 
0679                 InterpreterMode = ACPI_IMODE_LOAD_PASS2;
0680             }
0681             else
0682             {
0683                 /* Return a failure if name not found */
0684 
0685                 InterpreterMode = ACPI_IMODE_EXECUTE;
0686             }
0687 
0688             Status = AcpiNsLookup (WalkState->ScopeInfo, NameString,
0689                 ACPI_TYPE_ANY, InterpreterMode,
0690                 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, WalkState,
0691                 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc));
0692             /*
0693              * The only case where we pass through (ignore) a NOT_FOUND
0694              * error is for the CondRefOf opcode.
0695              */
0696             if (Status == AE_NOT_FOUND)
0697             {
0698                 if (ParentOp->Common.AmlOpcode == AML_CONDITIONAL_REF_OF_OP)
0699                 {
0700                     /*
0701                      * For the Conditional Reference op, it's OK if
0702                      * the name is not found;  We just need a way to
0703                      * indicate this to the interpreter, set the
0704                      * object to the root
0705                      */
0706                     ObjDesc = ACPI_CAST_PTR (
0707                         ACPI_OPERAND_OBJECT, AcpiGbl_RootNode);
0708                     Status = AE_OK;
0709                 }
0710                 else if (ParentOp->Common.AmlOpcode == AML_EXTERNAL_OP)
0711                 {
0712                     /*
0713                      * This opcode should never appear here. It is used only
0714                      * by AML disassemblers and is surrounded by an If(0)
0715                      * by the ASL compiler.
0716                      *
0717                      * Therefore, if we see it here, it is a serious error.
0718                      */
0719                     Status = AE_AML_BAD_OPCODE;
0720                 }
0721                 else
0722                 {
0723                     /*
0724                      * We just plain didn't find it -- which is a
0725                      * very serious error at this point
0726                      */
0727                     Status = AE_AML_NAME_NOT_FOUND;
0728                 }
0729             }
0730 
0731             if (ACPI_FAILURE (Status))
0732             {
0733                 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
0734                     NameString, Status);
0735             }
0736         }
0737 
0738         /* Free the namestring created above */
0739 
0740         ACPI_FREE (NameString);
0741 
0742         /* Check status from the lookup */
0743 
0744         if (ACPI_FAILURE (Status))
0745         {
0746             return_ACPI_STATUS (Status);
0747         }
0748 
0749         /* Put the resulting object onto the current object stack */
0750 
0751         Status = AcpiDsObjStackPush (ObjDesc, WalkState);
0752         if (ACPI_FAILURE (Status))
0753         {
0754             return_ACPI_STATUS (Status);
0755         }
0756 
0757         AcpiDbDisplayArgumentObject (ObjDesc, WalkState);
0758     }
0759     else
0760     {
0761         /* Check for null name case */
0762 
0763         if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
0764             !(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))
0765         {
0766             /*
0767              * If the name is null, this means that this is an
0768              * optional result parameter that was not specified
0769              * in the original ASL. Create a Zero Constant for a
0770              * placeholder. (Store to a constant is a Noop.)
0771              */
0772             Opcode = AML_ZERO_OP;       /* Has no arguments! */
0773 
0774             ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
0775                 "Null namepath: Arg=%p\n", Arg));
0776         }
0777         else
0778         {
0779             Opcode = Arg->Common.AmlOpcode;
0780         }
0781 
0782         /* Get the object type of the argument */
0783 
0784         OpInfo = AcpiPsGetOpcodeInfo (Opcode);
0785         if (OpInfo->ObjectType == ACPI_TYPE_INVALID)
0786         {
0787             return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
0788         }
0789 
0790         if ((OpInfo->Flags & AML_HAS_RETVAL) ||
0791             (Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))
0792         {
0793             /*
0794              * Use value that was already previously returned
0795              * by the evaluation of this argument
0796              */
0797             Status = AcpiDsResultPop (&ObjDesc, WalkState);
0798             if (ACPI_FAILURE (Status))
0799             {
0800                 /*
0801                  * Only error is underflow, and this indicates
0802                  * a missing or null operand!
0803                  */
0804                 ACPI_EXCEPTION ((AE_INFO, Status,
0805                     "Missing or null operand"));
0806                 return_ACPI_STATUS (Status);
0807             }
0808         }
0809         else
0810         {
0811             /* Create an ACPI_INTERNAL_OBJECT for the argument */
0812 
0813             ObjDesc = AcpiUtCreateInternalObject (OpInfo->ObjectType);
0814             if (!ObjDesc)
0815             {
0816                 return_ACPI_STATUS (AE_NO_MEMORY);
0817             }
0818 
0819             /* Initialize the new object */
0820 
0821             Status = AcpiDsInitObjectFromOp (
0822                 WalkState, Arg, Opcode, &ObjDesc);
0823             if (ACPI_FAILURE (Status))
0824             {
0825                 AcpiUtDeleteObjectDesc (ObjDesc);
0826                 return_ACPI_STATUS (Status);
0827             }
0828         }
0829 
0830         /* Put the operand object on the object stack */
0831 
0832         Status = AcpiDsObjStackPush (ObjDesc, WalkState);
0833         if (ACPI_FAILURE (Status))
0834         {
0835             return_ACPI_STATUS (Status);
0836         }
0837 
0838         AcpiDbDisplayArgumentObject (ObjDesc, WalkState);
0839     }
0840 
0841     return_ACPI_STATUS (AE_OK);
0842 }
0843 
0844 
0845 /*******************************************************************************
0846  *
0847  * FUNCTION:    AcpiDsCreateOperands
0848  *
0849  * PARAMETERS:  WalkState           - Current state
0850  *              FirstArg            - First argument of a parser argument tree
0851  *
0852  * RETURN:      Status
0853  *
0854  * DESCRIPTION: Convert an operator's arguments from a parse tree format to
0855  *              namespace objects and place those argument object on the object
0856  *              stack in preparation for evaluation by the interpreter.
0857  *
0858  ******************************************************************************/
0859 
0860 ACPI_STATUS
0861 AcpiDsCreateOperands (
0862     ACPI_WALK_STATE         *WalkState,
0863     ACPI_PARSE_OBJECT       *FirstArg)
0864 {
0865     ACPI_STATUS             Status = AE_OK;
0866     ACPI_PARSE_OBJECT       *Arg;
0867     ACPI_PARSE_OBJECT       *Arguments[ACPI_OBJ_NUM_OPERANDS];
0868     UINT32                  ArgCount = 0;
0869     UINT32                  Index = WalkState->NumOperands;
0870     UINT32                  i;
0871 
0872 
0873     ACPI_FUNCTION_TRACE_PTR (DsCreateOperands, FirstArg);
0874 
0875 
0876     /* Get all arguments in the list */
0877 
0878     Arg = FirstArg;
0879     while (Arg)
0880     {
0881         if (Index >= ACPI_OBJ_NUM_OPERANDS)
0882         {
0883             return_ACPI_STATUS (AE_BAD_DATA);
0884         }
0885 
0886         Arguments[Index] = Arg;
0887         WalkState->Operands [Index] = NULL;
0888 
0889         /* Move on to next argument, if any */
0890 
0891         Arg = Arg->Common.Next;
0892         ArgCount++;
0893         Index++;
0894     }
0895 
0896     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
0897         "NumOperands %d, ArgCount %d, Index %d\n",
0898         WalkState->NumOperands, ArgCount, Index));
0899 
0900     /* Create the interpreter arguments, in reverse order */
0901 
0902     Index--;
0903     for (i = 0; i < ArgCount; i++)
0904     {
0905         Arg = Arguments[Index];
0906         WalkState->OperandIndex = (UINT8) Index;
0907 
0908         Status = AcpiDsCreateOperand (WalkState, Arg, Index);
0909         if (ACPI_FAILURE (Status))
0910         {
0911             goto Cleanup;
0912         }
0913 
0914         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
0915             "Created Arg #%u (%p) %u args total\n",
0916             Index, Arg, ArgCount));
0917         Index--;
0918     }
0919 
0920     return_ACPI_STATUS (Status);
0921 
0922 
0923 Cleanup:
0924     /*
0925      * We must undo everything done above; meaning that we must
0926      * pop everything off of the operand stack and delete those
0927      * objects
0928      */
0929     AcpiDsObjStackPopAndDelete (ArgCount, WalkState);
0930 
0931     ACPI_EXCEPTION ((AE_INFO, Status, "While creating Arg %u", Index));
0932     return_ACPI_STATUS (Status);
0933 }
0934 
0935 
0936 /*****************************************************************************
0937  *
0938  * FUNCTION:    AcpiDsEvaluateNamePath
0939  *
0940  * PARAMETERS:  WalkState       - Current state of the parse tree walk,
0941  *                                the opcode of current operation should be
0942  *                                AML_INT_NAMEPATH_OP
0943  *
0944  * RETURN:      Status
0945  *
0946  * DESCRIPTION: Translate the -NamePath- parse tree object to the equivalent
0947  *              interpreter object, convert it to value, if needed, duplicate
0948  *              it, if needed, and push it onto the current result stack.
0949  *
0950  ****************************************************************************/
0951 
0952 ACPI_STATUS
0953 AcpiDsEvaluateNamePath (
0954     ACPI_WALK_STATE         *WalkState)
0955 {
0956     ACPI_STATUS             Status = AE_OK;
0957     ACPI_PARSE_OBJECT       *Op = WalkState->Op;
0958     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
0959     ACPI_OPERAND_OBJECT     *NewObjDesc;
0960     UINT8                   Type;
0961 
0962 
0963     ACPI_FUNCTION_TRACE_PTR (DsEvaluateNamePath, WalkState);
0964 
0965 
0966     if (!Op->Common.Parent)
0967     {
0968         /* This happens after certain exception processing */
0969 
0970         goto Exit;
0971     }
0972 
0973     if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
0974         (Op->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP) ||
0975         (Op->Common.Parent->Common.AmlOpcode == AML_REF_OF_OP))
0976     {
0977         /* TBD: Should we specify this feature as a bit of OpInfo->Flags of these opcodes? */
0978 
0979         goto Exit;
0980     }
0981 
0982     Status = AcpiDsCreateOperand (WalkState, Op, 0);
0983     if (ACPI_FAILURE (Status))
0984     {
0985         goto Exit;
0986     }
0987 
0988     if (Op->Common.Flags & ACPI_PARSEOP_TARGET)
0989     {
0990         NewObjDesc = *Operand;
0991         goto PushResult;
0992     }
0993 
0994     Type = (*Operand)->Common.Type;
0995 
0996     Status = AcpiExResolveToValue (Operand, WalkState);
0997     if (ACPI_FAILURE (Status))
0998     {
0999         goto Exit;
1000     }
1001 
1002     if (Type == ACPI_TYPE_INTEGER)
1003     {
1004         /* It was incremented by AcpiExResolveToValue */
1005 
1006         AcpiUtRemoveReference (*Operand);
1007 
1008         Status = AcpiUtCopyIobjectToIobject (
1009             *Operand, &NewObjDesc, WalkState);
1010         if (ACPI_FAILURE (Status))
1011         {
1012             goto Exit;
1013         }
1014     }
1015     else
1016     {
1017         /*
1018          * The object either was anew created or is
1019          * a Namespace node - don't decrement it.
1020          */
1021         NewObjDesc = *Operand;
1022     }
1023 
1024     /* Cleanup for name-path operand */
1025 
1026     Status = AcpiDsObjStackPop (1, WalkState);
1027     if (ACPI_FAILURE (Status))
1028     {
1029         WalkState->ResultObj = NewObjDesc;
1030         goto Exit;
1031     }
1032 
1033 PushResult:
1034 
1035     WalkState->ResultObj = NewObjDesc;
1036 
1037     Status = AcpiDsResultPush (WalkState->ResultObj, WalkState);
1038     if (ACPI_SUCCESS (Status))
1039     {
1040         /* Force to take it from stack */
1041 
1042         Op->Common.Flags |= ACPI_PARSEOP_IN_STACK;
1043     }
1044 
1045 Exit:
1046 
1047     return_ACPI_STATUS (Status);
1048 }