Subversion Repositories Kolibri OS

Rev

Rev 1498 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*******************************************************************************
  2.  *
  3.  * Module Name: dsutils - Dispatcher utilities
  4.  *
  5.  ******************************************************************************/
  6.  
  7. /******************************************************************************
  8.  *
  9.  * 1. Copyright Notice
  10.  *
  11.  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  12.  * All rights reserved.
  13.  *
  14.  * 2. License
  15.  *
  16.  * 2.1. This is your license from Intel Corp. under its intellectual property
  17.  * rights.  You may have additional license terms from the party that provided
  18.  * you this software, covering your right to use that party's intellectual
  19.  * property rights.
  20.  *
  21.  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
  22.  * copy of the source code appearing in this file ("Covered Code") an
  23.  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
  24.  * base code distributed originally by Intel ("Original Intel Code") to copy,
  25.  * make derivatives, distribute, use and display any portion of the Covered
  26.  * Code in any form, with the right to sublicense such rights; and
  27.  *
  28.  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
  29.  * license (with the right to sublicense), under only those claims of Intel
  30.  * patents that are infringed by the Original Intel Code, to make, use, sell,
  31.  * offer to sell, and import the Covered Code and derivative works thereof
  32.  * solely to the minimum extent necessary to exercise the above copyright
  33.  * license, and in no event shall the patent license extend to any additions
  34.  * to or modifications of the Original Intel Code.  No other license or right
  35.  * is granted directly or by implication, estoppel or otherwise;
  36.  *
  37.  * The above copyright and patent license is granted only if the following
  38.  * conditions are met:
  39.  *
  40.  * 3. Conditions
  41.  *
  42.  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
  43.  * Redistribution of source code of any substantial portion of the Covered
  44.  * Code or modification with rights to further distribute source must include
  45.  * the above Copyright Notice, the above License, this list of Conditions,
  46.  * and the following Disclaimer and Export Compliance provision.  In addition,
  47.  * Licensee must cause all Covered Code to which Licensee contributes to
  48.  * contain a file documenting the changes Licensee made to create that Covered
  49.  * Code and the date of any change.  Licensee must include in that file the
  50.  * documentation of any changes made by any predecessor Licensee.  Licensee
  51.  * must include a prominent statement that the modification is derived,
  52.  * directly or indirectly, from Original Intel Code.
  53.  *
  54.  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
  55.  * Redistribution of source code of any substantial portion of the Covered
  56.  * Code or modification without rights to further distribute source must
  57.  * include the following Disclaimer and Export Compliance provision in the
  58.  * documentation and/or other materials provided with distribution.  In
  59.  * addition, Licensee may not authorize further sublicense of source of any
  60.  * portion of the Covered Code, and must include terms to the effect that the
  61.  * license from Licensee to its licensee is limited to the intellectual
  62.  * property embodied in the software Licensee provides to its licensee, and
  63.  * not to intellectual property embodied in modifications its licensee may
  64.  * make.
  65.  *
  66.  * 3.3. Redistribution of Executable. Redistribution in executable form of any
  67.  * substantial portion of the Covered Code or modification must reproduce the
  68.  * above Copyright Notice, and the following Disclaimer and Export Compliance
  69.  * provision in the documentation and/or other materials provided with the
  70.  * distribution.
  71.  *
  72.  * 3.4. Intel retains all right, title, and interest in and to the Original
  73.  * Intel Code.
  74.  *
  75.  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
  76.  * Intel shall be used in advertising or otherwise to promote the sale, use or
  77.  * other dealings in products derived from or relating to the Covered Code
  78.  * without prior written authorization from Intel.
  79.  *
  80.  * 4. Disclaimer and Export Compliance
  81.  *
  82.  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
  83.  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
  84.  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
  85.  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
  86.  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
  87.  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
  88.  * PARTICULAR PURPOSE.
  89.  *
  90.  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
  91.  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
  92.  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
  93.  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
  94.  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
  95.  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
  96.  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
  97.  * LIMITED REMEDY.
  98.  *
  99.  * 4.3. Licensee shall not export, either directly or indirectly, any of this
  100.  * software or system incorporating such software without first obtaining any
  101.  * required license or other approval from the U. S. Department of Commerce or
  102.  * any other agency or department of the United States Government.  In the
  103.  * event Licensee exports any such software from the United States or
  104.  * re-exports any such software from a foreign destination, Licensee shall
  105.  * ensure that the distribution and export/re-export of the software is in
  106.  * compliance with all laws, regulations, orders, or other restrictions of the
  107.  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  108.  * any of its subsidiaries will export/re-export any technical data, process,
  109.  * software, or service, directly or indirectly, to any country for which the
  110.  * United States government or any agency thereof requires an export license,
  111.  * other governmental approval, or letter of assurance, without first obtaining
  112.  * such license, approval or letter.
  113.  *
  114.  *****************************************************************************/
  115.  
  116. #define __DSUTILS_C__
  117.  
  118. #include "acpi.h"
  119. #include "accommon.h"
  120. #include "acparser.h"
  121. #include "amlcode.h"
  122. #include "acdispat.h"
  123. #include "acinterp.h"
  124. #include "acnamesp.h"
  125. #include "acdebug.h"
  126.  
  127. #define _COMPONENT          ACPI_DISPATCHER
  128.         ACPI_MODULE_NAME    ("dsutils")
  129.  
  130.  
  131. /*******************************************************************************
  132.  *
  133.  * FUNCTION:    AcpiDsClearImplicitReturn
  134.  *
  135.  * PARAMETERS:  WalkState           - Current State
  136.  *
  137.  * RETURN:      None.
  138.  *
  139.  * DESCRIPTION: Clear and remove a reference on an implicit return value.  Used
  140.  *              to delete "stale" return values (if enabled, the return value
  141.  *              from every operator is saved at least momentarily, in case the
  142.  *              parent method exits.)
  143.  *
  144.  ******************************************************************************/
  145.  
  146. void
  147. AcpiDsClearImplicitReturn (
  148.     ACPI_WALK_STATE         *WalkState)
  149. {
  150.     ACPI_FUNCTION_NAME (DsClearImplicitReturn);
  151.  
  152.  
  153.     /*
  154.      * Slack must be enabled for this feature
  155.      */
  156.     if (!AcpiGbl_EnableInterpreterSlack)
  157.     {
  158.         return;
  159.     }
  160.  
  161.     if (WalkState->ImplicitReturnObj)
  162.     {
  163.         /*
  164.          * Delete any "stale" implicit return. However, in
  165.          * complex statements, the implicit return value can be
  166.          * bubbled up several levels.
  167.          */
  168.         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
  169.             "Removing reference on stale implicit return obj %p\n",
  170.             WalkState->ImplicitReturnObj));
  171.  
  172.         AcpiUtRemoveReference (WalkState->ImplicitReturnObj);
  173.         WalkState->ImplicitReturnObj = NULL;
  174.     }
  175. }
  176.  
  177.  
  178. #ifndef ACPI_NO_METHOD_EXECUTION
  179. /*******************************************************************************
  180.  *
  181.  * FUNCTION:    AcpiDsDoImplicitReturn
  182.  *
  183.  * PARAMETERS:  ReturnDesc          - The return value
  184.  *              WalkState           - Current State
  185.  *              AddReference        - True if a reference should be added to the
  186.  *                                    return object
  187.  *
  188.  * RETURN:      TRUE if implicit return enabled, FALSE otherwise
  189.  *
  190.  * DESCRIPTION: Implements the optional "implicit return".  We save the result
  191.  *              of every ASL operator and control method invocation in case the
  192.  *              parent method exit.  Before storing a new return value, we
  193.  *              delete the previous return value.
  194.  *
  195.  ******************************************************************************/
  196.  
  197. BOOLEAN
  198. AcpiDsDoImplicitReturn (
  199.     ACPI_OPERAND_OBJECT     *ReturnDesc,
  200.     ACPI_WALK_STATE         *WalkState,
  201.     BOOLEAN                 AddReference)
  202. {
  203.     ACPI_FUNCTION_NAME (DsDoImplicitReturn);
  204.  
  205.  
  206.     /*
  207.      * Slack must be enabled for this feature, and we must
  208.      * have a valid return object
  209.      */
  210.     if ((!AcpiGbl_EnableInterpreterSlack) ||
  211.         (!ReturnDesc))
  212.     {
  213.         return (FALSE);
  214.     }
  215.  
  216.     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
  217.             "Result %p will be implicitly returned; Prev=%p\n",
  218.             ReturnDesc,
  219.             WalkState->ImplicitReturnObj));
  220.  
  221.     /*
  222.      * Delete any "stale" implicit return value first. However, in
  223.      * complex statements, the implicit return value can be
  224.      * bubbled up several levels, so we don't clear the value if it
  225.      * is the same as the ReturnDesc.
  226.      */
  227.     if (WalkState->ImplicitReturnObj)
  228.     {
  229.         if (WalkState->ImplicitReturnObj == ReturnDesc)
  230.         {
  231.             return (TRUE);
  232.         }
  233.         AcpiDsClearImplicitReturn (WalkState);
  234.     }
  235.  
  236.     /* Save the implicit return value, add a reference if requested */
  237.  
  238.     WalkState->ImplicitReturnObj = ReturnDesc;
  239.     if (AddReference)
  240.     {
  241.         AcpiUtAddReference (ReturnDesc);
  242.     }
  243.  
  244.     return (TRUE);
  245. }
  246.  
  247.  
  248. /*******************************************************************************
  249.  *
  250.  * FUNCTION:    AcpiDsIsResultUsed
  251.  *
  252.  * PARAMETERS:  Op                  - Current Op
  253.  *              WalkState           - Current State
  254.  *
  255.  * RETURN:      TRUE if result is used, FALSE otherwise
  256.  *
  257.  * DESCRIPTION: Check if a result object will be used by the parent
  258.  *
  259.  ******************************************************************************/
  260.  
  261. BOOLEAN
  262. AcpiDsIsResultUsed (
  263.     ACPI_PARSE_OBJECT       *Op,
  264.     ACPI_WALK_STATE         *WalkState)
  265. {
  266.     const ACPI_OPCODE_INFO  *ParentInfo;
  267.  
  268.     ACPI_FUNCTION_TRACE_PTR (DsIsResultUsed, Op);
  269.  
  270.  
  271.     /* Must have both an Op and a Result Object */
  272.  
  273.     if (!Op)
  274.     {
  275.         ACPI_ERROR ((AE_INFO, "Null Op"));
  276.         return_UINT8 (TRUE);
  277.     }
  278.  
  279.     /*
  280.      * We know that this operator is not a
  281.      * Return() operator (would not come here.) The following code is the
  282.      * optional support for a so-called "implicit return". Some AML code
  283.      * assumes that the last value of the method is "implicitly" returned
  284.      * to the caller. Just save the last result as the return value.
  285.      * NOTE: this is optional because the ASL language does not actually
  286.      * support this behavior.
  287.      */
  288.     (void) AcpiDsDoImplicitReturn (WalkState->ResultObj, WalkState, TRUE);
  289.  
  290.     /*
  291.      * Now determine if the parent will use the result
  292.      *
  293.      * If there is no parent, or the parent is a ScopeOp, we are executing
  294.      * at the method level. An executing method typically has no parent,
  295.      * since each method is parsed separately.  A method invoked externally
  296.      * via ExecuteControlMethod has a ScopeOp as the parent.
  297.      */
  298.     if ((!Op->Common.Parent) ||
  299.         (Op->Common.Parent->Common.AmlOpcode == AML_SCOPE_OP))
  300.     {
  301.         /* No parent, the return value cannot possibly be used */
  302.  
  303.         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
  304.             "At Method level, result of [%s] not used\n",
  305.             AcpiPsGetOpcodeName (Op->Common.AmlOpcode)));
  306.         return_UINT8 (FALSE);
  307.     }
  308.  
  309.     /* Get info on the parent. The RootOp is AML_SCOPE */
  310.  
  311.     ParentInfo = AcpiPsGetOpcodeInfo (Op->Common.Parent->Common.AmlOpcode);
  312.     if (ParentInfo->Class == AML_CLASS_UNKNOWN)
  313.     {
  314.         ACPI_ERROR ((AE_INFO,
  315.             "Unknown parent opcode Op=%p", Op));
  316.         return_UINT8 (FALSE);
  317.     }
  318.  
  319.     /*
  320.      * Decide what to do with the result based on the parent.  If
  321.      * the parent opcode will not use the result, delete the object.
  322.      * Otherwise leave it as is, it will be deleted when it is used
  323.      * as an operand later.
  324.      */
  325.     switch (ParentInfo->Class)
  326.     {
  327.     case AML_CLASS_CONTROL:
  328.  
  329.         switch (Op->Common.Parent->Common.AmlOpcode)
  330.         {
  331.         case AML_RETURN_OP:
  332.  
  333.             /* Never delete the return value associated with a return opcode */
  334.  
  335.             goto ResultUsed;
  336.  
  337.         case AML_IF_OP:
  338.         case AML_WHILE_OP:
  339.  
  340.             /*
  341.              * If we are executing the predicate AND this is the predicate op,
  342.              * we will use the return value
  343.              */
  344.             if ((WalkState->ControlState->Common.State == ACPI_CONTROL_PREDICATE_EXECUTING) &&
  345.                 (WalkState->ControlState->Control.PredicateOp == Op))
  346.             {
  347.                 goto ResultUsed;
  348.             }
  349.             break;
  350.  
  351.         default:
  352.             /* Ignore other control opcodes */
  353.             break;
  354.         }
  355.  
  356.         /* The general control opcode returns no result */
  357.  
  358.         goto ResultNotUsed;
  359.  
  360.  
  361.     case AML_CLASS_CREATE:
  362.  
  363.         /*
  364.          * These opcodes allow TermArg(s) as operands and therefore
  365.          * the operands can be method calls.  The result is used.
  366.          */
  367.         goto ResultUsed;
  368.  
  369.  
  370.     case AML_CLASS_NAMED_OBJECT:
  371.  
  372.         if ((Op->Common.Parent->Common.AmlOpcode == AML_REGION_OP)       ||
  373.             (Op->Common.Parent->Common.AmlOpcode == AML_DATA_REGION_OP)  ||
  374.             (Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP)      ||
  375.             (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)  ||
  376.             (Op->Common.Parent->Common.AmlOpcode == AML_BUFFER_OP)       ||
  377.             (Op->Common.Parent->Common.AmlOpcode == AML_INT_EVAL_SUBTREE_OP) ||
  378.             (Op->Common.Parent->Common.AmlOpcode == AML_BANK_FIELD_OP))
  379.         {
  380.             /*
  381.              * These opcodes allow TermArg(s) as operands and therefore
  382.              * the operands can be method calls.  The result is used.
  383.              */
  384.             goto ResultUsed;
  385.         }
  386.  
  387.         goto ResultNotUsed;
  388.  
  389.  
  390.     default:
  391.  
  392.         /*
  393.          * In all other cases. the parent will actually use the return
  394.          * object, so keep it.
  395.          */
  396.         goto ResultUsed;
  397.     }
  398.  
  399.  
  400. ResultUsed:
  401.     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
  402.         "Result of [%s] used by Parent [%s] Op=%p\n",
  403.         AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
  404.         AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op));
  405.  
  406.     return_UINT8 (TRUE);
  407.  
  408.  
  409. ResultNotUsed:
  410.     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
  411.         "Result of [%s] not used by Parent [%s] Op=%p\n",
  412.         AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
  413.         AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op));
  414.  
  415.     return_UINT8 (FALSE);
  416. }
  417.  
  418.  
  419. /*******************************************************************************
  420.  *
  421.  * FUNCTION:    AcpiDsDeleteResultIfNotUsed
  422.  *
  423.  * PARAMETERS:  Op              - Current parse Op
  424.  *              ResultObj       - Result of the operation
  425.  *              WalkState       - Current state
  426.  *
  427.  * RETURN:      Status
  428.  *
  429.  * DESCRIPTION: Used after interpretation of an opcode.  If there is an internal
  430.  *              result descriptor, check if the parent opcode will actually use
  431.  *              this result.  If not, delete the result now so that it will
  432.  *              not become orphaned.
  433.  *
  434.  ******************************************************************************/
  435.  
  436. void
  437. AcpiDsDeleteResultIfNotUsed (
  438.     ACPI_PARSE_OBJECT       *Op,
  439.     ACPI_OPERAND_OBJECT     *ResultObj,
  440.     ACPI_WALK_STATE         *WalkState)
  441. {
  442.     ACPI_OPERAND_OBJECT     *ObjDesc;
  443.     ACPI_STATUS             Status;
  444.  
  445.  
  446.     ACPI_FUNCTION_TRACE_PTR (DsDeleteResultIfNotUsed, ResultObj);
  447.  
  448.  
  449.     if (!Op)
  450.     {
  451.         ACPI_ERROR ((AE_INFO, "Null Op"));
  452.         return_VOID;
  453.     }
  454.  
  455.     if (!ResultObj)
  456.     {
  457.         return_VOID;
  458.     }
  459.  
  460.     if (!AcpiDsIsResultUsed (Op, WalkState))
  461.     {
  462.         /* Must pop the result stack (ObjDesc should be equal to ResultObj) */
  463.  
  464.         Status = AcpiDsResultPop (&ObjDesc, WalkState);
  465.         if (ACPI_SUCCESS (Status))
  466.         {
  467.             AcpiUtRemoveReference (ResultObj);
  468.         }
  469.     }
  470.  
  471.     return_VOID;
  472. }
  473.  
  474.  
  475. /*******************************************************************************
  476.  *
  477.  * FUNCTION:    AcpiDsResolveOperands
  478.  *
  479.  * PARAMETERS:  WalkState           - Current walk state with operands on stack
  480.  *
  481.  * RETURN:      Status
  482.  *
  483.  * DESCRIPTION: Resolve all operands to their values.  Used to prepare
  484.  *              arguments to a control method invocation (a call from one
  485.  *              method to another.)
  486.  *
  487.  ******************************************************************************/
  488.  
  489. ACPI_STATUS
  490. AcpiDsResolveOperands (
  491.     ACPI_WALK_STATE         *WalkState)
  492. {
  493.     UINT32                  i;
  494.     ACPI_STATUS             Status = AE_OK;
  495.  
  496.  
  497.     ACPI_FUNCTION_TRACE_PTR (DsResolveOperands, WalkState);
  498.  
  499.  
  500.     /*
  501.      * Attempt to resolve each of the valid operands
  502.      * Method arguments are passed by reference, not by value.  This means
  503.      * that the actual objects are passed, not copies of the objects.
  504.      */
  505.     for (i = 0; i < WalkState->NumOperands; i++)
  506.     {
  507.         Status = AcpiExResolveToValue (&WalkState->Operands[i], WalkState);
  508.         if (ACPI_FAILURE (Status))
  509.         {
  510.             break;
  511.         }
  512.     }
  513.  
  514.     return_ACPI_STATUS (Status);
  515. }
  516.  
  517.  
  518. /*******************************************************************************
  519.  *
  520.  * FUNCTION:    AcpiDsClearOperands
  521.  *
  522.  * PARAMETERS:  WalkState           - Current walk state with operands on stack
  523.  *
  524.  * RETURN:      None
  525.  *
  526.  * DESCRIPTION: Clear all operands on the current walk state operand stack.
  527.  *
  528.  ******************************************************************************/
  529.  
  530. void
  531. AcpiDsClearOperands (
  532.     ACPI_WALK_STATE         *WalkState)
  533. {
  534.     UINT32                  i;
  535.  
  536.  
  537.     ACPI_FUNCTION_TRACE_PTR (DsClearOperands, WalkState);
  538.  
  539.  
  540.     /* Remove a reference on each operand on the stack */
  541.  
  542.     for (i = 0; i < WalkState->NumOperands; i++)
  543.     {
  544.         /*
  545.          * Remove a reference to all operands, including both
  546.          * "Arguments" and "Targets".
  547.          */
  548.         AcpiUtRemoveReference (WalkState->Operands[i]);
  549.         WalkState->Operands[i] = NULL;
  550.     }
  551.  
  552.     WalkState->NumOperands = 0;
  553.     return_VOID;
  554. }
  555. #endif
  556.  
  557.  
  558. /*******************************************************************************
  559.  *
  560.  * FUNCTION:    AcpiDsCreateOperand
  561.  *
  562.  * PARAMETERS:  WalkState       - Current walk state
  563.  *              Arg             - Parse object for the argument
  564.  *              ArgIndex        - Which argument (zero based)
  565.  *
  566.  * RETURN:      Status
  567.  *
  568.  * DESCRIPTION: Translate a parse tree object that is an argument to an AML
  569.  *              opcode to the equivalent interpreter object.  This may include
  570.  *              looking up a name or entering a new name into the internal
  571.  *              namespace.
  572.  *
  573.  ******************************************************************************/
  574.  
  575. ACPI_STATUS
  576. AcpiDsCreateOperand (
  577.     ACPI_WALK_STATE         *WalkState,
  578.     ACPI_PARSE_OBJECT       *Arg,
  579.     UINT32                  ArgIndex)
  580. {
  581.     ACPI_STATUS             Status = AE_OK;
  582.     char                    *NameString;
  583.     UINT32                  NameLength;
  584.     ACPI_OPERAND_OBJECT     *ObjDesc;
  585.     ACPI_PARSE_OBJECT       *ParentOp;
  586.     UINT16                  Opcode;
  587.     ACPI_INTERPRETER_MODE   InterpreterMode;
  588.     const ACPI_OPCODE_INFO  *OpInfo;
  589.  
  590.  
  591.     ACPI_FUNCTION_TRACE_PTR (DsCreateOperand, Arg);
  592.  
  593.  
  594.     /* A valid name must be looked up in the namespace */
  595.  
  596.     if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
  597.         (Arg->Common.Value.String) &&
  598.         !(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))
  599.     {
  600.         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", Arg));
  601.  
  602.         /* Get the entire name string from the AML stream */
  603.  
  604.         Status = AcpiExGetNameString (ACPI_TYPE_ANY, Arg->Common.Value.Buffer,
  605.                         &NameString, &NameLength);
  606.  
  607.         if (ACPI_FAILURE (Status))
  608.         {
  609.             return_ACPI_STATUS (Status);
  610.         }
  611.  
  612.         /* All prefixes have been handled, and the name is in NameString */
  613.  
  614.         /*
  615.          * Special handling for BufferField declarations.  This is a deferred
  616.          * opcode that unfortunately defines the field name as the last
  617.          * parameter instead of the first.  We get here when we are performing
  618.          * the deferred execution, so the actual name of the field is already
  619.          * in the namespace.  We don't want to attempt to look it up again
  620.          * because we may be executing in a different scope than where the
  621.          * actual opcode exists.
  622.          */
  623.         if ((WalkState->DeferredNode) &&
  624.             (WalkState->DeferredNode->Type == ACPI_TYPE_BUFFER_FIELD) &&
  625.             (ArgIndex == (UINT32) ((WalkState->Opcode == AML_CREATE_FIELD_OP) ? 3 : 2)))
  626.         {
  627.             ObjDesc = ACPI_CAST_PTR (
  628.                         ACPI_OPERAND_OBJECT, WalkState->DeferredNode);
  629.             Status = AE_OK;
  630.         }
  631.         else    /* All other opcodes */
  632.         {
  633.             /*
  634.              * Differentiate between a namespace "create" operation
  635.              * versus a "lookup" operation (IMODE_LOAD_PASS2 vs.
  636.              * IMODE_EXECUTE) in order to support the creation of
  637.              * namespace objects during the execution of control methods.
  638.              */
  639.             ParentOp = Arg->Common.Parent;
  640.             OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode);
  641.             if ((OpInfo->Flags & AML_NSNODE) &&
  642.                 (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) &&
  643.                 (ParentOp->Common.AmlOpcode != AML_REGION_OP) &&
  644.                 (ParentOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP))
  645.             {
  646.                 /* Enter name into namespace if not found */
  647.  
  648.                 InterpreterMode = ACPI_IMODE_LOAD_PASS2;
  649.             }
  650.             else
  651.             {
  652.                 /* Return a failure if name not found */
  653.  
  654.                 InterpreterMode = ACPI_IMODE_EXECUTE;
  655.             }
  656.  
  657.             Status = AcpiNsLookup (WalkState->ScopeInfo, NameString,
  658.                         ACPI_TYPE_ANY, InterpreterMode,
  659.                         ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
  660.                         WalkState,
  661.                         ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc));
  662.             /*
  663.              * The only case where we pass through (ignore) a NOT_FOUND
  664.              * error is for the CondRefOf opcode.
  665.              */
  666.             if (Status == AE_NOT_FOUND)
  667.             {
  668.                 if (ParentOp->Common.AmlOpcode == AML_COND_REF_OF_OP)
  669.                 {
  670.                     /*
  671.                      * For the Conditional Reference op, it's OK if
  672.                      * the name is not found;  We just need a way to
  673.                      * indicate this to the interpreter, set the
  674.                      * object to the root
  675.                      */
  676.                     ObjDesc = ACPI_CAST_PTR (
  677.                                 ACPI_OPERAND_OBJECT, AcpiGbl_RootNode);
  678.                     Status = AE_OK;
  679.                 }
  680.                 else
  681.                 {
  682.                     /*
  683.                      * We just plain didn't find it -- which is a
  684.                      * very serious error at this point
  685.                      */
  686.                     Status = AE_AML_NAME_NOT_FOUND;
  687.                 }
  688.             }
  689.  
  690.             if (ACPI_FAILURE (Status))
  691.             {
  692.                 ACPI_ERROR_NAMESPACE (NameString, Status);
  693.             }
  694.         }
  695.  
  696.         /* Free the namestring created above */
  697.  
  698.         ACPI_FREE (NameString);
  699.  
  700.         /* Check status from the lookup */
  701.  
  702.         if (ACPI_FAILURE (Status))
  703.         {
  704.             return_ACPI_STATUS (Status);
  705.         }
  706.  
  707.         /* Put the resulting object onto the current object stack */
  708.  
  709.         Status = AcpiDsObjStackPush (ObjDesc, WalkState);
  710.         if (ACPI_FAILURE (Status))
  711.         {
  712.             return_ACPI_STATUS (Status);
  713.         }
  714.         ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject (ObjDesc, WalkState));
  715.     }
  716.     else
  717.     {
  718.         /* Check for null name case */
  719.  
  720.         if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
  721.             !(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))
  722.         {
  723.             /*
  724.              * If the name is null, this means that this is an
  725.              * optional result parameter that was not specified
  726.              * in the original ASL.  Create a Zero Constant for a
  727.              * placeholder.  (Store to a constant is a Noop.)
  728.              */
  729.             Opcode = AML_ZERO_OP;       /* Has no arguments! */
  730.  
  731.             ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
  732.                 "Null namepath: Arg=%p\n", Arg));
  733.         }
  734.         else
  735.         {
  736.             Opcode = Arg->Common.AmlOpcode;
  737.         }
  738.  
  739.         /* Get the object type of the argument */
  740.  
  741.         OpInfo = AcpiPsGetOpcodeInfo (Opcode);
  742.         if (OpInfo->ObjectType == ACPI_TYPE_INVALID)
  743.         {
  744.             return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
  745.         }
  746.  
  747.         if ((OpInfo->Flags & AML_HAS_RETVAL) || (Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))
  748.         {
  749.             ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
  750.                 "Argument previously created, already stacked\n"));
  751.  
  752.             ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject (
  753.                 WalkState->Operands [WalkState->NumOperands - 1], WalkState));
  754.  
  755.             /*
  756.              * Use value that was already previously returned
  757.              * by the evaluation of this argument
  758.              */
  759.             Status = AcpiDsResultPop (&ObjDesc, WalkState);
  760.             if (ACPI_FAILURE (Status))
  761.             {
  762.                 /*
  763.                  * Only error is underflow, and this indicates
  764.                  * a missing or null operand!
  765.                  */
  766.                 ACPI_EXCEPTION ((AE_INFO, Status,
  767.                     "Missing or null operand"));
  768.                 return_ACPI_STATUS (Status);
  769.             }
  770.         }
  771.         else
  772.         {
  773.             /* Create an ACPI_INTERNAL_OBJECT for the argument */
  774.  
  775.             ObjDesc = AcpiUtCreateInternalObject (OpInfo->ObjectType);
  776.             if (!ObjDesc)
  777.             {
  778.                 return_ACPI_STATUS (AE_NO_MEMORY);
  779.             }
  780.  
  781.             /* Initialize the new object */
  782.  
  783.             Status = AcpiDsInitObjectFromOp (
  784.                         WalkState, Arg, Opcode, &ObjDesc);
  785.             if (ACPI_FAILURE (Status))
  786.             {
  787.                 AcpiUtDeleteObjectDesc (ObjDesc);
  788.                 return_ACPI_STATUS (Status);
  789.             }
  790.         }
  791.  
  792.         /* Put the operand object on the object stack */
  793.  
  794.         Status = AcpiDsObjStackPush (ObjDesc, WalkState);
  795.         if (ACPI_FAILURE (Status))
  796.         {
  797.             return_ACPI_STATUS (Status);
  798.         }
  799.  
  800.         ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject (ObjDesc, WalkState));
  801.     }
  802.  
  803.     return_ACPI_STATUS (AE_OK);
  804. }
  805.  
  806.  
  807. /*******************************************************************************
  808.  *
  809.  * FUNCTION:    AcpiDsCreateOperands
  810.  *
  811.  * PARAMETERS:  WalkState           - Current state
  812.  *              FirstArg            - First argument of a parser argument tree
  813.  *
  814.  * RETURN:      Status
  815.  *
  816.  * DESCRIPTION: Convert an operator's arguments from a parse tree format to
  817.  *              namespace objects and place those argument object on the object
  818.  *              stack in preparation for evaluation by the interpreter.
  819.  *
  820.  ******************************************************************************/
  821.  
  822. ACPI_STATUS
  823. AcpiDsCreateOperands (
  824.     ACPI_WALK_STATE         *WalkState,
  825.     ACPI_PARSE_OBJECT       *FirstArg)
  826. {
  827.     ACPI_STATUS             Status = AE_OK;
  828.     ACPI_PARSE_OBJECT       *Arg;
  829.     ACPI_PARSE_OBJECT       *Arguments[ACPI_OBJ_NUM_OPERANDS];
  830.     UINT32                  ArgCount = 0;
  831.     UINT32                  Index = WalkState->NumOperands;
  832.     UINT32                  i;
  833.  
  834.  
  835.     ACPI_FUNCTION_TRACE_PTR (DsCreateOperands, FirstArg);
  836.  
  837.  
  838.     /* Get all arguments in the list */
  839.  
  840.     Arg = FirstArg;
  841.     while (Arg)
  842.     {
  843.         if (Index >= ACPI_OBJ_NUM_OPERANDS)
  844.         {
  845.             return_ACPI_STATUS (AE_BAD_DATA);
  846.         }
  847.  
  848.         Arguments[Index] = Arg;
  849.         WalkState->Operands [Index] = NULL;
  850.  
  851.         /* Move on to next argument, if any */
  852.  
  853.         Arg = Arg->Common.Next;
  854.         ArgCount++;
  855.         Index++;
  856.     }
  857.  
  858.     Index--;
  859.  
  860.     /* It is the appropriate order to get objects from the Result stack */
  861.  
  862.     for (i = 0; i < ArgCount; i++)
  863.     {
  864.         Arg = Arguments[Index];
  865.  
  866.         /* Force the filling of the operand stack in inverse order */
  867.  
  868.         WalkState->OperandIndex = (UINT8) Index;
  869.  
  870.         Status = AcpiDsCreateOperand (WalkState, Arg, Index);
  871.         if (ACPI_FAILURE (Status))
  872.         {
  873.             goto Cleanup;
  874.         }
  875.  
  876.         Index--;
  877.  
  878.         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Arg #%u (%p) done, Arg1=%p\n",
  879.             Index, Arg, FirstArg));
  880.     }
  881.  
  882.     return_ACPI_STATUS (Status);
  883.  
  884.  
  885. Cleanup:
  886.     /*
  887.      * We must undo everything done above; meaning that we must
  888.      * pop everything off of the operand stack and delete those
  889.      * objects
  890.      */
  891.     AcpiDsObjStackPopAndDelete (ArgCount, WalkState);
  892.  
  893.     ACPI_EXCEPTION ((AE_INFO, Status, "While creating Arg %u", Index));
  894.     return_ACPI_STATUS (Status);
  895. }
  896.  
  897.  
  898. /*****************************************************************************
  899.  *
  900.  * FUNCTION:    AcpiDsEvaluateNamePath
  901.  *
  902.  * PARAMETERS:  WalkState       - Current state of the parse tree walk,
  903.  *                                the opcode of current operation should be
  904.  *                                AML_INT_NAMEPATH_OP
  905.  *
  906.  * RETURN:      Status
  907.  *
  908.  * DESCRIPTION: Translate the -NamePath- parse tree object to the equivalent
  909.  *              interpreter object, convert it to value, if needed, duplicate
  910.  *              it, if needed, and push it onto the current result stack.
  911.  *
  912.  ****************************************************************************/
  913.  
  914. ACPI_STATUS
  915. AcpiDsEvaluateNamePath (
  916.     ACPI_WALK_STATE         *WalkState)
  917. {
  918.     ACPI_STATUS             Status = AE_OK;
  919.     ACPI_PARSE_OBJECT       *Op = WalkState->Op;
  920.     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
  921.     ACPI_OPERAND_OBJECT     *NewObjDesc;
  922.     UINT8                   Type;
  923.  
  924.  
  925.     ACPI_FUNCTION_TRACE_PTR (DsEvaluateNamePath, WalkState);
  926.  
  927.  
  928.     if (!Op->Common.Parent)
  929.     {
  930.         /* This happens after certain exception processing */
  931.  
  932.         goto Exit;
  933.     }
  934.  
  935.     if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
  936.         (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP) ||
  937.         (Op->Common.Parent->Common.AmlOpcode == AML_REF_OF_OP))
  938.     {
  939.         /* TBD: Should we specify this feature as a bit of OpInfo->Flags of these opcodes? */
  940.  
  941.         goto Exit;
  942.     }
  943.  
  944.     Status = AcpiDsCreateOperand (WalkState, Op, 0);
  945.     if (ACPI_FAILURE (Status))
  946.     {
  947.         goto Exit;
  948.     }
  949.  
  950.     if (Op->Common.Flags & ACPI_PARSEOP_TARGET)
  951.     {
  952.         NewObjDesc = *Operand;
  953.         goto PushResult;
  954.     }
  955.  
  956.     Type = (*Operand)->Common.Type;
  957.  
  958.     Status = AcpiExResolveToValue (Operand, WalkState);
  959.     if (ACPI_FAILURE (Status))
  960.     {
  961.         goto Exit;
  962.     }
  963.  
  964.     if (Type == ACPI_TYPE_INTEGER)
  965.     {
  966.         /* It was incremented by AcpiExResolveToValue */
  967.  
  968.         AcpiUtRemoveReference (*Operand);
  969.  
  970.         Status = AcpiUtCopyIobjectToIobject (*Operand, &NewObjDesc, WalkState);
  971.         if (ACPI_FAILURE (Status))
  972.         {
  973.             goto Exit;
  974.         }
  975.     }
  976.     else
  977.     {
  978.         /*
  979.          * The object either was anew created or is
  980.          * a Namespace node - don't decrement it.
  981.          */
  982.         NewObjDesc = *Operand;
  983.     }
  984.  
  985.     /* Cleanup for name-path operand */
  986.  
  987.     Status = AcpiDsObjStackPop (1, WalkState);
  988.     if (ACPI_FAILURE (Status))
  989.     {
  990.         WalkState->ResultObj = NewObjDesc;
  991.         goto Exit;
  992.     }
  993.  
  994. PushResult:
  995.  
  996.     WalkState->ResultObj = NewObjDesc;
  997.  
  998.     Status = AcpiDsResultPush (WalkState->ResultObj, WalkState);
  999.     if (ACPI_SUCCESS (Status))
  1000.     {
  1001.         /* Force to take it from stack */
  1002.  
  1003.         Op->Common.Flags |= ACPI_PARSEOP_IN_STACK;
  1004.     }
  1005.  
  1006. Exit:
  1007.  
  1008.     return_ACPI_STATUS (Status);
  1009. }
  1010.