Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*******************************************************************************
  2.  *
  3.  * Module Name: dsutils - Dispatcher utilities
  4.  *
  5.  ******************************************************************************/
  6.  
  7. /*
  8.  * Copyright (C) 2000 - 2015, Intel Corp.
  9.  * All rights reserved.
  10.  *
  11.  * Redistribution and use in source and binary forms, with or without
  12.  * modification, are permitted provided that the following conditions
  13.  * are met:
  14.  * 1. Redistributions of source code must retain the above copyright
  15.  *    notice, this list of conditions, and the following disclaimer,
  16.  *    without modification.
  17.  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18.  *    substantially similar to the "NO WARRANTY" disclaimer below
  19.  *    ("Disclaimer") and any redistribution must be conditioned upon
  20.  *    including a substantially similar Disclaimer requirement for further
  21.  *    binary redistribution.
  22.  * 3. Neither the names of the above-listed copyright holders nor the names
  23.  *    of any contributors may be used to endorse or promote products derived
  24.  *    from this software without specific prior written permission.
  25.  *
  26.  * Alternatively, this software may be distributed under the terms of the
  27.  * GNU General Public License ("GPL") version 2 as published by the Free
  28.  * Software Foundation.
  29.  *
  30.  * NO WARRANTY
  31.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35.  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40.  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41.  * POSSIBILITY OF SUCH DAMAGES.
  42.  */
  43.  
  44. #include <acpi/acpi.h>
  45. #include "accommon.h"
  46. #include "acparser.h"
  47. #include "amlcode.h"
  48. #include "acdispat.h"
  49. #include "acinterp.h"
  50. #include "acnamesp.h"
  51. #include "acdebug.h"
  52.  
  53. #define _COMPONENT          ACPI_DISPATCHER
  54. ACPI_MODULE_NAME("dsutils")
  55.  
  56. /*******************************************************************************
  57.  *
  58.  * FUNCTION:    acpi_ds_clear_implicit_return
  59.  *
  60.  * PARAMETERS:  walk_state          - Current State
  61.  *
  62.  * RETURN:      None.
  63.  *
  64.  * DESCRIPTION: Clear and remove a reference on an implicit return value. Used
  65.  *              to delete "stale" return values (if enabled, the return value
  66.  *              from every operator is saved at least momentarily, in case the
  67.  *              parent method exits.)
  68.  *
  69.  ******************************************************************************/
  70. void acpi_ds_clear_implicit_return(struct acpi_walk_state *walk_state)
  71. {
  72.         ACPI_FUNCTION_NAME(ds_clear_implicit_return);
  73.  
  74.         /*
  75.          * Slack must be enabled for this feature
  76.          */
  77.         if (!acpi_gbl_enable_interpreter_slack) {
  78.                 return;
  79.         }
  80.  
  81.         if (walk_state->implicit_return_obj) {
  82.                 /*
  83.                  * Delete any "stale" implicit return. However, in
  84.                  * complex statements, the implicit return value can be
  85.                  * bubbled up several levels.
  86.                  */
  87.                 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
  88.                                   "Removing reference on stale implicit return obj %p\n",
  89.                                   walk_state->implicit_return_obj));
  90.  
  91.                 acpi_ut_remove_reference(walk_state->implicit_return_obj);
  92.                 walk_state->implicit_return_obj = NULL;
  93.         }
  94. }
  95.  
  96. #ifndef ACPI_NO_METHOD_EXECUTION
  97. /*******************************************************************************
  98.  *
  99.  * FUNCTION:    acpi_ds_do_implicit_return
  100.  *
  101.  * PARAMETERS:  return_desc         - The return value
  102.  *              walk_state          - Current State
  103.  *              add_reference       - True if a reference should be added to the
  104.  *                                    return object
  105.  *
  106.  * RETURN:      TRUE if implicit return enabled, FALSE otherwise
  107.  *
  108.  * DESCRIPTION: Implements the optional "implicit return".  We save the result
  109.  *              of every ASL operator and control method invocation in case the
  110.  *              parent method exit. Before storing a new return value, we
  111.  *              delete the previous return value.
  112.  *
  113.  ******************************************************************************/
  114.  
  115. u8
  116. acpi_ds_do_implicit_return(union acpi_operand_object *return_desc,
  117.                            struct acpi_walk_state *walk_state, u8 add_reference)
  118. {
  119.         ACPI_FUNCTION_NAME(ds_do_implicit_return);
  120.  
  121.         /*
  122.          * Slack must be enabled for this feature, and we must
  123.          * have a valid return object
  124.          */
  125.         if ((!acpi_gbl_enable_interpreter_slack) || (!return_desc)) {
  126.                 return (FALSE);
  127.         }
  128.  
  129.         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
  130.                           "Result %p will be implicitly returned; Prev=%p\n",
  131.                           return_desc, walk_state->implicit_return_obj));
  132.  
  133.         /*
  134.          * Delete any "stale" implicit return value first. However, in
  135.          * complex statements, the implicit return value can be
  136.          * bubbled up several levels, so we don't clear the value if it
  137.          * is the same as the return_desc.
  138.          */
  139.         if (walk_state->implicit_return_obj) {
  140.                 if (walk_state->implicit_return_obj == return_desc) {
  141.                         return (TRUE);
  142.                 }
  143.                 acpi_ds_clear_implicit_return(walk_state);
  144.         }
  145.  
  146.         /* Save the implicit return value, add a reference if requested */
  147.  
  148.         walk_state->implicit_return_obj = return_desc;
  149.         if (add_reference) {
  150.                 acpi_ut_add_reference(return_desc);
  151.         }
  152.  
  153.         return (TRUE);
  154. }
  155.  
  156. /*******************************************************************************
  157.  *
  158.  * FUNCTION:    acpi_ds_is_result_used
  159.  *
  160.  * PARAMETERS:  op                  - Current Op
  161.  *              walk_state          - Current State
  162.  *
  163.  * RETURN:      TRUE if result is used, FALSE otherwise
  164.  *
  165.  * DESCRIPTION: Check if a result object will be used by the parent
  166.  *
  167.  ******************************************************************************/
  168.  
  169. u8
  170. acpi_ds_is_result_used(union acpi_parse_object * op,
  171.                        struct acpi_walk_state * walk_state)
  172. {
  173.         const struct acpi_opcode_info *parent_info;
  174.  
  175.         ACPI_FUNCTION_TRACE_PTR(ds_is_result_used, op);
  176.  
  177.         /* Must have both an Op and a Result Object */
  178.  
  179.         if (!op) {
  180.                 ACPI_ERROR((AE_INFO, "Null Op"));
  181.                 return_UINT8(TRUE);
  182.         }
  183.  
  184.         /*
  185.          * We know that this operator is not a
  186.          * Return() operator (would not come here.) The following code is the
  187.          * optional support for a so-called "implicit return". Some AML code
  188.          * assumes that the last value of the method is "implicitly" returned
  189.          * to the caller. Just save the last result as the return value.
  190.          * NOTE: this is optional because the ASL language does not actually
  191.          * support this behavior.
  192.          */
  193.         (void)acpi_ds_do_implicit_return(walk_state->result_obj, walk_state,
  194.                                          TRUE);
  195.  
  196.         /*
  197.          * Now determine if the parent will use the result
  198.          *
  199.          * If there is no parent, or the parent is a scope_op, we are executing
  200.          * at the method level. An executing method typically has no parent,
  201.          * since each method is parsed separately. A method invoked externally
  202.          * via execute_control_method has a scope_op as the parent.
  203.          */
  204.         if ((!op->common.parent) ||
  205.             (op->common.parent->common.aml_opcode == AML_SCOPE_OP)) {
  206.  
  207.                 /* No parent, the return value cannot possibly be used */
  208.  
  209.                 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
  210.                                   "At Method level, result of [%s] not used\n",
  211.                                   acpi_ps_get_opcode_name(op->common.
  212.                                                           aml_opcode)));
  213.                 return_UINT8(FALSE);
  214.         }
  215.  
  216.         /* Get info on the parent. The root_op is AML_SCOPE */
  217.  
  218.         parent_info =
  219.             acpi_ps_get_opcode_info(op->common.parent->common.aml_opcode);
  220.         if (parent_info->class == AML_CLASS_UNKNOWN) {
  221.                 ACPI_ERROR((AE_INFO, "Unknown parent opcode Op=%p", op));
  222.                 return_UINT8(FALSE);
  223.         }
  224.  
  225.         /*
  226.          * Decide what to do with the result based on the parent. If
  227.          * the parent opcode will not use the result, delete the object.
  228.          * Otherwise leave it as is, it will be deleted when it is used
  229.          * as an operand later.
  230.          */
  231.         switch (parent_info->class) {
  232.         case AML_CLASS_CONTROL:
  233.  
  234.                 switch (op->common.parent->common.aml_opcode) {
  235.                 case AML_RETURN_OP:
  236.  
  237.                         /* Never delete the return value associated with a return opcode */
  238.  
  239.                         goto result_used;
  240.  
  241.                 case AML_IF_OP:
  242.                 case AML_WHILE_OP:
  243.                         /*
  244.                          * If we are executing the predicate AND this is the predicate op,
  245.                          * we will use the return value
  246.                          */
  247.                         if ((walk_state->control_state->common.state ==
  248.                              ACPI_CONTROL_PREDICATE_EXECUTING)
  249.                             && (walk_state->control_state->control.
  250.                                 predicate_op == op)) {
  251.                                 goto result_used;
  252.                         }
  253.                         break;
  254.  
  255.                 default:
  256.  
  257.                         /* Ignore other control opcodes */
  258.  
  259.                         break;
  260.                 }
  261.  
  262.                 /* The general control opcode returns no result */
  263.  
  264.                 goto result_not_used;
  265.  
  266.         case AML_CLASS_CREATE:
  267.                 /*
  268.                  * These opcodes allow term_arg(s) as operands and therefore
  269.                  * the operands can be method calls. The result is used.
  270.                  */
  271.                 goto result_used;
  272.  
  273.         case AML_CLASS_NAMED_OBJECT:
  274.  
  275.                 if ((op->common.parent->common.aml_opcode == AML_REGION_OP) ||
  276.                     (op->common.parent->common.aml_opcode == AML_DATA_REGION_OP)
  277.                     || (op->common.parent->common.aml_opcode == AML_PACKAGE_OP)
  278.                     || (op->common.parent->common.aml_opcode ==
  279.                         AML_VAR_PACKAGE_OP)
  280.                     || (op->common.parent->common.aml_opcode == AML_BUFFER_OP)
  281.                     || (op->common.parent->common.aml_opcode ==
  282.                         AML_INT_EVAL_SUBTREE_OP)
  283.                     || (op->common.parent->common.aml_opcode ==
  284.                         AML_BANK_FIELD_OP)) {
  285.                         /*
  286.                          * These opcodes allow term_arg(s) as operands and therefore
  287.                          * the operands can be method calls. The result is used.
  288.                          */
  289.                         goto result_used;
  290.                 }
  291.  
  292.                 goto result_not_used;
  293.  
  294.         default:
  295.                 /*
  296.                  * In all other cases. the parent will actually use the return
  297.                  * object, so keep it.
  298.                  */
  299.                 goto result_used;
  300.         }
  301.  
  302. result_used:
  303.         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
  304.                           "Result of [%s] used by Parent [%s] Op=%p\n",
  305.                           acpi_ps_get_opcode_name(op->common.aml_opcode),
  306.                           acpi_ps_get_opcode_name(op->common.parent->common.
  307.                                                   aml_opcode), op));
  308.  
  309.         return_UINT8(TRUE);
  310.  
  311. result_not_used:
  312.         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
  313.                           "Result of [%s] not used by Parent [%s] Op=%p\n",
  314.                           acpi_ps_get_opcode_name(op->common.aml_opcode),
  315.                           acpi_ps_get_opcode_name(op->common.parent->common.
  316.                                                   aml_opcode), op));
  317.  
  318.         return_UINT8(FALSE);
  319. }
  320.  
  321. /*******************************************************************************
  322.  *
  323.  * FUNCTION:    acpi_ds_delete_result_if_not_used
  324.  *
  325.  * PARAMETERS:  op              - Current parse Op
  326.  *              result_obj      - Result of the operation
  327.  *              walk_state      - Current state
  328.  *
  329.  * RETURN:      Status
  330.  *
  331.  * DESCRIPTION: Used after interpretation of an opcode. If there is an internal
  332.  *              result descriptor, check if the parent opcode will actually use
  333.  *              this result. If not, delete the result now so that it will
  334.  *              not become orphaned.
  335.  *
  336.  ******************************************************************************/
  337.  
  338. void
  339. acpi_ds_delete_result_if_not_used(union acpi_parse_object *op,
  340.                                   union acpi_operand_object *result_obj,
  341.                                   struct acpi_walk_state *walk_state)
  342. {
  343.         union acpi_operand_object *obj_desc;
  344.         acpi_status status;
  345.  
  346.         ACPI_FUNCTION_TRACE_PTR(ds_delete_result_if_not_used, result_obj);
  347.  
  348.         if (!op) {
  349.                 ACPI_ERROR((AE_INFO, "Null Op"));
  350.                 return_VOID;
  351.         }
  352.  
  353.         if (!result_obj) {
  354.                 return_VOID;
  355.         }
  356.  
  357.         if (!acpi_ds_is_result_used(op, walk_state)) {
  358.  
  359.                 /* Must pop the result stack (obj_desc should be equal to result_obj) */
  360.  
  361.                 status = acpi_ds_result_pop(&obj_desc, walk_state);
  362.                 if (ACPI_SUCCESS(status)) {
  363.                         acpi_ut_remove_reference(result_obj);
  364.                 }
  365.         }
  366.  
  367.         return_VOID;
  368. }
  369.  
  370. /*******************************************************************************
  371.  *
  372.  * FUNCTION:    acpi_ds_resolve_operands
  373.  *
  374.  * PARAMETERS:  walk_state          - Current walk state with operands on stack
  375.  *
  376.  * RETURN:      Status
  377.  *
  378.  * DESCRIPTION: Resolve all operands to their values. Used to prepare
  379.  *              arguments to a control method invocation (a call from one
  380.  *              method to another.)
  381.  *
  382.  ******************************************************************************/
  383.  
  384. acpi_status acpi_ds_resolve_operands(struct acpi_walk_state *walk_state)
  385. {
  386.         u32 i;
  387.         acpi_status status = AE_OK;
  388.  
  389.         ACPI_FUNCTION_TRACE_PTR(ds_resolve_operands, walk_state);
  390.  
  391.         /*
  392.          * Attempt to resolve each of the valid operands
  393.          * Method arguments are passed by reference, not by value. This means
  394.          * that the actual objects are passed, not copies of the objects.
  395.          */
  396.         for (i = 0; i < walk_state->num_operands; i++) {
  397.                 status =
  398.                     acpi_ex_resolve_to_value(&walk_state->operands[i],
  399.                                              walk_state);
  400.                 if (ACPI_FAILURE(status)) {
  401.                         break;
  402.                 }
  403.         }
  404.  
  405.         return_ACPI_STATUS(status);
  406. }
  407.  
  408. /*******************************************************************************
  409.  *
  410.  * FUNCTION:    acpi_ds_clear_operands
  411.  *
  412.  * PARAMETERS:  walk_state          - Current walk state with operands on stack
  413.  *
  414.  * RETURN:      None
  415.  *
  416.  * DESCRIPTION: Clear all operands on the current walk state operand stack.
  417.  *
  418.  ******************************************************************************/
  419.  
  420. void acpi_ds_clear_operands(struct acpi_walk_state *walk_state)
  421. {
  422.         u32 i;
  423.  
  424.         ACPI_FUNCTION_TRACE_PTR(ds_clear_operands, walk_state);
  425.  
  426.         /* Remove a reference on each operand on the stack */
  427.  
  428.         for (i = 0; i < walk_state->num_operands; i++) {
  429.                 /*
  430.                  * Remove a reference to all operands, including both
  431.                  * "Arguments" and "Targets".
  432.                  */
  433.                 acpi_ut_remove_reference(walk_state->operands[i]);
  434.                 walk_state->operands[i] = NULL;
  435.         }
  436.  
  437.         walk_state->num_operands = 0;
  438.         return_VOID;
  439. }
  440. #endif
  441.  
  442. /*******************************************************************************
  443.  *
  444.  * FUNCTION:    acpi_ds_create_operand
  445.  *
  446.  * PARAMETERS:  walk_state      - Current walk state
  447.  *              arg             - Parse object for the argument
  448.  *              arg_index       - Which argument (zero based)
  449.  *
  450.  * RETURN:      Status
  451.  *
  452.  * DESCRIPTION: Translate a parse tree object that is an argument to an AML
  453.  *              opcode to the equivalent interpreter object. This may include
  454.  *              looking up a name or entering a new name into the internal
  455.  *              namespace.
  456.  *
  457.  ******************************************************************************/
  458.  
  459. acpi_status
  460. acpi_ds_create_operand(struct acpi_walk_state *walk_state,
  461.                        union acpi_parse_object *arg, u32 arg_index)
  462. {
  463.         acpi_status status = AE_OK;
  464.         char *name_string;
  465.         u32 name_length;
  466.         union acpi_operand_object *obj_desc;
  467.         union acpi_parse_object *parent_op;
  468.         u16 opcode;
  469.         acpi_interpreter_mode interpreter_mode;
  470.         const struct acpi_opcode_info *op_info;
  471.  
  472.         ACPI_FUNCTION_TRACE_PTR(ds_create_operand, arg);
  473.  
  474.         /* A valid name must be looked up in the namespace */
  475.  
  476.         if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
  477.             (arg->common.value.string) &&
  478.             !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
  479.                 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n",
  480.                                   arg));
  481.  
  482.                 /* Get the entire name string from the AML stream */
  483.  
  484.                 status =
  485.                     acpi_ex_get_name_string(ACPI_TYPE_ANY,
  486.                                             arg->common.value.buffer,
  487.                                             &name_string, &name_length);
  488.  
  489.                 if (ACPI_FAILURE(status)) {
  490.                         return_ACPI_STATUS(status);
  491.                 }
  492.  
  493.                 /* All prefixes have been handled, and the name is in name_string */
  494.  
  495.                 /*
  496.                  * Special handling for buffer_field declarations. This is a deferred
  497.                  * opcode that unfortunately defines the field name as the last
  498.                  * parameter instead of the first. We get here when we are performing
  499.                  * the deferred execution, so the actual name of the field is already
  500.                  * in the namespace. We don't want to attempt to look it up again
  501.                  * because we may be executing in a different scope than where the
  502.                  * actual opcode exists.
  503.                  */
  504.                 if ((walk_state->deferred_node) &&
  505.                     (walk_state->deferred_node->type == ACPI_TYPE_BUFFER_FIELD)
  506.                     && (arg_index ==
  507.                         (u32) ((walk_state->opcode ==
  508.                                 AML_CREATE_FIELD_OP) ? 3 : 2))) {
  509.                         obj_desc =
  510.                             ACPI_CAST_PTR(union acpi_operand_object,
  511.                                           walk_state->deferred_node);
  512.                         status = AE_OK;
  513.                 } else {        /* All other opcodes */
  514.  
  515.                         /*
  516.                          * Differentiate between a namespace "create" operation
  517.                          * versus a "lookup" operation (IMODE_LOAD_PASS2 vs.
  518.                          * IMODE_EXECUTE) in order to support the creation of
  519.                          * namespace objects during the execution of control methods.
  520.                          */
  521.                         parent_op = arg->common.parent;
  522.                         op_info =
  523.                             acpi_ps_get_opcode_info(parent_op->common.
  524.                                                     aml_opcode);
  525.                         if ((op_info->flags & AML_NSNODE)
  526.                             && (parent_op->common.aml_opcode !=
  527.                                 AML_INT_METHODCALL_OP)
  528.                             && (parent_op->common.aml_opcode != AML_REGION_OP)
  529.                             && (parent_op->common.aml_opcode !=
  530.                                 AML_INT_NAMEPATH_OP)) {
  531.  
  532.                                 /* Enter name into namespace if not found */
  533.  
  534.                                 interpreter_mode = ACPI_IMODE_LOAD_PASS2;
  535.                         } else {
  536.                                 /* Return a failure if name not found */
  537.  
  538.                                 interpreter_mode = ACPI_IMODE_EXECUTE;
  539.                         }
  540.  
  541.                         status =
  542.                             acpi_ns_lookup(walk_state->scope_info, name_string,
  543.                                            ACPI_TYPE_ANY, interpreter_mode,
  544.                                            ACPI_NS_SEARCH_PARENT |
  545.                                            ACPI_NS_DONT_OPEN_SCOPE, walk_state,
  546.                                            ACPI_CAST_INDIRECT_PTR(struct
  547.                                                                   acpi_namespace_node,
  548.                                                                   &obj_desc));
  549.                         /*
  550.                          * The only case where we pass through (ignore) a NOT_FOUND
  551.                          * error is for the cond_ref_of opcode.
  552.                          */
  553.                         if (status == AE_NOT_FOUND) {
  554.                                 if (parent_op->common.aml_opcode ==
  555.                                     AML_COND_REF_OF_OP) {
  556.                                         /*
  557.                                          * For the Conditional Reference op, it's OK if
  558.                                          * the name is not found;  We just need a way to
  559.                                          * indicate this to the interpreter, set the
  560.                                          * object to the root
  561.                                          */
  562.                                         obj_desc =
  563.                                             ACPI_CAST_PTR(union
  564.                                                                  acpi_operand_object,
  565.                                                                  acpi_gbl_root_node);
  566.                                         status = AE_OK;
  567.                                 } else if (parent_op->common.aml_opcode ==
  568.                                            AML_EXTERNAL_OP) {
  569.  
  570.                                         /* TBD: May only be temporary */
  571.  
  572.                                         obj_desc =
  573.                                             acpi_ut_create_string_object((acpi_size) name_length);
  574.  
  575.                                         strncpy(obj_desc->string.pointer,
  576.                                                 name_string, name_length);
  577.                                         status = AE_OK;
  578.                                 } else {
  579.                                         /*
  580.                                          * We just plain didn't find it -- which is a
  581.                                          * very serious error at this point
  582.                                          */
  583.                                         status = AE_AML_NAME_NOT_FOUND;
  584.                                 }
  585.                         }
  586.  
  587.                         if (ACPI_FAILURE(status)) {
  588.                                 ACPI_ERROR_NAMESPACE(name_string, status);
  589.                         }
  590.                 }
  591.  
  592.                 /* Free the namestring created above */
  593.  
  594.                 ACPI_FREE(name_string);
  595.  
  596.                 /* Check status from the lookup */
  597.  
  598.                 if (ACPI_FAILURE(status)) {
  599.                         return_ACPI_STATUS(status);
  600.                 }
  601.  
  602.                 /* Put the resulting object onto the current object stack */
  603.  
  604.                 status = acpi_ds_obj_stack_push(obj_desc, walk_state);
  605.                 if (ACPI_FAILURE(status)) {
  606.                         return_ACPI_STATUS(status);
  607.                 }
  608.                 ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
  609.                                    (obj_desc, walk_state));
  610.         } else {
  611.                 /* Check for null name case */
  612.  
  613.                 if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
  614.                     !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
  615.                         /*
  616.                          * If the name is null, this means that this is an
  617.                          * optional result parameter that was not specified
  618.                          * in the original ASL. Create a Zero Constant for a
  619.                          * placeholder. (Store to a constant is a Noop.)
  620.                          */
  621.                         opcode = AML_ZERO_OP;   /* Has no arguments! */
  622.  
  623.                         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
  624.                                           "Null namepath: Arg=%p\n", arg));
  625.                 } else {
  626.                         opcode = arg->common.aml_opcode;
  627.                 }
  628.  
  629.                 /* Get the object type of the argument */
  630.  
  631.                 op_info = acpi_ps_get_opcode_info(opcode);
  632.                 if (op_info->object_type == ACPI_TYPE_INVALID) {
  633.                         return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
  634.                 }
  635.  
  636.                 if ((op_info->flags & AML_HAS_RETVAL)
  637.                     || (arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
  638.                         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
  639.                                           "Argument previously created, already stacked\n"));
  640.  
  641.                         ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
  642.                                            (walk_state->
  643.                                             operands[walk_state->num_operands -
  644.                                                      1], walk_state));
  645.  
  646.                         /*
  647.                          * Use value that was already previously returned
  648.                          * by the evaluation of this argument
  649.                          */
  650.                         status = acpi_ds_result_pop(&obj_desc, walk_state);
  651.                         if (ACPI_FAILURE(status)) {
  652.                                 /*
  653.                                  * Only error is underflow, and this indicates
  654.                                  * a missing or null operand!
  655.                                  */
  656.                                 ACPI_EXCEPTION((AE_INFO, status,
  657.                                                 "Missing or null operand"));
  658.                                 return_ACPI_STATUS(status);
  659.                         }
  660.                 } else {
  661.                         /* Create an ACPI_INTERNAL_OBJECT for the argument */
  662.  
  663.                         obj_desc =
  664.                             acpi_ut_create_internal_object(op_info->
  665.                                                            object_type);
  666.                         if (!obj_desc) {
  667.                                 return_ACPI_STATUS(AE_NO_MEMORY);
  668.                         }
  669.  
  670.                         /* Initialize the new object */
  671.  
  672.                         status =
  673.                             acpi_ds_init_object_from_op(walk_state, arg, opcode,
  674.                                                         &obj_desc);
  675.                         if (ACPI_FAILURE(status)) {
  676.                                 acpi_ut_delete_object_desc(obj_desc);
  677.                                 return_ACPI_STATUS(status);
  678.                         }
  679.                 }
  680.  
  681.                 /* Put the operand object on the object stack */
  682.  
  683.                 status = acpi_ds_obj_stack_push(obj_desc, walk_state);
  684.                 if (ACPI_FAILURE(status)) {
  685.                         return_ACPI_STATUS(status);
  686.                 }
  687.  
  688.                 ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
  689.                                    (obj_desc, walk_state));
  690.         }
  691.  
  692.         return_ACPI_STATUS(AE_OK);
  693. }
  694.  
  695. /*******************************************************************************
  696.  *
  697.  * FUNCTION:    acpi_ds_create_operands
  698.  *
  699.  * PARAMETERS:  walk_state          - Current state
  700.  *              first_arg           - First argument of a parser argument tree
  701.  *
  702.  * RETURN:      Status
  703.  *
  704.  * DESCRIPTION: Convert an operator's arguments from a parse tree format to
  705.  *              namespace objects and place those argument object on the object
  706.  *              stack in preparation for evaluation by the interpreter.
  707.  *
  708.  ******************************************************************************/
  709.  
  710. acpi_status
  711. acpi_ds_create_operands(struct acpi_walk_state *walk_state,
  712.                         union acpi_parse_object *first_arg)
  713. {
  714.         acpi_status status = AE_OK;
  715.         union acpi_parse_object *arg;
  716.         union acpi_parse_object *arguments[ACPI_OBJ_NUM_OPERANDS];
  717.         u32 arg_count = 0;
  718.         u32 index = walk_state->num_operands;
  719.         u32 i;
  720.  
  721.         ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg);
  722.  
  723.         /* Get all arguments in the list */
  724.  
  725.         arg = first_arg;
  726.         while (arg) {
  727.                 if (index >= ACPI_OBJ_NUM_OPERANDS) {
  728.                         return_ACPI_STATUS(AE_BAD_DATA);
  729.                 }
  730.  
  731.                 arguments[index] = arg;
  732.                 walk_state->operands[index] = NULL;
  733.  
  734.                 /* Move on to next argument, if any */
  735.  
  736.                 arg = arg->common.next;
  737.                 arg_count++;
  738.                 index++;
  739.         }
  740.  
  741.         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
  742.                           "NumOperands %d, ArgCount %d, Index %d\n",
  743.                           walk_state->num_operands, arg_count, index));
  744.  
  745.         /* Create the interpreter arguments, in reverse order */
  746.  
  747.         index--;
  748.         for (i = 0; i < arg_count; i++) {
  749.                 arg = arguments[index];
  750.                 walk_state->operand_index = (u8)index;
  751.  
  752.                 status = acpi_ds_create_operand(walk_state, arg, index);
  753.                 if (ACPI_FAILURE(status)) {
  754.                         goto cleanup;
  755.                 }
  756.  
  757.                 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
  758.                                   "Created Arg #%u (%p) %u args total\n",
  759.                                   index, arg, arg_count));
  760.                 index--;
  761.         }
  762.  
  763.         return_ACPI_STATUS(status);
  764.  
  765. cleanup:
  766.         /*
  767.          * We must undo everything done above; meaning that we must
  768.          * pop everything off of the operand stack and delete those
  769.          * objects
  770.          */
  771.         acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state);
  772.  
  773.         ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %u", index));
  774.         return_ACPI_STATUS(status);
  775. }
  776.  
  777. /*****************************************************************************
  778.  *
  779.  * FUNCTION:    acpi_ds_evaluate_name_path
  780.  *
  781.  * PARAMETERS:  walk_state      - Current state of the parse tree walk,
  782.  *                                the opcode of current operation should be
  783.  *                                AML_INT_NAMEPATH_OP
  784.  *
  785.  * RETURN:      Status
  786.  *
  787.  * DESCRIPTION: Translate the -name_path- parse tree object to the equivalent
  788.  *              interpreter object, convert it to value, if needed, duplicate
  789.  *              it, if needed, and push it onto the current result stack.
  790.  *
  791.  ****************************************************************************/
  792.  
  793. acpi_status acpi_ds_evaluate_name_path(struct acpi_walk_state *walk_state)
  794. {
  795.         acpi_status status = AE_OK;
  796.         union acpi_parse_object *op = walk_state->op;
  797.         union acpi_operand_object **operand = &walk_state->operands[0];
  798.         union acpi_operand_object *new_obj_desc;
  799.         u8 type;
  800.  
  801.         ACPI_FUNCTION_TRACE_PTR(ds_evaluate_name_path, walk_state);
  802.  
  803.         if (!op->common.parent) {
  804.  
  805.                 /* This happens after certain exception processing */
  806.  
  807.                 goto exit;
  808.         }
  809.  
  810.         if ((op->common.parent->common.aml_opcode == AML_PACKAGE_OP) ||
  811.             (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP) ||
  812.             (op->common.parent->common.aml_opcode == AML_REF_OF_OP)) {
  813.  
  814.                 /* TBD: Should we specify this feature as a bit of op_info->Flags of these opcodes? */
  815.  
  816.                 goto exit;
  817.         }
  818.  
  819.         status = acpi_ds_create_operand(walk_state, op, 0);
  820.         if (ACPI_FAILURE(status)) {
  821.                 goto exit;
  822.         }
  823.  
  824.         if (op->common.flags & ACPI_PARSEOP_TARGET) {
  825.                 new_obj_desc = *operand;
  826.                 goto push_result;
  827.         }
  828.  
  829.         type = (*operand)->common.type;
  830.  
  831.         status = acpi_ex_resolve_to_value(operand, walk_state);
  832.         if (ACPI_FAILURE(status)) {
  833.                 goto exit;
  834.         }
  835.  
  836.         if (type == ACPI_TYPE_INTEGER) {
  837.  
  838.                 /* It was incremented by acpi_ex_resolve_to_value */
  839.  
  840.                 acpi_ut_remove_reference(*operand);
  841.  
  842.                 status =
  843.                     acpi_ut_copy_iobject_to_iobject(*operand, &new_obj_desc,
  844.                                                     walk_state);
  845.                 if (ACPI_FAILURE(status)) {
  846.                         goto exit;
  847.                 }
  848.         } else {
  849.                 /*
  850.                  * The object either was anew created or is
  851.                  * a Namespace node - don't decrement it.
  852.                  */
  853.                 new_obj_desc = *operand;
  854.         }
  855.  
  856.         /* Cleanup for name-path operand */
  857.  
  858.         status = acpi_ds_obj_stack_pop(1, walk_state);
  859.         if (ACPI_FAILURE(status)) {
  860.                 walk_state->result_obj = new_obj_desc;
  861.                 goto exit;
  862.         }
  863.  
  864. push_result:
  865.  
  866.         walk_state->result_obj = new_obj_desc;
  867.  
  868.         status = acpi_ds_result_push(walk_state->result_obj, walk_state);
  869.         if (ACPI_SUCCESS(status)) {
  870.  
  871.                 /* Force to take it from stack */
  872.  
  873.                 op->common.flags |= ACPI_PARSEOP_IN_STACK;
  874.         }
  875.  
  876. exit:
  877.  
  878.         return_ACPI_STATUS(status);
  879. }
  880.