1433d6423SLionel Sambuc /******************************************************************************
2433d6423SLionel Sambuc *
3433d6423SLionel Sambuc * Module Name: dswexec - Dispatcher method execution callbacks;
4433d6423SLionel Sambuc * dispatch to interpreter.
5433d6423SLionel Sambuc *
6433d6423SLionel Sambuc *****************************************************************************/
7433d6423SLionel Sambuc
8*29492bb7SDavid van Moolenbroek /*
9*29492bb7SDavid van Moolenbroek * Copyright (C) 2000 - 2014, Intel Corp.
10433d6423SLionel Sambuc * All rights reserved.
11433d6423SLionel Sambuc *
12*29492bb7SDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
13*29492bb7SDavid van Moolenbroek * modification, are permitted provided that the following conditions
14*29492bb7SDavid van Moolenbroek * are met:
15*29492bb7SDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright
16*29492bb7SDavid van Moolenbroek * notice, this list of conditions, and the following disclaimer,
17*29492bb7SDavid van Moolenbroek * without modification.
18*29492bb7SDavid van Moolenbroek * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19*29492bb7SDavid van Moolenbroek * substantially similar to the "NO WARRANTY" disclaimer below
20*29492bb7SDavid van Moolenbroek * ("Disclaimer") and any redistribution must be conditioned upon
21*29492bb7SDavid van Moolenbroek * including a substantially similar Disclaimer requirement for further
22*29492bb7SDavid van Moolenbroek * binary redistribution.
23*29492bb7SDavid van Moolenbroek * 3. Neither the names of the above-listed copyright holders nor the names
24*29492bb7SDavid van Moolenbroek * of any contributors may be used to endorse or promote products derived
25*29492bb7SDavid van Moolenbroek * from this software without specific prior written permission.
26433d6423SLionel Sambuc *
27*29492bb7SDavid van Moolenbroek * Alternatively, this software may be distributed under the terms of the
28*29492bb7SDavid van Moolenbroek * GNU General Public License ("GPL") version 2 as published by the Free
29*29492bb7SDavid van Moolenbroek * Software Foundation.
30433d6423SLionel Sambuc *
31*29492bb7SDavid van Moolenbroek * NO WARRANTY
32*29492bb7SDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33*29492bb7SDavid van Moolenbroek * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34*29492bb7SDavid van Moolenbroek * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35*29492bb7SDavid van Moolenbroek * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36*29492bb7SDavid van Moolenbroek * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37*29492bb7SDavid van Moolenbroek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38*29492bb7SDavid van Moolenbroek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39*29492bb7SDavid van Moolenbroek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40*29492bb7SDavid van Moolenbroek * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41*29492bb7SDavid van Moolenbroek * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42*29492bb7SDavid van Moolenbroek * POSSIBILITY OF SUCH DAMAGES.
43*29492bb7SDavid van Moolenbroek */
44433d6423SLionel Sambuc
45433d6423SLionel Sambuc #include "acpi.h"
46433d6423SLionel Sambuc #include "accommon.h"
47433d6423SLionel Sambuc #include "acparser.h"
48433d6423SLionel Sambuc #include "amlcode.h"
49433d6423SLionel Sambuc #include "acdispat.h"
50433d6423SLionel Sambuc #include "acinterp.h"
51433d6423SLionel Sambuc #include "acnamesp.h"
52433d6423SLionel Sambuc #include "acdebug.h"
53433d6423SLionel Sambuc
54433d6423SLionel Sambuc
55433d6423SLionel Sambuc #define _COMPONENT ACPI_DISPATCHER
56433d6423SLionel Sambuc ACPI_MODULE_NAME ("dswexec")
57433d6423SLionel Sambuc
58433d6423SLionel Sambuc /*
59433d6423SLionel Sambuc * Dispatch table for opcode classes
60433d6423SLionel Sambuc */
61433d6423SLionel Sambuc static ACPI_EXECUTE_OP AcpiGbl_OpTypeDispatch [] =
62433d6423SLionel Sambuc {
63433d6423SLionel Sambuc AcpiExOpcode_0A_0T_1R,
64433d6423SLionel Sambuc AcpiExOpcode_1A_0T_0R,
65433d6423SLionel Sambuc AcpiExOpcode_1A_0T_1R,
66433d6423SLionel Sambuc AcpiExOpcode_1A_1T_0R,
67433d6423SLionel Sambuc AcpiExOpcode_1A_1T_1R,
68433d6423SLionel Sambuc AcpiExOpcode_2A_0T_0R,
69433d6423SLionel Sambuc AcpiExOpcode_2A_0T_1R,
70433d6423SLionel Sambuc AcpiExOpcode_2A_1T_1R,
71433d6423SLionel Sambuc AcpiExOpcode_2A_2T_1R,
72433d6423SLionel Sambuc AcpiExOpcode_3A_0T_0R,
73433d6423SLionel Sambuc AcpiExOpcode_3A_1T_1R,
74433d6423SLionel Sambuc AcpiExOpcode_6A_0T_1R
75433d6423SLionel Sambuc };
76433d6423SLionel Sambuc
77433d6423SLionel Sambuc
78433d6423SLionel Sambuc /*****************************************************************************
79433d6423SLionel Sambuc *
80433d6423SLionel Sambuc * FUNCTION: AcpiDsGetPredicateValue
81433d6423SLionel Sambuc *
82433d6423SLionel Sambuc * PARAMETERS: WalkState - Current state of the parse tree walk
83433d6423SLionel Sambuc * ResultObj - if non-zero, pop result from result stack
84433d6423SLionel Sambuc *
85433d6423SLionel Sambuc * RETURN: Status
86433d6423SLionel Sambuc *
87433d6423SLionel Sambuc * DESCRIPTION: Get the result of a predicate evaluation
88433d6423SLionel Sambuc *
89433d6423SLionel Sambuc ****************************************************************************/
90433d6423SLionel Sambuc
91433d6423SLionel Sambuc ACPI_STATUS
AcpiDsGetPredicateValue(ACPI_WALK_STATE * WalkState,ACPI_OPERAND_OBJECT * ResultObj)92433d6423SLionel Sambuc AcpiDsGetPredicateValue (
93433d6423SLionel Sambuc ACPI_WALK_STATE *WalkState,
94433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *ResultObj)
95433d6423SLionel Sambuc {
96433d6423SLionel Sambuc ACPI_STATUS Status = AE_OK;
97433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *ObjDesc;
98433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *LocalObjDesc = NULL;
99433d6423SLionel Sambuc
100433d6423SLionel Sambuc
101433d6423SLionel Sambuc ACPI_FUNCTION_TRACE_PTR (DsGetPredicateValue, WalkState);
102433d6423SLionel Sambuc
103433d6423SLionel Sambuc
104433d6423SLionel Sambuc WalkState->ControlState->Common.State = 0;
105433d6423SLionel Sambuc
106433d6423SLionel Sambuc if (ResultObj)
107433d6423SLionel Sambuc {
108433d6423SLionel Sambuc Status = AcpiDsResultPop (&ObjDesc, WalkState);
109433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
110433d6423SLionel Sambuc {
111433d6423SLionel Sambuc ACPI_EXCEPTION ((AE_INFO, Status,
112433d6423SLionel Sambuc "Could not get result from predicate evaluation"));
113433d6423SLionel Sambuc
114433d6423SLionel Sambuc return_ACPI_STATUS (Status);
115433d6423SLionel Sambuc }
116433d6423SLionel Sambuc }
117433d6423SLionel Sambuc else
118433d6423SLionel Sambuc {
119433d6423SLionel Sambuc Status = AcpiDsCreateOperand (WalkState, WalkState->Op, 0);
120433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
121433d6423SLionel Sambuc {
122433d6423SLionel Sambuc return_ACPI_STATUS (Status);
123433d6423SLionel Sambuc }
124433d6423SLionel Sambuc
125433d6423SLionel Sambuc Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
126433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
127433d6423SLionel Sambuc {
128433d6423SLionel Sambuc return_ACPI_STATUS (Status);
129433d6423SLionel Sambuc }
130433d6423SLionel Sambuc
131433d6423SLionel Sambuc ObjDesc = WalkState->Operands [0];
132433d6423SLionel Sambuc }
133433d6423SLionel Sambuc
134433d6423SLionel Sambuc if (!ObjDesc)
135433d6423SLionel Sambuc {
136433d6423SLionel Sambuc ACPI_ERROR ((AE_INFO,
137433d6423SLionel Sambuc "No predicate ObjDesc=%p State=%p",
138433d6423SLionel Sambuc ObjDesc, WalkState));
139433d6423SLionel Sambuc
140433d6423SLionel Sambuc return_ACPI_STATUS (AE_AML_NO_OPERAND);
141433d6423SLionel Sambuc }
142433d6423SLionel Sambuc
143433d6423SLionel Sambuc /*
144433d6423SLionel Sambuc * Result of predicate evaluation must be an Integer
145433d6423SLionel Sambuc * object. Implicitly convert the argument if necessary.
146433d6423SLionel Sambuc */
147433d6423SLionel Sambuc Status = AcpiExConvertToInteger (ObjDesc, &LocalObjDesc, 16);
148433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
149433d6423SLionel Sambuc {
150433d6423SLionel Sambuc goto Cleanup;
151433d6423SLionel Sambuc }
152433d6423SLionel Sambuc
153433d6423SLionel Sambuc if (LocalObjDesc->Common.Type != ACPI_TYPE_INTEGER)
154433d6423SLionel Sambuc {
155433d6423SLionel Sambuc ACPI_ERROR ((AE_INFO,
156433d6423SLionel Sambuc "Bad predicate (not an integer) ObjDesc=%p State=%p Type=0x%X",
157433d6423SLionel Sambuc ObjDesc, WalkState, ObjDesc->Common.Type));
158433d6423SLionel Sambuc
159433d6423SLionel Sambuc Status = AE_AML_OPERAND_TYPE;
160433d6423SLionel Sambuc goto Cleanup;
161433d6423SLionel Sambuc }
162433d6423SLionel Sambuc
163433d6423SLionel Sambuc /* Truncate the predicate to 32-bits if necessary */
164433d6423SLionel Sambuc
165*29492bb7SDavid van Moolenbroek (void) AcpiExTruncateFor32bitTable (LocalObjDesc);
166433d6423SLionel Sambuc
167433d6423SLionel Sambuc /*
168433d6423SLionel Sambuc * Save the result of the predicate evaluation on
169433d6423SLionel Sambuc * the control stack
170433d6423SLionel Sambuc */
171433d6423SLionel Sambuc if (LocalObjDesc->Integer.Value)
172433d6423SLionel Sambuc {
173433d6423SLionel Sambuc WalkState->ControlState->Common.Value = TRUE;
174433d6423SLionel Sambuc }
175433d6423SLionel Sambuc else
176433d6423SLionel Sambuc {
177433d6423SLionel Sambuc /*
178433d6423SLionel Sambuc * Predicate is FALSE, we will just toss the
179433d6423SLionel Sambuc * rest of the package
180433d6423SLionel Sambuc */
181433d6423SLionel Sambuc WalkState->ControlState->Common.Value = FALSE;
182433d6423SLionel Sambuc Status = AE_CTRL_FALSE;
183433d6423SLionel Sambuc }
184433d6423SLionel Sambuc
185433d6423SLionel Sambuc /* Predicate can be used for an implicit return value */
186433d6423SLionel Sambuc
187433d6423SLionel Sambuc (void) AcpiDsDoImplicitReturn (LocalObjDesc, WalkState, TRUE);
188433d6423SLionel Sambuc
189433d6423SLionel Sambuc
190433d6423SLionel Sambuc Cleanup:
191433d6423SLionel Sambuc
192433d6423SLionel Sambuc ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n",
193433d6423SLionel Sambuc WalkState->ControlState->Common.Value, WalkState->Op));
194433d6423SLionel Sambuc
195433d6423SLionel Sambuc /* Break to debugger to display result */
196433d6423SLionel Sambuc
197433d6423SLionel Sambuc ACPI_DEBUGGER_EXEC (AcpiDbDisplayResultObject (LocalObjDesc, WalkState));
198433d6423SLionel Sambuc
199433d6423SLionel Sambuc /*
200433d6423SLionel Sambuc * Delete the predicate result object (we know that
201433d6423SLionel Sambuc * we don't need it anymore)
202433d6423SLionel Sambuc */
203433d6423SLionel Sambuc if (LocalObjDesc != ObjDesc)
204433d6423SLionel Sambuc {
205433d6423SLionel Sambuc AcpiUtRemoveReference (LocalObjDesc);
206433d6423SLionel Sambuc }
207433d6423SLionel Sambuc AcpiUtRemoveReference (ObjDesc);
208433d6423SLionel Sambuc
209433d6423SLionel Sambuc WalkState->ControlState->Common.State = ACPI_CONTROL_NORMAL;
210433d6423SLionel Sambuc return_ACPI_STATUS (Status);
211433d6423SLionel Sambuc }
212433d6423SLionel Sambuc
213433d6423SLionel Sambuc
214433d6423SLionel Sambuc /*****************************************************************************
215433d6423SLionel Sambuc *
216433d6423SLionel Sambuc * FUNCTION: AcpiDsExecBeginOp
217433d6423SLionel Sambuc *
218433d6423SLionel Sambuc * PARAMETERS: WalkState - Current state of the parse tree walk
219433d6423SLionel Sambuc * OutOp - Where to return op if a new one is created
220433d6423SLionel Sambuc *
221433d6423SLionel Sambuc * RETURN: Status
222433d6423SLionel Sambuc *
223433d6423SLionel Sambuc * DESCRIPTION: Descending callback used during the execution of control
224433d6423SLionel Sambuc * methods. This is where most operators and operands are
225433d6423SLionel Sambuc * dispatched to the interpreter.
226433d6423SLionel Sambuc *
227433d6423SLionel Sambuc ****************************************************************************/
228433d6423SLionel Sambuc
229433d6423SLionel Sambuc ACPI_STATUS
AcpiDsExecBeginOp(ACPI_WALK_STATE * WalkState,ACPI_PARSE_OBJECT ** OutOp)230433d6423SLionel Sambuc AcpiDsExecBeginOp (
231433d6423SLionel Sambuc ACPI_WALK_STATE *WalkState,
232433d6423SLionel Sambuc ACPI_PARSE_OBJECT **OutOp)
233433d6423SLionel Sambuc {
234433d6423SLionel Sambuc ACPI_PARSE_OBJECT *Op;
235433d6423SLionel Sambuc ACPI_STATUS Status = AE_OK;
236433d6423SLionel Sambuc UINT32 OpcodeClass;
237433d6423SLionel Sambuc
238433d6423SLionel Sambuc
239433d6423SLionel Sambuc ACPI_FUNCTION_TRACE_PTR (DsExecBeginOp, WalkState);
240433d6423SLionel Sambuc
241433d6423SLionel Sambuc
242433d6423SLionel Sambuc Op = WalkState->Op;
243433d6423SLionel Sambuc if (!Op)
244433d6423SLionel Sambuc {
245433d6423SLionel Sambuc Status = AcpiDsLoad2BeginOp (WalkState, OutOp);
246433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
247433d6423SLionel Sambuc {
248433d6423SLionel Sambuc goto ErrorExit;
249433d6423SLionel Sambuc }
250433d6423SLionel Sambuc
251433d6423SLionel Sambuc Op = *OutOp;
252433d6423SLionel Sambuc WalkState->Op = Op;
253433d6423SLionel Sambuc WalkState->Opcode = Op->Common.AmlOpcode;
254433d6423SLionel Sambuc WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
255433d6423SLionel Sambuc
256433d6423SLionel Sambuc if (AcpiNsOpensScope (WalkState->OpInfo->ObjectType))
257433d6423SLionel Sambuc {
258433d6423SLionel Sambuc ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
259433d6423SLionel Sambuc "(%s) Popping scope for Op %p\n",
260433d6423SLionel Sambuc AcpiUtGetTypeName (WalkState->OpInfo->ObjectType), Op));
261433d6423SLionel Sambuc
262433d6423SLionel Sambuc Status = AcpiDsScopeStackPop (WalkState);
263433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
264433d6423SLionel Sambuc {
265433d6423SLionel Sambuc goto ErrorExit;
266433d6423SLionel Sambuc }
267433d6423SLionel Sambuc }
268433d6423SLionel Sambuc }
269433d6423SLionel Sambuc
270433d6423SLionel Sambuc if (Op == WalkState->Origin)
271433d6423SLionel Sambuc {
272433d6423SLionel Sambuc if (OutOp)
273433d6423SLionel Sambuc {
274433d6423SLionel Sambuc *OutOp = Op;
275433d6423SLionel Sambuc }
276433d6423SLionel Sambuc
277433d6423SLionel Sambuc return_ACPI_STATUS (AE_OK);
278433d6423SLionel Sambuc }
279433d6423SLionel Sambuc
280433d6423SLionel Sambuc /*
281433d6423SLionel Sambuc * If the previous opcode was a conditional, this opcode
282433d6423SLionel Sambuc * must be the beginning of the associated predicate.
283433d6423SLionel Sambuc * Save this knowledge in the current scope descriptor
284433d6423SLionel Sambuc */
285433d6423SLionel Sambuc if ((WalkState->ControlState) &&
286433d6423SLionel Sambuc (WalkState->ControlState->Common.State ==
287433d6423SLionel Sambuc ACPI_CONTROL_CONDITIONAL_EXECUTING))
288433d6423SLionel Sambuc {
289433d6423SLionel Sambuc ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Exec predicate Op=%p State=%p\n",
290433d6423SLionel Sambuc Op, WalkState));
291433d6423SLionel Sambuc
292433d6423SLionel Sambuc WalkState->ControlState->Common.State = ACPI_CONTROL_PREDICATE_EXECUTING;
293433d6423SLionel Sambuc
294433d6423SLionel Sambuc /* Save start of predicate */
295433d6423SLionel Sambuc
296433d6423SLionel Sambuc WalkState->ControlState->Control.PredicateOp = Op;
297433d6423SLionel Sambuc }
298433d6423SLionel Sambuc
299433d6423SLionel Sambuc
300433d6423SLionel Sambuc OpcodeClass = WalkState->OpInfo->Class;
301433d6423SLionel Sambuc
302433d6423SLionel Sambuc /* We want to send namepaths to the load code */
303433d6423SLionel Sambuc
304433d6423SLionel Sambuc if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
305433d6423SLionel Sambuc {
306433d6423SLionel Sambuc OpcodeClass = AML_CLASS_NAMED_OBJECT;
307433d6423SLionel Sambuc }
308433d6423SLionel Sambuc
309433d6423SLionel Sambuc /*
310433d6423SLionel Sambuc * Handle the opcode based upon the opcode type
311433d6423SLionel Sambuc */
312433d6423SLionel Sambuc switch (OpcodeClass)
313433d6423SLionel Sambuc {
314433d6423SLionel Sambuc case AML_CLASS_CONTROL:
315433d6423SLionel Sambuc
316433d6423SLionel Sambuc Status = AcpiDsExecBeginControlOp (WalkState, Op);
317433d6423SLionel Sambuc break;
318433d6423SLionel Sambuc
319433d6423SLionel Sambuc case AML_CLASS_NAMED_OBJECT:
320433d6423SLionel Sambuc
321433d6423SLionel Sambuc if (WalkState->WalkType & ACPI_WALK_METHOD)
322433d6423SLionel Sambuc {
323433d6423SLionel Sambuc /*
324433d6423SLionel Sambuc * Found a named object declaration during method execution;
325433d6423SLionel Sambuc * we must enter this object into the namespace. The created
326433d6423SLionel Sambuc * object is temporary and will be deleted upon completion of
327433d6423SLionel Sambuc * the execution of this method.
328*29492bb7SDavid van Moolenbroek *
329*29492bb7SDavid van Moolenbroek * Note 10/2010: Except for the Scope() op. This opcode does
330*29492bb7SDavid van Moolenbroek * not actually create a new object, it refers to an existing
331*29492bb7SDavid van Moolenbroek * object. However, for Scope(), we want to indeed open a
332*29492bb7SDavid van Moolenbroek * new scope.
333433d6423SLionel Sambuc */
334*29492bb7SDavid van Moolenbroek if (Op->Common.AmlOpcode != AML_SCOPE_OP)
335*29492bb7SDavid van Moolenbroek {
336433d6423SLionel Sambuc Status = AcpiDsLoad2BeginOp (WalkState, NULL);
337433d6423SLionel Sambuc }
338*29492bb7SDavid van Moolenbroek else
339*29492bb7SDavid van Moolenbroek {
340*29492bb7SDavid van Moolenbroek Status = AcpiDsScopeStackPush (Op->Named.Node,
341*29492bb7SDavid van Moolenbroek Op->Named.Node->Type, WalkState);
342*29492bb7SDavid van Moolenbroek if (ACPI_FAILURE (Status))
343*29492bb7SDavid van Moolenbroek {
344*29492bb7SDavid van Moolenbroek return_ACPI_STATUS (Status);
345*29492bb7SDavid van Moolenbroek }
346*29492bb7SDavid van Moolenbroek }
347*29492bb7SDavid van Moolenbroek }
348433d6423SLionel Sambuc break;
349433d6423SLionel Sambuc
350433d6423SLionel Sambuc case AML_CLASS_EXECUTE:
351433d6423SLionel Sambuc case AML_CLASS_CREATE:
352433d6423SLionel Sambuc
353433d6423SLionel Sambuc break;
354433d6423SLionel Sambuc
355433d6423SLionel Sambuc default:
356*29492bb7SDavid van Moolenbroek
357433d6423SLionel Sambuc break;
358433d6423SLionel Sambuc }
359433d6423SLionel Sambuc
360433d6423SLionel Sambuc /* Nothing to do here during method execution */
361433d6423SLionel Sambuc
362433d6423SLionel Sambuc return_ACPI_STATUS (Status);
363433d6423SLionel Sambuc
364433d6423SLionel Sambuc
365433d6423SLionel Sambuc ErrorExit:
366433d6423SLionel Sambuc Status = AcpiDsMethodError (Status, WalkState);
367433d6423SLionel Sambuc return_ACPI_STATUS (Status);
368433d6423SLionel Sambuc }
369433d6423SLionel Sambuc
370433d6423SLionel Sambuc
371433d6423SLionel Sambuc /*****************************************************************************
372433d6423SLionel Sambuc *
373433d6423SLionel Sambuc * FUNCTION: AcpiDsExecEndOp
374433d6423SLionel Sambuc *
375433d6423SLionel Sambuc * PARAMETERS: WalkState - Current state of the parse tree walk
376433d6423SLionel Sambuc *
377433d6423SLionel Sambuc * RETURN: Status
378433d6423SLionel Sambuc *
379433d6423SLionel Sambuc * DESCRIPTION: Ascending callback used during the execution of control
380433d6423SLionel Sambuc * methods. The only thing we really need to do here is to
381433d6423SLionel Sambuc * notice the beginning of IF, ELSE, and WHILE blocks.
382433d6423SLionel Sambuc *
383433d6423SLionel Sambuc ****************************************************************************/
384433d6423SLionel Sambuc
385433d6423SLionel Sambuc ACPI_STATUS
AcpiDsExecEndOp(ACPI_WALK_STATE * WalkState)386433d6423SLionel Sambuc AcpiDsExecEndOp (
387433d6423SLionel Sambuc ACPI_WALK_STATE *WalkState)
388433d6423SLionel Sambuc {
389433d6423SLionel Sambuc ACPI_PARSE_OBJECT *Op;
390433d6423SLionel Sambuc ACPI_STATUS Status = AE_OK;
391433d6423SLionel Sambuc UINT32 OpType;
392433d6423SLionel Sambuc UINT32 OpClass;
393433d6423SLionel Sambuc ACPI_PARSE_OBJECT *NextOp;
394433d6423SLionel Sambuc ACPI_PARSE_OBJECT *FirstArg;
395433d6423SLionel Sambuc
396433d6423SLionel Sambuc
397433d6423SLionel Sambuc ACPI_FUNCTION_TRACE_PTR (DsExecEndOp, WalkState);
398433d6423SLionel Sambuc
399433d6423SLionel Sambuc
400433d6423SLionel Sambuc Op = WalkState->Op;
401433d6423SLionel Sambuc OpType = WalkState->OpInfo->Type;
402433d6423SLionel Sambuc OpClass = WalkState->OpInfo->Class;
403433d6423SLionel Sambuc
404433d6423SLionel Sambuc if (OpClass == AML_CLASS_UNKNOWN)
405433d6423SLionel Sambuc {
406433d6423SLionel Sambuc ACPI_ERROR ((AE_INFO, "Unknown opcode 0x%X", Op->Common.AmlOpcode));
407433d6423SLionel Sambuc return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
408433d6423SLionel Sambuc }
409433d6423SLionel Sambuc
410433d6423SLionel Sambuc FirstArg = Op->Common.Value.Arg;
411433d6423SLionel Sambuc
412433d6423SLionel Sambuc /* Init the walk state */
413433d6423SLionel Sambuc
414433d6423SLionel Sambuc WalkState->NumOperands = 0;
415433d6423SLionel Sambuc WalkState->OperandIndex = 0;
416433d6423SLionel Sambuc WalkState->ReturnDesc = NULL;
417433d6423SLionel Sambuc WalkState->ResultObj = NULL;
418433d6423SLionel Sambuc
419433d6423SLionel Sambuc /* Call debugger for single step support (DEBUG build only) */
420433d6423SLionel Sambuc
421433d6423SLionel Sambuc ACPI_DEBUGGER_EXEC (Status = AcpiDbSingleStep (WalkState, Op, OpClass));
422433d6423SLionel Sambuc ACPI_DEBUGGER_EXEC (if (ACPI_FAILURE (Status)) {return_ACPI_STATUS (Status);});
423433d6423SLionel Sambuc
424433d6423SLionel Sambuc /* Decode the Opcode Class */
425433d6423SLionel Sambuc
426433d6423SLionel Sambuc switch (OpClass)
427433d6423SLionel Sambuc {
428433d6423SLionel Sambuc case AML_CLASS_ARGUMENT: /* Constants, literals, etc. */
429433d6423SLionel Sambuc
430433d6423SLionel Sambuc if (WalkState->Opcode == AML_INT_NAMEPATH_OP)
431433d6423SLionel Sambuc {
432433d6423SLionel Sambuc Status = AcpiDsEvaluateNamePath (WalkState);
433433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
434433d6423SLionel Sambuc {
435433d6423SLionel Sambuc goto Cleanup;
436433d6423SLionel Sambuc }
437433d6423SLionel Sambuc }
438433d6423SLionel Sambuc break;
439433d6423SLionel Sambuc
440433d6423SLionel Sambuc case AML_CLASS_EXECUTE: /* Most operators with arguments */
441433d6423SLionel Sambuc
442433d6423SLionel Sambuc /* Build resolved operand stack */
443433d6423SLionel Sambuc
444433d6423SLionel Sambuc Status = AcpiDsCreateOperands (WalkState, FirstArg);
445433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
446433d6423SLionel Sambuc {
447433d6423SLionel Sambuc goto Cleanup;
448433d6423SLionel Sambuc }
449433d6423SLionel Sambuc
450433d6423SLionel Sambuc /*
451433d6423SLionel Sambuc * All opcodes require operand resolution, with the only exceptions
452433d6423SLionel Sambuc * being the ObjectType and SizeOf operators.
453433d6423SLionel Sambuc */
454433d6423SLionel Sambuc if (!(WalkState->OpInfo->Flags & AML_NO_OPERAND_RESOLVE))
455433d6423SLionel Sambuc {
456433d6423SLionel Sambuc /* Resolve all operands */
457433d6423SLionel Sambuc
458433d6423SLionel Sambuc Status = AcpiExResolveOperands (WalkState->Opcode,
459433d6423SLionel Sambuc &(WalkState->Operands [WalkState->NumOperands -1]),
460433d6423SLionel Sambuc WalkState);
461433d6423SLionel Sambuc }
462433d6423SLionel Sambuc
463433d6423SLionel Sambuc if (ACPI_SUCCESS (Status))
464433d6423SLionel Sambuc {
465433d6423SLionel Sambuc /*
466433d6423SLionel Sambuc * Dispatch the request to the appropriate interpreter handler
467433d6423SLionel Sambuc * routine. There is one routine per opcode "type" based upon the
468433d6423SLionel Sambuc * number of opcode arguments and return type.
469433d6423SLionel Sambuc */
470433d6423SLionel Sambuc Status = AcpiGbl_OpTypeDispatch[OpType] (WalkState);
471433d6423SLionel Sambuc }
472433d6423SLionel Sambuc else
473433d6423SLionel Sambuc {
474433d6423SLionel Sambuc /*
475433d6423SLionel Sambuc * Treat constructs of the form "Store(LocalX,LocalX)" as noops when the
476433d6423SLionel Sambuc * Local is uninitialized.
477433d6423SLionel Sambuc */
478433d6423SLionel Sambuc if ((Status == AE_AML_UNINITIALIZED_LOCAL) &&
479433d6423SLionel Sambuc (WalkState->Opcode == AML_STORE_OP) &&
480433d6423SLionel Sambuc (WalkState->Operands[0]->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
481433d6423SLionel Sambuc (WalkState->Operands[1]->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
482433d6423SLionel Sambuc (WalkState->Operands[0]->Reference.Class ==
483433d6423SLionel Sambuc WalkState->Operands[1]->Reference.Class) &&
484433d6423SLionel Sambuc (WalkState->Operands[0]->Reference.Value ==
485433d6423SLionel Sambuc WalkState->Operands[1]->Reference.Value))
486433d6423SLionel Sambuc {
487433d6423SLionel Sambuc Status = AE_OK;
488433d6423SLionel Sambuc }
489433d6423SLionel Sambuc else
490433d6423SLionel Sambuc {
491433d6423SLionel Sambuc ACPI_EXCEPTION ((AE_INFO, Status,
492433d6423SLionel Sambuc "While resolving operands for [%s]",
493433d6423SLionel Sambuc AcpiPsGetOpcodeName (WalkState->Opcode)));
494433d6423SLionel Sambuc }
495433d6423SLionel Sambuc }
496433d6423SLionel Sambuc
497433d6423SLionel Sambuc /* Always delete the argument objects and clear the operand stack */
498433d6423SLionel Sambuc
499433d6423SLionel Sambuc AcpiDsClearOperands (WalkState);
500433d6423SLionel Sambuc
501433d6423SLionel Sambuc /*
502433d6423SLionel Sambuc * If a result object was returned from above, push it on the
503433d6423SLionel Sambuc * current result stack
504433d6423SLionel Sambuc */
505433d6423SLionel Sambuc if (ACPI_SUCCESS (Status) &&
506433d6423SLionel Sambuc WalkState->ResultObj)
507433d6423SLionel Sambuc {
508433d6423SLionel Sambuc Status = AcpiDsResultPush (WalkState->ResultObj, WalkState);
509433d6423SLionel Sambuc }
510433d6423SLionel Sambuc break;
511433d6423SLionel Sambuc
512433d6423SLionel Sambuc default:
513433d6423SLionel Sambuc
514433d6423SLionel Sambuc switch (OpType)
515433d6423SLionel Sambuc {
516433d6423SLionel Sambuc case AML_TYPE_CONTROL: /* Type 1 opcode, IF/ELSE/WHILE/NOOP */
517433d6423SLionel Sambuc
518433d6423SLionel Sambuc /* 1 Operand, 0 ExternalResult, 0 InternalResult */
519433d6423SLionel Sambuc
520433d6423SLionel Sambuc Status = AcpiDsExecEndControlOp (WalkState, Op);
521433d6423SLionel Sambuc
522433d6423SLionel Sambuc break;
523433d6423SLionel Sambuc
524433d6423SLionel Sambuc case AML_TYPE_METHOD_CALL:
525433d6423SLionel Sambuc /*
526433d6423SLionel Sambuc * If the method is referenced from within a package
527433d6423SLionel Sambuc * declaration, it is not a invocation of the method, just
528433d6423SLionel Sambuc * a reference to it.
529433d6423SLionel Sambuc */
530433d6423SLionel Sambuc if ((Op->Asl.Parent) &&
531433d6423SLionel Sambuc ((Op->Asl.Parent->Asl.AmlOpcode == AML_PACKAGE_OP) ||
532433d6423SLionel Sambuc (Op->Asl.Parent->Asl.AmlOpcode == AML_VAR_PACKAGE_OP)))
533433d6423SLionel Sambuc {
534433d6423SLionel Sambuc ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
535433d6423SLionel Sambuc "Method Reference in a Package, Op=%p\n", Op));
536433d6423SLionel Sambuc
537433d6423SLionel Sambuc Op->Common.Node = (ACPI_NAMESPACE_NODE *) Op->Asl.Value.Arg->Asl.Node;
538433d6423SLionel Sambuc AcpiUtAddReference (Op->Asl.Value.Arg->Asl.Node->Object);
539433d6423SLionel Sambuc return_ACPI_STATUS (AE_OK);
540433d6423SLionel Sambuc }
541433d6423SLionel Sambuc
542*29492bb7SDavid van Moolenbroek ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
543*29492bb7SDavid van Moolenbroek "Method invocation, Op=%p\n", Op));
544433d6423SLionel Sambuc
545433d6423SLionel Sambuc /*
546433d6423SLionel Sambuc * (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains
547433d6423SLionel Sambuc * the method Node pointer
548433d6423SLionel Sambuc */
549433d6423SLionel Sambuc /* NextOp points to the op that holds the method name */
550433d6423SLionel Sambuc
551433d6423SLionel Sambuc NextOp = FirstArg;
552433d6423SLionel Sambuc
553433d6423SLionel Sambuc /* NextOp points to first argument op */
554433d6423SLionel Sambuc
555433d6423SLionel Sambuc NextOp = NextOp->Common.Next;
556433d6423SLionel Sambuc
557433d6423SLionel Sambuc /*
558433d6423SLionel Sambuc * Get the method's arguments and put them on the operand stack
559433d6423SLionel Sambuc */
560433d6423SLionel Sambuc Status = AcpiDsCreateOperands (WalkState, NextOp);
561433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
562433d6423SLionel Sambuc {
563433d6423SLionel Sambuc break;
564433d6423SLionel Sambuc }
565433d6423SLionel Sambuc
566433d6423SLionel Sambuc /*
567433d6423SLionel Sambuc * Since the operands will be passed to another control method,
568433d6423SLionel Sambuc * we must resolve all local references here (Local variables,
569433d6423SLionel Sambuc * arguments to *this* method, etc.)
570433d6423SLionel Sambuc */
571433d6423SLionel Sambuc Status = AcpiDsResolveOperands (WalkState);
572433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
573433d6423SLionel Sambuc {
574433d6423SLionel Sambuc /* On error, clear all resolved operands */
575433d6423SLionel Sambuc
576433d6423SLionel Sambuc AcpiDsClearOperands (WalkState);
577433d6423SLionel Sambuc break;
578433d6423SLionel Sambuc }
579433d6423SLionel Sambuc
580433d6423SLionel Sambuc /*
581433d6423SLionel Sambuc * Tell the walk loop to preempt this running method and
582433d6423SLionel Sambuc * execute the new method
583433d6423SLionel Sambuc */
584433d6423SLionel Sambuc Status = AE_CTRL_TRANSFER;
585433d6423SLionel Sambuc
586433d6423SLionel Sambuc /*
587433d6423SLionel Sambuc * Return now; we don't want to disturb anything,
588433d6423SLionel Sambuc * especially the operand count!
589433d6423SLionel Sambuc */
590433d6423SLionel Sambuc return_ACPI_STATUS (Status);
591433d6423SLionel Sambuc
592433d6423SLionel Sambuc case AML_TYPE_CREATE_FIELD:
593433d6423SLionel Sambuc
594433d6423SLionel Sambuc ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
595433d6423SLionel Sambuc "Executing CreateField Buffer/Index Op=%p\n", Op));
596433d6423SLionel Sambuc
597433d6423SLionel Sambuc Status = AcpiDsLoad2EndOp (WalkState);
598433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
599433d6423SLionel Sambuc {
600433d6423SLionel Sambuc break;
601433d6423SLionel Sambuc }
602433d6423SLionel Sambuc
603433d6423SLionel Sambuc Status = AcpiDsEvalBufferFieldOperands (WalkState, Op);
604433d6423SLionel Sambuc break;
605433d6423SLionel Sambuc
606433d6423SLionel Sambuc
607433d6423SLionel Sambuc case AML_TYPE_CREATE_OBJECT:
608433d6423SLionel Sambuc
609433d6423SLionel Sambuc ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
610433d6423SLionel Sambuc "Executing CreateObject (Buffer/Package) Op=%p\n", Op));
611433d6423SLionel Sambuc
612433d6423SLionel Sambuc switch (Op->Common.Parent->Common.AmlOpcode)
613433d6423SLionel Sambuc {
614433d6423SLionel Sambuc case AML_NAME_OP:
615433d6423SLionel Sambuc /*
616433d6423SLionel Sambuc * Put the Node on the object stack (Contains the ACPI Name
617433d6423SLionel Sambuc * of this object)
618433d6423SLionel Sambuc */
619433d6423SLionel Sambuc WalkState->Operands[0] = (void *) Op->Common.Parent->Common.Node;
620433d6423SLionel Sambuc WalkState->NumOperands = 1;
621433d6423SLionel Sambuc
622433d6423SLionel Sambuc Status = AcpiDsCreateNode (WalkState,
623433d6423SLionel Sambuc Op->Common.Parent->Common.Node,
624433d6423SLionel Sambuc Op->Common.Parent);
625433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
626433d6423SLionel Sambuc {
627433d6423SLionel Sambuc break;
628433d6423SLionel Sambuc }
629433d6423SLionel Sambuc
630433d6423SLionel Sambuc /* Fall through */
631433d6423SLionel Sambuc /*lint -fallthrough */
632433d6423SLionel Sambuc
633433d6423SLionel Sambuc case AML_INT_EVAL_SUBTREE_OP:
634433d6423SLionel Sambuc
635433d6423SLionel Sambuc Status = AcpiDsEvalDataObjectOperands (WalkState, Op,
636433d6423SLionel Sambuc AcpiNsGetAttachedObject (Op->Common.Parent->Common.Node));
637433d6423SLionel Sambuc break;
638433d6423SLionel Sambuc
639433d6423SLionel Sambuc default:
640433d6423SLionel Sambuc
641433d6423SLionel Sambuc Status = AcpiDsEvalDataObjectOperands (WalkState, Op, NULL);
642433d6423SLionel Sambuc break;
643433d6423SLionel Sambuc }
644433d6423SLionel Sambuc
645433d6423SLionel Sambuc /*
646433d6423SLionel Sambuc * If a result object was returned from above, push it on the
647433d6423SLionel Sambuc * current result stack
648433d6423SLionel Sambuc */
649433d6423SLionel Sambuc if (WalkState->ResultObj)
650433d6423SLionel Sambuc {
651433d6423SLionel Sambuc Status = AcpiDsResultPush (WalkState->ResultObj, WalkState);
652433d6423SLionel Sambuc }
653433d6423SLionel Sambuc break;
654433d6423SLionel Sambuc
655433d6423SLionel Sambuc case AML_TYPE_NAMED_FIELD:
656433d6423SLionel Sambuc case AML_TYPE_NAMED_COMPLEX:
657433d6423SLionel Sambuc case AML_TYPE_NAMED_SIMPLE:
658433d6423SLionel Sambuc case AML_TYPE_NAMED_NO_OBJ:
659433d6423SLionel Sambuc
660433d6423SLionel Sambuc Status = AcpiDsLoad2EndOp (WalkState);
661433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
662433d6423SLionel Sambuc {
663433d6423SLionel Sambuc break;
664433d6423SLionel Sambuc }
665433d6423SLionel Sambuc
666433d6423SLionel Sambuc if (Op->Common.AmlOpcode == AML_REGION_OP)
667433d6423SLionel Sambuc {
668433d6423SLionel Sambuc ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
669433d6423SLionel Sambuc "Executing OpRegion Address/Length Op=%p\n", Op));
670433d6423SLionel Sambuc
671433d6423SLionel Sambuc Status = AcpiDsEvalRegionOperands (WalkState, Op);
672433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
673433d6423SLionel Sambuc {
674433d6423SLionel Sambuc break;
675433d6423SLionel Sambuc }
676433d6423SLionel Sambuc }
677433d6423SLionel Sambuc else if (Op->Common.AmlOpcode == AML_DATA_REGION_OP)
678433d6423SLionel Sambuc {
679433d6423SLionel Sambuc ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
680433d6423SLionel Sambuc "Executing DataTableRegion Strings Op=%p\n", Op));
681433d6423SLionel Sambuc
682433d6423SLionel Sambuc Status = AcpiDsEvalTableRegionOperands (WalkState, Op);
683433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
684433d6423SLionel Sambuc {
685433d6423SLionel Sambuc break;
686433d6423SLionel Sambuc }
687433d6423SLionel Sambuc }
688433d6423SLionel Sambuc else if (Op->Common.AmlOpcode == AML_BANK_FIELD_OP)
689433d6423SLionel Sambuc {
690433d6423SLionel Sambuc ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
691433d6423SLionel Sambuc "Executing BankField Op=%p\n", Op));
692433d6423SLionel Sambuc
693433d6423SLionel Sambuc Status = AcpiDsEvalBankFieldOperands (WalkState, Op);
694433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
695433d6423SLionel Sambuc {
696433d6423SLionel Sambuc break;
697433d6423SLionel Sambuc }
698433d6423SLionel Sambuc }
699433d6423SLionel Sambuc break;
700433d6423SLionel Sambuc
701433d6423SLionel Sambuc case AML_TYPE_UNDEFINED:
702433d6423SLionel Sambuc
703433d6423SLionel Sambuc ACPI_ERROR ((AE_INFO,
704433d6423SLionel Sambuc "Undefined opcode type Op=%p", Op));
705433d6423SLionel Sambuc return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
706433d6423SLionel Sambuc
707433d6423SLionel Sambuc case AML_TYPE_BOGUS:
708433d6423SLionel Sambuc
709433d6423SLionel Sambuc ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
710433d6423SLionel Sambuc "Internal opcode=%X type Op=%p\n",
711433d6423SLionel Sambuc WalkState->Opcode, Op));
712433d6423SLionel Sambuc break;
713433d6423SLionel Sambuc
714433d6423SLionel Sambuc default:
715433d6423SLionel Sambuc
716433d6423SLionel Sambuc ACPI_ERROR ((AE_INFO,
717*29492bb7SDavid van Moolenbroek "Unimplemented opcode, class=0x%X type=0x%X Opcode=0x%X Op=%p",
718433d6423SLionel Sambuc OpClass, OpType, Op->Common.AmlOpcode, Op));
719433d6423SLionel Sambuc
720433d6423SLionel Sambuc Status = AE_NOT_IMPLEMENTED;
721433d6423SLionel Sambuc break;
722433d6423SLionel Sambuc }
723433d6423SLionel Sambuc }
724433d6423SLionel Sambuc
725433d6423SLionel Sambuc /*
726433d6423SLionel Sambuc * ACPI 2.0 support for 64-bit integers: Truncate numeric
727433d6423SLionel Sambuc * result value if we are executing from a 32-bit ACPI table
728433d6423SLionel Sambuc */
729*29492bb7SDavid van Moolenbroek (void) AcpiExTruncateFor32bitTable (WalkState->ResultObj);
730433d6423SLionel Sambuc
731433d6423SLionel Sambuc /*
732433d6423SLionel Sambuc * Check if we just completed the evaluation of a
733433d6423SLionel Sambuc * conditional predicate
734433d6423SLionel Sambuc */
735433d6423SLionel Sambuc if ((ACPI_SUCCESS (Status)) &&
736433d6423SLionel Sambuc (WalkState->ControlState) &&
737433d6423SLionel Sambuc (WalkState->ControlState->Common.State ==
738433d6423SLionel Sambuc ACPI_CONTROL_PREDICATE_EXECUTING) &&
739433d6423SLionel Sambuc (WalkState->ControlState->Control.PredicateOp == Op))
740433d6423SLionel Sambuc {
741433d6423SLionel Sambuc Status = AcpiDsGetPredicateValue (WalkState, WalkState->ResultObj);
742433d6423SLionel Sambuc WalkState->ResultObj = NULL;
743433d6423SLionel Sambuc }
744433d6423SLionel Sambuc
745433d6423SLionel Sambuc
746433d6423SLionel Sambuc Cleanup:
747433d6423SLionel Sambuc
748433d6423SLionel Sambuc if (WalkState->ResultObj)
749433d6423SLionel Sambuc {
750433d6423SLionel Sambuc /* Break to debugger to display result */
751433d6423SLionel Sambuc
752433d6423SLionel Sambuc ACPI_DEBUGGER_EXEC (AcpiDbDisplayResultObject (WalkState->ResultObj,
753433d6423SLionel Sambuc WalkState));
754433d6423SLionel Sambuc
755433d6423SLionel Sambuc /*
756433d6423SLionel Sambuc * Delete the result op if and only if:
757433d6423SLionel Sambuc * Parent will not use the result -- such as any
758433d6423SLionel Sambuc * non-nested type2 op in a method (parent will be method)
759433d6423SLionel Sambuc */
760433d6423SLionel Sambuc AcpiDsDeleteResultIfNotUsed (Op, WalkState->ResultObj, WalkState);
761433d6423SLionel Sambuc }
762433d6423SLionel Sambuc
763433d6423SLionel Sambuc #ifdef _UNDER_DEVELOPMENT
764433d6423SLionel Sambuc
765433d6423SLionel Sambuc if (WalkState->ParserState.Aml == WalkState->ParserState.AmlEnd)
766433d6423SLionel Sambuc {
767433d6423SLionel Sambuc AcpiDbMethodEnd (WalkState);
768433d6423SLionel Sambuc }
769433d6423SLionel Sambuc #endif
770433d6423SLionel Sambuc
771433d6423SLionel Sambuc /* Invoke exception handler on error */
772433d6423SLionel Sambuc
773433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
774433d6423SLionel Sambuc {
775433d6423SLionel Sambuc Status = AcpiDsMethodError (Status, WalkState);
776433d6423SLionel Sambuc }
777433d6423SLionel Sambuc
778433d6423SLionel Sambuc /* Always clear the object stack */
779433d6423SLionel Sambuc
780433d6423SLionel Sambuc WalkState->NumOperands = 0;
781433d6423SLionel Sambuc return_ACPI_STATUS (Status);
782433d6423SLionel Sambuc }
783