1*29492bb7SDavid van Moolenbroek /******************************************************************************
2*29492bb7SDavid van Moolenbroek *
3*29492bb7SDavid van Moolenbroek * Module Name: dscontrol - Support for execution control opcodes -
4*29492bb7SDavid van Moolenbroek * if/else/while/return
5*29492bb7SDavid van Moolenbroek *
6*29492bb7SDavid van Moolenbroek *****************************************************************************/
7*29492bb7SDavid van Moolenbroek
8*29492bb7SDavid van Moolenbroek /*
9*29492bb7SDavid van Moolenbroek * Copyright (C) 2000 - 2014, Intel Corp.
10*29492bb7SDavid van Moolenbroek * All rights reserved.
11*29492bb7SDavid van Moolenbroek *
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.
26*29492bb7SDavid van Moolenbroek *
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.
30*29492bb7SDavid van Moolenbroek *
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 */
44*29492bb7SDavid van Moolenbroek
45*29492bb7SDavid van Moolenbroek #include "acpi.h"
46*29492bb7SDavid van Moolenbroek #include "accommon.h"
47*29492bb7SDavid van Moolenbroek #include "amlcode.h"
48*29492bb7SDavid van Moolenbroek #include "acdispat.h"
49*29492bb7SDavid van Moolenbroek #include "acinterp.h"
50*29492bb7SDavid van Moolenbroek
51*29492bb7SDavid van Moolenbroek #define _COMPONENT ACPI_DISPATCHER
52*29492bb7SDavid van Moolenbroek ACPI_MODULE_NAME ("dscontrol")
53*29492bb7SDavid van Moolenbroek
54*29492bb7SDavid van Moolenbroek
55*29492bb7SDavid van Moolenbroek /*******************************************************************************
56*29492bb7SDavid van Moolenbroek *
57*29492bb7SDavid van Moolenbroek * FUNCTION: AcpiDsExecBeginControlOp
58*29492bb7SDavid van Moolenbroek *
59*29492bb7SDavid van Moolenbroek * PARAMETERS: WalkList - The list that owns the walk stack
60*29492bb7SDavid van Moolenbroek * Op - The control Op
61*29492bb7SDavid van Moolenbroek *
62*29492bb7SDavid van Moolenbroek * RETURN: Status
63*29492bb7SDavid van Moolenbroek *
64*29492bb7SDavid van Moolenbroek * DESCRIPTION: Handles all control ops encountered during control method
65*29492bb7SDavid van Moolenbroek * execution.
66*29492bb7SDavid van Moolenbroek *
67*29492bb7SDavid van Moolenbroek ******************************************************************************/
68*29492bb7SDavid van Moolenbroek
69*29492bb7SDavid van Moolenbroek ACPI_STATUS
AcpiDsExecBeginControlOp(ACPI_WALK_STATE * WalkState,ACPI_PARSE_OBJECT * Op)70*29492bb7SDavid van Moolenbroek AcpiDsExecBeginControlOp (
71*29492bb7SDavid van Moolenbroek ACPI_WALK_STATE *WalkState,
72*29492bb7SDavid van Moolenbroek ACPI_PARSE_OBJECT *Op)
73*29492bb7SDavid van Moolenbroek {
74*29492bb7SDavid van Moolenbroek ACPI_STATUS Status = AE_OK;
75*29492bb7SDavid van Moolenbroek ACPI_GENERIC_STATE *ControlState;
76*29492bb7SDavid van Moolenbroek
77*29492bb7SDavid van Moolenbroek
78*29492bb7SDavid van Moolenbroek ACPI_FUNCTION_NAME (DsExecBeginControlOp);
79*29492bb7SDavid van Moolenbroek
80*29492bb7SDavid van Moolenbroek
81*29492bb7SDavid van Moolenbroek ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n",
82*29492bb7SDavid van Moolenbroek Op, Op->Common.AmlOpcode, WalkState));
83*29492bb7SDavid van Moolenbroek
84*29492bb7SDavid van Moolenbroek switch (Op->Common.AmlOpcode)
85*29492bb7SDavid van Moolenbroek {
86*29492bb7SDavid van Moolenbroek case AML_WHILE_OP:
87*29492bb7SDavid van Moolenbroek /*
88*29492bb7SDavid van Moolenbroek * If this is an additional iteration of a while loop, continue.
89*29492bb7SDavid van Moolenbroek * There is no need to allocate a new control state.
90*29492bb7SDavid van Moolenbroek */
91*29492bb7SDavid van Moolenbroek if (WalkState->ControlState)
92*29492bb7SDavid van Moolenbroek {
93*29492bb7SDavid van Moolenbroek if (WalkState->ControlState->Control.AmlPredicateStart ==
94*29492bb7SDavid van Moolenbroek (WalkState->ParserState.Aml - 1))
95*29492bb7SDavid van Moolenbroek {
96*29492bb7SDavid van Moolenbroek /* Reset the state to start-of-loop */
97*29492bb7SDavid van Moolenbroek
98*29492bb7SDavid van Moolenbroek WalkState->ControlState->Common.State =
99*29492bb7SDavid van Moolenbroek ACPI_CONTROL_CONDITIONAL_EXECUTING;
100*29492bb7SDavid van Moolenbroek break;
101*29492bb7SDavid van Moolenbroek }
102*29492bb7SDavid van Moolenbroek }
103*29492bb7SDavid van Moolenbroek
104*29492bb7SDavid van Moolenbroek /*lint -fallthrough */
105*29492bb7SDavid van Moolenbroek
106*29492bb7SDavid van Moolenbroek case AML_IF_OP:
107*29492bb7SDavid van Moolenbroek /*
108*29492bb7SDavid van Moolenbroek * IF/WHILE: Create a new control state to manage these
109*29492bb7SDavid van Moolenbroek * constructs. We need to manage these as a stack, in order
110*29492bb7SDavid van Moolenbroek * to handle nesting.
111*29492bb7SDavid van Moolenbroek */
112*29492bb7SDavid van Moolenbroek ControlState = AcpiUtCreateControlState ();
113*29492bb7SDavid van Moolenbroek if (!ControlState)
114*29492bb7SDavid van Moolenbroek {
115*29492bb7SDavid van Moolenbroek Status = AE_NO_MEMORY;
116*29492bb7SDavid van Moolenbroek break;
117*29492bb7SDavid van Moolenbroek }
118*29492bb7SDavid van Moolenbroek /*
119*29492bb7SDavid van Moolenbroek * Save a pointer to the predicate for multiple executions
120*29492bb7SDavid van Moolenbroek * of a loop
121*29492bb7SDavid van Moolenbroek */
122*29492bb7SDavid van Moolenbroek ControlState->Control.AmlPredicateStart = WalkState->ParserState.Aml - 1;
123*29492bb7SDavid van Moolenbroek ControlState->Control.PackageEnd = WalkState->ParserState.PkgEnd;
124*29492bb7SDavid van Moolenbroek ControlState->Control.Opcode = Op->Common.AmlOpcode;
125*29492bb7SDavid van Moolenbroek
126*29492bb7SDavid van Moolenbroek
127*29492bb7SDavid van Moolenbroek /* Push the control state on this walk's control stack */
128*29492bb7SDavid van Moolenbroek
129*29492bb7SDavid van Moolenbroek AcpiUtPushGenericState (&WalkState->ControlState, ControlState);
130*29492bb7SDavid van Moolenbroek break;
131*29492bb7SDavid van Moolenbroek
132*29492bb7SDavid van Moolenbroek case AML_ELSE_OP:
133*29492bb7SDavid van Moolenbroek
134*29492bb7SDavid van Moolenbroek /* Predicate is in the state object */
135*29492bb7SDavid van Moolenbroek /* If predicate is true, the IF was executed, ignore ELSE part */
136*29492bb7SDavid van Moolenbroek
137*29492bb7SDavid van Moolenbroek if (WalkState->LastPredicate)
138*29492bb7SDavid van Moolenbroek {
139*29492bb7SDavid van Moolenbroek Status = AE_CTRL_TRUE;
140*29492bb7SDavid van Moolenbroek }
141*29492bb7SDavid van Moolenbroek
142*29492bb7SDavid van Moolenbroek break;
143*29492bb7SDavid van Moolenbroek
144*29492bb7SDavid van Moolenbroek case AML_RETURN_OP:
145*29492bb7SDavid van Moolenbroek
146*29492bb7SDavid van Moolenbroek break;
147*29492bb7SDavid van Moolenbroek
148*29492bb7SDavid van Moolenbroek default:
149*29492bb7SDavid van Moolenbroek
150*29492bb7SDavid van Moolenbroek break;
151*29492bb7SDavid van Moolenbroek }
152*29492bb7SDavid van Moolenbroek
153*29492bb7SDavid van Moolenbroek return (Status);
154*29492bb7SDavid van Moolenbroek }
155*29492bb7SDavid van Moolenbroek
156*29492bb7SDavid van Moolenbroek
157*29492bb7SDavid van Moolenbroek /*******************************************************************************
158*29492bb7SDavid van Moolenbroek *
159*29492bb7SDavid van Moolenbroek * FUNCTION: AcpiDsExecEndControlOp
160*29492bb7SDavid van Moolenbroek *
161*29492bb7SDavid van Moolenbroek * PARAMETERS: WalkList - The list that owns the walk stack
162*29492bb7SDavid van Moolenbroek * Op - The control Op
163*29492bb7SDavid van Moolenbroek *
164*29492bb7SDavid van Moolenbroek * RETURN: Status
165*29492bb7SDavid van Moolenbroek *
166*29492bb7SDavid van Moolenbroek * DESCRIPTION: Handles all control ops encountered during control method
167*29492bb7SDavid van Moolenbroek * execution.
168*29492bb7SDavid van Moolenbroek *
169*29492bb7SDavid van Moolenbroek ******************************************************************************/
170*29492bb7SDavid van Moolenbroek
171*29492bb7SDavid van Moolenbroek ACPI_STATUS
AcpiDsExecEndControlOp(ACPI_WALK_STATE * WalkState,ACPI_PARSE_OBJECT * Op)172*29492bb7SDavid van Moolenbroek AcpiDsExecEndControlOp (
173*29492bb7SDavid van Moolenbroek ACPI_WALK_STATE *WalkState,
174*29492bb7SDavid van Moolenbroek ACPI_PARSE_OBJECT *Op)
175*29492bb7SDavid van Moolenbroek {
176*29492bb7SDavid van Moolenbroek ACPI_STATUS Status = AE_OK;
177*29492bb7SDavid van Moolenbroek ACPI_GENERIC_STATE *ControlState;
178*29492bb7SDavid van Moolenbroek
179*29492bb7SDavid van Moolenbroek
180*29492bb7SDavid van Moolenbroek ACPI_FUNCTION_NAME (DsExecEndControlOp);
181*29492bb7SDavid van Moolenbroek
182*29492bb7SDavid van Moolenbroek
183*29492bb7SDavid van Moolenbroek switch (Op->Common.AmlOpcode)
184*29492bb7SDavid van Moolenbroek {
185*29492bb7SDavid van Moolenbroek case AML_IF_OP:
186*29492bb7SDavid van Moolenbroek
187*29492bb7SDavid van Moolenbroek ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", Op));
188*29492bb7SDavid van Moolenbroek
189*29492bb7SDavid van Moolenbroek /*
190*29492bb7SDavid van Moolenbroek * Save the result of the predicate in case there is an
191*29492bb7SDavid van Moolenbroek * ELSE to come
192*29492bb7SDavid van Moolenbroek */
193*29492bb7SDavid van Moolenbroek WalkState->LastPredicate =
194*29492bb7SDavid van Moolenbroek (BOOLEAN) WalkState->ControlState->Common.Value;
195*29492bb7SDavid van Moolenbroek
196*29492bb7SDavid van Moolenbroek /*
197*29492bb7SDavid van Moolenbroek * Pop the control state that was created at the start
198*29492bb7SDavid van Moolenbroek * of the IF and free it
199*29492bb7SDavid van Moolenbroek */
200*29492bb7SDavid van Moolenbroek ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
201*29492bb7SDavid van Moolenbroek AcpiUtDeleteGenericState (ControlState);
202*29492bb7SDavid van Moolenbroek break;
203*29492bb7SDavid van Moolenbroek
204*29492bb7SDavid van Moolenbroek case AML_ELSE_OP:
205*29492bb7SDavid van Moolenbroek
206*29492bb7SDavid van Moolenbroek break;
207*29492bb7SDavid van Moolenbroek
208*29492bb7SDavid van Moolenbroek case AML_WHILE_OP:
209*29492bb7SDavid van Moolenbroek
210*29492bb7SDavid van Moolenbroek ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", Op));
211*29492bb7SDavid van Moolenbroek
212*29492bb7SDavid van Moolenbroek ControlState = WalkState->ControlState;
213*29492bb7SDavid van Moolenbroek if (ControlState->Common.Value)
214*29492bb7SDavid van Moolenbroek {
215*29492bb7SDavid van Moolenbroek /* Predicate was true, the body of the loop was just executed */
216*29492bb7SDavid van Moolenbroek
217*29492bb7SDavid van Moolenbroek /*
218*29492bb7SDavid van Moolenbroek * This loop counter mechanism allows the interpreter to escape
219*29492bb7SDavid van Moolenbroek * possibly infinite loops. This can occur in poorly written AML
220*29492bb7SDavid van Moolenbroek * when the hardware does not respond within a while loop and the
221*29492bb7SDavid van Moolenbroek * loop does not implement a timeout.
222*29492bb7SDavid van Moolenbroek */
223*29492bb7SDavid van Moolenbroek ControlState->Control.LoopCount++;
224*29492bb7SDavid van Moolenbroek if (ControlState->Control.LoopCount > ACPI_MAX_LOOP_ITERATIONS)
225*29492bb7SDavid van Moolenbroek {
226*29492bb7SDavid van Moolenbroek Status = AE_AML_INFINITE_LOOP;
227*29492bb7SDavid van Moolenbroek break;
228*29492bb7SDavid van Moolenbroek }
229*29492bb7SDavid van Moolenbroek
230*29492bb7SDavid van Moolenbroek /*
231*29492bb7SDavid van Moolenbroek * Go back and evaluate the predicate and maybe execute the loop
232*29492bb7SDavid van Moolenbroek * another time
233*29492bb7SDavid van Moolenbroek */
234*29492bb7SDavid van Moolenbroek Status = AE_CTRL_PENDING;
235*29492bb7SDavid van Moolenbroek WalkState->AmlLastWhile = ControlState->Control.AmlPredicateStart;
236*29492bb7SDavid van Moolenbroek break;
237*29492bb7SDavid van Moolenbroek }
238*29492bb7SDavid van Moolenbroek
239*29492bb7SDavid van Moolenbroek /* Predicate was false, terminate this while loop */
240*29492bb7SDavid van Moolenbroek
241*29492bb7SDavid van Moolenbroek ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
242*29492bb7SDavid van Moolenbroek "[WHILE_OP] termination! Op=%p\n",Op));
243*29492bb7SDavid van Moolenbroek
244*29492bb7SDavid van Moolenbroek /* Pop this control state and free it */
245*29492bb7SDavid van Moolenbroek
246*29492bb7SDavid van Moolenbroek ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
247*29492bb7SDavid van Moolenbroek AcpiUtDeleteGenericState (ControlState);
248*29492bb7SDavid van Moolenbroek break;
249*29492bb7SDavid van Moolenbroek
250*29492bb7SDavid van Moolenbroek case AML_RETURN_OP:
251*29492bb7SDavid van Moolenbroek
252*29492bb7SDavid van Moolenbroek ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
253*29492bb7SDavid van Moolenbroek "[RETURN_OP] Op=%p Arg=%p\n",Op, Op->Common.Value.Arg));
254*29492bb7SDavid van Moolenbroek
255*29492bb7SDavid van Moolenbroek /*
256*29492bb7SDavid van Moolenbroek * One optional operand -- the return value
257*29492bb7SDavid van Moolenbroek * It can be either an immediate operand or a result that
258*29492bb7SDavid van Moolenbroek * has been bubbled up the tree
259*29492bb7SDavid van Moolenbroek */
260*29492bb7SDavid van Moolenbroek if (Op->Common.Value.Arg)
261*29492bb7SDavid van Moolenbroek {
262*29492bb7SDavid van Moolenbroek /* Since we have a real Return(), delete any implicit return */
263*29492bb7SDavid van Moolenbroek
264*29492bb7SDavid van Moolenbroek AcpiDsClearImplicitReturn (WalkState);
265*29492bb7SDavid van Moolenbroek
266*29492bb7SDavid van Moolenbroek /* Return statement has an immediate operand */
267*29492bb7SDavid van Moolenbroek
268*29492bb7SDavid van Moolenbroek Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg);
269*29492bb7SDavid van Moolenbroek if (ACPI_FAILURE (Status))
270*29492bb7SDavid van Moolenbroek {
271*29492bb7SDavid van Moolenbroek return (Status);
272*29492bb7SDavid van Moolenbroek }
273*29492bb7SDavid van Moolenbroek
274*29492bb7SDavid van Moolenbroek /*
275*29492bb7SDavid van Moolenbroek * If value being returned is a Reference (such as
276*29492bb7SDavid van Moolenbroek * an arg or local), resolve it now because it may
277*29492bb7SDavid van Moolenbroek * cease to exist at the end of the method.
278*29492bb7SDavid van Moolenbroek */
279*29492bb7SDavid van Moolenbroek Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
280*29492bb7SDavid van Moolenbroek if (ACPI_FAILURE (Status))
281*29492bb7SDavid van Moolenbroek {
282*29492bb7SDavid van Moolenbroek return (Status);
283*29492bb7SDavid van Moolenbroek }
284*29492bb7SDavid van Moolenbroek
285*29492bb7SDavid van Moolenbroek /*
286*29492bb7SDavid van Moolenbroek * Get the return value and save as the last result
287*29492bb7SDavid van Moolenbroek * value. This is the only place where WalkState->ReturnDesc
288*29492bb7SDavid van Moolenbroek * is set to anything other than zero!
289*29492bb7SDavid van Moolenbroek */
290*29492bb7SDavid van Moolenbroek WalkState->ReturnDesc = WalkState->Operands[0];
291*29492bb7SDavid van Moolenbroek }
292*29492bb7SDavid van Moolenbroek else if (WalkState->ResultCount)
293*29492bb7SDavid van Moolenbroek {
294*29492bb7SDavid van Moolenbroek /* Since we have a real Return(), delete any implicit return */
295*29492bb7SDavid van Moolenbroek
296*29492bb7SDavid van Moolenbroek AcpiDsClearImplicitReturn (WalkState);
297*29492bb7SDavid van Moolenbroek
298*29492bb7SDavid van Moolenbroek /*
299*29492bb7SDavid van Moolenbroek * The return value has come from a previous calculation.
300*29492bb7SDavid van Moolenbroek *
301*29492bb7SDavid van Moolenbroek * If value being returned is a Reference (such as
302*29492bb7SDavid van Moolenbroek * an arg or local), resolve it now because it may
303*29492bb7SDavid van Moolenbroek * cease to exist at the end of the method.
304*29492bb7SDavid van Moolenbroek *
305*29492bb7SDavid van Moolenbroek * Allow references created by the Index operator to return
306*29492bb7SDavid van Moolenbroek * unchanged.
307*29492bb7SDavid van Moolenbroek */
308*29492bb7SDavid van Moolenbroek if ((ACPI_GET_DESCRIPTOR_TYPE (WalkState->Results->Results.ObjDesc[0]) == ACPI_DESC_TYPE_OPERAND) &&
309*29492bb7SDavid van Moolenbroek ((WalkState->Results->Results.ObjDesc [0])->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
310*29492bb7SDavid van Moolenbroek ((WalkState->Results->Results.ObjDesc [0])->Reference.Class != ACPI_REFCLASS_INDEX))
311*29492bb7SDavid van Moolenbroek {
312*29492bb7SDavid van Moolenbroek Status = AcpiExResolveToValue (&WalkState->Results->Results.ObjDesc [0], WalkState);
313*29492bb7SDavid van Moolenbroek if (ACPI_FAILURE (Status))
314*29492bb7SDavid van Moolenbroek {
315*29492bb7SDavid van Moolenbroek return (Status);
316*29492bb7SDavid van Moolenbroek }
317*29492bb7SDavid van Moolenbroek }
318*29492bb7SDavid van Moolenbroek
319*29492bb7SDavid van Moolenbroek WalkState->ReturnDesc = WalkState->Results->Results.ObjDesc [0];
320*29492bb7SDavid van Moolenbroek }
321*29492bb7SDavid van Moolenbroek else
322*29492bb7SDavid van Moolenbroek {
323*29492bb7SDavid van Moolenbroek /* No return operand */
324*29492bb7SDavid van Moolenbroek
325*29492bb7SDavid van Moolenbroek if (WalkState->NumOperands)
326*29492bb7SDavid van Moolenbroek {
327*29492bb7SDavid van Moolenbroek AcpiUtRemoveReference (WalkState->Operands [0]);
328*29492bb7SDavid van Moolenbroek }
329*29492bb7SDavid van Moolenbroek
330*29492bb7SDavid van Moolenbroek WalkState->Operands [0] = NULL;
331*29492bb7SDavid van Moolenbroek WalkState->NumOperands = 0;
332*29492bb7SDavid van Moolenbroek WalkState->ReturnDesc = NULL;
333*29492bb7SDavid van Moolenbroek }
334*29492bb7SDavid van Moolenbroek
335*29492bb7SDavid van Moolenbroek
336*29492bb7SDavid van Moolenbroek ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
337*29492bb7SDavid van Moolenbroek "Completed RETURN_OP State=%p, RetVal=%p\n",
338*29492bb7SDavid van Moolenbroek WalkState, WalkState->ReturnDesc));
339*29492bb7SDavid van Moolenbroek
340*29492bb7SDavid van Moolenbroek /* End the control method execution right now */
341*29492bb7SDavid van Moolenbroek
342*29492bb7SDavid van Moolenbroek Status = AE_CTRL_TERMINATE;
343*29492bb7SDavid van Moolenbroek break;
344*29492bb7SDavid van Moolenbroek
345*29492bb7SDavid van Moolenbroek case AML_NOOP_OP:
346*29492bb7SDavid van Moolenbroek
347*29492bb7SDavid van Moolenbroek /* Just do nothing! */
348*29492bb7SDavid van Moolenbroek
349*29492bb7SDavid van Moolenbroek break;
350*29492bb7SDavid van Moolenbroek
351*29492bb7SDavid van Moolenbroek case AML_BREAK_POINT_OP:
352*29492bb7SDavid van Moolenbroek
353*29492bb7SDavid van Moolenbroek /*
354*29492bb7SDavid van Moolenbroek * Set the single-step flag. This will cause the debugger (if present)
355*29492bb7SDavid van Moolenbroek * to break to the console within the AML debugger at the start of the
356*29492bb7SDavid van Moolenbroek * next AML instruction.
357*29492bb7SDavid van Moolenbroek */
358*29492bb7SDavid van Moolenbroek ACPI_DEBUGGER_EXEC (
359*29492bb7SDavid van Moolenbroek AcpiGbl_CmSingleStep = TRUE);
360*29492bb7SDavid van Moolenbroek ACPI_DEBUGGER_EXEC (
361*29492bb7SDavid van Moolenbroek AcpiOsPrintf ("**break** Executed AML BreakPoint opcode\n"));
362*29492bb7SDavid van Moolenbroek
363*29492bb7SDavid van Moolenbroek /* Call to the OSL in case OS wants a piece of the action */
364*29492bb7SDavid van Moolenbroek
365*29492bb7SDavid van Moolenbroek Status = AcpiOsSignal (ACPI_SIGNAL_BREAKPOINT,
366*29492bb7SDavid van Moolenbroek "Executed AML Breakpoint opcode");
367*29492bb7SDavid van Moolenbroek break;
368*29492bb7SDavid van Moolenbroek
369*29492bb7SDavid van Moolenbroek case AML_BREAK_OP:
370*29492bb7SDavid van Moolenbroek case AML_CONTINUE_OP: /* ACPI 2.0 */
371*29492bb7SDavid van Moolenbroek
372*29492bb7SDavid van Moolenbroek /* Pop and delete control states until we find a while */
373*29492bb7SDavid van Moolenbroek
374*29492bb7SDavid van Moolenbroek while (WalkState->ControlState &&
375*29492bb7SDavid van Moolenbroek (WalkState->ControlState->Control.Opcode != AML_WHILE_OP))
376*29492bb7SDavid van Moolenbroek {
377*29492bb7SDavid van Moolenbroek ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
378*29492bb7SDavid van Moolenbroek AcpiUtDeleteGenericState (ControlState);
379*29492bb7SDavid van Moolenbroek }
380*29492bb7SDavid van Moolenbroek
381*29492bb7SDavid van Moolenbroek /* No while found? */
382*29492bb7SDavid van Moolenbroek
383*29492bb7SDavid van Moolenbroek if (!WalkState->ControlState)
384*29492bb7SDavid van Moolenbroek {
385*29492bb7SDavid van Moolenbroek return (AE_AML_NO_WHILE);
386*29492bb7SDavid van Moolenbroek }
387*29492bb7SDavid van Moolenbroek
388*29492bb7SDavid van Moolenbroek /* Was: WalkState->AmlLastWhile = WalkState->ControlState->Control.AmlPredicateStart; */
389*29492bb7SDavid van Moolenbroek
390*29492bb7SDavid van Moolenbroek WalkState->AmlLastWhile = WalkState->ControlState->Control.PackageEnd;
391*29492bb7SDavid van Moolenbroek
392*29492bb7SDavid van Moolenbroek /* Return status depending on opcode */
393*29492bb7SDavid van Moolenbroek
394*29492bb7SDavid van Moolenbroek if (Op->Common.AmlOpcode == AML_BREAK_OP)
395*29492bb7SDavid van Moolenbroek {
396*29492bb7SDavid van Moolenbroek Status = AE_CTRL_BREAK;
397*29492bb7SDavid van Moolenbroek }
398*29492bb7SDavid van Moolenbroek else
399*29492bb7SDavid van Moolenbroek {
400*29492bb7SDavid van Moolenbroek Status = AE_CTRL_CONTINUE;
401*29492bb7SDavid van Moolenbroek }
402*29492bb7SDavid van Moolenbroek break;
403*29492bb7SDavid van Moolenbroek
404*29492bb7SDavid van Moolenbroek default:
405*29492bb7SDavid van Moolenbroek
406*29492bb7SDavid van Moolenbroek ACPI_ERROR ((AE_INFO, "Unknown control opcode=0x%X Op=%p",
407*29492bb7SDavid van Moolenbroek Op->Common.AmlOpcode, Op));
408*29492bb7SDavid van Moolenbroek
409*29492bb7SDavid van Moolenbroek Status = AE_AML_BAD_OPCODE;
410*29492bb7SDavid van Moolenbroek break;
411*29492bb7SDavid van Moolenbroek }
412*29492bb7SDavid van Moolenbroek
413*29492bb7SDavid van Moolenbroek return (Status);
414*29492bb7SDavid van Moolenbroek }
415