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