dswexec.c revision 44f6c01242da4e162f28d8e1216a8c7a91174605
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Module Name: dswexec - Dispatcher method execution callbacks;
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *                        dispatch to interpreter.
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2000 - 2005, R. Byron Moore
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * All rights reserved.
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Redistribution and use in source and binary forms, with or without
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * modification, are permitted provided that the following conditions
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * are met:
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1. Redistributions of source code must retain the above copyright
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    notice, this list of conditions, and the following disclaimer,
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    without modification.
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2. Redistributions in binary form must reproduce at minimum a disclaimer
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    substantially similar to the "NO WARRANTY" disclaimer below
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    ("Disclaimer") and any redistribution must be conditioned upon
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    including a substantially similar Disclaimer requirement for further
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    binary redistribution.
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3. Neither the names of the above-listed copyright holders nor the names
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    of any contributors may be used to endorse or promote products derived
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    from this software without specific prior written permission.
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Alternatively, this software may be distributed under the terms of the
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * GNU General Public License ("GPL") version 2 as published by the Free
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Software Foundation.
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NO WARRANTY
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * POSSIBILITY OF SUCH DAMAGES.
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/acpi.h>
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/acparser.h>
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/amlcode.h>
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/acdispat.h>
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/acinterp.h>
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/acnamesp.h>
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/acdebug.h>
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/acdisasm.h>
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _COMPONENT          ACPI_DISPATCHER
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 ACPI_MODULE_NAME    ("dswexec")
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Dispatch table for opcode classes
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ACPI_EXECUTE_OP      acpi_gbl_op_type_dispatch [] = {
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  acpi_ex_opcode_0A_0T_1R,
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  acpi_ex_opcode_1A_0T_0R,
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  acpi_ex_opcode_1A_0T_1R,
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  acpi_ex_opcode_1A_1T_0R,
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  acpi_ex_opcode_1A_1T_1R,
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  acpi_ex_opcode_2A_0T_0R,
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  acpi_ex_opcode_2A_0T_1R,
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  acpi_ex_opcode_2A_1T_1R,
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  acpi_ex_opcode_2A_2T_1R,
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  acpi_ex_opcode_3A_0T_0R,
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  acpi_ex_opcode_3A_1T_1R,
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  acpi_ex_opcode_6A_0T_1R};
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7644f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*****************************************************************************
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ds_get_predicate_value
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS:  walk_state      - Current state of the parse tree walk
8244f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore *              result_obj      - if non-zero, pop result from result stack
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Get the result of a predicate evaluation
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ****************************************************************************/
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_ds_get_predicate_value (
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct acpi_walk_state          *walk_state,
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	union acpi_operand_object       *result_obj) {
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	acpi_status                     status = AE_OK;
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	union acpi_operand_object       *obj_desc;
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	union acpi_operand_object       *local_obj_desc = NULL;
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ACPI_FUNCTION_TRACE_PTR ("ds_get_predicate_value", walk_state);
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	walk_state->control_state->common.state = 0;
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (result_obj) {
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = acpi_ds_result_pop (&obj_desc, walk_state);
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ACPI_FAILURE (status)) {
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				"Could not get result from predicate evaluation, %s\n",
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				acpi_format_exception (status)));
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return_ACPI_STATUS (status);
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else {
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = acpi_ds_create_operand (walk_state, walk_state->op, 0);
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ACPI_FAILURE (status)) {
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return_ACPI_STATUS (status);
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = acpi_ex_resolve_to_value (&walk_state->operands [0], walk_state);
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ACPI_FAILURE (status)) {
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return_ACPI_STATUS (status);
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		obj_desc = walk_state->operands [0];
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!obj_desc) {
12944f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
13044f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore			"No predicate obj_desc=%p State=%p\n",
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			obj_desc, walk_state));
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return_ACPI_STATUS (AE_AML_NO_OPERAND);
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Result of predicate evaluation must be an Integer
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * object. Implicitly convert the argument if necessary.
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	status = acpi_ex_convert_to_integer (obj_desc, &local_obj_desc, 16);
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ACPI_FAILURE (status)) {
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto cleanup;
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ACPI_GET_OBJECT_TYPE (local_obj_desc) != ACPI_TYPE_INTEGER) {
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			"Bad predicate (not an integer) obj_desc=%p State=%p Type=%X\n",
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			obj_desc, walk_state, ACPI_GET_OBJECT_TYPE (obj_desc)));
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = AE_AML_OPERAND_TYPE;
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto cleanup;
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Truncate the predicate to 32-bits if necessary */
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	acpi_ex_truncate_for32bit_table (local_obj_desc);
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Save the result of the predicate evaluation on
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * the control stack
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (local_obj_desc->integer.value) {
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		walk_state->control_state->common.value = TRUE;
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else {
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Predicate is FALSE, we will just toss the
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * rest of the package
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		walk_state->control_state->common.value = FALSE;
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = AE_CTRL_FALSE;
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldscleanup:
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n",
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		walk_state->control_state->common.value, walk_state->op));
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 /* Break to debugger to display result */
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ACPI_DEBUGGER_EXEC (acpi_db_display_result_object (local_obj_desc, walk_state));
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Delete the predicate result object (we know that
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * we don't need it anymore)
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (local_obj_desc != obj_desc) {
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		acpi_ut_remove_reference (local_obj_desc);
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	acpi_ut_remove_reference (obj_desc);
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	walk_state->control_state->common.state = ACPI_CONTROL_NORMAL;
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return_ACPI_STATUS (status);
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*****************************************************************************
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ds_exec_begin_op
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS:  walk_state      - Current state of the parse tree walk
20344f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore *              out_op          - Where to return op if a new one is created
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Descending callback used during the execution of control
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              methods.  This is where most operators and operands are
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              dispatched to the interpreter.
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ****************************************************************************/
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_ds_exec_begin_op (
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct acpi_walk_state          *walk_state,
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	union acpi_parse_object         **out_op)
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	union acpi_parse_object         *op;
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	acpi_status                     status = AE_OK;
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32                             opcode_class;
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ACPI_FUNCTION_TRACE_PTR ("ds_exec_begin_op", walk_state);
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	op = walk_state->op;
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!op) {
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = acpi_ds_load2_begin_op (walk_state, out_op);
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ACPI_FAILURE (status)) {
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return_ACPI_STATUS (status);
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		op = *out_op;
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		walk_state->op = op;
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		walk_state->opcode = op->common.aml_opcode;
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (acpi_ns_opens_scope (walk_state->op_info->object_type)) {
23944f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
24044f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore				"(%s) Popping scope for Op %p\n",
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				acpi_ut_get_type_name (walk_state->op_info->object_type), op));
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			status = acpi_ds_scope_stack_pop (walk_state);
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (ACPI_FAILURE (status)) {
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return_ACPI_STATUS (status);
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (op == walk_state->origin) {
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (out_op) {
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			*out_op = op;
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return_ACPI_STATUS (AE_OK);
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * If the previous opcode was a conditional, this opcode
2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * must be the beginning of the associated predicate.
2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Save this knowledge in the current scope descriptor
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((walk_state->control_state) &&
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		(walk_state->control_state->common.state ==
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ACPI_CONTROL_CONDITIONAL_EXECUTING)) {
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Exec predicate Op=%p State=%p\n",
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				  op, walk_state));
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		walk_state->control_state->common.state = ACPI_CONTROL_PREDICATE_EXECUTING;
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Save start of predicate */
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		walk_state->control_state->control.predicate_op = op;
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	opcode_class = walk_state->op_info->class;
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* We want to send namepaths to the load code */
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		opcode_class = AML_CLASS_NAMED_OBJECT;
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Handle the opcode based upon the opcode type
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (opcode_class) {
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case AML_CLASS_CONTROL:
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = acpi_ds_result_stack_push (walk_state);
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ACPI_FAILURE (status)) {
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return_ACPI_STATUS (status);
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = acpi_ds_exec_begin_control_op (walk_state, op);
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case AML_CLASS_NAMED_OBJECT:
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (walk_state->walk_type == ACPI_WALK_METHOD) {
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
30444f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore			 * Found a named object declaration during method execution;
30544f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore			 * we must enter this object into the namespace.  The created
30644f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore			 * object is temporary and will be deleted upon completion of
30744f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore			 * the execution of this method.
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			status = acpi_ds_load2_begin_op (walk_state, NULL);
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (op->common.aml_opcode == AML_REGION_OP) {
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			status = acpi_ds_result_stack_push (walk_state);
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case AML_CLASS_EXECUTE:
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case AML_CLASS_CREATE:
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Most operators with arguments.
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Start a new result/operand state
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = acpi_ds_result_stack_push (walk_state);
3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Nothing to do here during method execution */
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return_ACPI_STATUS (status);
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*****************************************************************************
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION:    acpi_ds_exec_end_op
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS:  walk_state      - Current state of the parse tree walk
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN:      Status
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Ascending callback used during the execution of control
3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              methods.  The only thing we really need to do here is to
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              notice the beginning of IF, ELSE, and WHILE blocks.
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ****************************************************************************/
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status
3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_ds_exec_end_op (
3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct acpi_walk_state          *walk_state)
3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	union acpi_parse_object         *op;
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	acpi_status                     status = AE_OK;
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32                             op_type;
3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32                             op_class;
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	union acpi_parse_object         *next_op;
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	union acpi_parse_object         *first_arg;
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ACPI_FUNCTION_TRACE_PTR ("ds_exec_end_op", walk_state);
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	op      = walk_state->op;
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	op_type = walk_state->op_info->type;
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	op_class = walk_state->op_info->class;
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (op_class == AML_CLASS_UNKNOWN) {
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode %X\n", op->common.aml_opcode));
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	first_arg = op->common.value.arg;
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Init the walk state */
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	walk_state->num_operands = 0;
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	walk_state->return_desc = NULL;
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	walk_state->result_obj = NULL;
3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Call debugger for single step support (DEBUG build only) */
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ACPI_DEBUGGER_EXEC (status = acpi_db_single_step (walk_state, op, op_class));
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ACPI_DEBUGGER_EXEC (if (ACPI_FAILURE (status)) {return_ACPI_STATUS (status);});
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Decode the Opcode Class */
3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (op_class) {
39344f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore	case AML_CLASS_ARGUMENT:    /* constants, literals, etc. - do nothing */
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case AML_CLASS_EXECUTE:     /* most operators with arguments */
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Build resolved operand stack */
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = acpi_ds_create_operands (walk_state, first_arg);
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ACPI_FAILURE (status)) {
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto cleanup;
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Done with this result state (Now that operand stack is built) */
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = acpi_ds_result_stack_pop (walk_state);
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ACPI_FAILURE (status)) {
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto cleanup;
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * All opcodes require operand resolution, with the only exceptions
4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * being the object_type and size_of operators.
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!(walk_state->op_info->flags & AML_NO_OPERAND_RESOLVE)) {
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Resolve all operands */
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			status = acpi_ex_resolve_operands (walk_state->opcode,
42144f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore					 &(walk_state->operands [walk_state->num_operands -1]),
42244f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore					 walk_state);
4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (ACPI_SUCCESS (status)) {
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
42544f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore					acpi_ps_get_opcode_name (walk_state->opcode),
42644f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore					walk_state->num_operands, "after ex_resolve_operands");
4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ACPI_SUCCESS (status)) {
4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * Dispatch the request to the appropriate interpreter handler
4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * routine.  There is one routine per opcode "type" based upon the
4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * number of opcode arguments and return type.
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			status = acpi_gbl_op_type_dispatch[op_type] (walk_state);
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else {
4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * Treat constructs of the form "Store(local_x,local_x)" as noops when the
4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * Local is uninitialized.
4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if  ((status == AE_AML_UNINITIALIZED_LOCAL) &&
4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				(walk_state->opcode == AML_STORE_OP) &&
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				(walk_state->operands[0]->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				(walk_state->operands[1]->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				(walk_state->operands[0]->reference.opcode ==
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 walk_state->operands[1]->reference.opcode) &&
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				(walk_state->operands[0]->reference.offset ==
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 walk_state->operands[1]->reference.offset)) {
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				status = AE_OK;
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else {
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					"[%s]: Could not resolve operands, %s\n",
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					acpi_ps_get_opcode_name (walk_state->opcode),
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					acpi_format_exception (status)));
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Always delete the argument objects and clear the operand stack */
4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		acpi_ds_clear_operands (walk_state);
4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * If a result object was returned from above, push it on the
4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * current result stack
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ACPI_SUCCESS (status) &&
4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			walk_state->result_obj) {
4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			status = acpi_ds_result_push (walk_state->result_obj, walk_state);
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		switch (op_type) {
4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case AML_TYPE_CONTROL:    /* Type 1 opcode, IF/ELSE/WHILE/NOOP */
4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* 1 Operand, 0 external_result, 0 internal_result */
4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			status = acpi_ds_exec_end_control_op (walk_state, op);
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* Make sure to properly pop the result stack */
4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (ACPI_SUCCESS (status)) {
4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				status = acpi_ds_result_stack_pop (walk_state);
4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else if (status == AE_CTRL_PENDING) {
4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				status = acpi_ds_result_stack_pop (walk_state);
4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (ACPI_SUCCESS (status)) {
4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					status = AE_CTRL_PENDING;
4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case AML_TYPE_METHOD_CALL:
5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * If the method is referenced from within a package
5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * declaration, it is not a invocation of the method, just
5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * a reference to it.
5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if ((op->asl.parent) &&
5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   ((op->asl.parent->asl.aml_opcode == AML_PACKAGE_OP) ||
5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				(op->asl.parent->asl.aml_opcode == AML_VAR_PACKAGE_OP))) {
51044f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore				ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
51144f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore					"Method Reference in a Package, Op=%p\n", op));
5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				op->common.node = (struct acpi_namespace_node *) op->asl.value.arg->asl.node->object;
5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				acpi_ut_add_reference (op->asl.value.arg->asl.node->object);
5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return_ACPI_STATUS (AE_OK);
5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Method invocation, Op=%p\n", op));
5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains
5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * the method Node pointer
5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* next_op points to the op that holds the method name */
5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			next_op = first_arg;
5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* next_op points to first argument op */
5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			next_op = next_op->common.next;
5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * Get the method's arguments and put them on the operand stack
5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			status = acpi_ds_create_operands (walk_state, next_op);
5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (ACPI_FAILURE (status)) {
5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * Since the operands will be passed to another control method,
5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * we must resolve all local references here (Local variables,
5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * arguments to *this* method, etc.)
5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			status = acpi_ds_resolve_operands (walk_state);
5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (ACPI_FAILURE (status)) {
5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* On error, clear all resolved operands */
5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				acpi_ds_clear_operands (walk_state);
5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * Tell the walk loop to preempt this running method and
5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * execute the new method
5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			status = AE_CTRL_TRANSFER;
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * Return now; we don't want to disturb anything,
5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * especially the operand count!
5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return_ACPI_STATUS (status);
5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case AML_TYPE_CREATE_FIELD:
5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				"Executing create_field Buffer/Index Op=%p\n", op));
5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			status = acpi_ds_load2_end_op (walk_state);
5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (ACPI_FAILURE (status)) {
5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			status = acpi_ds_eval_buffer_field_operands (walk_state, op);
5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case AML_TYPE_CREATE_OBJECT:
5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				"Executing create_object (Buffer/Package) Op=%p\n", op));
5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			switch (op->common.parent->common.aml_opcode) {
5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case AML_NAME_OP:
5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/*
58844f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore				 * Put the Node on the object stack (Contains the ACPI Name
58944f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore				 * of this object)
5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 */
5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				walk_state->operands[0] = (void *) op->common.parent->common.node;
5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				walk_state->num_operands = 1;
5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
59444f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore				status = acpi_ds_create_node (walk_state,
59544f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore						 op->common.parent->common.node,
59644f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore						 op->common.parent);
5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (ACPI_FAILURE (status)) {
5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					break;
5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* Fall through */
6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/*lint -fallthrough */
6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case AML_INT_EVAL_SUBTREE_OP:
6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				status = acpi_ds_eval_data_object_operands (walk_state, op,
60744f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore						 acpi_ns_get_attached_object (op->common.parent->common.node));
6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			default:
6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				status = acpi_ds_eval_data_object_operands (walk_state, op, NULL);
6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
61644f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore			/* Done with result state (Now that operand stack is built) */
6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			status = acpi_ds_result_stack_pop (walk_state);
6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (ACPI_FAILURE (status)) {
6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				goto cleanup;
6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * If a result object was returned from above, push it on the
6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * current result stack
6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
62744f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore			if (walk_state->result_obj) {
6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				status = acpi_ds_result_push (walk_state->result_obj, walk_state);
6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case AML_TYPE_NAMED_FIELD:
6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case AML_TYPE_NAMED_COMPLEX:
6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case AML_TYPE_NAMED_SIMPLE:
6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case AML_TYPE_NAMED_NO_OBJ:
6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			status = acpi_ds_load2_end_op (walk_state);
6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (ACPI_FAILURE (status)) {
6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (op->common.aml_opcode == AML_REGION_OP) {
6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					"Executing op_region Address/Length Op=%p\n", op));
6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				status = acpi_ds_eval_region_operands (walk_state, op);
6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (ACPI_FAILURE (status)) {
6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					break;
6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				status = acpi_ds_result_stack_pop (walk_state);
6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case AML_TYPE_UNDEFINED:
6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
66044f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
66144f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore				"Undefined opcode type Op=%p\n", op));
6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case AML_TYPE_BOGUS:
6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				"Internal opcode=%X type Op=%p\n",
6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				walk_state->opcode, op));
6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		default:
6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				"Unimplemented opcode, class=%X type=%X Opcode=%X Op=%p\n",
6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				op_class, op_type, op->common.aml_opcode, op));
6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			status = AE_NOT_IMPLEMENTED;
6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * ACPI 2.0 support for 64-bit integers: Truncate numeric
6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * result value if we are executing from a 32-bit ACPI table
6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	acpi_ex_truncate_for32bit_table (walk_state->result_obj);
6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Check if we just completed the evaluation of a
6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * conditional predicate
6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((ACPI_SUCCESS (status)) &&
6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		(walk_state->control_state) &&
6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		(walk_state->control_state->common.state ==
6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ACPI_CONTROL_PREDICATE_EXECUTING) &&
6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		(walk_state->control_state->control.predicate_op == op)) {
7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = acpi_ds_get_predicate_value (walk_state, walk_state->result_obj);
7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		walk_state->result_obj = NULL;
7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldscleanup:
7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Invoke exception handler on error */
7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ACPI_FAILURE (status) &&
7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		acpi_gbl_exception_handler &&
7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		!(status & AE_CODE_CONTROL)) {
7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		acpi_ex_exit_interpreter ();
7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = acpi_gbl_exception_handler (status,
7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 walk_state->method_node->name.integer, walk_state->opcode,
7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 walk_state->aml_offset, NULL);
71644f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore		(void) acpi_ex_enter_interpreter ();
7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (walk_state->result_obj) {
7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Break to debugger to display result */
7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
72244f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore		ACPI_DEBUGGER_EXEC (acpi_db_display_result_object (walk_state->result_obj,
72344f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore				 walk_state));
7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Delete the result op if and only if:
7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Parent will not use the result -- such as any
7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * non-nested type2 op in a method (parent will be method)
7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		acpi_ds_delete_result_if_not_used (op, walk_state->result_obj, walk_state);
7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef _UNDER_DEVELOPMENT
7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (walk_state->parser_state.aml == walk_state->parser_state.aml_end) {
7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		acpi_db_method_end (walk_state);
7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Always clear the object stack */
7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	walk_state->num_operands = 0;
7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef ACPI_DISASSEMBLER
7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* On error, display method locals/args */
7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ACPI_FAILURE (status)) {
7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		acpi_dm_dump_method_info (status, walk_state, op);
7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return_ACPI_STATUS (status);
7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
757