167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: dswexec - Dispatcher method execution callbacks; 467754Smsmith * dispatch to interpreter. 567754Smsmith * 667754Smsmith *****************************************************************************/ 767754Smsmith 8217365Sjkim/* 9281075Sdim * Copyright (C) 2000 - 2015, 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 45193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 46193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 47193341Sjkim#include <contrib/dev/acpica/include/acparser.h> 48193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 49193341Sjkim#include <contrib/dev/acpica/include/acdispat.h> 50193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 51193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 52193341Sjkim#include <contrib/dev/acpica/include/acdebug.h> 5367754Smsmith 5467754Smsmith 5577424Smsmith#define _COMPONENT ACPI_DISPATCHER 5691116Smsmith ACPI_MODULE_NAME ("dswexec") 5767754Smsmith 5885756Smsmith/* 5987031Smsmith * Dispatch table for opcode classes 6085756Smsmith */ 61167802Sjkimstatic ACPI_EXECUTE_OP AcpiGbl_OpTypeDispatch [] = 62167802Sjkim{ 63167802Sjkim AcpiExOpcode_0A_0T_1R, 64167802Sjkim AcpiExOpcode_1A_0T_0R, 65167802Sjkim AcpiExOpcode_1A_0T_1R, 66167802Sjkim AcpiExOpcode_1A_1T_0R, 67167802Sjkim AcpiExOpcode_1A_1T_1R, 68167802Sjkim AcpiExOpcode_2A_0T_0R, 69167802Sjkim AcpiExOpcode_2A_0T_1R, 70167802Sjkim AcpiExOpcode_2A_1T_1R, 71167802Sjkim AcpiExOpcode_2A_2T_1R, 72167802Sjkim AcpiExOpcode_3A_0T_0R, 73167802Sjkim AcpiExOpcode_3A_1T_1R, 74167802Sjkim AcpiExOpcode_6A_0T_1R 75167802Sjkim}; 7667754Smsmith 77151937Sjkim 7867754Smsmith/***************************************************************************** 7967754Smsmith * 8067754Smsmith * FUNCTION: AcpiDsGetPredicateValue 8167754Smsmith * 8267754Smsmith * PARAMETERS: WalkState - Current state of the parse tree walk 83151937Sjkim * ResultObj - if non-zero, pop result from result stack 8467754Smsmith * 8567754Smsmith * RETURN: Status 8667754Smsmith * 8771867Smsmith * DESCRIPTION: Get the result of a predicate evaluation 8867754Smsmith * 8967754Smsmith ****************************************************************************/ 9067754Smsmith 9167754SmsmithACPI_STATUS 9267754SmsmithAcpiDsGetPredicateValue ( 9367754Smsmith ACPI_WALK_STATE *WalkState, 9491116Smsmith ACPI_OPERAND_OBJECT *ResultObj) 9567754Smsmith{ 9667754Smsmith ACPI_STATUS Status = AE_OK; 9767754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 98151937Sjkim ACPI_OPERAND_OBJECT *LocalObjDesc = NULL; 9967754Smsmith 10067754Smsmith 101167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsGetPredicateValue, WalkState); 10267754Smsmith 10367754Smsmith 10467754Smsmith WalkState->ControlState->Common.State = 0; 10567754Smsmith 10691116Smsmith if (ResultObj) 10767754Smsmith { 10869746Smsmith Status = AcpiDsResultPop (&ObjDesc, WalkState); 10967754Smsmith if (ACPI_FAILURE (Status)) 11067754Smsmith { 111167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 112167802Sjkim "Could not get result from predicate evaluation")); 11369450Smsmith 11467754Smsmith return_ACPI_STATUS (Status); 11567754Smsmith } 11667754Smsmith } 11767754Smsmith else 11867754Smsmith { 11984491Smsmith Status = AcpiDsCreateOperand (WalkState, WalkState->Op, 0); 12067754Smsmith if (ACPI_FAILURE (Status)) 12167754Smsmith { 12267754Smsmith return_ACPI_STATUS (Status); 12367754Smsmith } 12467754Smsmith 12577424Smsmith Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState); 12667754Smsmith if (ACPI_FAILURE (Status)) 12767754Smsmith { 12867754Smsmith return_ACPI_STATUS (Status); 12967754Smsmith } 13067754Smsmith 13167754Smsmith ObjDesc = WalkState->Operands [0]; 13267754Smsmith } 13367754Smsmith 13467754Smsmith if (!ObjDesc) 13567754Smsmith { 136167802Sjkim ACPI_ERROR ((AE_INFO, 137167802Sjkim "No predicate ObjDesc=%p State=%p", 13867754Smsmith ObjDesc, WalkState)); 13967754Smsmith 14067754Smsmith return_ACPI_STATUS (AE_AML_NO_OPERAND); 14167754Smsmith } 14267754Smsmith 14369450Smsmith /* 144151937Sjkim * Result of predicate evaluation must be an Integer 145151937Sjkim * object. Implicitly convert the argument if necessary. 14667754Smsmith */ 147151937Sjkim Status = AcpiExConvertToInteger (ObjDesc, &LocalObjDesc, 16); 148151937Sjkim if (ACPI_FAILURE (Status)) 14967754Smsmith { 150151937Sjkim goto Cleanup; 151151937Sjkim } 152151937Sjkim 153193267Sjkim if (LocalObjDesc->Common.Type != ACPI_TYPE_INTEGER) 154151937Sjkim { 155167802Sjkim ACPI_ERROR ((AE_INFO, 156204773Sjkim "Bad predicate (not an integer) ObjDesc=%p State=%p Type=0x%X", 157193267Sjkim ObjDesc, WalkState, ObjDesc->Common.Type)); 15867754Smsmith 15967754Smsmith Status = AE_AML_OPERAND_TYPE; 16067754Smsmith goto Cleanup; 16167754Smsmith } 16267754Smsmith 16371867Smsmith /* Truncate the predicate to 32-bits if necessary */ 16469450Smsmith 165245582Sjkim (void) AcpiExTruncateFor32bitTable (LocalObjDesc); 16669450Smsmith 16769450Smsmith /* 16867754Smsmith * Save the result of the predicate evaluation on 16969450Smsmith * the control stack 17067754Smsmith */ 171151937Sjkim if (LocalObjDesc->Integer.Value) 17267754Smsmith { 17367754Smsmith WalkState->ControlState->Common.Value = TRUE; 17467754Smsmith } 17567754Smsmith else 17667754Smsmith { 17769450Smsmith /* 17867754Smsmith * Predicate is FALSE, we will just toss the 17969450Smsmith * rest of the package 18067754Smsmith */ 18167754Smsmith WalkState->ControlState->Common.Value = FALSE; 18267754Smsmith Status = AE_CTRL_FALSE; 18367754Smsmith } 18467754Smsmith 185193267Sjkim /* Predicate can be used for an implicit return value */ 18667754Smsmith 187193267Sjkim (void) AcpiDsDoImplicitReturn (LocalObjDesc, WalkState, TRUE); 188193267Sjkim 189193267Sjkim 19067754SmsmithCleanup: 19167754Smsmith 19287031Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n", 19384491Smsmith WalkState->ControlState->Common.Value, WalkState->Op)); 19467754Smsmith 19567754Smsmith /* Break to debugger to display result */ 19667754Smsmith 197151937Sjkim ACPI_DEBUGGER_EXEC (AcpiDbDisplayResultObject (LocalObjDesc, WalkState)); 19867754Smsmith 19969450Smsmith /* 20067754Smsmith * Delete the predicate result object (we know that 20167754Smsmith * we don't need it anymore) 20267754Smsmith */ 203151937Sjkim if (LocalObjDesc != ObjDesc) 204151937Sjkim { 205151937Sjkim AcpiUtRemoveReference (LocalObjDesc); 206151937Sjkim } 20777424Smsmith AcpiUtRemoveReference (ObjDesc); 20867754Smsmith 20991116Smsmith WalkState->ControlState->Common.State = ACPI_CONTROL_NORMAL; 21067754Smsmith return_ACPI_STATUS (Status); 21167754Smsmith} 21267754Smsmith 21367754Smsmith 21467754Smsmith/***************************************************************************** 21567754Smsmith * 21667754Smsmith * FUNCTION: AcpiDsExecBeginOp 21767754Smsmith * 21867754Smsmith * PARAMETERS: WalkState - Current state of the parse tree walk 219151937Sjkim * OutOp - Where to return op if a new one is created 22067754Smsmith * 22167754Smsmith * RETURN: Status 22267754Smsmith * 22367754Smsmith * DESCRIPTION: Descending callback used during the execution of control 224241973Sjkim * methods. This is where most operators and operands are 22567754Smsmith * dispatched to the interpreter. 22667754Smsmith * 22767754Smsmith ****************************************************************************/ 22867754Smsmith 22967754SmsmithACPI_STATUS 23067754SmsmithAcpiDsExecBeginOp ( 23167754Smsmith ACPI_WALK_STATE *WalkState, 23267754Smsmith ACPI_PARSE_OBJECT **OutOp) 23367754Smsmith{ 23484491Smsmith ACPI_PARSE_OBJECT *Op; 23567754Smsmith ACPI_STATUS Status = AE_OK; 23685756Smsmith UINT32 OpcodeClass; 23767754Smsmith 23867754Smsmith 239167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsExecBeginOp, WalkState); 24067754Smsmith 24167754Smsmith 24284491Smsmith Op = WalkState->Op; 24367754Smsmith if (!Op) 24467754Smsmith { 24584491Smsmith Status = AcpiDsLoad2BeginOp (WalkState, OutOp); 24667754Smsmith if (ACPI_FAILURE (Status)) 24767754Smsmith { 248167802Sjkim goto ErrorExit; 24967754Smsmith } 25067754Smsmith 25167754Smsmith Op = *OutOp; 25284491Smsmith WalkState->Op = Op; 25399679Siwasaki WalkState->Opcode = Op->Common.AmlOpcode; 25499679Siwasaki WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 25591116Smsmith 25691116Smsmith if (AcpiNsOpensScope (WalkState->OpInfo->ObjectType)) 25791116Smsmith { 258151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 259151937Sjkim "(%s) Popping scope for Op %p\n", 26091116Smsmith AcpiUtGetTypeName (WalkState->OpInfo->ObjectType), Op)); 26199679Siwasaki 26299679Siwasaki Status = AcpiDsScopeStackPop (WalkState); 26399679Siwasaki if (ACPI_FAILURE (Status)) 26499679Siwasaki { 265167802Sjkim goto ErrorExit; 26699679Siwasaki } 26791116Smsmith } 26867754Smsmith } 26967754Smsmith 27067754Smsmith if (Op == WalkState->Origin) 27167754Smsmith { 27267754Smsmith if (OutOp) 27367754Smsmith { 27467754Smsmith *OutOp = Op; 27567754Smsmith } 27667754Smsmith 27767754Smsmith return_ACPI_STATUS (AE_OK); 27867754Smsmith } 27967754Smsmith 28067754Smsmith /* 28167754Smsmith * If the previous opcode was a conditional, this opcode 28267754Smsmith * must be the beginning of the associated predicate. 28367754Smsmith * Save this knowledge in the current scope descriptor 28467754Smsmith */ 28567754Smsmith if ((WalkState->ControlState) && 28667754Smsmith (WalkState->ControlState->Common.State == 28791116Smsmith ACPI_CONTROL_CONDITIONAL_EXECUTING)) 28867754Smsmith { 28985756Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Exec predicate Op=%p State=%p\n", 29067754Smsmith Op, WalkState)); 29167754Smsmith 29291116Smsmith WalkState->ControlState->Common.State = ACPI_CONTROL_PREDICATE_EXECUTING; 29367754Smsmith 29467754Smsmith /* Save start of predicate */ 29567754Smsmith 29667754Smsmith WalkState->ControlState->Control.PredicateOp = Op; 29767754Smsmith } 29867754Smsmith 29967754Smsmith 30085756Smsmith OpcodeClass = WalkState->OpInfo->Class; 30167754Smsmith 30267754Smsmith /* We want to send namepaths to the load code */ 30367754Smsmith 30499679Siwasaki if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) 30567754Smsmith { 30685756Smsmith OpcodeClass = AML_CLASS_NAMED_OBJECT; 30767754Smsmith } 30867754Smsmith 30967754Smsmith /* 31067754Smsmith * Handle the opcode based upon the opcode type 31167754Smsmith */ 31283174Smsmith switch (OpcodeClass) 31367754Smsmith { 31485756Smsmith case AML_CLASS_CONTROL: 31567754Smsmith 31667754Smsmith Status = AcpiDsExecBeginControlOp (WalkState, Op); 31767754Smsmith break; 31867754Smsmith 31985756Smsmith case AML_CLASS_NAMED_OBJECT: 32067754Smsmith 321167802Sjkim if (WalkState->WalkType & ACPI_WALK_METHOD) 32267754Smsmith { 32367754Smsmith /* 324151937Sjkim * Found a named object declaration during method execution; 325241973Sjkim * we must enter this object into the namespace. The created 326151937Sjkim * object is temporary and will be deleted upon completion of 327151937Sjkim * the execution of this method. 328216471Sjkim * 329216471Sjkim * Note 10/2010: Except for the Scope() op. This opcode does 330216471Sjkim * not actually create a new object, it refers to an existing 331216471Sjkim * object. However, for Scope(), we want to indeed open a 332216471Sjkim * new scope. 33367754Smsmith */ 334216471Sjkim if (Op->Common.AmlOpcode != AML_SCOPE_OP) 335216471Sjkim { 336216471Sjkim Status = AcpiDsLoad2BeginOp (WalkState, NULL); 337216471Sjkim } 338216471Sjkim else 339216471Sjkim { 340216471Sjkim Status = AcpiDsScopeStackPush (Op->Named.Node, 341216471Sjkim Op->Named.Node->Type, WalkState); 342216471Sjkim if (ACPI_FAILURE (Status)) 343216471Sjkim { 344216471Sjkim return_ACPI_STATUS (Status); 345216471Sjkim } 346216471Sjkim } 34767754Smsmith } 34867754Smsmith break; 34967754Smsmith 35085756Smsmith case AML_CLASS_EXECUTE: 35185756Smsmith case AML_CLASS_CREATE: 35269746Smsmith 35369746Smsmith break; 35469746Smsmith 355250838Sjkim default: 35669746Smsmith 35767754Smsmith break; 35867754Smsmith } 35967754Smsmith 36067754Smsmith /* Nothing to do here during method execution */ 36167754Smsmith 36267754Smsmith return_ACPI_STATUS (Status); 363167802Sjkim 364167802Sjkim 365167802SjkimErrorExit: 366167802Sjkim Status = AcpiDsMethodError (Status, WalkState); 367167802Sjkim return_ACPI_STATUS (Status); 36867754Smsmith} 36967754Smsmith 37067754Smsmith 37167754Smsmith/***************************************************************************** 37267754Smsmith * 37367754Smsmith * FUNCTION: AcpiDsExecEndOp 37467754Smsmith * 37567754Smsmith * PARAMETERS: WalkState - Current state of the parse tree walk 37667754Smsmith * 37767754Smsmith * RETURN: Status 37867754Smsmith * 37967754Smsmith * DESCRIPTION: Ascending callback used during the execution of control 380241973Sjkim * methods. The only thing we really need to do here is to 38167754Smsmith * notice the beginning of IF, ELSE, and WHILE blocks. 38267754Smsmith * 38367754Smsmith ****************************************************************************/ 38467754Smsmith 38567754SmsmithACPI_STATUS 38667754SmsmithAcpiDsExecEndOp ( 38784491Smsmith ACPI_WALK_STATE *WalkState) 38867754Smsmith{ 38984491Smsmith ACPI_PARSE_OBJECT *Op; 39067754Smsmith ACPI_STATUS Status = AE_OK; 39185756Smsmith UINT32 OpType; 39285756Smsmith UINT32 OpClass; 39367754Smsmith ACPI_PARSE_OBJECT *NextOp; 39467754Smsmith ACPI_PARSE_OBJECT *FirstArg; 39567754Smsmith 39667754Smsmith 397167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsExecEndOp, WalkState); 39867754Smsmith 39967754Smsmith 40085756Smsmith Op = WalkState->Op; 40185756Smsmith OpType = WalkState->OpInfo->Type; 40285756Smsmith OpClass = WalkState->OpInfo->Class; 40367754Smsmith 40485756Smsmith if (OpClass == AML_CLASS_UNKNOWN) 40567754Smsmith { 406204773Sjkim ACPI_ERROR ((AE_INFO, "Unknown opcode 0x%X", Op->Common.AmlOpcode)); 40767754Smsmith return_ACPI_STATUS (AE_NOT_IMPLEMENTED); 40867754Smsmith } 40967754Smsmith 41099679Siwasaki FirstArg = Op->Common.Value.Arg; 41167754Smsmith 41267754Smsmith /* Init the walk state */ 41367754Smsmith 41467754Smsmith WalkState->NumOperands = 0; 415167802Sjkim WalkState->OperandIndex = 0; 41667754Smsmith WalkState->ReturnDesc = NULL; 41784491Smsmith WalkState->ResultObj = NULL; 41867754Smsmith 41967754Smsmith /* Call debugger for single step support (DEBUG build only) */ 42067754Smsmith 42191116Smsmith ACPI_DEBUGGER_EXEC (Status = AcpiDbSingleStep (WalkState, Op, OpClass)); 42291116Smsmith ACPI_DEBUGGER_EXEC (if (ACPI_FAILURE (Status)) {return_ACPI_STATUS (Status);}); 42367754Smsmith 42487031Smsmith /* Decode the Opcode Class */ 42567754Smsmith 42685756Smsmith switch (OpClass) 42767754Smsmith { 428167802Sjkim case AML_CLASS_ARGUMENT: /* Constants, literals, etc. */ 429167802Sjkim 430167802Sjkim if (WalkState->Opcode == AML_INT_NAMEPATH_OP) 431167802Sjkim { 432167802Sjkim Status = AcpiDsEvaluateNamePath (WalkState); 433167802Sjkim if (ACPI_FAILURE (Status)) 434167802Sjkim { 435167802Sjkim goto Cleanup; 436167802Sjkim } 437167802Sjkim } 43867754Smsmith break; 43967754Smsmith 440167802Sjkim case AML_CLASS_EXECUTE: /* Most operators with arguments */ 44167754Smsmith 44269746Smsmith /* Build resolved operand stack */ 44369746Smsmith 44467754Smsmith Status = AcpiDsCreateOperands (WalkState, FirstArg); 44567754Smsmith if (ACPI_FAILURE (Status)) 44667754Smsmith { 44767754Smsmith goto Cleanup; 44867754Smsmith } 44967754Smsmith 450151937Sjkim /* 451151937Sjkim * All opcodes require operand resolution, with the only exceptions 452151937Sjkim * being the ObjectType and SizeOf operators. 453151937Sjkim */ 454151937Sjkim if (!(WalkState->OpInfo->Flags & AML_NO_OPERAND_RESOLVE)) 455151937Sjkim { 456151937Sjkim /* Resolve all operands */ 45783174Smsmith 458151937Sjkim Status = AcpiExResolveOperands (WalkState->Opcode, 45987031Smsmith &(WalkState->Operands [WalkState->NumOperands -1]), 46083174Smsmith WalkState); 461151937Sjkim } 462151937Sjkim 46387031Smsmith if (ACPI_SUCCESS (Status)) 46483174Smsmith { 46583174Smsmith /* 46687031Smsmith * Dispatch the request to the appropriate interpreter handler 467241973Sjkim * routine. There is one routine per opcode "type" based upon the 46887031Smsmith * number of opcode arguments and return type. 46983174Smsmith */ 470138287Smarks Status = AcpiGbl_OpTypeDispatch[OpType] (WalkState); 47183174Smsmith } 47287031Smsmith else 47387031Smsmith { 474123315Snjl /* 475123315Snjl * Treat constructs of the form "Store(LocalX,LocalX)" as noops when the 476123315Snjl * Local is uninitialized. 477123315Snjl */ 478123315Snjl if ((Status == AE_AML_UNINITIALIZED_LOCAL) && 479123315Snjl (WalkState->Opcode == AML_STORE_OP) && 480123315Snjl (WalkState->Operands[0]->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) && 481123315Snjl (WalkState->Operands[1]->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) && 482193267Sjkim (WalkState->Operands[0]->Reference.Class == 483193267Sjkim WalkState->Operands[1]->Reference.Class) && 484193267Sjkim (WalkState->Operands[0]->Reference.Value == 485193267Sjkim WalkState->Operands[1]->Reference.Value)) 486123315Snjl { 487123315Snjl Status = AE_OK; 488123315Snjl } 489123315Snjl else 490123315Snjl { 491167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 492167802Sjkim "While resolving operands for [%s]", 493167802Sjkim AcpiPsGetOpcodeName (WalkState->Opcode))); 494123315Snjl } 49587031Smsmith } 49683174Smsmith 49787031Smsmith /* Always delete the argument objects and clear the operand stack */ 49883174Smsmith 499107325Siwasaki AcpiDsClearOperands (WalkState); 50083174Smsmith 50169746Smsmith /* 50269746Smsmith * If a result object was returned from above, push it on the 50369746Smsmith * current result stack 50469746Smsmith */ 50569746Smsmith if (ACPI_SUCCESS (Status) && 50684491Smsmith WalkState->ResultObj) 50769746Smsmith { 50884491Smsmith Status = AcpiDsResultPush (WalkState->ResultObj, WalkState); 50969746Smsmith } 51067754Smsmith break; 51167754Smsmith 51285756Smsmith default: 51367754Smsmith 51485756Smsmith switch (OpType) 51585756Smsmith { 51685756Smsmith case AML_TYPE_CONTROL: /* Type 1 opcode, IF/ELSE/WHILE/NOOP */ 51767754Smsmith 51885756Smsmith /* 1 Operand, 0 ExternalResult, 0 InternalResult */ 51967754Smsmith 52085756Smsmith Status = AcpiDsExecEndControlOp (WalkState, Op); 521151937Sjkim 52285756Smsmith break; 52367754Smsmith 52485756Smsmith case AML_TYPE_METHOD_CALL: 525151937Sjkim /* 526151937Sjkim * If the method is referenced from within a package 527151937Sjkim * declaration, it is not a invocation of the method, just 528151937Sjkim * a reference to it. 529151937Sjkim */ 530151937Sjkim if ((Op->Asl.Parent) && 531151937Sjkim ((Op->Asl.Parent->Asl.AmlOpcode == AML_PACKAGE_OP) || 532151937Sjkim (Op->Asl.Parent->Asl.AmlOpcode == AML_VAR_PACKAGE_OP))) 533151937Sjkim { 534151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 535151937Sjkim "Method Reference in a Package, Op=%p\n", Op)); 536167802Sjkim 537193267Sjkim Op->Common.Node = (ACPI_NAMESPACE_NODE *) Op->Asl.Value.Arg->Asl.Node; 538151937Sjkim AcpiUtAddReference (Op->Asl.Value.Arg->Asl.Node->Object); 539151937Sjkim return_ACPI_STATUS (AE_OK); 540151937Sjkim } 541151937Sjkim 542281075Sdim ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 543281075Sdim "Method invocation, Op=%p\n", Op)); 54467754Smsmith 54585756Smsmith /* 546151937Sjkim * (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains 54785756Smsmith * the method Node pointer 54885756Smsmith */ 54985756Smsmith /* NextOp points to the op that holds the method name */ 55067754Smsmith 55185756Smsmith NextOp = FirstArg; 55267754Smsmith 55385756Smsmith /* NextOp points to first argument op */ 55467754Smsmith 55599679Siwasaki NextOp = NextOp->Common.Next; 55667754Smsmith 55785756Smsmith /* 55885756Smsmith * Get the method's arguments and put them on the operand stack 55985756Smsmith */ 56085756Smsmith Status = AcpiDsCreateOperands (WalkState, NextOp); 56185756Smsmith if (ACPI_FAILURE (Status)) 56285756Smsmith { 56385756Smsmith break; 56485756Smsmith } 56567754Smsmith 56685756Smsmith /* 56791116Smsmith * Since the operands will be passed to another control method, 56891116Smsmith * we must resolve all local references here (Local variables, 56987031Smsmith * arguments to *this* method, etc.) 57085756Smsmith */ 57185756Smsmith Status = AcpiDsResolveOperands (WalkState); 57285756Smsmith if (ACPI_FAILURE (Status)) 57385756Smsmith { 574107325Siwasaki /* On error, clear all resolved operands */ 575107325Siwasaki 576107325Siwasaki AcpiDsClearOperands (WalkState); 57785756Smsmith break; 57885756Smsmith } 57967754Smsmith 58085756Smsmith /* 58185756Smsmith * Tell the walk loop to preempt this running method and 58285756Smsmith * execute the new method 58385756Smsmith */ 58485756Smsmith Status = AE_CTRL_TRANSFER; 58567754Smsmith 58685756Smsmith /* 58785756Smsmith * Return now; we don't want to disturb anything, 58885756Smsmith * especially the operand count! 58985756Smsmith */ 59085756Smsmith return_ACPI_STATUS (Status); 59167754Smsmith 59285756Smsmith case AML_TYPE_CREATE_FIELD: 59367754Smsmith 59485756Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 59585756Smsmith "Executing CreateField Buffer/Index Op=%p\n", Op)); 59667754Smsmith 59785756Smsmith Status = AcpiDsLoad2EndOp (WalkState); 59885756Smsmith if (ACPI_FAILURE (Status)) 59985756Smsmith { 60085756Smsmith break; 60185756Smsmith } 60267754Smsmith 60385756Smsmith Status = AcpiDsEvalBufferFieldOperands (WalkState, Op); 60467754Smsmith break; 60567754Smsmith 60667754Smsmith 60799146Siwasaki case AML_TYPE_CREATE_OBJECT: 60899146Siwasaki 60999146Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 61099146Siwasaki "Executing CreateObject (Buffer/Package) Op=%p\n", Op)); 61199146Siwasaki 61299679Siwasaki switch (Op->Common.Parent->Common.AmlOpcode) 61399146Siwasaki { 61499146Siwasaki case AML_NAME_OP: 61599146Siwasaki /* 616151937Sjkim * Put the Node on the object stack (Contains the ACPI Name 617151937Sjkim * of this object) 61899146Siwasaki */ 61999679Siwasaki WalkState->Operands[0] = (void *) Op->Common.Parent->Common.Node; 62099146Siwasaki WalkState->NumOperands = 1; 62199146Siwasaki 622151937Sjkim Status = AcpiDsCreateNode (WalkState, 623151937Sjkim Op->Common.Parent->Common.Node, 624151937Sjkim Op->Common.Parent); 62599146Siwasaki if (ACPI_FAILURE (Status)) 62699146Siwasaki { 62799146Siwasaki break; 62899146Siwasaki } 62999146Siwasaki 63099146Siwasaki /* Fall through */ 63199679Siwasaki /*lint -fallthrough */ 63299146Siwasaki 63399146Siwasaki case AML_INT_EVAL_SUBTREE_OP: 63499146Siwasaki 635102550Siwasaki Status = AcpiDsEvalDataObjectOperands (WalkState, Op, 636151937Sjkim AcpiNsGetAttachedObject (Op->Common.Parent->Common.Node)); 63799146Siwasaki break; 63899146Siwasaki 63999146Siwasaki default: 64099146Siwasaki 64199146Siwasaki Status = AcpiDsEvalDataObjectOperands (WalkState, Op, NULL); 64299146Siwasaki break; 64399146Siwasaki } 64499146Siwasaki 64599146Siwasaki /* 64699146Siwasaki * If a result object was returned from above, push it on the 64799146Siwasaki * current result stack 64899146Siwasaki */ 649151937Sjkim if (WalkState->ResultObj) 65099146Siwasaki { 65199146Siwasaki Status = AcpiDsResultPush (WalkState->ResultObj, WalkState); 65299146Siwasaki } 65399146Siwasaki break; 65499146Siwasaki 65585756Smsmith case AML_TYPE_NAMED_FIELD: 65685756Smsmith case AML_TYPE_NAMED_COMPLEX: 65785756Smsmith case AML_TYPE_NAMED_SIMPLE: 65891116Smsmith case AML_TYPE_NAMED_NO_OBJ: 65967754Smsmith 66085756Smsmith Status = AcpiDsLoad2EndOp (WalkState); 66169746Smsmith if (ACPI_FAILURE (Status)) 66269746Smsmith { 66369746Smsmith break; 66469746Smsmith } 66567754Smsmith 66699679Siwasaki if (Op->Common.AmlOpcode == AML_REGION_OP) 66785756Smsmith { 66885756Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 66985756Smsmith "Executing OpRegion Address/Length Op=%p\n", Op)); 67085756Smsmith 67185756Smsmith Status = AcpiDsEvalRegionOperands (WalkState, Op); 67285756Smsmith if (ACPI_FAILURE (Status)) 67385756Smsmith { 67485756Smsmith break; 67585756Smsmith } 67685756Smsmith } 677193267Sjkim else if (Op->Common.AmlOpcode == AML_DATA_REGION_OP) 678193267Sjkim { 679193267Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 680193267Sjkim "Executing DataTableRegion Strings Op=%p\n", Op)); 681193267Sjkim 682193267Sjkim Status = AcpiDsEvalTableRegionOperands (WalkState, Op); 683193267Sjkim if (ACPI_FAILURE (Status)) 684193267Sjkim { 685193267Sjkim break; 686193267Sjkim } 687193267Sjkim } 688193267Sjkim else if (Op->Common.AmlOpcode == AML_BANK_FIELD_OP) 689193267Sjkim { 690193267Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 691193267Sjkim "Executing BankField Op=%p\n", Op)); 692193267Sjkim 693193267Sjkim Status = AcpiDsEvalBankFieldOperands (WalkState, Op); 694193267Sjkim if (ACPI_FAILURE (Status)) 695193267Sjkim { 696193267Sjkim break; 697193267Sjkim } 698193267Sjkim } 69967754Smsmith break; 70067754Smsmith 70185756Smsmith case AML_TYPE_UNDEFINED: 70267754Smsmith 703167802Sjkim ACPI_ERROR ((AE_INFO, 704167802Sjkim "Undefined opcode type Op=%p", Op)); 70585756Smsmith return_ACPI_STATUS (AE_NOT_IMPLEMENTED); 70667754Smsmith 70785756Smsmith case AML_TYPE_BOGUS: 70887031Smsmith 70991116Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 71087031Smsmith "Internal opcode=%X type Op=%p\n", 71185756Smsmith WalkState->Opcode, Op)); 71267754Smsmith break; 71367754Smsmith 71467754Smsmith default: 71567754Smsmith 716167802Sjkim ACPI_ERROR ((AE_INFO, 717249112Sjkim "Unimplemented opcode, class=0x%X type=0x%X Opcode=0x%X Op=%p", 71899679Siwasaki OpClass, OpType, Op->Common.AmlOpcode, Op)); 71985756Smsmith 72085756Smsmith Status = AE_NOT_IMPLEMENTED; 72167754Smsmith break; 72267754Smsmith } 72367754Smsmith } 72467754Smsmith 72567754Smsmith /* 72691116Smsmith * ACPI 2.0 support for 64-bit integers: Truncate numeric 72787031Smsmith * result value if we are executing from a 32-bit ACPI table 72869450Smsmith */ 729245582Sjkim (void) AcpiExTruncateFor32bitTable (WalkState->ResultObj); 73069450Smsmith 73169450Smsmith /* 73267754Smsmith * Check if we just completed the evaluation of a 73367754Smsmith * conditional predicate 73467754Smsmith */ 735138287Smarks if ((ACPI_SUCCESS (Status)) && 736138287Smarks (WalkState->ControlState) && 73767754Smsmith (WalkState->ControlState->Common.State == 73891116Smsmith ACPI_CONTROL_PREDICATE_EXECUTING) && 73967754Smsmith (WalkState->ControlState->Control.PredicateOp == Op)) 74067754Smsmith { 74191116Smsmith Status = AcpiDsGetPredicateValue (WalkState, WalkState->ResultObj); 74284491Smsmith WalkState->ResultObj = NULL; 74367754Smsmith } 74467754Smsmith 74567754Smsmith 74667754SmsmithCleanup: 747138287Smarks 74884491Smsmith if (WalkState->ResultObj) 74967754Smsmith { 75067754Smsmith /* Break to debugger to display result */ 75167754Smsmith 752151937Sjkim ACPI_DEBUGGER_EXEC (AcpiDbDisplayResultObject (WalkState->ResultObj, 753151937Sjkim WalkState)); 75467754Smsmith 75567754Smsmith /* 75667754Smsmith * Delete the result op if and only if: 75767754Smsmith * Parent will not use the result -- such as any 75867754Smsmith * non-nested type2 op in a method (parent will be method) 75967754Smsmith */ 76084491Smsmith AcpiDsDeleteResultIfNotUsed (Op, WalkState->ResultObj, WalkState); 76167754Smsmith } 76267754Smsmith 763117521Snjl#ifdef _UNDER_DEVELOPMENT 764114237Snjl 765114237Snjl if (WalkState->ParserState.Aml == WalkState->ParserState.AmlEnd) 766114237Snjl { 767114237Snjl AcpiDbMethodEnd (WalkState); 768114237Snjl } 769114237Snjl#endif 770114237Snjl 771167802Sjkim /* Invoke exception handler on error */ 77267754Smsmith 773117521Snjl if (ACPI_FAILURE (Status)) 774117521Snjl { 775167802Sjkim Status = AcpiDsMethodError (Status, WalkState); 776117521Snjl } 777117521Snjl 778167802Sjkim /* Always clear the object stack */ 779167802Sjkim 780167802Sjkim WalkState->NumOperands = 0; 78167754Smsmith return_ACPI_STATUS (Status); 78267754Smsmith} 783