1 /******************************************************************************
3 * Module Name: dswexec - Dispatcher method execution callbacks;
4 * dispatch to interpreter.
7 *****************************************************************************/
9 /******************************************************************************
13 * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
14 * All rights reserved.
18 * 2.1. This is your license from Intel Corp. under its intellectual property
19 * rights. You may have additional license terms from the party that provided
20 * you this software, covering your right to use that party's intellectual
23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24 * copy of the source code appearing in this file ("Covered Code") an
25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26 * base code distributed originally by Intel ("Original Intel Code") to copy,
27 * make derivatives, distribute, use and display any portion of the Covered
28 * Code in any form, with the right to sublicense such rights; and
30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31 * license (with the right to sublicense), under only those claims of Intel
32 * patents that are infringed by the Original Intel Code, to make, use, sell,
33 * offer to sell, and import the Covered Code and derivative works thereof
34 * solely to the minimum extent necessary to exercise the above copyright
35 * license, and in no event shall the patent license extend to any additions
36 * to or modifications of the Original Intel Code. No other license or right
37 * is granted directly or by implication, estoppel or otherwise;
39 * The above copyright and patent license is granted only if the following
44 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45 * Redistribution of source code of any substantial portion of the Covered
46 * Code or modification with rights to further distribute source must include
47 * the above Copyright Notice, the above License, this list of Conditions,
48 * and the following Disclaimer and Export Compliance provision. In addition,
49 * Licensee must cause all Covered Code to which Licensee contributes to
50 * contain a file documenting the changes Licensee made to create that Covered
51 * Code and the date of any change. Licensee must include in that file the
52 * documentation of any changes made by any predecessor Licensee. Licensee
53 * must include a prominent statement that the modification is derived,
54 * directly or indirectly, from Original Intel Code.
56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57 * Redistribution of source code of any substantial portion of the Covered
58 * Code or modification without rights to further distribute source must
59 * include the following Disclaimer and Export Compliance provision in the
60 * documentation and/or other materials provided with distribution. In
61 * addition, Licensee may not authorize further sublicense of source of any
62 * portion of the Covered Code, and must include terms to the effect that the
63 * license from Licensee to its licensee is limited to the intellectual
64 * property embodied in the software Licensee provides to its licensee, and
65 * not to intellectual property embodied in modifications its licensee may
68 * 3.3. Redistribution of Executable. Redistribution in executable form of any
69 * substantial portion of the Covered Code or modification must reproduce the
70 * above Copyright Notice, and the following Disclaimer and Export Compliance
71 * provision in the documentation and/or other materials provided with the
74 * 3.4. Intel retains all right, title, and interest in and to the Original
77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78 * Intel shall be used in advertising or otherwise to promote the sale, use or
79 * other dealings in products derived from or relating to the Covered Code
80 * without prior written authorization from Intel.
82 * 4. Disclaimer and Export Compliance
84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
87 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
88 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
101 * 4.3. Licensee shall not export, either directly or indirectly, any of this
102 * software or system incorporating such software without first obtaining any
103 * required license or other approval from the U. S. Department of Commerce or
104 * any other agency or department of the United States Government. In the
105 * event Licensee exports any such software from the United States or
106 * re-exports any such software from a foreign destination, Licensee shall
107 * ensure that the distribution and export/re-export of the software is in
108 * compliance with all laws, regulations, orders, or other restrictions of the
109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110 * any of its subsidiaries will export/re-export any technical data, process,
111 * software, or service, directly or indirectly, to any country for which the
112 * United States government or any agency thereof requires an export license,
113 * other governmental approval, or letter of assurance, without first obtaining
114 * such license, approval or letter.
116 *****************************************************************************/
118 #define __DSWEXEC_C__
121 #include "acparser.h"
123 #include "acdispat.h"
124 #include "acinterp.h"
125 #include "acnamesp.h"
129 #define _COMPONENT ACPI_DISPATCHER
130 MODULE_NAME ("dswexec")
133 /*****************************************************************************
135 * FUNCTION: AcpiDsGetPredicateValue
137 * PARAMETERS: WalkState - Current state of the parse tree walk
141 * DESCRIPTION: Get the result of a predicate evaluation
143 ****************************************************************************/
146 AcpiDsGetPredicateValue (
147 ACPI_WALK_STATE *WalkState,
148 ACPI_PARSE_OBJECT *Op,
151 ACPI_STATUS Status = AE_OK;
152 ACPI_OPERAND_OBJECT *ObjDesc;
155 FUNCTION_TRACE_PTR ("DsGetPredicateValue", WalkState);
158 WalkState->ControlState->Common.State = 0;
162 Status = AcpiDsResultPop (&ObjDesc, WalkState);
163 if (ACPI_FAILURE (Status))
165 DEBUG_PRINTP (ACPI_ERROR,
166 ("Could not get result from predicate evaluation, %s\n",
167 AcpiUtFormatException (Status)));
169 return_ACPI_STATUS (Status);
175 Status = AcpiDsCreateOperand (WalkState, Op, 0);
176 if (ACPI_FAILURE (Status))
178 return_ACPI_STATUS (Status);
181 Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
182 if (ACPI_FAILURE (Status))
184 return_ACPI_STATUS (Status);
187 ObjDesc = WalkState->Operands [0];
192 DEBUG_PRINTP (ACPI_ERROR, ("No predicate ObjDesc=%X State=%X\n",
193 ObjDesc, WalkState));
195 return_ACPI_STATUS (AE_AML_NO_OPERAND);
200 * Result of predicate evaluation currently must
204 if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
206 DEBUG_PRINTP (ACPI_ERROR,
207 ("Bad predicate (not a number) ObjDesc=%X State=%X Type=%X\n",
208 ObjDesc, WalkState, ObjDesc->Common.Type));
210 Status = AE_AML_OPERAND_TYPE;
215 /* Truncate the predicate to 32-bits if necessary */
217 AcpiExTruncateFor32bitTable (ObjDesc, WalkState);
220 * Save the result of the predicate evaluation on
224 if (ObjDesc->Integer.Value)
226 WalkState->ControlState->Common.Value = TRUE;
232 * Predicate is FALSE, we will just toss the
233 * rest of the package
236 WalkState->ControlState->Common.Value = FALSE;
237 Status = AE_CTRL_FALSE;
243 DEBUG_PRINTP (TRACE_EXEC, ("Completed a predicate eval=%X Op=%X\n",
244 WalkState->ControlState->Common.Value, Op));
246 /* Break to debugger to display result */
248 DEBUGGER_EXEC (AcpiDbDisplayResultObject (ObjDesc, WalkState));
251 * Delete the predicate result object (we know that
252 * we don't need it anymore)
255 AcpiUtRemoveReference (ObjDesc);
257 WalkState->ControlState->Common.State = CONTROL_NORMAL;
259 return_ACPI_STATUS (Status);
263 /*****************************************************************************
265 * FUNCTION: AcpiDsExecBeginOp
267 * PARAMETERS: WalkState - Current state of the parse tree walk
268 * Op - Op that has been just been reached in the
269 * walk; Arguments have not been evaluated yet.
273 * DESCRIPTION: Descending callback used during the execution of control
274 * methods. This is where most operators and operands are
275 * dispatched to the interpreter.
277 ****************************************************************************/
282 ACPI_PARSE_OBJECT *Op,
283 ACPI_WALK_STATE *WalkState,
284 ACPI_PARSE_OBJECT **OutOp)
286 ACPI_OPCODE_INFO *OpInfo;
287 ACPI_STATUS Status = AE_OK;
290 FUNCTION_TRACE_PTR ("DsExecBeginOp", Op);
295 Status = AcpiDsLoad2BeginOp (Opcode, NULL, WalkState, OutOp);
296 if (ACPI_FAILURE (Status))
298 return_ACPI_STATUS (Status);
304 if (Op == WalkState->Origin)
311 return_ACPI_STATUS (AE_OK);
315 * If the previous opcode was a conditional, this opcode
316 * must be the beginning of the associated predicate.
317 * Save this knowledge in the current scope descriptor
320 if ((WalkState->ControlState) &&
321 (WalkState->ControlState->Common.State ==
322 CONTROL_CONDITIONAL_EXECUTING))
324 DEBUG_PRINTP (TRACE_EXEC, ("Exec predicate Op=%X State=%X\n",
327 WalkState->ControlState->Common.State = CONTROL_PREDICATE_EXECUTING;
329 /* Save start of predicate */
331 WalkState->ControlState->Control.PredicateOp = Op;
335 OpInfo = AcpiPsGetOpcodeInfo (Op->Opcode);
337 /* We want to send namepaths to the load code */
339 if (Op->Opcode == AML_INT_NAMEPATH_OP)
341 OpInfo->Flags = OPTYPE_NAMED_OBJECT;
346 * Handle the opcode based upon the opcode type
349 switch (ACPI_GET_OP_CLASS (OpInfo))
353 Status = AcpiDsResultStackPush (WalkState);
354 if (ACPI_FAILURE (Status))
356 return_ACPI_STATUS (Status);
359 Status = AcpiDsExecBeginControlOp (WalkState, Op);
363 case OPTYPE_NAMED_OBJECT:
365 if (WalkState->WalkType == WALK_METHOD)
368 * Found a named object declaration during method
369 * execution; we must enter this object into the
370 * namespace. The created object is temporary and
371 * will be deleted upon completion of the execution
375 Status = AcpiDsLoad2BeginOp (Op->Opcode, Op, WalkState, NULL);
379 if (Op->Opcode == AML_REGION_OP)
381 Status = AcpiDsResultStackPush (WalkState);
387 /* most operators with arguments */
389 case OPTYPE_MONADIC1:
391 case OPTYPE_MONADIC2:
392 case OPTYPE_MONADIC2R:
394 case OPTYPE_DYADIC2R:
395 case OPTYPE_DYADIC2S:
396 case OPTYPE_RECONFIGURATION:
400 case OPTYPE_CREATE_FIELD:
402 /* Start a new result/operand state */
404 Status = AcpiDsResultStackPush (WalkState);
412 /* Nothing to do here during method execution */
414 return_ACPI_STATUS (Status);
418 /*****************************************************************************
420 * FUNCTION: AcpiDsExecEndOp
422 * PARAMETERS: WalkState - Current state of the parse tree walk
423 * Op - Op that has been just been completed in the
424 * walk; Arguments have now been evaluated.
428 * DESCRIPTION: Ascending callback used during the execution of control
429 * methods. The only thing we really need to do here is to
430 * notice the beginning of IF, ELSE, and WHILE blocks.
432 ****************************************************************************/
436 ACPI_WALK_STATE *WalkState,
437 ACPI_PARSE_OBJECT *Op)
439 ACPI_STATUS Status = AE_OK;
442 ACPI_PARSE_OBJECT *NextOp;
443 ACPI_PARSE_OBJECT *FirstArg;
444 ACPI_OPERAND_OBJECT *ResultObj = NULL;
445 ACPI_OPCODE_INFO *OpInfo;
448 FUNCTION_TRACE_PTR ("DsExecEndOp", Op);
451 Opcode = (UINT16) Op->Opcode;
454 OpInfo = AcpiPsGetOpcodeInfo (Op->Opcode);
455 if (ACPI_GET_OP_TYPE (OpInfo) != ACPI_OP_TYPE_OPCODE)
457 DEBUG_PRINTP (ACPI_ERROR, ("Unknown opcode %X\n", Op->Opcode));
458 return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
461 Optype = (UINT8) ACPI_GET_OP_CLASS (OpInfo);
462 FirstArg = Op->Value.Arg;
464 /* Init the walk state */
466 WalkState->NumOperands = 0;
467 WalkState->ReturnDesc = NULL;
468 WalkState->OpInfo = OpInfo;
469 WalkState->Opcode = Opcode;
472 /* Call debugger for single step support (DEBUG build only) */
474 DEBUGGER_EXEC (Status = AcpiDbSingleStep (WalkState, Op, Optype));
475 DEBUGGER_EXEC (if (ACPI_FAILURE (Status)) {return_ACPI_STATUS (Status);});
478 /* Decode the opcode */
482 case OPTYPE_UNDEFINED:
484 DEBUG_PRINTP (ACPI_ERROR, ("Undefined opcode type Op=%X\n", Op));
485 return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
490 DEBUG_PRINTP (TRACE_DISPATCH, ("Internal opcode=%X type Op=%X\n",
494 case OPTYPE_CONSTANT: /* argument type only */
495 case OPTYPE_LITERAL: /* argument type only */
496 case OPTYPE_DATA_TERM: /* argument type only */
497 case OPTYPE_LOCAL_VARIABLE: /* argument type only */
498 case OPTYPE_METHOD_ARGUMENT: /* argument type only */
502 /* most operators with arguments */
504 case OPTYPE_MONADIC1:
506 case OPTYPE_MONADIC2:
507 case OPTYPE_MONADIC2R:
509 case OPTYPE_DYADIC2R:
510 case OPTYPE_DYADIC2S:
511 case OPTYPE_RECONFIGURATION:
517 /* Build resolved operand stack */
519 Status = AcpiDsCreateOperands (WalkState, FirstArg);
520 if (ACPI_FAILURE (Status))
525 /* Done with this result state (Now that operand stack is built) */
527 Status = AcpiDsResultStackPop (WalkState);
528 if (ACPI_FAILURE (Status))
535 case OPTYPE_MONADIC1:
537 /* 1 Operand, 0 ExternalResult, 0 InternalResult */
539 Status = AcpiExMonadic1 (Opcode, WalkState);
543 case OPTYPE_MONADIC2:
545 /* 1 Operand, 0 ExternalResult, 1 InternalResult */
547 Status = AcpiExMonadic2 (Opcode, WalkState, &ResultObj);
551 case OPTYPE_MONADIC2R:
553 /* 1 Operand, 1 ExternalResult, 1 InternalResult */
555 Status = AcpiExMonadic2R (Opcode, WalkState, &ResultObj);
561 /* 2 Operands, 0 ExternalResult, 0 InternalResult */
563 Status = AcpiExDyadic1 (Opcode, WalkState);
569 /* 2 Operands, 0 ExternalResult, 1 InternalResult */
571 Status = AcpiExDyadic2 (Opcode, WalkState, &ResultObj);
575 case OPTYPE_DYADIC2R:
577 /* 2 Operands, 1 or 2 ExternalResults, 1 InternalResult */
579 Status = AcpiExDyadic2R (Opcode, WalkState, &ResultObj);
583 case OPTYPE_DYADIC2S: /* Synchronization Operator */
585 /* 2 Operands, 0 ExternalResult, 1 InternalResult */
587 Status = AcpiExDyadic2S (Opcode, WalkState, &ResultObj);
591 case OPTYPE_INDEX: /* Type 2 opcode with 3 operands */
593 /* 3 Operands, 1 ExternalResult, 1 InternalResult */
595 Status = AcpiExIndex (WalkState, &ResultObj);
599 case OPTYPE_MATCH: /* Type 2 opcode with 6 operands */
601 /* 6 Operands, 0 ExternalResult, 1 InternalResult */
603 Status = AcpiExMatch (WalkState, &ResultObj);
607 case OPTYPE_RECONFIGURATION:
609 /* 1 or 2 operands, 0 Internal Result */
611 Status = AcpiExReconfiguration (Opcode, WalkState);
617 /* 3 Operands, 0 ExternalResult, 0 InternalResult */
619 Status = AcpiExFatal (WalkState);
624 * If a result object was returned from above, push it on the
625 * current result stack
627 if (ACPI_SUCCESS (Status) &&
630 Status = AcpiDsResultPush (ResultObj, WalkState);
636 case OPTYPE_CONTROL: /* Type 1 opcode, IF/ELSE/WHILE/NOOP */
638 /* 1 Operand, 0 ExternalResult, 0 InternalResult */
640 Status = AcpiDsExecEndControlOp (WalkState, Op);
642 AcpiDsResultStackPop (WalkState);
646 case OPTYPE_METHOD_CALL:
648 DEBUG_PRINTP (TRACE_DISPATCH, ("Method invocation, Op=%X\n", Op));
651 * (AML_METHODCALL) Op->Value->Arg->Node contains
652 * the method Node pointer
654 /* NextOp points to the op that holds the method name */
658 /* NextOp points to first argument op */
660 NextOp = NextOp->Next;
663 * Get the method's arguments and put them on the operand stack
665 Status = AcpiDsCreateOperands (WalkState, NextOp);
666 if (ACPI_FAILURE (Status))
672 * Since the operands will be passed to another
673 * control method, we must resolve all local
674 * references here (Local variables, arguments
675 * to *this* method, etc.)
678 Status = AcpiDsResolveOperands (WalkState);
679 if (ACPI_FAILURE (Status))
685 * Tell the walk loop to preempt this running method and
686 * execute the new method
688 Status = AE_CTRL_TRANSFER;
691 * Return now; we don't want to disturb anything,
692 * especially the operand count!
694 return_ACPI_STATUS (Status);
698 case OPTYPE_CREATE_FIELD:
700 DEBUG_PRINTP (TRACE_EXEC,
701 ("Executing CreateField Buffer/Index Op=%X\n", Op));
703 Status = AcpiDsLoad2EndOp (WalkState, Op);
704 if (ACPI_FAILURE (Status))
709 Status = AcpiDsEvalBufferFieldOperands (WalkState, Op);
713 case OPTYPE_NAMED_OBJECT:
715 Status = AcpiDsLoad2EndOp (WalkState, Op);
716 if (ACPI_FAILURE (Status))
725 DEBUG_PRINTP (TRACE_EXEC,
726 ("Executing OpRegion Address/Length Op=%X\n", Op));
728 Status = AcpiDsEvalRegionOperands (WalkState, Op);
729 if (ACPI_FAILURE (Status))
734 Status = AcpiDsResultStackPop (WalkState);
744 /* Alias creation was already handled by call
750 /* Nothing needs to be done */
760 DEBUG_PRINTP (ACPI_ERROR,
761 ("Unimplemented opcode, type=%X Opcode=%X Op=%X\n",
762 Optype, Op->Opcode, Op));
764 Status = AE_NOT_IMPLEMENTED;
770 * ACPI 2.0 support for 64-bit integers:
771 * Truncate numeric result value if we are executing from a 32-bit ACPI table
773 AcpiExTruncateFor32bitTable (ResultObj, WalkState);
776 * Check if we just completed the evaluation of a
777 * conditional predicate
780 if ((WalkState->ControlState) &&
781 (WalkState->ControlState->Common.State ==
782 CONTROL_PREDICATE_EXECUTING) &&
783 (WalkState->ControlState->Control.PredicateOp == Op))
785 Status = AcpiDsGetPredicateValue (WalkState, Op, (UINT32) ResultObj);
793 /* Break to debugger to display result */
795 DEBUGGER_EXEC (AcpiDbDisplayResultObject (ResultObj, WalkState));
798 * Delete the result op if and only if:
799 * Parent will not use the result -- such as any
800 * non-nested type2 op in a method (parent will be method)
802 AcpiDsDeleteResultIfNotUsed (Op, ResultObj, WalkState);
805 /* Always clear the object stack */
807 /* TBD: [Investigate] Clear stack of return value,
808 but don't delete it */
809 WalkState->NumOperands = 0;
811 return_ACPI_STATUS (Status);