xref: /minix3/minix/drivers/power/acpi/dispatcher/dscontrol.c (revision 29492bb71c7148a089a5afafa0c99409161218df)
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