1db2bae30SDana Myers /******************************************************************************
2db2bae30SDana Myers *
3db2bae30SDana Myers * Module Name: dswexec - Dispatcher method execution callbacks;
4db2bae30SDana Myers * dispatch to interpreter.
5db2bae30SDana Myers *
6db2bae30SDana Myers *****************************************************************************/
7db2bae30SDana Myers
826f3cdf0SGordon Ross /*
9*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp.
10db2bae30SDana Myers * All rights reserved.
11db2bae30SDana Myers *
1226f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without
1326f3cdf0SGordon Ross * modification, are permitted provided that the following conditions
1426f3cdf0SGordon Ross * are met:
1526f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright
1626f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer,
1726f3cdf0SGordon Ross * without modification.
1826f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1926f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below
2026f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon
2126f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further
2226f3cdf0SGordon Ross * binary redistribution.
2326f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names
2426f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived
2526f3cdf0SGordon Ross * from this software without specific prior written permission.
26db2bae30SDana Myers *
2726f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the
2826f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free
2926f3cdf0SGordon Ross * Software Foundation.
30db2bae30SDana Myers *
3126f3cdf0SGordon Ross * NO WARRANTY
3226f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3326f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3426f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3526f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3626f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3726f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3826f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3926f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4026f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4126f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4226f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES.
4326f3cdf0SGordon Ross */
44db2bae30SDana Myers
45db2bae30SDana Myers #include "acpi.h"
46aa2aa9a6SDana Myers #include "accommon.h"
47db2bae30SDana Myers #include "acparser.h"
48db2bae30SDana Myers #include "amlcode.h"
49db2bae30SDana Myers #include "acdispat.h"
50db2bae30SDana Myers #include "acinterp.h"
51db2bae30SDana Myers #include "acnamesp.h"
52db2bae30SDana Myers #include "acdebug.h"
53db2bae30SDana Myers
54db2bae30SDana Myers
55db2bae30SDana Myers #define _COMPONENT ACPI_DISPATCHER
56db2bae30SDana Myers ACPI_MODULE_NAME ("dswexec")
57db2bae30SDana Myers
58db2bae30SDana Myers /*
59db2bae30SDana Myers * Dispatch table for opcode classes
60db2bae30SDana Myers */
61db2bae30SDana Myers static ACPI_EXECUTE_OP AcpiGbl_OpTypeDispatch [] =
62db2bae30SDana Myers {
63db2bae30SDana Myers AcpiExOpcode_0A_0T_1R,
64db2bae30SDana Myers AcpiExOpcode_1A_0T_0R,
65db2bae30SDana Myers AcpiExOpcode_1A_0T_1R,
66db2bae30SDana Myers AcpiExOpcode_1A_1T_0R,
67db2bae30SDana Myers AcpiExOpcode_1A_1T_1R,
68db2bae30SDana Myers AcpiExOpcode_2A_0T_0R,
69db2bae30SDana Myers AcpiExOpcode_2A_0T_1R,
70db2bae30SDana Myers AcpiExOpcode_2A_1T_1R,
71db2bae30SDana Myers AcpiExOpcode_2A_2T_1R,
72db2bae30SDana Myers AcpiExOpcode_3A_0T_0R,
73db2bae30SDana Myers AcpiExOpcode_3A_1T_1R,
74db2bae30SDana Myers AcpiExOpcode_6A_0T_1R
75db2bae30SDana Myers };
76db2bae30SDana Myers
77db2bae30SDana Myers
78db2bae30SDana Myers /*****************************************************************************
79db2bae30SDana Myers *
80db2bae30SDana Myers * FUNCTION: AcpiDsGetPredicateValue
81db2bae30SDana Myers *
82db2bae30SDana Myers * PARAMETERS: WalkState - Current state of the parse tree walk
83db2bae30SDana Myers * ResultObj - if non-zero, pop result from result stack
84db2bae30SDana Myers *
85db2bae30SDana Myers * RETURN: Status
86db2bae30SDana Myers *
87db2bae30SDana Myers * DESCRIPTION: Get the result of a predicate evaluation
88db2bae30SDana Myers *
89db2bae30SDana Myers ****************************************************************************/
90db2bae30SDana Myers
91db2bae30SDana Myers ACPI_STATUS
AcpiDsGetPredicateValue(ACPI_WALK_STATE * WalkState,ACPI_OPERAND_OBJECT * ResultObj)92db2bae30SDana Myers AcpiDsGetPredicateValue (
93db2bae30SDana Myers ACPI_WALK_STATE *WalkState,
94db2bae30SDana Myers ACPI_OPERAND_OBJECT *ResultObj)
95db2bae30SDana Myers {
96db2bae30SDana Myers ACPI_STATUS Status = AE_OK;
97db2bae30SDana Myers ACPI_OPERAND_OBJECT *ObjDesc;
98db2bae30SDana Myers ACPI_OPERAND_OBJECT *LocalObjDesc = NULL;
99db2bae30SDana Myers
100db2bae30SDana Myers
101db2bae30SDana Myers ACPI_FUNCTION_TRACE_PTR (DsGetPredicateValue, WalkState);
102db2bae30SDana Myers
103db2bae30SDana Myers
104db2bae30SDana Myers WalkState->ControlState->Common.State = 0;
105db2bae30SDana Myers
106db2bae30SDana Myers if (ResultObj)
107db2bae30SDana Myers {
108db2bae30SDana Myers Status = AcpiDsResultPop (&ObjDesc, WalkState);
109db2bae30SDana Myers if (ACPI_FAILURE (Status))
110db2bae30SDana Myers {
111db2bae30SDana Myers ACPI_EXCEPTION ((AE_INFO, Status,
112db2bae30SDana Myers "Could not get result from predicate evaluation"));
113db2bae30SDana Myers
114db2bae30SDana Myers return_ACPI_STATUS (Status);
115db2bae30SDana Myers }
116db2bae30SDana Myers }
117db2bae30SDana Myers else
118db2bae30SDana Myers {
119db2bae30SDana Myers Status = AcpiDsCreateOperand (WalkState, WalkState->Op, 0);
120db2bae30SDana Myers if (ACPI_FAILURE (Status))
121db2bae30SDana Myers {
122db2bae30SDana Myers return_ACPI_STATUS (Status);
123db2bae30SDana Myers }
124db2bae30SDana Myers
125db2bae30SDana Myers Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
126db2bae30SDana Myers if (ACPI_FAILURE (Status))
127db2bae30SDana Myers {
128db2bae30SDana Myers return_ACPI_STATUS (Status);
129db2bae30SDana Myers }
130db2bae30SDana Myers
131db2bae30SDana Myers ObjDesc = WalkState->Operands [0];
132db2bae30SDana Myers }
133db2bae30SDana Myers
134db2bae30SDana Myers if (!ObjDesc)
135db2bae30SDana Myers {
136db2bae30SDana Myers ACPI_ERROR ((AE_INFO,
137db2bae30SDana Myers "No predicate ObjDesc=%p State=%p",
138db2bae30SDana Myers ObjDesc, WalkState));
139db2bae30SDana Myers
140db2bae30SDana Myers return_ACPI_STATUS (AE_AML_NO_OPERAND);
141db2bae30SDana Myers }
142db2bae30SDana Myers
143db2bae30SDana Myers /*
144db2bae30SDana Myers * Result of predicate evaluation must be an Integer
145db2bae30SDana Myers * object. Implicitly convert the argument if necessary.
146db2bae30SDana Myers */
147db2bae30SDana Myers Status = AcpiExConvertToInteger (ObjDesc, &LocalObjDesc, 16);
148db2bae30SDana Myers if (ACPI_FAILURE (Status))
149db2bae30SDana Myers {
150db2bae30SDana Myers goto Cleanup;
151db2bae30SDana Myers }
152db2bae30SDana Myers
153aa2aa9a6SDana Myers if (LocalObjDesc->Common.Type != ACPI_TYPE_INTEGER)
154db2bae30SDana Myers {
155db2bae30SDana Myers ACPI_ERROR ((AE_INFO,
15626f3cdf0SGordon Ross "Bad predicate (not an integer) ObjDesc=%p State=%p Type=0x%X",
157aa2aa9a6SDana Myers ObjDesc, WalkState, ObjDesc->Common.Type));
158db2bae30SDana Myers
159db2bae30SDana Myers Status = AE_AML_OPERAND_TYPE;
160db2bae30SDana Myers goto Cleanup;
161db2bae30SDana Myers }
162db2bae30SDana Myers
163db2bae30SDana Myers /* Truncate the predicate to 32-bits if necessary */
164db2bae30SDana Myers
165*385cc6b4SJerry Jelinek (void) AcpiExTruncateFor32bitTable (LocalObjDesc);
166db2bae30SDana Myers
167db2bae30SDana Myers /*
168db2bae30SDana Myers * Save the result of the predicate evaluation on
169db2bae30SDana Myers * the control stack
170db2bae30SDana Myers */
171db2bae30SDana Myers if (LocalObjDesc->Integer.Value)
172db2bae30SDana Myers {
173db2bae30SDana Myers WalkState->ControlState->Common.Value = TRUE;
174db2bae30SDana Myers }
175db2bae30SDana Myers else
176db2bae30SDana Myers {
177db2bae30SDana Myers /*
178db2bae30SDana Myers * Predicate is FALSE, we will just toss the
179db2bae30SDana Myers * rest of the package
180db2bae30SDana Myers */
181db2bae30SDana Myers WalkState->ControlState->Common.Value = FALSE;
182db2bae30SDana Myers Status = AE_CTRL_FALSE;
183db2bae30SDana Myers }
184db2bae30SDana Myers
185aa2aa9a6SDana Myers /* Predicate can be used for an implicit return value */
186aa2aa9a6SDana Myers
187aa2aa9a6SDana Myers (void) AcpiDsDoImplicitReturn (LocalObjDesc, WalkState, TRUE);
188aa2aa9a6SDana Myers
189db2bae30SDana Myers
190db2bae30SDana Myers Cleanup:
191db2bae30SDana Myers
192*385cc6b4SJerry Jelinek ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
193*385cc6b4SJerry Jelinek "Completed a predicate eval=%X Op=%p\n",
194db2bae30SDana Myers WalkState->ControlState->Common.Value, WalkState->Op));
195db2bae30SDana Myers
196*385cc6b4SJerry Jelinek #ifdef ACPI_DEBUGGER
197db2bae30SDana Myers /* Break to debugger to display result */
198db2bae30SDana Myers
199*385cc6b4SJerry Jelinek AcpiDbDisplayResultObject (LocalObjDesc, WalkState);
200*385cc6b4SJerry Jelinek #endif
201db2bae30SDana Myers
202db2bae30SDana Myers /*
203db2bae30SDana Myers * Delete the predicate result object (we know that
204db2bae30SDana Myers * we don't need it anymore)
205db2bae30SDana Myers */
206db2bae30SDana Myers if (LocalObjDesc != ObjDesc)
207db2bae30SDana Myers {
208db2bae30SDana Myers AcpiUtRemoveReference (LocalObjDesc);
209db2bae30SDana Myers }
210db2bae30SDana Myers AcpiUtRemoveReference (ObjDesc);
211db2bae30SDana Myers
212db2bae30SDana Myers WalkState->ControlState->Common.State = ACPI_CONTROL_NORMAL;
213db2bae30SDana Myers return_ACPI_STATUS (Status);
214db2bae30SDana Myers }
215db2bae30SDana Myers
216db2bae30SDana Myers
217db2bae30SDana Myers /*****************************************************************************
218db2bae30SDana Myers *
219db2bae30SDana Myers * FUNCTION: AcpiDsExecBeginOp
220db2bae30SDana Myers *
221db2bae30SDana Myers * PARAMETERS: WalkState - Current state of the parse tree walk
222db2bae30SDana Myers * OutOp - Where to return op if a new one is created
223db2bae30SDana Myers *
224db2bae30SDana Myers * RETURN: Status
225db2bae30SDana Myers *
226db2bae30SDana Myers * DESCRIPTION: Descending callback used during the execution of control
227db2bae30SDana Myers * methods. This is where most operators and operands are
228db2bae30SDana Myers * dispatched to the interpreter.
229db2bae30SDana Myers *
230db2bae30SDana Myers ****************************************************************************/
231db2bae30SDana Myers
232db2bae30SDana Myers ACPI_STATUS
AcpiDsExecBeginOp(ACPI_WALK_STATE * WalkState,ACPI_PARSE_OBJECT ** OutOp)233db2bae30SDana Myers AcpiDsExecBeginOp (
234db2bae30SDana Myers ACPI_WALK_STATE *WalkState,
235db2bae30SDana Myers ACPI_PARSE_OBJECT **OutOp)
236db2bae30SDana Myers {
237db2bae30SDana Myers ACPI_PARSE_OBJECT *Op;
238db2bae30SDana Myers ACPI_STATUS Status = AE_OK;
239db2bae30SDana Myers UINT32 OpcodeClass;
240db2bae30SDana Myers
241db2bae30SDana Myers
242db2bae30SDana Myers ACPI_FUNCTION_TRACE_PTR (DsExecBeginOp, WalkState);
243db2bae30SDana Myers
244db2bae30SDana Myers
245db2bae30SDana Myers Op = WalkState->Op;
246db2bae30SDana Myers if (!Op)
247db2bae30SDana Myers {
248db2bae30SDana Myers Status = AcpiDsLoad2BeginOp (WalkState, OutOp);
249db2bae30SDana Myers if (ACPI_FAILURE (Status))
250db2bae30SDana Myers {
251db2bae30SDana Myers goto ErrorExit;
252db2bae30SDana Myers }
253db2bae30SDana Myers
254db2bae30SDana Myers Op = *OutOp;
255db2bae30SDana Myers WalkState->Op = Op;
256db2bae30SDana Myers WalkState->Opcode = Op->Common.AmlOpcode;
257db2bae30SDana Myers WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
258db2bae30SDana Myers
259db2bae30SDana Myers if (AcpiNsOpensScope (WalkState->OpInfo->ObjectType))
260db2bae30SDana Myers {
261db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
262db2bae30SDana Myers "(%s) Popping scope for Op %p\n",
263db2bae30SDana Myers AcpiUtGetTypeName (WalkState->OpInfo->ObjectType), Op));
264db2bae30SDana Myers
265db2bae30SDana Myers Status = AcpiDsScopeStackPop (WalkState);
266db2bae30SDana Myers if (ACPI_FAILURE (Status))
267db2bae30SDana Myers {
268db2bae30SDana Myers goto ErrorExit;
269db2bae30SDana Myers }
270db2bae30SDana Myers }
271db2bae30SDana Myers }
272db2bae30SDana Myers
273db2bae30SDana Myers if (Op == WalkState->Origin)
274db2bae30SDana Myers {
275db2bae30SDana Myers if (OutOp)
276db2bae30SDana Myers {
277db2bae30SDana Myers *OutOp = Op;
278db2bae30SDana Myers }
279db2bae30SDana Myers
280db2bae30SDana Myers return_ACPI_STATUS (AE_OK);
281db2bae30SDana Myers }
282db2bae30SDana Myers
283db2bae30SDana Myers /*
284db2bae30SDana Myers * If the previous opcode was a conditional, this opcode
285db2bae30SDana Myers * must be the beginning of the associated predicate.
286db2bae30SDana Myers * Save this knowledge in the current scope descriptor
287db2bae30SDana Myers */
288db2bae30SDana Myers if ((WalkState->ControlState) &&
289db2bae30SDana Myers (WalkState->ControlState->Common.State ==
290db2bae30SDana Myers ACPI_CONTROL_CONDITIONAL_EXECUTING))
291db2bae30SDana Myers {
292*385cc6b4SJerry Jelinek ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
293*385cc6b4SJerry Jelinek "Exec predicate Op=%p State=%p\n",
294db2bae30SDana Myers Op, WalkState));
295db2bae30SDana Myers
296*385cc6b4SJerry Jelinek WalkState->ControlState->Common.State =
297*385cc6b4SJerry Jelinek ACPI_CONTROL_PREDICATE_EXECUTING;
298db2bae30SDana Myers
299db2bae30SDana Myers /* Save start of predicate */
300db2bae30SDana Myers
301db2bae30SDana Myers WalkState->ControlState->Control.PredicateOp = Op;
302db2bae30SDana Myers }
303db2bae30SDana Myers
304db2bae30SDana Myers
305db2bae30SDana Myers OpcodeClass = WalkState->OpInfo->Class;
306db2bae30SDana Myers
307db2bae30SDana Myers /* We want to send namepaths to the load code */
308db2bae30SDana Myers
309db2bae30SDana Myers if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
310db2bae30SDana Myers {
311db2bae30SDana Myers OpcodeClass = AML_CLASS_NAMED_OBJECT;
312db2bae30SDana Myers }
313db2bae30SDana Myers
314db2bae30SDana Myers /*
315db2bae30SDana Myers * Handle the opcode based upon the opcode type
316db2bae30SDana Myers */
317db2bae30SDana Myers switch (OpcodeClass)
318db2bae30SDana Myers {
319db2bae30SDana Myers case AML_CLASS_CONTROL:
320db2bae30SDana Myers
321db2bae30SDana Myers Status = AcpiDsExecBeginControlOp (WalkState, Op);
322db2bae30SDana Myers break;
323db2bae30SDana Myers
324db2bae30SDana Myers case AML_CLASS_NAMED_OBJECT:
325db2bae30SDana Myers
326db2bae30SDana Myers if (WalkState->WalkType & ACPI_WALK_METHOD)
327db2bae30SDana Myers {
328db2bae30SDana Myers /*
329db2bae30SDana Myers * Found a named object declaration during method execution;
330db2bae30SDana Myers * we must enter this object into the namespace. The created
331db2bae30SDana Myers * object is temporary and will be deleted upon completion of
332db2bae30SDana Myers * the execution of this method.
33326f3cdf0SGordon Ross *
33426f3cdf0SGordon Ross * Note 10/2010: Except for the Scope() op. This opcode does
33526f3cdf0SGordon Ross * not actually create a new object, it refers to an existing
33626f3cdf0SGordon Ross * object. However, for Scope(), we want to indeed open a
33726f3cdf0SGordon Ross * new scope.
338db2bae30SDana Myers */
33926f3cdf0SGordon Ross if (Op->Common.AmlOpcode != AML_SCOPE_OP)
34026f3cdf0SGordon Ross {
341db2bae30SDana Myers Status = AcpiDsLoad2BeginOp (WalkState, NULL);
342db2bae30SDana Myers }
34326f3cdf0SGordon Ross else
34426f3cdf0SGordon Ross {
345*385cc6b4SJerry Jelinek Status = AcpiDsScopeStackPush (
346*385cc6b4SJerry Jelinek Op->Named.Node, Op->Named.Node->Type, WalkState);
34726f3cdf0SGordon Ross if (ACPI_FAILURE (Status))
34826f3cdf0SGordon Ross {
34926f3cdf0SGordon Ross return_ACPI_STATUS (Status);
35026f3cdf0SGordon Ross }
35126f3cdf0SGordon Ross }
35226f3cdf0SGordon Ross }
353db2bae30SDana Myers break;
354db2bae30SDana Myers
355db2bae30SDana Myers case AML_CLASS_EXECUTE:
356db2bae30SDana Myers case AML_CLASS_CREATE:
357db2bae30SDana Myers
358db2bae30SDana Myers break;
359db2bae30SDana Myers
360db2bae30SDana Myers default:
361*385cc6b4SJerry Jelinek
362db2bae30SDana Myers break;
363db2bae30SDana Myers }
364db2bae30SDana Myers
365db2bae30SDana Myers /* Nothing to do here during method execution */
366db2bae30SDana Myers
367db2bae30SDana Myers return_ACPI_STATUS (Status);
368db2bae30SDana Myers
369db2bae30SDana Myers
370db2bae30SDana Myers ErrorExit:
371db2bae30SDana Myers Status = AcpiDsMethodError (Status, WalkState);
372db2bae30SDana Myers return_ACPI_STATUS (Status);
373db2bae30SDana Myers }
374db2bae30SDana Myers
375db2bae30SDana Myers
376db2bae30SDana Myers /*****************************************************************************
377db2bae30SDana Myers *
378db2bae30SDana Myers * FUNCTION: AcpiDsExecEndOp
379db2bae30SDana Myers *
380db2bae30SDana Myers * PARAMETERS: WalkState - Current state of the parse tree walk
381db2bae30SDana Myers *
382db2bae30SDana Myers * RETURN: Status
383db2bae30SDana Myers *
384db2bae30SDana Myers * DESCRIPTION: Ascending callback used during the execution of control
385db2bae30SDana Myers * methods. The only thing we really need to do here is to
386db2bae30SDana Myers * notice the beginning of IF, ELSE, and WHILE blocks.
387db2bae30SDana Myers *
388db2bae30SDana Myers ****************************************************************************/
389db2bae30SDana Myers
390db2bae30SDana Myers ACPI_STATUS
AcpiDsExecEndOp(ACPI_WALK_STATE * WalkState)391db2bae30SDana Myers AcpiDsExecEndOp (
392db2bae30SDana Myers ACPI_WALK_STATE *WalkState)
393db2bae30SDana Myers {
394db2bae30SDana Myers ACPI_PARSE_OBJECT *Op;
395db2bae30SDana Myers ACPI_STATUS Status = AE_OK;
396db2bae30SDana Myers UINT32 OpType;
397db2bae30SDana Myers UINT32 OpClass;
398db2bae30SDana Myers ACPI_PARSE_OBJECT *NextOp;
399db2bae30SDana Myers ACPI_PARSE_OBJECT *FirstArg;
400db2bae30SDana Myers
401db2bae30SDana Myers
402db2bae30SDana Myers ACPI_FUNCTION_TRACE_PTR (DsExecEndOp, WalkState);
403db2bae30SDana Myers
404db2bae30SDana Myers
405db2bae30SDana Myers Op = WalkState->Op;
406db2bae30SDana Myers OpType = WalkState->OpInfo->Type;
407db2bae30SDana Myers OpClass = WalkState->OpInfo->Class;
408db2bae30SDana Myers
409db2bae30SDana Myers if (OpClass == AML_CLASS_UNKNOWN)
410db2bae30SDana Myers {
41126f3cdf0SGordon Ross ACPI_ERROR ((AE_INFO, "Unknown opcode 0x%X", Op->Common.AmlOpcode));
412db2bae30SDana Myers return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
413db2bae30SDana Myers }
414db2bae30SDana Myers
415db2bae30SDana Myers FirstArg = Op->Common.Value.Arg;
416db2bae30SDana Myers
417db2bae30SDana Myers /* Init the walk state */
418db2bae30SDana Myers
419db2bae30SDana Myers WalkState->NumOperands = 0;
420db2bae30SDana Myers WalkState->OperandIndex = 0;
421db2bae30SDana Myers WalkState->ReturnDesc = NULL;
422db2bae30SDana Myers WalkState->ResultObj = NULL;
423db2bae30SDana Myers
424*385cc6b4SJerry Jelinek #ifdef ACPI_DEBUGGER
425db2bae30SDana Myers /* Call debugger for single step support (DEBUG build only) */
426db2bae30SDana Myers
427*385cc6b4SJerry Jelinek Status = AcpiDbSingleStep (WalkState, Op, OpClass);
428*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status))
429*385cc6b4SJerry Jelinek {
430*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status);
431*385cc6b4SJerry Jelinek }
432*385cc6b4SJerry Jelinek #endif
433db2bae30SDana Myers
434db2bae30SDana Myers /* Decode the Opcode Class */
435db2bae30SDana Myers
436db2bae30SDana Myers switch (OpClass)
437db2bae30SDana Myers {
438db2bae30SDana Myers case AML_CLASS_ARGUMENT: /* Constants, literals, etc. */
439db2bae30SDana Myers
440db2bae30SDana Myers if (WalkState->Opcode == AML_INT_NAMEPATH_OP)
441db2bae30SDana Myers {
442db2bae30SDana Myers Status = AcpiDsEvaluateNamePath (WalkState);
443db2bae30SDana Myers if (ACPI_FAILURE (Status))
444db2bae30SDana Myers {
445db2bae30SDana Myers goto Cleanup;
446db2bae30SDana Myers }
447db2bae30SDana Myers }
448db2bae30SDana Myers break;
449db2bae30SDana Myers
450db2bae30SDana Myers case AML_CLASS_EXECUTE: /* Most operators with arguments */
451db2bae30SDana Myers
452db2bae30SDana Myers /* Build resolved operand stack */
453db2bae30SDana Myers
454db2bae30SDana Myers Status = AcpiDsCreateOperands (WalkState, FirstArg);
455db2bae30SDana Myers if (ACPI_FAILURE (Status))
456db2bae30SDana Myers {
457db2bae30SDana Myers goto Cleanup;
458db2bae30SDana Myers }
459db2bae30SDana Myers
460db2bae30SDana Myers /*
461db2bae30SDana Myers * All opcodes require operand resolution, with the only exceptions
462db2bae30SDana Myers * being the ObjectType and SizeOf operators.
463db2bae30SDana Myers */
464db2bae30SDana Myers if (!(WalkState->OpInfo->Flags & AML_NO_OPERAND_RESOLVE))
465db2bae30SDana Myers {
466db2bae30SDana Myers /* Resolve all operands */
467db2bae30SDana Myers
468db2bae30SDana Myers Status = AcpiExResolveOperands (WalkState->Opcode,
469db2bae30SDana Myers &(WalkState->Operands [WalkState->NumOperands -1]),
470db2bae30SDana Myers WalkState);
471db2bae30SDana Myers }
472db2bae30SDana Myers
473db2bae30SDana Myers if (ACPI_SUCCESS (Status))
474db2bae30SDana Myers {
475db2bae30SDana Myers /*
476db2bae30SDana Myers * Dispatch the request to the appropriate interpreter handler
477db2bae30SDana Myers * routine. There is one routine per opcode "type" based upon the
478db2bae30SDana Myers * number of opcode arguments and return type.
479db2bae30SDana Myers */
480db2bae30SDana Myers Status = AcpiGbl_OpTypeDispatch[OpType] (WalkState);
481db2bae30SDana Myers }
482db2bae30SDana Myers else
483db2bae30SDana Myers {
484db2bae30SDana Myers /*
485db2bae30SDana Myers * Treat constructs of the form "Store(LocalX,LocalX)" as noops when the
486db2bae30SDana Myers * Local is uninitialized.
487db2bae30SDana Myers */
488db2bae30SDana Myers if ((Status == AE_AML_UNINITIALIZED_LOCAL) &&
489db2bae30SDana Myers (WalkState->Opcode == AML_STORE_OP) &&
490db2bae30SDana Myers (WalkState->Operands[0]->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
491db2bae30SDana Myers (WalkState->Operands[1]->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
492db2bae30SDana Myers (WalkState->Operands[0]->Reference.Class ==
493db2bae30SDana Myers WalkState->Operands[1]->Reference.Class) &&
494db2bae30SDana Myers (WalkState->Operands[0]->Reference.Value ==
495db2bae30SDana Myers WalkState->Operands[1]->Reference.Value))
496db2bae30SDana Myers {
497db2bae30SDana Myers Status = AE_OK;
498db2bae30SDana Myers }
499db2bae30SDana Myers else
500db2bae30SDana Myers {
501db2bae30SDana Myers ACPI_EXCEPTION ((AE_INFO, Status,
502db2bae30SDana Myers "While resolving operands for [%s]",
503db2bae30SDana Myers AcpiPsGetOpcodeName (WalkState->Opcode)));
504db2bae30SDana Myers }
505db2bae30SDana Myers }
506db2bae30SDana Myers
507db2bae30SDana Myers /* Always delete the argument objects and clear the operand stack */
508db2bae30SDana Myers
509db2bae30SDana Myers AcpiDsClearOperands (WalkState);
510db2bae30SDana Myers
511db2bae30SDana Myers /*
512db2bae30SDana Myers * If a result object was returned from above, push it on the
513db2bae30SDana Myers * current result stack
514db2bae30SDana Myers */
515db2bae30SDana Myers if (ACPI_SUCCESS (Status) &&
516db2bae30SDana Myers WalkState->ResultObj)
517db2bae30SDana Myers {
518db2bae30SDana Myers Status = AcpiDsResultPush (WalkState->ResultObj, WalkState);
519db2bae30SDana Myers }
520db2bae30SDana Myers break;
521db2bae30SDana Myers
522db2bae30SDana Myers default:
523db2bae30SDana Myers
524db2bae30SDana Myers switch (OpType)
525db2bae30SDana Myers {
526db2bae30SDana Myers case AML_TYPE_CONTROL: /* Type 1 opcode, IF/ELSE/WHILE/NOOP */
527db2bae30SDana Myers
528db2bae30SDana Myers /* 1 Operand, 0 ExternalResult, 0 InternalResult */
529db2bae30SDana Myers
530db2bae30SDana Myers Status = AcpiDsExecEndControlOp (WalkState, Op);
531db2bae30SDana Myers
532db2bae30SDana Myers break;
533db2bae30SDana Myers
534db2bae30SDana Myers case AML_TYPE_METHOD_CALL:
535db2bae30SDana Myers /*
536db2bae30SDana Myers * If the method is referenced from within a package
537db2bae30SDana Myers * declaration, it is not a invocation of the method, just
538db2bae30SDana Myers * a reference to it.
539db2bae30SDana Myers */
540db2bae30SDana Myers if ((Op->Asl.Parent) &&
541db2bae30SDana Myers ((Op->Asl.Parent->Asl.AmlOpcode == AML_PACKAGE_OP) ||
542db2bae30SDana Myers (Op->Asl.Parent->Asl.AmlOpcode == AML_VAR_PACKAGE_OP)))
543db2bae30SDana Myers {
544db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
545db2bae30SDana Myers "Method Reference in a Package, Op=%p\n", Op));
546db2bae30SDana Myers
547*385cc6b4SJerry Jelinek Op->Common.Node = (ACPI_NAMESPACE_NODE *)
548*385cc6b4SJerry Jelinek Op->Asl.Value.Arg->Asl.Node;
549db2bae30SDana Myers AcpiUtAddReference (Op->Asl.Value.Arg->Asl.Node->Object);
550db2bae30SDana Myers return_ACPI_STATUS (AE_OK);
551db2bae30SDana Myers }
552db2bae30SDana Myers
553*385cc6b4SJerry Jelinek ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
554*385cc6b4SJerry Jelinek "Method invocation, Op=%p\n", Op));
555db2bae30SDana Myers
556db2bae30SDana Myers /*
557db2bae30SDana Myers * (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains
558db2bae30SDana Myers * the method Node pointer
559db2bae30SDana Myers */
560db2bae30SDana Myers /* NextOp points to the op that holds the method name */
561db2bae30SDana Myers
562db2bae30SDana Myers NextOp = FirstArg;
563db2bae30SDana Myers
564db2bae30SDana Myers /* NextOp points to first argument op */
565db2bae30SDana Myers
566db2bae30SDana Myers NextOp = NextOp->Common.Next;
567db2bae30SDana Myers
568db2bae30SDana Myers /*
569db2bae30SDana Myers * Get the method's arguments and put them on the operand stack
570db2bae30SDana Myers */
571db2bae30SDana Myers Status = AcpiDsCreateOperands (WalkState, NextOp);
572db2bae30SDana Myers if (ACPI_FAILURE (Status))
573db2bae30SDana Myers {
574db2bae30SDana Myers break;
575db2bae30SDana Myers }
576db2bae30SDana Myers
577db2bae30SDana Myers /*
578db2bae30SDana Myers * Since the operands will be passed to another control method,
579db2bae30SDana Myers * we must resolve all local references here (Local variables,
580db2bae30SDana Myers * arguments to *this* method, etc.)
581db2bae30SDana Myers */
582db2bae30SDana Myers Status = AcpiDsResolveOperands (WalkState);
583db2bae30SDana Myers if (ACPI_FAILURE (Status))
584db2bae30SDana Myers {
585db2bae30SDana Myers /* On error, clear all resolved operands */
586db2bae30SDana Myers
587db2bae30SDana Myers AcpiDsClearOperands (WalkState);
588db2bae30SDana Myers break;
589db2bae30SDana Myers }
590db2bae30SDana Myers
591db2bae30SDana Myers /*
592db2bae30SDana Myers * Tell the walk loop to preempt this running method and
593db2bae30SDana Myers * execute the new method
594db2bae30SDana Myers */
595db2bae30SDana Myers Status = AE_CTRL_TRANSFER;
596db2bae30SDana Myers
597db2bae30SDana Myers /*
598db2bae30SDana Myers * Return now; we don't want to disturb anything,
599db2bae30SDana Myers * especially the operand count!
600db2bae30SDana Myers */
601db2bae30SDana Myers return_ACPI_STATUS (Status);
602db2bae30SDana Myers
603db2bae30SDana Myers case AML_TYPE_CREATE_FIELD:
604db2bae30SDana Myers
605db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
606db2bae30SDana Myers "Executing CreateField Buffer/Index Op=%p\n", Op));
607db2bae30SDana Myers
608db2bae30SDana Myers Status = AcpiDsLoad2EndOp (WalkState);
609db2bae30SDana Myers if (ACPI_FAILURE (Status))
610db2bae30SDana Myers {
611db2bae30SDana Myers break;
612db2bae30SDana Myers }
613db2bae30SDana Myers
614db2bae30SDana Myers Status = AcpiDsEvalBufferFieldOperands (WalkState, Op);
615db2bae30SDana Myers break;
616db2bae30SDana Myers
617db2bae30SDana Myers
618db2bae30SDana Myers case AML_TYPE_CREATE_OBJECT:
619db2bae30SDana Myers
620db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
621db2bae30SDana Myers "Executing CreateObject (Buffer/Package) Op=%p\n", Op));
622db2bae30SDana Myers
623db2bae30SDana Myers switch (Op->Common.Parent->Common.AmlOpcode)
624db2bae30SDana Myers {
625db2bae30SDana Myers case AML_NAME_OP:
626db2bae30SDana Myers /*
627db2bae30SDana Myers * Put the Node on the object stack (Contains the ACPI Name
628db2bae30SDana Myers * of this object)
629db2bae30SDana Myers */
630*385cc6b4SJerry Jelinek WalkState->Operands[0] = (void *)
631*385cc6b4SJerry Jelinek Op->Common.Parent->Common.Node;
632db2bae30SDana Myers WalkState->NumOperands = 1;
633db2bae30SDana Myers
634db2bae30SDana Myers Status = AcpiDsCreateNode (WalkState,
635*385cc6b4SJerry Jelinek Op->Common.Parent->Common.Node, Op->Common.Parent);
636db2bae30SDana Myers if (ACPI_FAILURE (Status))
637db2bae30SDana Myers {
638db2bae30SDana Myers break;
639db2bae30SDana Myers }
640db2bae30SDana Myers
641db2bae30SDana Myers /* Fall through */
642db2bae30SDana Myers /*lint -fallthrough */
643db2bae30SDana Myers
644db2bae30SDana Myers case AML_INT_EVAL_SUBTREE_OP:
645db2bae30SDana Myers
646db2bae30SDana Myers Status = AcpiDsEvalDataObjectOperands (WalkState, Op,
647db2bae30SDana Myers AcpiNsGetAttachedObject (Op->Common.Parent->Common.Node));
648db2bae30SDana Myers break;
649db2bae30SDana Myers
650db2bae30SDana Myers default:
651db2bae30SDana Myers
652db2bae30SDana Myers Status = AcpiDsEvalDataObjectOperands (WalkState, Op, NULL);
653db2bae30SDana Myers break;
654db2bae30SDana Myers }
655db2bae30SDana Myers
656db2bae30SDana Myers /*
657db2bae30SDana Myers * If a result object was returned from above, push it on the
658db2bae30SDana Myers * current result stack
659db2bae30SDana Myers */
660db2bae30SDana Myers if (WalkState->ResultObj)
661db2bae30SDana Myers {
662db2bae30SDana Myers Status = AcpiDsResultPush (WalkState->ResultObj, WalkState);
663db2bae30SDana Myers }
664db2bae30SDana Myers break;
665db2bae30SDana Myers
666db2bae30SDana Myers case AML_TYPE_NAMED_FIELD:
667db2bae30SDana Myers case AML_TYPE_NAMED_COMPLEX:
668db2bae30SDana Myers case AML_TYPE_NAMED_SIMPLE:
669db2bae30SDana Myers case AML_TYPE_NAMED_NO_OBJ:
670db2bae30SDana Myers
671db2bae30SDana Myers Status = AcpiDsLoad2EndOp (WalkState);
672db2bae30SDana Myers if (ACPI_FAILURE (Status))
673db2bae30SDana Myers {
674db2bae30SDana Myers break;
675db2bae30SDana Myers }
676db2bae30SDana Myers
677db2bae30SDana Myers if (Op->Common.AmlOpcode == AML_REGION_OP)
678db2bae30SDana Myers {
679db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
680db2bae30SDana Myers "Executing OpRegion Address/Length Op=%p\n", Op));
681db2bae30SDana Myers
682db2bae30SDana Myers Status = AcpiDsEvalRegionOperands (WalkState, Op);
683db2bae30SDana Myers if (ACPI_FAILURE (Status))
684db2bae30SDana Myers {
685db2bae30SDana Myers break;
686db2bae30SDana Myers }
687db2bae30SDana Myers }
688db2bae30SDana Myers else if (Op->Common.AmlOpcode == AML_DATA_REGION_OP)
689db2bae30SDana Myers {
690db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
691db2bae30SDana Myers "Executing DataTableRegion Strings Op=%p\n", Op));
692db2bae30SDana Myers
693db2bae30SDana Myers Status = AcpiDsEvalTableRegionOperands (WalkState, Op);
694db2bae30SDana Myers if (ACPI_FAILURE (Status))
695db2bae30SDana Myers {
696db2bae30SDana Myers break;
697db2bae30SDana Myers }
698db2bae30SDana Myers }
699db2bae30SDana Myers else if (Op->Common.AmlOpcode == AML_BANK_FIELD_OP)
700db2bae30SDana Myers {
701db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
702db2bae30SDana Myers "Executing BankField Op=%p\n", Op));
703db2bae30SDana Myers
704db2bae30SDana Myers Status = AcpiDsEvalBankFieldOperands (WalkState, Op);
705db2bae30SDana Myers if (ACPI_FAILURE (Status))
706db2bae30SDana Myers {
707db2bae30SDana Myers break;
708db2bae30SDana Myers }
709db2bae30SDana Myers }
710db2bae30SDana Myers break;
711db2bae30SDana Myers
712db2bae30SDana Myers case AML_TYPE_UNDEFINED:
713db2bae30SDana Myers
714db2bae30SDana Myers ACPI_ERROR ((AE_INFO,
715db2bae30SDana Myers "Undefined opcode type Op=%p", Op));
716db2bae30SDana Myers return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
717db2bae30SDana Myers
718db2bae30SDana Myers case AML_TYPE_BOGUS:
719db2bae30SDana Myers
720db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
721db2bae30SDana Myers "Internal opcode=%X type Op=%p\n",
722db2bae30SDana Myers WalkState->Opcode, Op));
723db2bae30SDana Myers break;
724db2bae30SDana Myers
725db2bae30SDana Myers default:
726db2bae30SDana Myers
727db2bae30SDana Myers ACPI_ERROR ((AE_INFO,
728*385cc6b4SJerry Jelinek "Unimplemented opcode, class=0x%X "
729*385cc6b4SJerry Jelinek "type=0x%X Opcode=0x%X Op=%p",
730db2bae30SDana Myers OpClass, OpType, Op->Common.AmlOpcode, Op));
731db2bae30SDana Myers
732db2bae30SDana Myers Status = AE_NOT_IMPLEMENTED;
733db2bae30SDana Myers break;
734db2bae30SDana Myers }
735db2bae30SDana Myers }
736db2bae30SDana Myers
737db2bae30SDana Myers /*
738db2bae30SDana Myers * ACPI 2.0 support for 64-bit integers: Truncate numeric
739db2bae30SDana Myers * result value if we are executing from a 32-bit ACPI table
740db2bae30SDana Myers */
741*385cc6b4SJerry Jelinek (void) AcpiExTruncateFor32bitTable (WalkState->ResultObj);
742db2bae30SDana Myers
743db2bae30SDana Myers /*
744db2bae30SDana Myers * Check if we just completed the evaluation of a
745db2bae30SDana Myers * conditional predicate
746db2bae30SDana Myers */
747db2bae30SDana Myers if ((ACPI_SUCCESS (Status)) &&
748db2bae30SDana Myers (WalkState->ControlState) &&
749db2bae30SDana Myers (WalkState->ControlState->Common.State ==
750db2bae30SDana Myers ACPI_CONTROL_PREDICATE_EXECUTING) &&
751db2bae30SDana Myers (WalkState->ControlState->Control.PredicateOp == Op))
752db2bae30SDana Myers {
753db2bae30SDana Myers Status = AcpiDsGetPredicateValue (WalkState, WalkState->ResultObj);
754db2bae30SDana Myers WalkState->ResultObj = NULL;
755db2bae30SDana Myers }
756db2bae30SDana Myers
757db2bae30SDana Myers
758db2bae30SDana Myers Cleanup:
759db2bae30SDana Myers
760db2bae30SDana Myers if (WalkState->ResultObj)
761db2bae30SDana Myers {
762*385cc6b4SJerry Jelinek #ifdef ACPI_DEBUGGER
763db2bae30SDana Myers /* Break to debugger to display result */
764db2bae30SDana Myers
765*385cc6b4SJerry Jelinek AcpiDbDisplayResultObject (WalkState->ResultObj,WalkState);
766*385cc6b4SJerry Jelinek #endif
767db2bae30SDana Myers
768db2bae30SDana Myers /*
769db2bae30SDana Myers * Delete the result op if and only if:
770db2bae30SDana Myers * Parent will not use the result -- such as any
771db2bae30SDana Myers * non-nested type2 op in a method (parent will be method)
772db2bae30SDana Myers */
773db2bae30SDana Myers AcpiDsDeleteResultIfNotUsed (Op, WalkState->ResultObj, WalkState);
774db2bae30SDana Myers }
775db2bae30SDana Myers
776db2bae30SDana Myers #ifdef _UNDER_DEVELOPMENT
777db2bae30SDana Myers
778db2bae30SDana Myers if (WalkState->ParserState.Aml == WalkState->ParserState.AmlEnd)
779db2bae30SDana Myers {
780db2bae30SDana Myers AcpiDbMethodEnd (WalkState);
781db2bae30SDana Myers }
782db2bae30SDana Myers #endif
783db2bae30SDana Myers
784db2bae30SDana Myers /* Invoke exception handler on error */
785db2bae30SDana Myers
786db2bae30SDana Myers if (ACPI_FAILURE (Status))
787db2bae30SDana Myers {
788db2bae30SDana Myers Status = AcpiDsMethodError (Status, WalkState);
789db2bae30SDana Myers }
790db2bae30SDana Myers
791db2bae30SDana Myers /* Always clear the object stack */
792db2bae30SDana Myers
793db2bae30SDana Myers WalkState->NumOperands = 0;
794db2bae30SDana Myers return_ACPI_STATUS (Status);
795db2bae30SDana Myers }
796