xref: /OK3568_Linux_fs/kernel/drivers/acpi/acpica/dswexec.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2*4882a593Smuzhiyun /******************************************************************************
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Module Name: dswexec - Dispatcher method execution callbacks;
5*4882a593Smuzhiyun  *                        dispatch to interpreter.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Copyright (C) 2000 - 2020, Intel Corp.
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  *****************************************************************************/
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include <acpi/acpi.h>
12*4882a593Smuzhiyun #include "accommon.h"
13*4882a593Smuzhiyun #include "acparser.h"
14*4882a593Smuzhiyun #include "amlcode.h"
15*4882a593Smuzhiyun #include "acdispat.h"
16*4882a593Smuzhiyun #include "acinterp.h"
17*4882a593Smuzhiyun #include "acnamesp.h"
18*4882a593Smuzhiyun #include "acdebug.h"
19*4882a593Smuzhiyun #ifdef ACPI_EXEC_APP
20*4882a593Smuzhiyun #include "aecommon.h"
21*4882a593Smuzhiyun #endif
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #define _COMPONENT          ACPI_DISPATCHER
24*4882a593Smuzhiyun ACPI_MODULE_NAME("dswexec")
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun /*
27*4882a593Smuzhiyun  * Dispatch table for opcode classes
28*4882a593Smuzhiyun  */
29*4882a593Smuzhiyun static acpi_execute_op acpi_gbl_op_type_dispatch[] = {
30*4882a593Smuzhiyun 	acpi_ex_opcode_0A_0T_1R,
31*4882a593Smuzhiyun 	acpi_ex_opcode_1A_0T_0R,
32*4882a593Smuzhiyun 	acpi_ex_opcode_1A_0T_1R,
33*4882a593Smuzhiyun 	acpi_ex_opcode_1A_1T_0R,
34*4882a593Smuzhiyun 	acpi_ex_opcode_1A_1T_1R,
35*4882a593Smuzhiyun 	acpi_ex_opcode_2A_0T_0R,
36*4882a593Smuzhiyun 	acpi_ex_opcode_2A_0T_1R,
37*4882a593Smuzhiyun 	acpi_ex_opcode_2A_1T_1R,
38*4882a593Smuzhiyun 	acpi_ex_opcode_2A_2T_1R,
39*4882a593Smuzhiyun 	acpi_ex_opcode_3A_0T_0R,
40*4882a593Smuzhiyun 	acpi_ex_opcode_3A_1T_1R,
41*4882a593Smuzhiyun 	acpi_ex_opcode_6A_0T_1R
42*4882a593Smuzhiyun };
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun /*****************************************************************************
45*4882a593Smuzhiyun  *
46*4882a593Smuzhiyun  * FUNCTION:    acpi_ds_get_predicate_value
47*4882a593Smuzhiyun  *
48*4882a593Smuzhiyun  * PARAMETERS:  walk_state      - Current state of the parse tree walk
49*4882a593Smuzhiyun  *              result_obj      - if non-zero, pop result from result stack
50*4882a593Smuzhiyun  *
51*4882a593Smuzhiyun  * RETURN:      Status
52*4882a593Smuzhiyun  *
53*4882a593Smuzhiyun  * DESCRIPTION: Get the result of a predicate evaluation
54*4882a593Smuzhiyun  *
55*4882a593Smuzhiyun  ****************************************************************************/
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun acpi_status
acpi_ds_get_predicate_value(struct acpi_walk_state * walk_state,union acpi_operand_object * result_obj)58*4882a593Smuzhiyun acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state,
59*4882a593Smuzhiyun 			    union acpi_operand_object *result_obj)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun 	acpi_status status = AE_OK;
62*4882a593Smuzhiyun 	union acpi_operand_object *obj_desc;
63*4882a593Smuzhiyun 	union acpi_operand_object *local_obj_desc = NULL;
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE_PTR(ds_get_predicate_value, walk_state);
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 	walk_state->control_state->common.state = 0;
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	if (result_obj) {
70*4882a593Smuzhiyun 		status = acpi_ds_result_pop(&obj_desc, walk_state);
71*4882a593Smuzhiyun 		if (ACPI_FAILURE(status)) {
72*4882a593Smuzhiyun 			ACPI_EXCEPTION((AE_INFO, status,
73*4882a593Smuzhiyun 					"Could not get result from predicate evaluation"));
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 			return_ACPI_STATUS(status);
76*4882a593Smuzhiyun 		}
77*4882a593Smuzhiyun 	} else {
78*4882a593Smuzhiyun 		status = acpi_ds_create_operand(walk_state, walk_state->op, 0);
79*4882a593Smuzhiyun 		if (ACPI_FAILURE(status)) {
80*4882a593Smuzhiyun 			return_ACPI_STATUS(status);
81*4882a593Smuzhiyun 		}
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 		status =
84*4882a593Smuzhiyun 		    acpi_ex_resolve_to_value(&walk_state->operands[0],
85*4882a593Smuzhiyun 					     walk_state);
86*4882a593Smuzhiyun 		if (ACPI_FAILURE(status)) {
87*4882a593Smuzhiyun 			return_ACPI_STATUS(status);
88*4882a593Smuzhiyun 		}
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 		obj_desc = walk_state->operands[0];
91*4882a593Smuzhiyun 	}
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	if (!obj_desc) {
94*4882a593Smuzhiyun 		ACPI_ERROR((AE_INFO,
95*4882a593Smuzhiyun 			    "No predicate ObjDesc=%p State=%p",
96*4882a593Smuzhiyun 			    obj_desc, walk_state));
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_AML_NO_OPERAND);
99*4882a593Smuzhiyun 	}
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	/*
102*4882a593Smuzhiyun 	 * Result of predicate evaluation must be an Integer
103*4882a593Smuzhiyun 	 * object. Implicitly convert the argument if necessary.
104*4882a593Smuzhiyun 	 */
105*4882a593Smuzhiyun 	status = acpi_ex_convert_to_integer(obj_desc, &local_obj_desc,
106*4882a593Smuzhiyun 					    ACPI_IMPLICIT_CONVERSION);
107*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
108*4882a593Smuzhiyun 		goto cleanup;
109*4882a593Smuzhiyun 	}
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	if (local_obj_desc->common.type != ACPI_TYPE_INTEGER) {
112*4882a593Smuzhiyun 		ACPI_ERROR((AE_INFO,
113*4882a593Smuzhiyun 			    "Bad predicate (not an integer) ObjDesc=%p State=%p Type=0x%X",
114*4882a593Smuzhiyun 			    obj_desc, walk_state, obj_desc->common.type));
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 		status = AE_AML_OPERAND_TYPE;
117*4882a593Smuzhiyun 		goto cleanup;
118*4882a593Smuzhiyun 	}
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	/* Truncate the predicate to 32-bits if necessary */
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	(void)acpi_ex_truncate_for32bit_table(local_obj_desc);
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 	/*
125*4882a593Smuzhiyun 	 * Save the result of the predicate evaluation on
126*4882a593Smuzhiyun 	 * the control stack
127*4882a593Smuzhiyun 	 */
128*4882a593Smuzhiyun 	if (local_obj_desc->integer.value) {
129*4882a593Smuzhiyun 		walk_state->control_state->common.value = TRUE;
130*4882a593Smuzhiyun 	} else {
131*4882a593Smuzhiyun 		/*
132*4882a593Smuzhiyun 		 * Predicate is FALSE, we will just toss the
133*4882a593Smuzhiyun 		 * rest of the package
134*4882a593Smuzhiyun 		 */
135*4882a593Smuzhiyun 		walk_state->control_state->common.value = FALSE;
136*4882a593Smuzhiyun 		status = AE_CTRL_FALSE;
137*4882a593Smuzhiyun 	}
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	/* Predicate can be used for an implicit return value */
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	(void)acpi_ds_do_implicit_return(local_obj_desc, walk_state, TRUE);
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun cleanup:
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
146*4882a593Smuzhiyun 			  "Completed a predicate eval=%X Op=%p\n",
147*4882a593Smuzhiyun 			  walk_state->control_state->common.value,
148*4882a593Smuzhiyun 			  walk_state->op));
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	/* Break to debugger to display result */
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	acpi_db_display_result_object(local_obj_desc, walk_state);
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 	/*
155*4882a593Smuzhiyun 	 * Delete the predicate result object (we know that
156*4882a593Smuzhiyun 	 * we don't need it anymore)
157*4882a593Smuzhiyun 	 */
158*4882a593Smuzhiyun 	if (local_obj_desc != obj_desc) {
159*4882a593Smuzhiyun 		acpi_ut_remove_reference(local_obj_desc);
160*4882a593Smuzhiyun 	}
161*4882a593Smuzhiyun 	acpi_ut_remove_reference(obj_desc);
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	walk_state->control_state->common.state = ACPI_CONTROL_NORMAL;
164*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun /*****************************************************************************
168*4882a593Smuzhiyun  *
169*4882a593Smuzhiyun  * FUNCTION:    acpi_ds_exec_begin_op
170*4882a593Smuzhiyun  *
171*4882a593Smuzhiyun  * PARAMETERS:  walk_state      - Current state of the parse tree walk
172*4882a593Smuzhiyun  *              out_op          - Where to return op if a new one is created
173*4882a593Smuzhiyun  *
174*4882a593Smuzhiyun  * RETURN:      Status
175*4882a593Smuzhiyun  *
176*4882a593Smuzhiyun  * DESCRIPTION: Descending callback used during the execution of control
177*4882a593Smuzhiyun  *              methods. This is where most operators and operands are
178*4882a593Smuzhiyun  *              dispatched to the interpreter.
179*4882a593Smuzhiyun  *
180*4882a593Smuzhiyun  ****************************************************************************/
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun acpi_status
acpi_ds_exec_begin_op(struct acpi_walk_state * walk_state,union acpi_parse_object ** out_op)183*4882a593Smuzhiyun acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
184*4882a593Smuzhiyun 		      union acpi_parse_object **out_op)
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun 	union acpi_parse_object *op;
187*4882a593Smuzhiyun 	acpi_status status = AE_OK;
188*4882a593Smuzhiyun 	u32 opcode_class;
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE_PTR(ds_exec_begin_op, walk_state);
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun 	op = walk_state->op;
193*4882a593Smuzhiyun 	if (!op) {
194*4882a593Smuzhiyun 		status = acpi_ds_load2_begin_op(walk_state, out_op);
195*4882a593Smuzhiyun 		if (ACPI_FAILURE(status)) {
196*4882a593Smuzhiyun 			goto error_exit;
197*4882a593Smuzhiyun 		}
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 		op = *out_op;
200*4882a593Smuzhiyun 		walk_state->op = op;
201*4882a593Smuzhiyun 		walk_state->opcode = op->common.aml_opcode;
202*4882a593Smuzhiyun 		walk_state->op_info =
203*4882a593Smuzhiyun 		    acpi_ps_get_opcode_info(op->common.aml_opcode);
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 		if (acpi_ns_opens_scope(walk_state->op_info->object_type)) {
206*4882a593Smuzhiyun 			ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
207*4882a593Smuzhiyun 					  "(%s) Popping scope for Op %p\n",
208*4882a593Smuzhiyun 					  acpi_ut_get_type_name(walk_state->
209*4882a593Smuzhiyun 								op_info->
210*4882a593Smuzhiyun 								object_type),
211*4882a593Smuzhiyun 					  op));
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 			status = acpi_ds_scope_stack_pop(walk_state);
214*4882a593Smuzhiyun 			if (ACPI_FAILURE(status)) {
215*4882a593Smuzhiyun 				goto error_exit;
216*4882a593Smuzhiyun 			}
217*4882a593Smuzhiyun 		}
218*4882a593Smuzhiyun 	}
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	if (op == walk_state->origin) {
221*4882a593Smuzhiyun 		if (out_op) {
222*4882a593Smuzhiyun 			*out_op = op;
223*4882a593Smuzhiyun 		}
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_OK);
226*4882a593Smuzhiyun 	}
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	/*
229*4882a593Smuzhiyun 	 * If the previous opcode was a conditional, this opcode
230*4882a593Smuzhiyun 	 * must be the beginning of the associated predicate.
231*4882a593Smuzhiyun 	 * Save this knowledge in the current scope descriptor
232*4882a593Smuzhiyun 	 */
233*4882a593Smuzhiyun 	if ((walk_state->control_state) &&
234*4882a593Smuzhiyun 	    (walk_state->control_state->common.state ==
235*4882a593Smuzhiyun 	     ACPI_CONTROL_CONDITIONAL_EXECUTING)) {
236*4882a593Smuzhiyun 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
237*4882a593Smuzhiyun 				  "Exec predicate Op=%p State=%p\n",
238*4882a593Smuzhiyun 				  op, walk_state));
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 		walk_state->control_state->common.state =
241*4882a593Smuzhiyun 		    ACPI_CONTROL_PREDICATE_EXECUTING;
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 		/* Save start of predicate */
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 		walk_state->control_state->control.predicate_op = op;
246*4882a593Smuzhiyun 	}
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	opcode_class = walk_state->op_info->class;
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	/* We want to send namepaths to the load code */
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 	if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
253*4882a593Smuzhiyun 		opcode_class = AML_CLASS_NAMED_OBJECT;
254*4882a593Smuzhiyun 	}
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	/*
257*4882a593Smuzhiyun 	 * Handle the opcode based upon the opcode type
258*4882a593Smuzhiyun 	 */
259*4882a593Smuzhiyun 	switch (opcode_class) {
260*4882a593Smuzhiyun 	case AML_CLASS_CONTROL:
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun 		status = acpi_ds_exec_begin_control_op(walk_state, op);
263*4882a593Smuzhiyun 		break;
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 	case AML_CLASS_NAMED_OBJECT:
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun 		if (walk_state->walk_type & ACPI_WALK_METHOD) {
268*4882a593Smuzhiyun 			/*
269*4882a593Smuzhiyun 			 * Found a named object declaration during method execution;
270*4882a593Smuzhiyun 			 * we must enter this object into the namespace. The created
271*4882a593Smuzhiyun 			 * object is temporary and will be deleted upon completion of
272*4882a593Smuzhiyun 			 * the execution of this method.
273*4882a593Smuzhiyun 			 *
274*4882a593Smuzhiyun 			 * Note 10/2010: Except for the Scope() op. This opcode does
275*4882a593Smuzhiyun 			 * not actually create a new object, it refers to an existing
276*4882a593Smuzhiyun 			 * object. However, for Scope(), we want to indeed open a
277*4882a593Smuzhiyun 			 * new scope.
278*4882a593Smuzhiyun 			 */
279*4882a593Smuzhiyun 			if (op->common.aml_opcode != AML_SCOPE_OP) {
280*4882a593Smuzhiyun 				status =
281*4882a593Smuzhiyun 				    acpi_ds_load2_begin_op(walk_state, NULL);
282*4882a593Smuzhiyun 			} else {
283*4882a593Smuzhiyun 				status =
284*4882a593Smuzhiyun 				    acpi_ds_scope_stack_push(op->named.node,
285*4882a593Smuzhiyun 							     op->named.node->
286*4882a593Smuzhiyun 							     type, walk_state);
287*4882a593Smuzhiyun 				if (ACPI_FAILURE(status)) {
288*4882a593Smuzhiyun 					return_ACPI_STATUS(status);
289*4882a593Smuzhiyun 				}
290*4882a593Smuzhiyun 			}
291*4882a593Smuzhiyun 		}
292*4882a593Smuzhiyun 		break;
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 	case AML_CLASS_EXECUTE:
295*4882a593Smuzhiyun 	case AML_CLASS_CREATE:
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun 		break;
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 	default:
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 		break;
302*4882a593Smuzhiyun 	}
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun 	/* Nothing to do here during method execution */
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun error_exit:
309*4882a593Smuzhiyun 	status = acpi_ds_method_error(status, walk_state);
310*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
311*4882a593Smuzhiyun }
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun /*****************************************************************************
314*4882a593Smuzhiyun  *
315*4882a593Smuzhiyun  * FUNCTION:    acpi_ds_exec_end_op
316*4882a593Smuzhiyun  *
317*4882a593Smuzhiyun  * PARAMETERS:  walk_state      - Current state of the parse tree walk
318*4882a593Smuzhiyun  *
319*4882a593Smuzhiyun  * RETURN:      Status
320*4882a593Smuzhiyun  *
321*4882a593Smuzhiyun  * DESCRIPTION: Ascending callback used during the execution of control
322*4882a593Smuzhiyun  *              methods. The only thing we really need to do here is to
323*4882a593Smuzhiyun  *              notice the beginning of IF, ELSE, and WHILE blocks.
324*4882a593Smuzhiyun  *
325*4882a593Smuzhiyun  ****************************************************************************/
326*4882a593Smuzhiyun 
acpi_ds_exec_end_op(struct acpi_walk_state * walk_state)327*4882a593Smuzhiyun acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
328*4882a593Smuzhiyun {
329*4882a593Smuzhiyun 	union acpi_parse_object *op;
330*4882a593Smuzhiyun 	acpi_status status = AE_OK;
331*4882a593Smuzhiyun 	u32 op_type;
332*4882a593Smuzhiyun 	u32 op_class;
333*4882a593Smuzhiyun 	union acpi_parse_object *next_op;
334*4882a593Smuzhiyun 	union acpi_parse_object *first_arg;
335*4882a593Smuzhiyun #ifdef ACPI_EXEC_APP
336*4882a593Smuzhiyun 	char *namepath;
337*4882a593Smuzhiyun 	union acpi_operand_object *obj_desc;
338*4882a593Smuzhiyun #endif
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE_PTR(ds_exec_end_op, walk_state);
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 	op = walk_state->op;
343*4882a593Smuzhiyun 	op_type = walk_state->op_info->type;
344*4882a593Smuzhiyun 	op_class = walk_state->op_info->class;
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun 	if (op_class == AML_CLASS_UNKNOWN) {
347*4882a593Smuzhiyun 		ACPI_ERROR((AE_INFO, "Unknown opcode 0x%X",
348*4882a593Smuzhiyun 			    op->common.aml_opcode));
349*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
350*4882a593Smuzhiyun 	}
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun 	first_arg = op->common.value.arg;
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun 	/* Init the walk state */
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun 	walk_state->num_operands = 0;
357*4882a593Smuzhiyun 	walk_state->operand_index = 0;
358*4882a593Smuzhiyun 	walk_state->return_desc = NULL;
359*4882a593Smuzhiyun 	walk_state->result_obj = NULL;
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun 	/* Call debugger for single step support (DEBUG build only) */
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun 	status = acpi_db_single_step(walk_state, op, op_class);
364*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
365*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
366*4882a593Smuzhiyun 	}
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun 	/* Decode the Opcode Class */
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun 	switch (op_class) {
371*4882a593Smuzhiyun 	case AML_CLASS_ARGUMENT:	/* Constants, literals, etc. */
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 		if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
374*4882a593Smuzhiyun 			status = acpi_ds_evaluate_name_path(walk_state);
375*4882a593Smuzhiyun 			if (ACPI_FAILURE(status)) {
376*4882a593Smuzhiyun 				goto cleanup;
377*4882a593Smuzhiyun 			}
378*4882a593Smuzhiyun 		}
379*4882a593Smuzhiyun 		break;
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun 	case AML_CLASS_EXECUTE:	/* Most operators with arguments */
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 		/* Build resolved operand stack */
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun 		status = acpi_ds_create_operands(walk_state, first_arg);
386*4882a593Smuzhiyun 		if (ACPI_FAILURE(status)) {
387*4882a593Smuzhiyun 			goto cleanup;
388*4882a593Smuzhiyun 		}
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun 		/*
391*4882a593Smuzhiyun 		 * All opcodes require operand resolution, with the only exceptions
392*4882a593Smuzhiyun 		 * being the object_type and size_of operators.
393*4882a593Smuzhiyun 		 */
394*4882a593Smuzhiyun 		if (!(walk_state->op_info->flags & AML_NO_OPERAND_RESOLVE)) {
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun 			/* Resolve all operands */
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun 			status = acpi_ex_resolve_operands(walk_state->opcode,
399*4882a593Smuzhiyun 							  &(walk_state->
400*4882a593Smuzhiyun 							    operands
401*4882a593Smuzhiyun 							    [walk_state->
402*4882a593Smuzhiyun 							     num_operands - 1]),
403*4882a593Smuzhiyun 							  walk_state);
404*4882a593Smuzhiyun 		}
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun 		if (ACPI_SUCCESS(status)) {
407*4882a593Smuzhiyun 			/*
408*4882a593Smuzhiyun 			 * Dispatch the request to the appropriate interpreter handler
409*4882a593Smuzhiyun 			 * routine. There is one routine per opcode "type" based upon the
410*4882a593Smuzhiyun 			 * number of opcode arguments and return type.
411*4882a593Smuzhiyun 			 */
412*4882a593Smuzhiyun 			status =
413*4882a593Smuzhiyun 			    acpi_gbl_op_type_dispatch[op_type] (walk_state);
414*4882a593Smuzhiyun 		} else {
415*4882a593Smuzhiyun 			/*
416*4882a593Smuzhiyun 			 * Treat constructs of the form "Store(LocalX,LocalX)" as noops when the
417*4882a593Smuzhiyun 			 * Local is uninitialized.
418*4882a593Smuzhiyun 			 */
419*4882a593Smuzhiyun 			if ((status == AE_AML_UNINITIALIZED_LOCAL) &&
420*4882a593Smuzhiyun 			    (walk_state->opcode == AML_STORE_OP) &&
421*4882a593Smuzhiyun 			    (walk_state->operands[0]->common.type ==
422*4882a593Smuzhiyun 			     ACPI_TYPE_LOCAL_REFERENCE)
423*4882a593Smuzhiyun 			    && (walk_state->operands[1]->common.type ==
424*4882a593Smuzhiyun 				ACPI_TYPE_LOCAL_REFERENCE)
425*4882a593Smuzhiyun 			    && (walk_state->operands[0]->reference.class ==
426*4882a593Smuzhiyun 				walk_state->operands[1]->reference.class)
427*4882a593Smuzhiyun 			    && (walk_state->operands[0]->reference.value ==
428*4882a593Smuzhiyun 				walk_state->operands[1]->reference.value)) {
429*4882a593Smuzhiyun 				status = AE_OK;
430*4882a593Smuzhiyun 			} else {
431*4882a593Smuzhiyun 				ACPI_EXCEPTION((AE_INFO, status,
432*4882a593Smuzhiyun 						"While resolving operands for [%s]",
433*4882a593Smuzhiyun 						acpi_ps_get_opcode_name
434*4882a593Smuzhiyun 						(walk_state->opcode)));
435*4882a593Smuzhiyun 			}
436*4882a593Smuzhiyun 		}
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun 		/* Always delete the argument objects and clear the operand stack */
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun 		acpi_ds_clear_operands(walk_state);
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun 		/*
443*4882a593Smuzhiyun 		 * If a result object was returned from above, push it on the
444*4882a593Smuzhiyun 		 * current result stack
445*4882a593Smuzhiyun 		 */
446*4882a593Smuzhiyun 		if (ACPI_SUCCESS(status) && walk_state->result_obj) {
447*4882a593Smuzhiyun 			status =
448*4882a593Smuzhiyun 			    acpi_ds_result_push(walk_state->result_obj,
449*4882a593Smuzhiyun 						walk_state);
450*4882a593Smuzhiyun 		}
451*4882a593Smuzhiyun 		break;
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun 	default:
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun 		switch (op_type) {
456*4882a593Smuzhiyun 		case AML_TYPE_CONTROL:	/* Type 1 opcode, IF/ELSE/WHILE/NOOP */
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun 			/* 1 Operand, 0 external_result, 0 internal_result */
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun 			status = acpi_ds_exec_end_control_op(walk_state, op);
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun 			break;
463*4882a593Smuzhiyun 
464*4882a593Smuzhiyun 		case AML_TYPE_METHOD_CALL:
465*4882a593Smuzhiyun 			/*
466*4882a593Smuzhiyun 			 * If the method is referenced from within a package
467*4882a593Smuzhiyun 			 * declaration, it is not a invocation of the method, just
468*4882a593Smuzhiyun 			 * a reference to it.
469*4882a593Smuzhiyun 			 */
470*4882a593Smuzhiyun 			if ((op->asl.parent) &&
471*4882a593Smuzhiyun 			    ((op->asl.parent->asl.aml_opcode == AML_PACKAGE_OP)
472*4882a593Smuzhiyun 			     || (op->asl.parent->asl.aml_opcode ==
473*4882a593Smuzhiyun 				 AML_VARIABLE_PACKAGE_OP))) {
474*4882a593Smuzhiyun 				ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
475*4882a593Smuzhiyun 						  "Method Reference in a Package, Op=%p\n",
476*4882a593Smuzhiyun 						  op));
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun 				op->common.node = (struct acpi_namespace_node *)
479*4882a593Smuzhiyun 				    op->asl.value.arg->asl.node;
480*4882a593Smuzhiyun 				acpi_ut_add_reference(op->asl.value.arg->asl.
481*4882a593Smuzhiyun 						      node->object);
482*4882a593Smuzhiyun 				return_ACPI_STATUS(AE_OK);
483*4882a593Smuzhiyun 			}
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun 			ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
486*4882a593Smuzhiyun 					  "Method invocation, Op=%p\n", op));
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun 			/*
489*4882a593Smuzhiyun 			 * (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains
490*4882a593Smuzhiyun 			 * the method Node pointer
491*4882a593Smuzhiyun 			 */
492*4882a593Smuzhiyun 			/* next_op points to the op that holds the method name */
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun 			next_op = first_arg;
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun 			/* next_op points to first argument op */
497*4882a593Smuzhiyun 
498*4882a593Smuzhiyun 			next_op = next_op->common.next;
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun 			/*
501*4882a593Smuzhiyun 			 * Get the method's arguments and put them on the operand stack
502*4882a593Smuzhiyun 			 */
503*4882a593Smuzhiyun 			status = acpi_ds_create_operands(walk_state, next_op);
504*4882a593Smuzhiyun 			if (ACPI_FAILURE(status)) {
505*4882a593Smuzhiyun 				break;
506*4882a593Smuzhiyun 			}
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun 			/*
509*4882a593Smuzhiyun 			 * Since the operands will be passed to another control method,
510*4882a593Smuzhiyun 			 * we must resolve all local references here (Local variables,
511*4882a593Smuzhiyun 			 * arguments to *this* method, etc.)
512*4882a593Smuzhiyun 			 */
513*4882a593Smuzhiyun 			status = acpi_ds_resolve_operands(walk_state);
514*4882a593Smuzhiyun 			if (ACPI_FAILURE(status)) {
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun 				/* On error, clear all resolved operands */
517*4882a593Smuzhiyun 
518*4882a593Smuzhiyun 				acpi_ds_clear_operands(walk_state);
519*4882a593Smuzhiyun 				break;
520*4882a593Smuzhiyun 			}
521*4882a593Smuzhiyun 
522*4882a593Smuzhiyun 			/*
523*4882a593Smuzhiyun 			 * Tell the walk loop to preempt this running method and
524*4882a593Smuzhiyun 			 * execute the new method
525*4882a593Smuzhiyun 			 */
526*4882a593Smuzhiyun 			status = AE_CTRL_TRANSFER;
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun 			/*
529*4882a593Smuzhiyun 			 * Return now; we don't want to disturb anything,
530*4882a593Smuzhiyun 			 * especially the operand count!
531*4882a593Smuzhiyun 			 */
532*4882a593Smuzhiyun 			return_ACPI_STATUS(status);
533*4882a593Smuzhiyun 
534*4882a593Smuzhiyun 		case AML_TYPE_CREATE_FIELD:
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun 			ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
537*4882a593Smuzhiyun 					  "Executing CreateField Buffer/Index Op=%p\n",
538*4882a593Smuzhiyun 					  op));
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun 			status = acpi_ds_load2_end_op(walk_state);
541*4882a593Smuzhiyun 			if (ACPI_FAILURE(status)) {
542*4882a593Smuzhiyun 				break;
543*4882a593Smuzhiyun 			}
544*4882a593Smuzhiyun 
545*4882a593Smuzhiyun 			status =
546*4882a593Smuzhiyun 			    acpi_ds_eval_buffer_field_operands(walk_state, op);
547*4882a593Smuzhiyun 			if (ACPI_FAILURE(status)) {
548*4882a593Smuzhiyun 				break;
549*4882a593Smuzhiyun 			}
550*4882a593Smuzhiyun #ifdef ACPI_EXEC_APP
551*4882a593Smuzhiyun 			/*
552*4882a593Smuzhiyun 			 * acpi_exec support for namespace initialization file (initialize
553*4882a593Smuzhiyun 			 * buffer_fields in this code.)
554*4882a593Smuzhiyun 			 */
555*4882a593Smuzhiyun 			namepath =
556*4882a593Smuzhiyun 			    acpi_ns_get_external_pathname(op->common.node);
557*4882a593Smuzhiyun 			status = ae_lookup_init_file_entry(namepath, &obj_desc);
558*4882a593Smuzhiyun 			if (ACPI_SUCCESS(status)) {
559*4882a593Smuzhiyun 				status =
560*4882a593Smuzhiyun 				    acpi_ex_write_data_to_field(obj_desc,
561*4882a593Smuzhiyun 								op->common.
562*4882a593Smuzhiyun 								node->object,
563*4882a593Smuzhiyun 								NULL);
564*4882a593Smuzhiyun 				if ACPI_FAILURE
565*4882a593Smuzhiyun 					(status) {
566*4882a593Smuzhiyun 					ACPI_EXCEPTION((AE_INFO, status,
567*4882a593Smuzhiyun 							"While writing to buffer field"));
568*4882a593Smuzhiyun 					}
569*4882a593Smuzhiyun 			}
570*4882a593Smuzhiyun 			ACPI_FREE(namepath);
571*4882a593Smuzhiyun 			status = AE_OK;
572*4882a593Smuzhiyun #endif
573*4882a593Smuzhiyun 			break;
574*4882a593Smuzhiyun 
575*4882a593Smuzhiyun 		case AML_TYPE_CREATE_OBJECT:
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun 			ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
578*4882a593Smuzhiyun 					  "Executing CreateObject (Buffer/Package) Op=%p Child=%p ParentOpcode=%4.4X\n",
579*4882a593Smuzhiyun 					  op, op->named.value.arg,
580*4882a593Smuzhiyun 					  op->common.parent->common.
581*4882a593Smuzhiyun 					  aml_opcode));
582*4882a593Smuzhiyun 
583*4882a593Smuzhiyun 			switch (op->common.parent->common.aml_opcode) {
584*4882a593Smuzhiyun 			case AML_NAME_OP:
585*4882a593Smuzhiyun 				/*
586*4882a593Smuzhiyun 				 * Put the Node on the object stack (Contains the ACPI Name
587*4882a593Smuzhiyun 				 * of this object)
588*4882a593Smuzhiyun 				 */
589*4882a593Smuzhiyun 				walk_state->operands[0] = (void *)
590*4882a593Smuzhiyun 				    op->common.parent->common.node;
591*4882a593Smuzhiyun 				walk_state->num_operands = 1;
592*4882a593Smuzhiyun 
593*4882a593Smuzhiyun 				status = acpi_ds_create_node(walk_state,
594*4882a593Smuzhiyun 							     op->common.parent->
595*4882a593Smuzhiyun 							     common.node,
596*4882a593Smuzhiyun 							     op->common.parent);
597*4882a593Smuzhiyun 				if (ACPI_FAILURE(status)) {
598*4882a593Smuzhiyun 					break;
599*4882a593Smuzhiyun 				}
600*4882a593Smuzhiyun 
601*4882a593Smuzhiyun 				/* Fall through */
602*4882a593Smuzhiyun 				/*lint -fallthrough */
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun 			case AML_INT_EVAL_SUBTREE_OP:
605*4882a593Smuzhiyun 
606*4882a593Smuzhiyun 				status =
607*4882a593Smuzhiyun 				    acpi_ds_eval_data_object_operands
608*4882a593Smuzhiyun 				    (walk_state, op,
609*4882a593Smuzhiyun 				     acpi_ns_get_attached_object(op->common.
610*4882a593Smuzhiyun 								 parent->common.
611*4882a593Smuzhiyun 								 node));
612*4882a593Smuzhiyun 				break;
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun 			default:
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun 				status =
617*4882a593Smuzhiyun 				    acpi_ds_eval_data_object_operands
618*4882a593Smuzhiyun 				    (walk_state, op, NULL);
619*4882a593Smuzhiyun 				break;
620*4882a593Smuzhiyun 			}
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun 			/*
623*4882a593Smuzhiyun 			 * If a result object was returned from above, push it on the
624*4882a593Smuzhiyun 			 * current result stack
625*4882a593Smuzhiyun 			 */
626*4882a593Smuzhiyun 			if (walk_state->result_obj) {
627*4882a593Smuzhiyun 				status =
628*4882a593Smuzhiyun 				    acpi_ds_result_push(walk_state->result_obj,
629*4882a593Smuzhiyun 							walk_state);
630*4882a593Smuzhiyun 			}
631*4882a593Smuzhiyun 			break;
632*4882a593Smuzhiyun 
633*4882a593Smuzhiyun 		case AML_TYPE_NAMED_FIELD:
634*4882a593Smuzhiyun 		case AML_TYPE_NAMED_COMPLEX:
635*4882a593Smuzhiyun 		case AML_TYPE_NAMED_SIMPLE:
636*4882a593Smuzhiyun 		case AML_TYPE_NAMED_NO_OBJ:
637*4882a593Smuzhiyun 
638*4882a593Smuzhiyun 			status = acpi_ds_load2_end_op(walk_state);
639*4882a593Smuzhiyun 			if (ACPI_FAILURE(status)) {
640*4882a593Smuzhiyun 				break;
641*4882a593Smuzhiyun 			}
642*4882a593Smuzhiyun 
643*4882a593Smuzhiyun 			if (op->common.aml_opcode == AML_REGION_OP) {
644*4882a593Smuzhiyun 				ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
645*4882a593Smuzhiyun 						  "Executing OpRegion Address/Length Op=%p\n",
646*4882a593Smuzhiyun 						  op));
647*4882a593Smuzhiyun 
648*4882a593Smuzhiyun 				status =
649*4882a593Smuzhiyun 				    acpi_ds_eval_region_operands(walk_state,
650*4882a593Smuzhiyun 								 op);
651*4882a593Smuzhiyun 				if (ACPI_FAILURE(status)) {
652*4882a593Smuzhiyun 					break;
653*4882a593Smuzhiyun 				}
654*4882a593Smuzhiyun 			} else if (op->common.aml_opcode == AML_DATA_REGION_OP) {
655*4882a593Smuzhiyun 				ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
656*4882a593Smuzhiyun 						  "Executing DataTableRegion Strings Op=%p\n",
657*4882a593Smuzhiyun 						  op));
658*4882a593Smuzhiyun 
659*4882a593Smuzhiyun 				status =
660*4882a593Smuzhiyun 				    acpi_ds_eval_table_region_operands
661*4882a593Smuzhiyun 				    (walk_state, op);
662*4882a593Smuzhiyun 				if (ACPI_FAILURE(status)) {
663*4882a593Smuzhiyun 					break;
664*4882a593Smuzhiyun 				}
665*4882a593Smuzhiyun 			} else if (op->common.aml_opcode == AML_BANK_FIELD_OP) {
666*4882a593Smuzhiyun 				ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
667*4882a593Smuzhiyun 						  "Executing BankField Op=%p\n",
668*4882a593Smuzhiyun 						  op));
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun 				status =
671*4882a593Smuzhiyun 				    acpi_ds_eval_bank_field_operands(walk_state,
672*4882a593Smuzhiyun 								     op);
673*4882a593Smuzhiyun 				if (ACPI_FAILURE(status)) {
674*4882a593Smuzhiyun 					break;
675*4882a593Smuzhiyun 				}
676*4882a593Smuzhiyun 			}
677*4882a593Smuzhiyun 			break;
678*4882a593Smuzhiyun 
679*4882a593Smuzhiyun 		case AML_TYPE_UNDEFINED:
680*4882a593Smuzhiyun 
681*4882a593Smuzhiyun 			ACPI_ERROR((AE_INFO,
682*4882a593Smuzhiyun 				    "Undefined opcode type Op=%p", op));
683*4882a593Smuzhiyun 			return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
684*4882a593Smuzhiyun 
685*4882a593Smuzhiyun 		case AML_TYPE_BOGUS:
686*4882a593Smuzhiyun 
687*4882a593Smuzhiyun 			ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
688*4882a593Smuzhiyun 					  "Internal opcode=%X type Op=%p\n",
689*4882a593Smuzhiyun 					  walk_state->opcode, op));
690*4882a593Smuzhiyun 			break;
691*4882a593Smuzhiyun 
692*4882a593Smuzhiyun 		default:
693*4882a593Smuzhiyun 
694*4882a593Smuzhiyun 			ACPI_ERROR((AE_INFO,
695*4882a593Smuzhiyun 				    "Unimplemented opcode, class=0x%X "
696*4882a593Smuzhiyun 				    "type=0x%X Opcode=0x%X Op=%p",
697*4882a593Smuzhiyun 				    op_class, op_type, op->common.aml_opcode,
698*4882a593Smuzhiyun 				    op));
699*4882a593Smuzhiyun 
700*4882a593Smuzhiyun 			status = AE_NOT_IMPLEMENTED;
701*4882a593Smuzhiyun 			break;
702*4882a593Smuzhiyun 		}
703*4882a593Smuzhiyun 	}
704*4882a593Smuzhiyun 
705*4882a593Smuzhiyun 	/*
706*4882a593Smuzhiyun 	 * ACPI 2.0 support for 64-bit integers: Truncate numeric
707*4882a593Smuzhiyun 	 * result value if we are executing from a 32-bit ACPI table
708*4882a593Smuzhiyun 	 */
709*4882a593Smuzhiyun 	(void)acpi_ex_truncate_for32bit_table(walk_state->result_obj);
710*4882a593Smuzhiyun 
711*4882a593Smuzhiyun 	/*
712*4882a593Smuzhiyun 	 * Check if we just completed the evaluation of a
713*4882a593Smuzhiyun 	 * conditional predicate
714*4882a593Smuzhiyun 	 */
715*4882a593Smuzhiyun 	if ((ACPI_SUCCESS(status)) &&
716*4882a593Smuzhiyun 	    (walk_state->control_state) &&
717*4882a593Smuzhiyun 	    (walk_state->control_state->common.state ==
718*4882a593Smuzhiyun 	     ACPI_CONTROL_PREDICATE_EXECUTING) &&
719*4882a593Smuzhiyun 	    (walk_state->control_state->control.predicate_op == op)) {
720*4882a593Smuzhiyun 		status =
721*4882a593Smuzhiyun 		    acpi_ds_get_predicate_value(walk_state,
722*4882a593Smuzhiyun 						walk_state->result_obj);
723*4882a593Smuzhiyun 		walk_state->result_obj = NULL;
724*4882a593Smuzhiyun 	}
725*4882a593Smuzhiyun 
726*4882a593Smuzhiyun cleanup:
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun 	if (walk_state->result_obj) {
729*4882a593Smuzhiyun 
730*4882a593Smuzhiyun 		/* Break to debugger to display result */
731*4882a593Smuzhiyun 
732*4882a593Smuzhiyun 		acpi_db_display_result_object(walk_state->result_obj,
733*4882a593Smuzhiyun 					      walk_state);
734*4882a593Smuzhiyun 
735*4882a593Smuzhiyun 		/*
736*4882a593Smuzhiyun 		 * Delete the result op if and only if:
737*4882a593Smuzhiyun 		 * Parent will not use the result -- such as any
738*4882a593Smuzhiyun 		 * non-nested type2 op in a method (parent will be method)
739*4882a593Smuzhiyun 		 */
740*4882a593Smuzhiyun 		acpi_ds_delete_result_if_not_used(op, walk_state->result_obj,
741*4882a593Smuzhiyun 						  walk_state);
742*4882a593Smuzhiyun 	}
743*4882a593Smuzhiyun #ifdef _UNDER_DEVELOPMENT
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun 	if (walk_state->parser_state.aml == walk_state->parser_state.aml_end) {
746*4882a593Smuzhiyun 		acpi_db_method_end(walk_state);
747*4882a593Smuzhiyun 	}
748*4882a593Smuzhiyun #endif
749*4882a593Smuzhiyun 
750*4882a593Smuzhiyun 	/* Invoke exception handler on error */
751*4882a593Smuzhiyun 
752*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
753*4882a593Smuzhiyun 		status = acpi_ds_method_error(status, walk_state);
754*4882a593Smuzhiyun 	}
755*4882a593Smuzhiyun 
756*4882a593Smuzhiyun 	/* Always clear the object stack */
757*4882a593Smuzhiyun 
758*4882a593Smuzhiyun 	walk_state->num_operands = 0;
759*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
760*4882a593Smuzhiyun }
761