dswexec.c revision 245582
167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: dswexec - Dispatcher method execution callbacks; 467754Smsmith * dispatch to interpreter. 567754Smsmith * 667754Smsmith *****************************************************************************/ 767754Smsmith 8217365Sjkim/* 9245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp. 1070243Smsmith * All rights reserved. 1167754Smsmith * 12217365Sjkim * Redistribution and use in source and binary forms, with or without 13217365Sjkim * modification, are permitted provided that the following conditions 14217365Sjkim * are met: 15217365Sjkim * 1. Redistributions of source code must retain the above copyright 16217365Sjkim * notice, this list of conditions, and the following disclaimer, 17217365Sjkim * without modification. 18217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 20217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 21217365Sjkim * including a substantially similar Disclaimer requirement for further 22217365Sjkim * binary redistribution. 23217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 24217365Sjkim * of any contributors may be used to endorse or promote products derived 25217365Sjkim * from this software without specific prior written permission. 2667754Smsmith * 27217365Sjkim * Alternatively, this software may be distributed under the terms of the 28217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 29217365Sjkim * Software Foundation. 3067754Smsmith * 31217365Sjkim * NO WARRANTY 32217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 43217365Sjkim */ 4467754Smsmith 4567754Smsmith#define __DSWEXEC_C__ 4667754Smsmith 47193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 48193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 49193341Sjkim#include <contrib/dev/acpica/include/acparser.h> 50193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 51193341Sjkim#include <contrib/dev/acpica/include/acdispat.h> 52193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 53193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 54193341Sjkim#include <contrib/dev/acpica/include/acdebug.h> 5567754Smsmith 5667754Smsmith 5777424Smsmith#define _COMPONENT ACPI_DISPATCHER 5891116Smsmith ACPI_MODULE_NAME ("dswexec") 5967754Smsmith 6085756Smsmith/* 6187031Smsmith * Dispatch table for opcode classes 6285756Smsmith */ 63167802Sjkimstatic ACPI_EXECUTE_OP AcpiGbl_OpTypeDispatch [] = 64167802Sjkim{ 65167802Sjkim AcpiExOpcode_0A_0T_1R, 66167802Sjkim AcpiExOpcode_1A_0T_0R, 67167802Sjkim AcpiExOpcode_1A_0T_1R, 68167802Sjkim AcpiExOpcode_1A_1T_0R, 69167802Sjkim AcpiExOpcode_1A_1T_1R, 70167802Sjkim AcpiExOpcode_2A_0T_0R, 71167802Sjkim AcpiExOpcode_2A_0T_1R, 72167802Sjkim AcpiExOpcode_2A_1T_1R, 73167802Sjkim AcpiExOpcode_2A_2T_1R, 74167802Sjkim AcpiExOpcode_3A_0T_0R, 75167802Sjkim AcpiExOpcode_3A_1T_1R, 76167802Sjkim AcpiExOpcode_6A_0T_1R 77167802Sjkim}; 7867754Smsmith 79151937Sjkim 8067754Smsmith/***************************************************************************** 8167754Smsmith * 8267754Smsmith * FUNCTION: AcpiDsGetPredicateValue 8367754Smsmith * 8467754Smsmith * PARAMETERS: WalkState - Current state of the parse tree walk 85151937Sjkim * ResultObj - if non-zero, pop result from result stack 8667754Smsmith * 8767754Smsmith * RETURN: Status 8867754Smsmith * 8971867Smsmith * DESCRIPTION: Get the result of a predicate evaluation 9067754Smsmith * 9167754Smsmith ****************************************************************************/ 9267754Smsmith 9367754SmsmithACPI_STATUS 9467754SmsmithAcpiDsGetPredicateValue ( 9567754Smsmith ACPI_WALK_STATE *WalkState, 9691116Smsmith ACPI_OPERAND_OBJECT *ResultObj) 9767754Smsmith{ 9867754Smsmith ACPI_STATUS Status = AE_OK; 9967754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 100151937Sjkim ACPI_OPERAND_OBJECT *LocalObjDesc = NULL; 10167754Smsmith 10267754Smsmith 103167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsGetPredicateValue, WalkState); 10467754Smsmith 10567754Smsmith 10667754Smsmith WalkState->ControlState->Common.State = 0; 10767754Smsmith 10891116Smsmith if (ResultObj) 10967754Smsmith { 11069746Smsmith Status = AcpiDsResultPop (&ObjDesc, WalkState); 11167754Smsmith if (ACPI_FAILURE (Status)) 11267754Smsmith { 113167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 114167802Sjkim "Could not get result from predicate evaluation")); 11569450Smsmith 11667754Smsmith return_ACPI_STATUS (Status); 11767754Smsmith } 11867754Smsmith } 11967754Smsmith else 12067754Smsmith { 12184491Smsmith Status = AcpiDsCreateOperand (WalkState, WalkState->Op, 0); 12267754Smsmith if (ACPI_FAILURE (Status)) 12367754Smsmith { 12467754Smsmith return_ACPI_STATUS (Status); 12567754Smsmith } 12667754Smsmith 12777424Smsmith Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState); 12867754Smsmith if (ACPI_FAILURE (Status)) 12967754Smsmith { 13067754Smsmith return_ACPI_STATUS (Status); 13167754Smsmith } 13267754Smsmith 13367754Smsmith ObjDesc = WalkState->Operands [0]; 13467754Smsmith } 13567754Smsmith 13667754Smsmith if (!ObjDesc) 13767754Smsmith { 138167802Sjkim ACPI_ERROR ((AE_INFO, 139167802Sjkim "No predicate ObjDesc=%p State=%p", 14067754Smsmith ObjDesc, WalkState)); 14167754Smsmith 14267754Smsmith return_ACPI_STATUS (AE_AML_NO_OPERAND); 14367754Smsmith } 14467754Smsmith 14569450Smsmith /* 146151937Sjkim * Result of predicate evaluation must be an Integer 147151937Sjkim * object. Implicitly convert the argument if necessary. 14867754Smsmith */ 149151937Sjkim Status = AcpiExConvertToInteger (ObjDesc, &LocalObjDesc, 16); 150151937Sjkim if (ACPI_FAILURE (Status)) 15167754Smsmith { 152151937Sjkim goto Cleanup; 153151937Sjkim } 154151937Sjkim 155193267Sjkim if (LocalObjDesc->Common.Type != ACPI_TYPE_INTEGER) 156151937Sjkim { 157167802Sjkim ACPI_ERROR ((AE_INFO, 158204773Sjkim "Bad predicate (not an integer) ObjDesc=%p State=%p Type=0x%X", 159193267Sjkim ObjDesc, WalkState, ObjDesc->Common.Type)); 16067754Smsmith 16167754Smsmith Status = AE_AML_OPERAND_TYPE; 16267754Smsmith goto Cleanup; 16367754Smsmith } 16467754Smsmith 16571867Smsmith /* Truncate the predicate to 32-bits if necessary */ 16669450Smsmith 167245582Sjkim (void) AcpiExTruncateFor32bitTable (LocalObjDesc); 16869450Smsmith 16969450Smsmith /* 17067754Smsmith * Save the result of the predicate evaluation on 17169450Smsmith * the control stack 17267754Smsmith */ 173151937Sjkim if (LocalObjDesc->Integer.Value) 17467754Smsmith { 17567754Smsmith WalkState->ControlState->Common.Value = TRUE; 17667754Smsmith } 17767754Smsmith else 17867754Smsmith { 17969450Smsmith /* 18067754Smsmith * Predicate is FALSE, we will just toss the 18169450Smsmith * rest of the package 18267754Smsmith */ 18367754Smsmith WalkState->ControlState->Common.Value = FALSE; 18467754Smsmith Status = AE_CTRL_FALSE; 18567754Smsmith } 18667754Smsmith 187193267Sjkim /* Predicate can be used for an implicit return value */ 18867754Smsmith 189193267Sjkim (void) AcpiDsDoImplicitReturn (LocalObjDesc, WalkState, TRUE); 190193267Sjkim 191193267Sjkim 19267754SmsmithCleanup: 19367754Smsmith 19487031Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n", 19584491Smsmith WalkState->ControlState->Common.Value, WalkState->Op)); 19667754Smsmith 19767754Smsmith /* Break to debugger to display result */ 19867754Smsmith 199151937Sjkim ACPI_DEBUGGER_EXEC (AcpiDbDisplayResultObject (LocalObjDesc, WalkState)); 20067754Smsmith 20169450Smsmith /* 20267754Smsmith * Delete the predicate result object (we know that 20367754Smsmith * we don't need it anymore) 20467754Smsmith */ 205151937Sjkim if (LocalObjDesc != ObjDesc) 206151937Sjkim { 207151937Sjkim AcpiUtRemoveReference (LocalObjDesc); 208151937Sjkim } 20977424Smsmith AcpiUtRemoveReference (ObjDesc); 21067754Smsmith 21191116Smsmith WalkState->ControlState->Common.State = ACPI_CONTROL_NORMAL; 21267754Smsmith return_ACPI_STATUS (Status); 21367754Smsmith} 21467754Smsmith 21567754Smsmith 21667754Smsmith/***************************************************************************** 21767754Smsmith * 21867754Smsmith * FUNCTION: AcpiDsExecBeginOp 21967754Smsmith * 22067754Smsmith * PARAMETERS: WalkState - Current state of the parse tree walk 221151937Sjkim * OutOp - Where to return op if a new one is created 22267754Smsmith * 22367754Smsmith * RETURN: Status 22467754Smsmith * 22567754Smsmith * DESCRIPTION: Descending callback used during the execution of control 226241973Sjkim * methods. This is where most operators and operands are 22767754Smsmith * dispatched to the interpreter. 22867754Smsmith * 22967754Smsmith ****************************************************************************/ 23067754Smsmith 23167754SmsmithACPI_STATUS 23267754SmsmithAcpiDsExecBeginOp ( 23367754Smsmith ACPI_WALK_STATE *WalkState, 23467754Smsmith ACPI_PARSE_OBJECT **OutOp) 23567754Smsmith{ 23684491Smsmith ACPI_PARSE_OBJECT *Op; 23767754Smsmith ACPI_STATUS Status = AE_OK; 23885756Smsmith UINT32 OpcodeClass; 23967754Smsmith 24067754Smsmith 241167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsExecBeginOp, WalkState); 24267754Smsmith 24367754Smsmith 24484491Smsmith Op = WalkState->Op; 24567754Smsmith if (!Op) 24667754Smsmith { 24784491Smsmith Status = AcpiDsLoad2BeginOp (WalkState, OutOp); 24867754Smsmith if (ACPI_FAILURE (Status)) 24967754Smsmith { 250167802Sjkim goto ErrorExit; 25167754Smsmith } 25267754Smsmith 25367754Smsmith Op = *OutOp; 25484491Smsmith WalkState->Op = Op; 25599679Siwasaki WalkState->Opcode = Op->Common.AmlOpcode; 25699679Siwasaki WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 25791116Smsmith 25891116Smsmith if (AcpiNsOpensScope (WalkState->OpInfo->ObjectType)) 25991116Smsmith { 260151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 261151937Sjkim "(%s) Popping scope for Op %p\n", 26291116Smsmith AcpiUtGetTypeName (WalkState->OpInfo->ObjectType), Op)); 26399679Siwasaki 26499679Siwasaki Status = AcpiDsScopeStackPop (WalkState); 26599679Siwasaki if (ACPI_FAILURE (Status)) 26699679Siwasaki { 267167802Sjkim goto ErrorExit; 26899679Siwasaki } 26991116Smsmith } 27067754Smsmith } 27167754Smsmith 27267754Smsmith if (Op == WalkState->Origin) 27367754Smsmith { 27467754Smsmith if (OutOp) 27567754Smsmith { 27667754Smsmith *OutOp = Op; 27767754Smsmith } 27867754Smsmith 27967754Smsmith return_ACPI_STATUS (AE_OK); 28067754Smsmith } 28167754Smsmith 28267754Smsmith /* 28367754Smsmith * If the previous opcode was a conditional, this opcode 28467754Smsmith * must be the beginning of the associated predicate. 28567754Smsmith * Save this knowledge in the current scope descriptor 28667754Smsmith */ 28767754Smsmith if ((WalkState->ControlState) && 28867754Smsmith (WalkState->ControlState->Common.State == 28991116Smsmith ACPI_CONTROL_CONDITIONAL_EXECUTING)) 29067754Smsmith { 29185756Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Exec predicate Op=%p State=%p\n", 29267754Smsmith Op, WalkState)); 29367754Smsmith 29491116Smsmith WalkState->ControlState->Common.State = ACPI_CONTROL_PREDICATE_EXECUTING; 29567754Smsmith 29667754Smsmith /* Save start of predicate */ 29767754Smsmith 29867754Smsmith WalkState->ControlState->Control.PredicateOp = Op; 29967754Smsmith } 30067754Smsmith 30167754Smsmith 30285756Smsmith OpcodeClass = WalkState->OpInfo->Class; 30367754Smsmith 30467754Smsmith /* We want to send namepaths to the load code */ 30567754Smsmith 30699679Siwasaki if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) 30767754Smsmith { 30885756Smsmith OpcodeClass = AML_CLASS_NAMED_OBJECT; 30967754Smsmith } 31067754Smsmith 31167754Smsmith /* 31267754Smsmith * Handle the opcode based upon the opcode type 31367754Smsmith */ 31483174Smsmith switch (OpcodeClass) 31567754Smsmith { 31685756Smsmith case AML_CLASS_CONTROL: 31767754Smsmith 31867754Smsmith Status = AcpiDsExecBeginControlOp (WalkState, Op); 31967754Smsmith break; 32067754Smsmith 32167754Smsmith 32285756Smsmith case AML_CLASS_NAMED_OBJECT: 32367754Smsmith 324167802Sjkim if (WalkState->WalkType & ACPI_WALK_METHOD) 32567754Smsmith { 32667754Smsmith /* 327151937Sjkim * Found a named object declaration during method execution; 328241973Sjkim * we must enter this object into the namespace. The created 329151937Sjkim * object is temporary and will be deleted upon completion of 330151937Sjkim * the execution of this method. 331216471Sjkim * 332216471Sjkim * Note 10/2010: Except for the Scope() op. This opcode does 333216471Sjkim * not actually create a new object, it refers to an existing 334216471Sjkim * object. However, for Scope(), we want to indeed open a 335216471Sjkim * new scope. 33667754Smsmith */ 337216471Sjkim if (Op->Common.AmlOpcode != AML_SCOPE_OP) 338216471Sjkim { 339216471Sjkim Status = AcpiDsLoad2BeginOp (WalkState, NULL); 340216471Sjkim } 341216471Sjkim else 342216471Sjkim { 343216471Sjkim Status = AcpiDsScopeStackPush (Op->Named.Node, 344216471Sjkim Op->Named.Node->Type, WalkState); 345216471Sjkim if (ACPI_FAILURE (Status)) 346216471Sjkim { 347216471Sjkim return_ACPI_STATUS (Status); 348216471Sjkim } 349216471Sjkim } 35067754Smsmith } 35167754Smsmith break; 35267754Smsmith 35367754Smsmith 35485756Smsmith case AML_CLASS_EXECUTE: 35585756Smsmith case AML_CLASS_CREATE: 35669746Smsmith 35769746Smsmith break; 35869746Smsmith 35969746Smsmith 36067754Smsmith default: 36167754Smsmith break; 36267754Smsmith } 36367754Smsmith 36467754Smsmith /* Nothing to do here during method execution */ 36567754Smsmith 36667754Smsmith return_ACPI_STATUS (Status); 367167802Sjkim 368167802Sjkim 369167802SjkimErrorExit: 370167802Sjkim Status = AcpiDsMethodError (Status, WalkState); 371167802Sjkim return_ACPI_STATUS (Status); 37267754Smsmith} 37367754Smsmith 37467754Smsmith 37567754Smsmith/***************************************************************************** 37667754Smsmith * 37767754Smsmith * FUNCTION: AcpiDsExecEndOp 37867754Smsmith * 37967754Smsmith * PARAMETERS: WalkState - Current state of the parse tree walk 38067754Smsmith * 38167754Smsmith * RETURN: Status 38267754Smsmith * 38367754Smsmith * DESCRIPTION: Ascending callback used during the execution of control 384241973Sjkim * methods. The only thing we really need to do here is to 38567754Smsmith * notice the beginning of IF, ELSE, and WHILE blocks. 38667754Smsmith * 38767754Smsmith ****************************************************************************/ 38867754Smsmith 38967754SmsmithACPI_STATUS 39067754SmsmithAcpiDsExecEndOp ( 39184491Smsmith ACPI_WALK_STATE *WalkState) 39267754Smsmith{ 39384491Smsmith ACPI_PARSE_OBJECT *Op; 39467754Smsmith ACPI_STATUS Status = AE_OK; 39585756Smsmith UINT32 OpType; 39685756Smsmith UINT32 OpClass; 39767754Smsmith ACPI_PARSE_OBJECT *NextOp; 39867754Smsmith ACPI_PARSE_OBJECT *FirstArg; 39967754Smsmith 40067754Smsmith 401167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsExecEndOp, WalkState); 40267754Smsmith 40367754Smsmith 40485756Smsmith Op = WalkState->Op; 40585756Smsmith OpType = WalkState->OpInfo->Type; 40685756Smsmith OpClass = WalkState->OpInfo->Class; 40767754Smsmith 40885756Smsmith if (OpClass == AML_CLASS_UNKNOWN) 40967754Smsmith { 410204773Sjkim ACPI_ERROR ((AE_INFO, "Unknown opcode 0x%X", Op->Common.AmlOpcode)); 41167754Smsmith return_ACPI_STATUS (AE_NOT_IMPLEMENTED); 41267754Smsmith } 41367754Smsmith 41499679Siwasaki FirstArg = Op->Common.Value.Arg; 41567754Smsmith 41667754Smsmith /* Init the walk state */ 41767754Smsmith 41867754Smsmith WalkState->NumOperands = 0; 419167802Sjkim WalkState->OperandIndex = 0; 42067754Smsmith WalkState->ReturnDesc = NULL; 42184491Smsmith WalkState->ResultObj = NULL; 42267754Smsmith 42367754Smsmith /* Call debugger for single step support (DEBUG build only) */ 42467754Smsmith 42591116Smsmith ACPI_DEBUGGER_EXEC (Status = AcpiDbSingleStep (WalkState, Op, OpClass)); 42691116Smsmith ACPI_DEBUGGER_EXEC (if (ACPI_FAILURE (Status)) {return_ACPI_STATUS (Status);}); 42767754Smsmith 42887031Smsmith /* Decode the Opcode Class */ 42967754Smsmith 43085756Smsmith switch (OpClass) 43167754Smsmith { 432167802Sjkim case AML_CLASS_ARGUMENT: /* Constants, literals, etc. */ 433167802Sjkim 434167802Sjkim if (WalkState->Opcode == AML_INT_NAMEPATH_OP) 435167802Sjkim { 436167802Sjkim Status = AcpiDsEvaluateNamePath (WalkState); 437167802Sjkim if (ACPI_FAILURE (Status)) 438167802Sjkim { 439167802Sjkim goto Cleanup; 440167802Sjkim } 441167802Sjkim } 44267754Smsmith break; 44367754Smsmith 44491116Smsmith 445167802Sjkim case AML_CLASS_EXECUTE: /* Most operators with arguments */ 44667754Smsmith 44769746Smsmith /* Build resolved operand stack */ 44869746Smsmith 44967754Smsmith Status = AcpiDsCreateOperands (WalkState, FirstArg); 45067754Smsmith if (ACPI_FAILURE (Status)) 45167754Smsmith { 45267754Smsmith goto Cleanup; 45367754Smsmith } 45467754Smsmith 455151937Sjkim /* 456151937Sjkim * All opcodes require operand resolution, with the only exceptions 457151937Sjkim * being the ObjectType and SizeOf operators. 458151937Sjkim */ 459151937Sjkim if (!(WalkState->OpInfo->Flags & AML_NO_OPERAND_RESOLVE)) 460151937Sjkim { 461151937Sjkim /* Resolve all operands */ 46283174Smsmith 463151937Sjkim Status = AcpiExResolveOperands (WalkState->Opcode, 46487031Smsmith &(WalkState->Operands [WalkState->NumOperands -1]), 46583174Smsmith WalkState); 466151937Sjkim } 467151937Sjkim 46887031Smsmith if (ACPI_SUCCESS (Status)) 46983174Smsmith { 47083174Smsmith /* 47187031Smsmith * Dispatch the request to the appropriate interpreter handler 472241973Sjkim * routine. There is one routine per opcode "type" based upon the 47387031Smsmith * number of opcode arguments and return type. 47483174Smsmith */ 475138287Smarks Status = AcpiGbl_OpTypeDispatch[OpType] (WalkState); 47683174Smsmith } 47787031Smsmith else 47887031Smsmith { 479123315Snjl /* 480123315Snjl * Treat constructs of the form "Store(LocalX,LocalX)" as noops when the 481123315Snjl * Local is uninitialized. 482123315Snjl */ 483123315Snjl if ((Status == AE_AML_UNINITIALIZED_LOCAL) && 484123315Snjl (WalkState->Opcode == AML_STORE_OP) && 485123315Snjl (WalkState->Operands[0]->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) && 486123315Snjl (WalkState->Operands[1]->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) && 487193267Sjkim (WalkState->Operands[0]->Reference.Class == 488193267Sjkim WalkState->Operands[1]->Reference.Class) && 489193267Sjkim (WalkState->Operands[0]->Reference.Value == 490193267Sjkim WalkState->Operands[1]->Reference.Value)) 491123315Snjl { 492123315Snjl Status = AE_OK; 493123315Snjl } 494123315Snjl else 495123315Snjl { 496167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 497167802Sjkim "While resolving operands for [%s]", 498167802Sjkim AcpiPsGetOpcodeName (WalkState->Opcode))); 499123315Snjl } 50087031Smsmith } 50183174Smsmith 50287031Smsmith /* Always delete the argument objects and clear the operand stack */ 50383174Smsmith 504107325Siwasaki AcpiDsClearOperands (WalkState); 50583174Smsmith 50669746Smsmith /* 50769746Smsmith * If a result object was returned from above, push it on the 50869746Smsmith * current result stack 50969746Smsmith */ 51069746Smsmith if (ACPI_SUCCESS (Status) && 51184491Smsmith WalkState->ResultObj) 51269746Smsmith { 51384491Smsmith Status = AcpiDsResultPush (WalkState->ResultObj, WalkState); 51469746Smsmith } 51567754Smsmith break; 51667754Smsmith 51767754Smsmith 51885756Smsmith default: 51967754Smsmith 52085756Smsmith switch (OpType) 52185756Smsmith { 52285756Smsmith case AML_TYPE_CONTROL: /* Type 1 opcode, IF/ELSE/WHILE/NOOP */ 52367754Smsmith 52485756Smsmith /* 1 Operand, 0 ExternalResult, 0 InternalResult */ 52567754Smsmith 52685756Smsmith Status = AcpiDsExecEndControlOp (WalkState, Op); 527151937Sjkim 52885756Smsmith break; 52967754Smsmith 53067754Smsmith 53185756Smsmith case AML_TYPE_METHOD_CALL: 53267754Smsmith 533151937Sjkim /* 534151937Sjkim * If the method is referenced from within a package 535151937Sjkim * declaration, it is not a invocation of the method, just 536151937Sjkim * a reference to it. 537151937Sjkim */ 538151937Sjkim if ((Op->Asl.Parent) && 539151937Sjkim ((Op->Asl.Parent->Asl.AmlOpcode == AML_PACKAGE_OP) || 540151937Sjkim (Op->Asl.Parent->Asl.AmlOpcode == AML_VAR_PACKAGE_OP))) 541151937Sjkim { 542151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 543151937Sjkim "Method Reference in a Package, Op=%p\n", Op)); 544167802Sjkim 545193267Sjkim Op->Common.Node = (ACPI_NAMESPACE_NODE *) Op->Asl.Value.Arg->Asl.Node; 546151937Sjkim AcpiUtAddReference (Op->Asl.Value.Arg->Asl.Node->Object); 547151937Sjkim return_ACPI_STATUS (AE_OK); 548151937Sjkim } 549151937Sjkim 55085756Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Method invocation, Op=%p\n", Op)); 55167754Smsmith 55285756Smsmith /* 553151937Sjkim * (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains 55485756Smsmith * the method Node pointer 55585756Smsmith */ 55685756Smsmith /* NextOp points to the op that holds the method name */ 55767754Smsmith 55885756Smsmith NextOp = FirstArg; 55967754Smsmith 56085756Smsmith /* NextOp points to first argument op */ 56167754Smsmith 56299679Siwasaki NextOp = NextOp->Common.Next; 56367754Smsmith 56485756Smsmith /* 56585756Smsmith * Get the method's arguments and put them on the operand stack 56685756Smsmith */ 56785756Smsmith Status = AcpiDsCreateOperands (WalkState, NextOp); 56885756Smsmith if (ACPI_FAILURE (Status)) 56985756Smsmith { 57085756Smsmith break; 57185756Smsmith } 57267754Smsmith 57385756Smsmith /* 57491116Smsmith * Since the operands will be passed to another control method, 57591116Smsmith * we must resolve all local references here (Local variables, 57687031Smsmith * arguments to *this* method, etc.) 57785756Smsmith */ 57885756Smsmith Status = AcpiDsResolveOperands (WalkState); 57985756Smsmith if (ACPI_FAILURE (Status)) 58085756Smsmith { 581107325Siwasaki /* On error, clear all resolved operands */ 582107325Siwasaki 583107325Siwasaki AcpiDsClearOperands (WalkState); 58485756Smsmith break; 58585756Smsmith } 58667754Smsmith 58785756Smsmith /* 58885756Smsmith * Tell the walk loop to preempt this running method and 58985756Smsmith * execute the new method 59085756Smsmith */ 59185756Smsmith Status = AE_CTRL_TRANSFER; 59267754Smsmith 59385756Smsmith /* 59485756Smsmith * Return now; we don't want to disturb anything, 59585756Smsmith * especially the operand count! 59685756Smsmith */ 59785756Smsmith return_ACPI_STATUS (Status); 59867754Smsmith 59967754Smsmith 60085756Smsmith case AML_TYPE_CREATE_FIELD: 60167754Smsmith 60285756Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 60385756Smsmith "Executing CreateField Buffer/Index Op=%p\n", Op)); 60467754Smsmith 60585756Smsmith Status = AcpiDsLoad2EndOp (WalkState); 60685756Smsmith if (ACPI_FAILURE (Status)) 60785756Smsmith { 60885756Smsmith break; 60985756Smsmith } 61067754Smsmith 61185756Smsmith Status = AcpiDsEvalBufferFieldOperands (WalkState, Op); 61267754Smsmith break; 61367754Smsmith 61467754Smsmith 61599146Siwasaki case AML_TYPE_CREATE_OBJECT: 61699146Siwasaki 61799146Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 61899146Siwasaki "Executing CreateObject (Buffer/Package) Op=%p\n", Op)); 61999146Siwasaki 62099679Siwasaki switch (Op->Common.Parent->Common.AmlOpcode) 62199146Siwasaki { 62299146Siwasaki case AML_NAME_OP: 62399146Siwasaki 62499146Siwasaki /* 625151937Sjkim * Put the Node on the object stack (Contains the ACPI Name 626151937Sjkim * of this object) 62799146Siwasaki */ 62899679Siwasaki WalkState->Operands[0] = (void *) Op->Common.Parent->Common.Node; 62999146Siwasaki WalkState->NumOperands = 1; 63099146Siwasaki 631151937Sjkim Status = AcpiDsCreateNode (WalkState, 632151937Sjkim Op->Common.Parent->Common.Node, 633151937Sjkim Op->Common.Parent); 63499146Siwasaki if (ACPI_FAILURE (Status)) 63599146Siwasaki { 63699146Siwasaki break; 63799146Siwasaki } 63899146Siwasaki 63999146Siwasaki /* Fall through */ 64099679Siwasaki /*lint -fallthrough */ 64199146Siwasaki 64299146Siwasaki case AML_INT_EVAL_SUBTREE_OP: 64399146Siwasaki 644102550Siwasaki Status = AcpiDsEvalDataObjectOperands (WalkState, Op, 645151937Sjkim AcpiNsGetAttachedObject (Op->Common.Parent->Common.Node)); 64699146Siwasaki break; 64799146Siwasaki 64899146Siwasaki default: 64999146Siwasaki 65099146Siwasaki Status = AcpiDsEvalDataObjectOperands (WalkState, Op, NULL); 65199146Siwasaki break; 65299146Siwasaki } 65399146Siwasaki 65499146Siwasaki /* 65599146Siwasaki * If a result object was returned from above, push it on the 65699146Siwasaki * current result stack 65799146Siwasaki */ 658151937Sjkim if (WalkState->ResultObj) 65999146Siwasaki { 66099146Siwasaki Status = AcpiDsResultPush (WalkState->ResultObj, WalkState); 66199146Siwasaki } 66299146Siwasaki break; 66399146Siwasaki 66499146Siwasaki 66585756Smsmith case AML_TYPE_NAMED_FIELD: 66685756Smsmith case AML_TYPE_NAMED_COMPLEX: 66785756Smsmith case AML_TYPE_NAMED_SIMPLE: 66891116Smsmith case AML_TYPE_NAMED_NO_OBJ: 66967754Smsmith 67085756Smsmith Status = AcpiDsLoad2EndOp (WalkState); 67169746Smsmith if (ACPI_FAILURE (Status)) 67269746Smsmith { 67369746Smsmith break; 67469746Smsmith } 67567754Smsmith 67699679Siwasaki if (Op->Common.AmlOpcode == AML_REGION_OP) 67785756Smsmith { 67885756Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 67985756Smsmith "Executing OpRegion Address/Length Op=%p\n", Op)); 68085756Smsmith 68185756Smsmith Status = AcpiDsEvalRegionOperands (WalkState, Op); 68285756Smsmith if (ACPI_FAILURE (Status)) 68385756Smsmith { 68485756Smsmith break; 68585756Smsmith } 68685756Smsmith } 687193267Sjkim else if (Op->Common.AmlOpcode == AML_DATA_REGION_OP) 688193267Sjkim { 689193267Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 690193267Sjkim "Executing DataTableRegion Strings Op=%p\n", Op)); 691193267Sjkim 692193267Sjkim Status = AcpiDsEvalTableRegionOperands (WalkState, Op); 693193267Sjkim if (ACPI_FAILURE (Status)) 694193267Sjkim { 695193267Sjkim break; 696193267Sjkim } 697193267Sjkim } 698193267Sjkim else if (Op->Common.AmlOpcode == AML_BANK_FIELD_OP) 699193267Sjkim { 700193267Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 701193267Sjkim "Executing BankField Op=%p\n", Op)); 702193267Sjkim 703193267Sjkim Status = AcpiDsEvalBankFieldOperands (WalkState, Op); 704193267Sjkim if (ACPI_FAILURE (Status)) 705193267Sjkim { 706193267Sjkim break; 707193267Sjkim } 708193267Sjkim } 70967754Smsmith break; 71067754Smsmith 71187031Smsmith 71285756Smsmith case AML_TYPE_UNDEFINED: 71367754Smsmith 714167802Sjkim ACPI_ERROR ((AE_INFO, 715167802Sjkim "Undefined opcode type Op=%p", Op)); 71685756Smsmith return_ACPI_STATUS (AE_NOT_IMPLEMENTED); 71767754Smsmith 71867754Smsmith 71985756Smsmith case AML_TYPE_BOGUS: 72087031Smsmith 72191116Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 72287031Smsmith "Internal opcode=%X type Op=%p\n", 72385756Smsmith WalkState->Opcode, Op)); 72467754Smsmith break; 72567754Smsmith 72687031Smsmith 72767754Smsmith default: 72867754Smsmith 729167802Sjkim ACPI_ERROR ((AE_INFO, 730204773Sjkim "Unimplemented opcode, class=0x%X type=0x%X Opcode=-0x%X Op=%p", 73199679Siwasaki OpClass, OpType, Op->Common.AmlOpcode, Op)); 73285756Smsmith 73385756Smsmith Status = AE_NOT_IMPLEMENTED; 73467754Smsmith break; 73567754Smsmith } 73667754Smsmith } 73767754Smsmith 73867754Smsmith /* 73991116Smsmith * ACPI 2.0 support for 64-bit integers: Truncate numeric 74087031Smsmith * result value if we are executing from a 32-bit ACPI table 74169450Smsmith */ 742245582Sjkim (void) AcpiExTruncateFor32bitTable (WalkState->ResultObj); 74369450Smsmith 74469450Smsmith /* 74567754Smsmith * Check if we just completed the evaluation of a 74667754Smsmith * conditional predicate 74767754Smsmith */ 748138287Smarks if ((ACPI_SUCCESS (Status)) && 749138287Smarks (WalkState->ControlState) && 75067754Smsmith (WalkState->ControlState->Common.State == 75191116Smsmith ACPI_CONTROL_PREDICATE_EXECUTING) && 75267754Smsmith (WalkState->ControlState->Control.PredicateOp == Op)) 75367754Smsmith { 75491116Smsmith Status = AcpiDsGetPredicateValue (WalkState, WalkState->ResultObj); 75584491Smsmith WalkState->ResultObj = NULL; 75667754Smsmith } 75767754Smsmith 75867754Smsmith 75967754SmsmithCleanup: 760138287Smarks 76184491Smsmith if (WalkState->ResultObj) 76267754Smsmith { 76367754Smsmith /* Break to debugger to display result */ 76467754Smsmith 765151937Sjkim ACPI_DEBUGGER_EXEC (AcpiDbDisplayResultObject (WalkState->ResultObj, 766151937Sjkim WalkState)); 76767754Smsmith 76867754Smsmith /* 76967754Smsmith * Delete the result op if and only if: 77067754Smsmith * Parent will not use the result -- such as any 77167754Smsmith * non-nested type2 op in a method (parent will be method) 77267754Smsmith */ 77384491Smsmith AcpiDsDeleteResultIfNotUsed (Op, WalkState->ResultObj, WalkState); 77467754Smsmith } 77567754Smsmith 776117521Snjl#ifdef _UNDER_DEVELOPMENT 777114237Snjl 778114237Snjl if (WalkState->ParserState.Aml == WalkState->ParserState.AmlEnd) 779114237Snjl { 780114237Snjl AcpiDbMethodEnd (WalkState); 781114237Snjl } 782114237Snjl#endif 783114237Snjl 784167802Sjkim /* Invoke exception handler on error */ 78567754Smsmith 786117521Snjl if (ACPI_FAILURE (Status)) 787117521Snjl { 788167802Sjkim Status = AcpiDsMethodError (Status, WalkState); 789117521Snjl } 790117521Snjl 791167802Sjkim /* Always clear the object stack */ 792167802Sjkim 793167802Sjkim WalkState->NumOperands = 0; 79467754Smsmith return_ACPI_STATUS (Status); 79567754Smsmith} 796