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