dswexec.c revision 241973
1191783Srmacklem/****************************************************************************** 2191783Srmacklem * 3191783Srmacklem * Module Name: dswexec - Dispatcher method execution callbacks; 4191783Srmacklem * dispatch to interpreter. 5191783Srmacklem * 6191783Srmacklem *****************************************************************************/ 7191783Srmacklem 8191783Srmacklem/* 9191783Srmacklem * Copyright (C) 2000 - 2012, Intel Corp. 10191783Srmacklem * All rights reserved. 11191783Srmacklem * 12191783Srmacklem * Redistribution and use in source and binary forms, with or without 13191783Srmacklem * modification, are permitted provided that the following conditions 14191783Srmacklem * are met: 15191783Srmacklem * 1. Redistributions of source code must retain the above copyright 16191783Srmacklem * notice, this list of conditions, and the following disclaimer, 17191783Srmacklem * without modification. 18191783Srmacklem * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19191783Srmacklem * substantially similar to the "NO WARRANTY" disclaimer below 20191783Srmacklem * ("Disclaimer") and any redistribution must be conditioned upon 21191783Srmacklem * including a substantially similar Disclaimer requirement for further 22191783Srmacklem * binary redistribution. 23191783Srmacklem * 3. Neither the names of the above-listed copyright holders nor the names 24191783Srmacklem * of any contributors may be used to endorse or promote products derived 25191783Srmacklem * from this software without specific prior written permission. 26191783Srmacklem * 27191783Srmacklem * Alternatively, this software may be distributed under the terms of the 28191783Srmacklem * GNU General Public License ("GPL") version 2 as published by the Free 29191783Srmacklem * Software Foundation. 30191783Srmacklem * 31191783Srmacklem * NO WARRANTY 32191783Srmacklem * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33191783Srmacklem * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34191783Srmacklem * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35191783Srmacklem * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36191783Srmacklem * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37191783Srmacklem * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38191783Srmacklem * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39191783Srmacklem * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40191783Srmacklem * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41191783Srmacklem * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42191783Srmacklem * POSSIBILITY OF SUCH DAMAGES. 43191783Srmacklem */ 44191783Srmacklem 45191783Srmacklem#define __DSWEXEC_C__ 46191783Srmacklem 47191783Srmacklem#include <contrib/dev/acpica/include/acpi.h> 48191783Srmacklem#include <contrib/dev/acpica/include/accommon.h> 49191783Srmacklem#include <contrib/dev/acpica/include/acparser.h> 50191783Srmacklem#include <contrib/dev/acpica/include/amlcode.h> 51191783Srmacklem#include <contrib/dev/acpica/include/acdispat.h> 52191783Srmacklem#include <contrib/dev/acpica/include/acinterp.h> 53191783Srmacklem#include <contrib/dev/acpica/include/acnamesp.h> 54191783Srmacklem#include <contrib/dev/acpica/include/acdebug.h> 55191783Srmacklem 56191783Srmacklem 57191783Srmacklem#define _COMPONENT ACPI_DISPATCHER 58191783Srmacklem ACPI_MODULE_NAME ("dswexec") 59191783Srmacklem 60191783Srmacklem/* 61191783Srmacklem * Dispatch table for opcode classes 62191783Srmacklem */ 63191783Srmacklemstatic ACPI_EXECUTE_OP AcpiGbl_OpTypeDispatch [] = 64191783Srmacklem{ 65191783Srmacklem AcpiExOpcode_0A_0T_1R, 66191783Srmacklem AcpiExOpcode_1A_0T_0R, 67191783Srmacklem AcpiExOpcode_1A_0T_1R, 68191783Srmacklem AcpiExOpcode_1A_1T_0R, 69191783Srmacklem AcpiExOpcode_1A_1T_1R, 70191783Srmacklem AcpiExOpcode_2A_0T_0R, 71191783Srmacklem AcpiExOpcode_2A_0T_1R, 72191783Srmacklem AcpiExOpcode_2A_1T_1R, 73191783Srmacklem AcpiExOpcode_2A_2T_1R, 74191783Srmacklem AcpiExOpcode_3A_0T_0R, 75191783Srmacklem AcpiExOpcode_3A_1T_1R, 76191783Srmacklem AcpiExOpcode_6A_0T_1R 77191783Srmacklem}; 78191783Srmacklem 79191783Srmacklem 80191783Srmacklem/***************************************************************************** 81191783Srmacklem * 82191783Srmacklem * FUNCTION: AcpiDsGetPredicateValue 83191783Srmacklem * 84191783Srmacklem * PARAMETERS: WalkState - Current state of the parse tree walk 85191783Srmacklem * ResultObj - if non-zero, pop result from result stack 86191783Srmacklem * 87191783Srmacklem * RETURN: Status 88192115Srmacklem * 89191783Srmacklem * DESCRIPTION: Get the result of a predicate evaluation 90191783Srmacklem * 91191783Srmacklem ****************************************************************************/ 92191783Srmacklem 93191783SrmacklemACPI_STATUS 94191783SrmacklemAcpiDsGetPredicateValue ( 95191783Srmacklem ACPI_WALK_STATE *WalkState, 96191783Srmacklem ACPI_OPERAND_OBJECT *ResultObj) 97191783Srmacklem{ 98191783Srmacklem ACPI_STATUS Status = AE_OK; 99191783Srmacklem ACPI_OPERAND_OBJECT *ObjDesc; 100191783Srmacklem ACPI_OPERAND_OBJECT *LocalObjDesc = NULL; 101191783Srmacklem 102191783Srmacklem 103191783Srmacklem ACPI_FUNCTION_TRACE_PTR (DsGetPredicateValue, WalkState); 104191783Srmacklem 105191783Srmacklem 106191783Srmacklem WalkState->ControlState->Common.State = 0; 107191783Srmacklem 108191783Srmacklem if (ResultObj) 109191783Srmacklem { 110191783Srmacklem Status = AcpiDsResultPop (&ObjDesc, WalkState); 111191783Srmacklem if (ACPI_FAILURE (Status)) 112191783Srmacklem { 113191783Srmacklem ACPI_EXCEPTION ((AE_INFO, Status, 114191783Srmacklem "Could not get result from predicate evaluation")); 115191783Srmacklem 116191783Srmacklem return_ACPI_STATUS (Status); 117191783Srmacklem } 118191783Srmacklem } 119191783Srmacklem else 120191783Srmacklem { 121191783Srmacklem Status = AcpiDsCreateOperand (WalkState, WalkState->Op, 0); 122191783Srmacklem if (ACPI_FAILURE (Status)) 123191783Srmacklem { 124191783Srmacklem return_ACPI_STATUS (Status); 125191783Srmacklem } 126191783Srmacklem 127220530Srmacklem Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState); 128191783Srmacklem if (ACPI_FAILURE (Status)) 129192115Srmacklem { 130191783Srmacklem return_ACPI_STATUS (Status); 131191783Srmacklem } 132191783Srmacklem 133191783Srmacklem ObjDesc = WalkState->Operands [0]; 134191783Srmacklem } 135191783Srmacklem 136191783Srmacklem if (!ObjDesc) 137191783Srmacklem { 138191783Srmacklem ACPI_ERROR ((AE_INFO, 139191783Srmacklem "No predicate ObjDesc=%p State=%p", 140191783Srmacklem ObjDesc, WalkState)); 141191783Srmacklem 142191783Srmacklem return_ACPI_STATUS (AE_AML_NO_OPERAND); 143191783Srmacklem } 144191783Srmacklem 145191783Srmacklem /* 146191783Srmacklem * Result of predicate evaluation must be an Integer 147191783Srmacklem * object. Implicitly convert the argument if necessary. 148191783Srmacklem */ 149191783Srmacklem Status = AcpiExConvertToInteger (ObjDesc, &LocalObjDesc, 16); 150191783Srmacklem if (ACPI_FAILURE (Status)) 151191783Srmacklem { 152191783Srmacklem goto Cleanup; 153191783Srmacklem } 154191783Srmacklem 155191783Srmacklem if (LocalObjDesc->Common.Type != ACPI_TYPE_INTEGER) 156191783Srmacklem { 157191783Srmacklem ACPI_ERROR ((AE_INFO, 158191783Srmacklem "Bad predicate (not an integer) ObjDesc=%p State=%p Type=0x%X", 159191783Srmacklem ObjDesc, WalkState, ObjDesc->Common.Type)); 160191783Srmacklem 161191783Srmacklem Status = AE_AML_OPERAND_TYPE; 162191783Srmacklem goto Cleanup; 163191783Srmacklem } 164191783Srmacklem 165191783Srmacklem /* Truncate the predicate to 32-bits if necessary */ 166191783Srmacklem 167191783Srmacklem AcpiExTruncateFor32bitTable (LocalObjDesc); 168191783Srmacklem 169191783Srmacklem /* 170191783Srmacklem * Save the result of the predicate evaluation on 171191783Srmacklem * the control stack 172191783Srmacklem */ 173191783Srmacklem if (LocalObjDesc->Integer.Value) 174191783Srmacklem { 175191783Srmacklem WalkState->ControlState->Common.Value = TRUE; 176191783Srmacklem } 177191783Srmacklem else 178191783Srmacklem { 179191783Srmacklem /* 180191783Srmacklem * Predicate is FALSE, we will just toss the 181191783Srmacklem * rest of the package 182191783Srmacklem */ 183191783Srmacklem WalkState->ControlState->Common.Value = FALSE; 184191783Srmacklem Status = AE_CTRL_FALSE; 185191783Srmacklem } 186191783Srmacklem 187191783Srmacklem /* Predicate can be used for an implicit return value */ 188191783Srmacklem 189191783Srmacklem (void) AcpiDsDoImplicitReturn (LocalObjDesc, WalkState, TRUE); 190191783Srmacklem 191191783Srmacklem 192191783SrmacklemCleanup: 193191783Srmacklem 194191783Srmacklem ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n", 195191783Srmacklem WalkState->ControlState->Common.Value, WalkState->Op)); 196191783Srmacklem 197191783Srmacklem /* Break to debugger to display result */ 198191783Srmacklem 199191783Srmacklem ACPI_DEBUGGER_EXEC (AcpiDbDisplayResultObject (LocalObjDesc, WalkState)); 200191783Srmacklem 201191783Srmacklem /* 202191783Srmacklem * Delete the predicate result object (we know that 203191783Srmacklem * we don't need it anymore) 204191783Srmacklem */ 205191783Srmacklem if (LocalObjDesc != ObjDesc) 206191783Srmacklem { 207191783Srmacklem AcpiUtRemoveReference (LocalObjDesc); 208191783Srmacklem } 209191783Srmacklem AcpiUtRemoveReference (ObjDesc); 210191783Srmacklem 211191783Srmacklem WalkState->ControlState->Common.State = ACPI_CONTROL_NORMAL; 212191783Srmacklem return_ACPI_STATUS (Status); 213192115Srmacklem} 214191783Srmacklem 215191783Srmacklem 216191783Srmacklem/***************************************************************************** 217192115Srmacklem * 218191783Srmacklem * FUNCTION: AcpiDsExecBeginOp 219191783Srmacklem * 220191783Srmacklem * PARAMETERS: WalkState - Current state of the parse tree walk 221191783Srmacklem * OutOp - Where to return op if a new one is created 222191783Srmacklem * 223191783Srmacklem * RETURN: Status 224191783Srmacklem * 225191783Srmacklem * DESCRIPTION: Descending callback used during the execution of control 226191783Srmacklem * methods. This is where most operators and operands are 227191783Srmacklem * dispatched to the interpreter. 228192115Srmacklem * 229191783Srmacklem ****************************************************************************/ 230191783Srmacklem 231191783SrmacklemACPI_STATUS 232191783SrmacklemAcpiDsExecBeginOp ( 233191783Srmacklem ACPI_WALK_STATE *WalkState, 234191783Srmacklem ACPI_PARSE_OBJECT **OutOp) 235191783Srmacklem{ 236191783Srmacklem ACPI_PARSE_OBJECT *Op; 237191783Srmacklem ACPI_STATUS Status = AE_OK; 238191783Srmacklem UINT32 OpcodeClass; 239191783Srmacklem 240191783Srmacklem 241191783Srmacklem ACPI_FUNCTION_TRACE_PTR (DsExecBeginOp, WalkState); 242191783Srmacklem 243191783Srmacklem 244191783Srmacklem Op = WalkState->Op; 245191783Srmacklem if (!Op) 246191783Srmacklem { 247191783Srmacklem Status = AcpiDsLoad2BeginOp (WalkState, OutOp); 248191783Srmacklem if (ACPI_FAILURE (Status)) 249191783Srmacklem { 250191783Srmacklem goto ErrorExit; 251191783Srmacklem } 252191783Srmacklem 253191783Srmacklem Op = *OutOp; 254191783Srmacklem WalkState->Op = Op; 255211951Srmacklem WalkState->Opcode = Op->Common.AmlOpcode; 256205941Srmacklem WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 257191783Srmacklem 258191783Srmacklem if (AcpiNsOpensScope (WalkState->OpInfo->ObjectType)) 259192115Srmacklem { 260192115Srmacklem ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 261191783Srmacklem "(%s) Popping scope for Op %p\n", 262192115Srmacklem AcpiUtGetTypeName (WalkState->OpInfo->ObjectType), Op)); 263191783Srmacklem 264191783Srmacklem Status = AcpiDsScopeStackPop (WalkState); 265191783Srmacklem if (ACPI_FAILURE (Status)) 266191783Srmacklem { 267191783Srmacklem goto ErrorExit; 268191783Srmacklem } 269191783Srmacklem } 270191783Srmacklem } 271191783Srmacklem 272191783Srmacklem if (Op == WalkState->Origin) 273191783Srmacklem { 274191783Srmacklem if (OutOp) 275191783Srmacklem { 276191783Srmacklem *OutOp = Op; 277191783Srmacklem } 278191783Srmacklem 279191783Srmacklem return_ACPI_STATUS (AE_OK); 280191783Srmacklem } 281191783Srmacklem 282192115Srmacklem /* 283216700Srmacklem * If the previous opcode was a conditional, this opcode 284191783Srmacklem * must be the beginning of the associated predicate. 285191783Srmacklem * Save this knowledge in the current scope descriptor 286191783Srmacklem */ 287191783Srmacklem if ((WalkState->ControlState) && 288191783Srmacklem (WalkState->ControlState->Common.State == 289191783Srmacklem ACPI_CONTROL_CONDITIONAL_EXECUTING)) 290191783Srmacklem { 291220645Srmacklem ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Exec predicate Op=%p State=%p\n", 292191783Srmacklem Op, WalkState)); 293220648Srmacklem 294191783Srmacklem WalkState->ControlState->Common.State = ACPI_CONTROL_PREDICATE_EXECUTING; 295191783Srmacklem 296191783Srmacklem /* Save start of predicate */ 297191783Srmacklem 298191783Srmacklem WalkState->ControlState->Control.PredicateOp = Op; 299191783Srmacklem } 300191783Srmacklem 301191783Srmacklem 302191783Srmacklem OpcodeClass = WalkState->OpInfo->Class; 303191783Srmacklem 304191783Srmacklem /* We want to send namepaths to the load code */ 305191783Srmacklem 306191783Srmacklem if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) 307191783Srmacklem { 308191783Srmacklem OpcodeClass = AML_CLASS_NAMED_OBJECT; 309191783Srmacklem } 310191783Srmacklem 311191783Srmacklem /* 312192121Srmacklem * Handle the opcode based upon the opcode type 313191783Srmacklem */ 314192115Srmacklem switch (OpcodeClass) 315191783Srmacklem { 316192115Srmacklem case AML_CLASS_CONTROL: 317191783Srmacklem 318191783Srmacklem Status = AcpiDsExecBeginControlOp (WalkState, Op); 319191783Srmacklem break; 320191783Srmacklem 321191783Srmacklem 322191783Srmacklem case AML_CLASS_NAMED_OBJECT: 323191783Srmacklem 324191783Srmacklem if (WalkState->WalkType & ACPI_WALK_METHOD) 325191783Srmacklem { 326191783Srmacklem /* 327207170Srmacklem * Found a named object declaration during method execution; 328191783Srmacklem * we must enter this object into the namespace. The created 329191783Srmacklem * object is temporary and will be deleted upon completion of 330192115Srmacklem * the execution of this method. 331220648Srmacklem * 332191783Srmacklem * Note 10/2010: Except for the Scope() op. This opcode does 333192115Srmacklem * not actually create a new object, it refers to an existing 334191783Srmacklem * object. However, for Scope(), we want to indeed open a 335191783Srmacklem * new scope. 336191783Srmacklem */ 337191783Srmacklem if (Op->Common.AmlOpcode != AML_SCOPE_OP) 338191783Srmacklem { 339191783Srmacklem Status = AcpiDsLoad2BeginOp (WalkState, NULL); 340191783Srmacklem } 341191783Srmacklem else 342192115Srmacklem { 343191783Srmacklem Status = AcpiDsScopeStackPush (Op->Named.Node, 344191783Srmacklem Op->Named.Node->Type, WalkState); 345191783Srmacklem if (ACPI_FAILURE (Status)) 346191783Srmacklem { 347191783Srmacklem return_ACPI_STATUS (Status); 348191783Srmacklem } 349191783Srmacklem } 350191783Srmacklem } 351191783Srmacklem break; 352191783Srmacklem 353191783Srmacklem 354192337Srmacklem case AML_CLASS_EXECUTE: 355191783Srmacklem case AML_CLASS_CREATE: 356191783Srmacklem 357191783Srmacklem break; 358191783Srmacklem 359191783Srmacklem 360191783Srmacklem default: 361191783Srmacklem break; 362191783Srmacklem } 363191783Srmacklem 364191783Srmacklem /* Nothing to do here during method execution */ 365191783Srmacklem 366191783Srmacklem return_ACPI_STATUS (Status); 367191783Srmacklem 368191783Srmacklem 369191783SrmacklemErrorExit: 370191783Srmacklem Status = AcpiDsMethodError (Status, WalkState); 371191783Srmacklem return_ACPI_STATUS (Status); 372191783Srmacklem} 373191783Srmacklem 374191783Srmacklem 375207082Srmacklem/***************************************************************************** 376191783Srmacklem * 377191783Srmacklem * FUNCTION: AcpiDsExecEndOp 378191783Srmacklem * 379191783Srmacklem * PARAMETERS: WalkState - Current state of the parse tree walk 380191783Srmacklem * 381191783Srmacklem * RETURN: Status 382191783Srmacklem * 383191783Srmacklem * DESCRIPTION: Ascending callback used during the execution of control 384191783Srmacklem * methods. The only thing we really need to do here is to 385191783Srmacklem * notice the beginning of IF, ELSE, and WHILE blocks. 386191783Srmacklem * 387191783Srmacklem ****************************************************************************/ 388191783Srmacklem 389191783SrmacklemACPI_STATUS 390191783SrmacklemAcpiDsExecEndOp ( 391191783Srmacklem ACPI_WALK_STATE *WalkState) 392191783Srmacklem{ 393191783Srmacklem ACPI_PARSE_OBJECT *Op; 394191783Srmacklem ACPI_STATUS Status = AE_OK; 395191783Srmacklem UINT32 OpType; 396191783Srmacklem UINT32 OpClass; 397191783Srmacklem ACPI_PARSE_OBJECT *NextOp; 398191783Srmacklem ACPI_PARSE_OBJECT *FirstArg; 399191783Srmacklem 400191783Srmacklem 401191783Srmacklem ACPI_FUNCTION_TRACE_PTR (DsExecEndOp, WalkState); 402191783Srmacklem 403191783Srmacklem 404191783Srmacklem Op = WalkState->Op; 405191783Srmacklem OpType = WalkState->OpInfo->Type; 406191783Srmacklem OpClass = WalkState->OpInfo->Class; 407191783Srmacklem 408191783Srmacklem if (OpClass == AML_CLASS_UNKNOWN) 409191783Srmacklem { 410191783Srmacklem ACPI_ERROR ((AE_INFO, "Unknown opcode 0x%X", Op->Common.AmlOpcode)); 411191783Srmacklem return_ACPI_STATUS (AE_NOT_IMPLEMENTED); 412191783Srmacklem } 413191783Srmacklem 414191783Srmacklem FirstArg = Op->Common.Value.Arg; 415191783Srmacklem 416191783Srmacklem /* Init the walk state */ 417191783Srmacklem 418191783Srmacklem WalkState->NumOperands = 0; 419191783Srmacklem WalkState->OperandIndex = 0; 420191783Srmacklem WalkState->ReturnDesc = NULL; 421191783Srmacklem WalkState->ResultObj = NULL; 422191783Srmacklem 423191783Srmacklem /* Call debugger for single step support (DEBUG build only) */ 424191783Srmacklem 425191783Srmacklem ACPI_DEBUGGER_EXEC (Status = AcpiDbSingleStep (WalkState, Op, OpClass)); 426191783Srmacklem ACPI_DEBUGGER_EXEC (if (ACPI_FAILURE (Status)) {return_ACPI_STATUS (Status);}); 427191783Srmacklem 428191783Srmacklem /* Decode the Opcode Class */ 429192115Srmacklem 430191783Srmacklem switch (OpClass) 431191783Srmacklem { 432191783Srmacklem case AML_CLASS_ARGUMENT: /* Constants, literals, etc. */ 433191783Srmacklem 434191783Srmacklem if (WalkState->Opcode == AML_INT_NAMEPATH_OP) 435191783Srmacklem { 436191783Srmacklem Status = AcpiDsEvaluateNamePath (WalkState); 437191783Srmacklem if (ACPI_FAILURE (Status)) 438191783Srmacklem { 439191783Srmacklem goto Cleanup; 440191783Srmacklem } 441191783Srmacklem } 442191783Srmacklem break; 443191783Srmacklem 444191783Srmacklem 445191783Srmacklem case AML_CLASS_EXECUTE: /* Most operators with arguments */ 446191783Srmacklem 447191783Srmacklem /* Build resolved operand stack */ 448191783Srmacklem 449191783Srmacklem Status = AcpiDsCreateOperands (WalkState, FirstArg); 450191783Srmacklem if (ACPI_FAILURE (Status)) 451191783Srmacklem { 452191783Srmacklem goto Cleanup; 453191783Srmacklem } 454191783Srmacklem 455191783Srmacklem /* 456191783Srmacklem * All opcodes require operand resolution, with the only exceptions 457191783Srmacklem * being the ObjectType and SizeOf operators. 458191783Srmacklem */ 459191783Srmacklem if (!(WalkState->OpInfo->Flags & AML_NO_OPERAND_RESOLVE)) 460195510Srmacklem { 461195510Srmacklem /* Resolve all operands */ 462195510Srmacklem 463191783Srmacklem Status = AcpiExResolveOperands (WalkState->Opcode, 464191783Srmacklem &(WalkState->Operands [WalkState->NumOperands -1]), 465191783Srmacklem WalkState); 466191783Srmacklem } 467191783Srmacklem 468191783Srmacklem if (ACPI_SUCCESS (Status)) 469191783Srmacklem { 470191783Srmacklem /* 471191783Srmacklem * Dispatch the request to the appropriate interpreter handler 472191783Srmacklem * routine. There is one routine per opcode "type" based upon the 473210786Srmacklem * number of opcode arguments and return type. 474191783Srmacklem */ 475191783Srmacklem Status = AcpiGbl_OpTypeDispatch[OpType] (WalkState); 476191783Srmacklem } 477191783Srmacklem else 478191783Srmacklem { 479191783Srmacklem /* 480191783Srmacklem * Treat constructs of the form "Store(LocalX,LocalX)" as noops when the 481191783Srmacklem * Local is uninitialized. 482191783Srmacklem */ 483191783Srmacklem if ((Status == AE_AML_UNINITIALIZED_LOCAL) && 484191783Srmacklem (WalkState->Opcode == AML_STORE_OP) && 485191783Srmacklem (WalkState->Operands[0]->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) && 486191783Srmacklem (WalkState->Operands[1]->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) && 487191783Srmacklem (WalkState->Operands[0]->Reference.Class == 488192115Srmacklem WalkState->Operands[1]->Reference.Class) && 489191783Srmacklem (WalkState->Operands[0]->Reference.Value == 490191783Srmacklem WalkState->Operands[1]->Reference.Value)) 491191783Srmacklem { 492191783Srmacklem Status = AE_OK; 493191783Srmacklem } 494191783Srmacklem else 495191783Srmacklem { 496191783Srmacklem ACPI_EXCEPTION ((AE_INFO, Status, 497191783Srmacklem "While resolving operands for [%s]", 498191783Srmacklem AcpiPsGetOpcodeName (WalkState->Opcode))); 499191783Srmacklem } 500191783Srmacklem } 501191783Srmacklem 502191783Srmacklem /* Always delete the argument objects and clear the operand stack */ 503191783Srmacklem 504192115Srmacklem AcpiDsClearOperands (WalkState); 505191783Srmacklem 506191783Srmacklem /* 507192115Srmacklem * If a result object was returned from above, push it on the 508207082Srmacklem * current result stack 509191783Srmacklem */ 510192115Srmacklem if (ACPI_SUCCESS (Status) && 511191783Srmacklem WalkState->ResultObj) 512191783Srmacklem { 513192115Srmacklem Status = AcpiDsResultPush (WalkState->ResultObj, WalkState); 514191783Srmacklem } 515216693Srmacklem break; 516191783Srmacklem 517191783Srmacklem 518191783Srmacklem default: 519200999Srmacklem 520200999Srmacklem switch (OpType) 521191783Srmacklem { 522191783Srmacklem case AML_TYPE_CONTROL: /* Type 1 opcode, IF/ELSE/WHILE/NOOP */ 523191783Srmacklem 524191783Srmacklem /* 1 Operand, 0 ExternalResult, 0 InternalResult */ 525191783Srmacklem 526191783Srmacklem Status = AcpiDsExecEndControlOp (WalkState, Op); 527191783Srmacklem 528191783Srmacklem break; 529191783Srmacklem 530191783Srmacklem 531191783Srmacklem case AML_TYPE_METHOD_CALL: 532199616Srmacklem 533191783Srmacklem /* 534191783Srmacklem * If the method is referenced from within a package 535191783Srmacklem * declaration, it is not a invocation of the method, just 536191783Srmacklem * a reference to it. 537191783Srmacklem */ 538191783Srmacklem if ((Op->Asl.Parent) && 539191783Srmacklem ((Op->Asl.Parent->Asl.AmlOpcode == AML_PACKAGE_OP) || 540191783Srmacklem (Op->Asl.Parent->Asl.AmlOpcode == AML_VAR_PACKAGE_OP))) 541191783Srmacklem { 542191783Srmacklem ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 543191783Srmacklem "Method Reference in a Package, Op=%p\n", Op)); 544191783Srmacklem 545191783Srmacklem Op->Common.Node = (ACPI_NAMESPACE_NODE *) Op->Asl.Value.Arg->Asl.Node; 546191783Srmacklem AcpiUtAddReference (Op->Asl.Value.Arg->Asl.Node->Object); 547191783Srmacklem return_ACPI_STATUS (AE_OK); 548191783Srmacklem } 549191783Srmacklem 550191783Srmacklem ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Method invocation, Op=%p\n", Op)); 551191783Srmacklem 552191990Sattilio /* 553191783Srmacklem * (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains 554191783Srmacklem * the method Node pointer 555199616Srmacklem */ 556191783Srmacklem /* NextOp points to the op that holds the method name */ 557191783Srmacklem 558191783Srmacklem NextOp = FirstArg; 559191783Srmacklem 560220645Srmacklem /* NextOp points to first argument op */ 561191783Srmacklem 562220648Srmacklem NextOp = NextOp->Common.Next; 563191783Srmacklem 564191783Srmacklem /* 565191783Srmacklem * Get the method's arguments and put them on the operand stack 566191783Srmacklem */ 567191783Srmacklem Status = AcpiDsCreateOperands (WalkState, NextOp); 568191783Srmacklem if (ACPI_FAILURE (Status)) 569216700Srmacklem { 570191783Srmacklem break; 571191783Srmacklem } 572191783Srmacklem 573191783Srmacklem /* 574191783Srmacklem * Since the operands will be passed to another control method, 575191783Srmacklem * we must resolve all local references here (Local variables, 576192121Srmacklem * arguments to *this* method, etc.) 577214255Srmacklem */ 578217432Srmacklem Status = AcpiDsResolveOperands (WalkState); 579191783Srmacklem if (ACPI_FAILURE (Status)) 580192115Srmacklem { 581191783Srmacklem /* On error, clear all resolved operands */ 582191783Srmacklem 583191783Srmacklem AcpiDsClearOperands (WalkState); 584191783Srmacklem break; 585192115Srmacklem } 586192115Srmacklem 587192115Srmacklem /* 588192115Srmacklem * Tell the walk loop to preempt this running method and 589192115Srmacklem * execute the new method 590192115Srmacklem */ 591192115Srmacklem Status = AE_CTRL_TRANSFER; 592191783Srmacklem 593192115Srmacklem /* 594191783Srmacklem * Return now; we don't want to disturb anything, 595191783Srmacklem * especially the operand count! 596191783Srmacklem */ 597191783Srmacklem return_ACPI_STATUS (Status); 598192115Srmacklem 599191783Srmacklem 600191783Srmacklem case AML_TYPE_CREATE_FIELD: 601191783Srmacklem 602 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 603 "Executing CreateField Buffer/Index Op=%p\n", Op)); 604 605 Status = AcpiDsLoad2EndOp (WalkState); 606 if (ACPI_FAILURE (Status)) 607 { 608 break; 609 } 610 611 Status = AcpiDsEvalBufferFieldOperands (WalkState, Op); 612 break; 613 614 615 case AML_TYPE_CREATE_OBJECT: 616 617 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 618 "Executing CreateObject (Buffer/Package) Op=%p\n", Op)); 619 620 switch (Op->Common.Parent->Common.AmlOpcode) 621 { 622 case AML_NAME_OP: 623 624 /* 625 * Put the Node on the object stack (Contains the ACPI Name 626 * of this object) 627 */ 628 WalkState->Operands[0] = (void *) Op->Common.Parent->Common.Node; 629 WalkState->NumOperands = 1; 630 631 Status = AcpiDsCreateNode (WalkState, 632 Op->Common.Parent->Common.Node, 633 Op->Common.Parent); 634 if (ACPI_FAILURE (Status)) 635 { 636 break; 637 } 638 639 /* Fall through */ 640 /*lint -fallthrough */ 641 642 case AML_INT_EVAL_SUBTREE_OP: 643 644 Status = AcpiDsEvalDataObjectOperands (WalkState, Op, 645 AcpiNsGetAttachedObject (Op->Common.Parent->Common.Node)); 646 break; 647 648 default: 649 650 Status = AcpiDsEvalDataObjectOperands (WalkState, Op, NULL); 651 break; 652 } 653 654 /* 655 * If a result object was returned from above, push it on the 656 * current result stack 657 */ 658 if (WalkState->ResultObj) 659 { 660 Status = AcpiDsResultPush (WalkState->ResultObj, WalkState); 661 } 662 break; 663 664 665 case AML_TYPE_NAMED_FIELD: 666 case AML_TYPE_NAMED_COMPLEX: 667 case AML_TYPE_NAMED_SIMPLE: 668 case AML_TYPE_NAMED_NO_OBJ: 669 670 Status = AcpiDsLoad2EndOp (WalkState); 671 if (ACPI_FAILURE (Status)) 672 { 673 break; 674 } 675 676 if (Op->Common.AmlOpcode == AML_REGION_OP) 677 { 678 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 679 "Executing OpRegion Address/Length Op=%p\n", Op)); 680 681 Status = AcpiDsEvalRegionOperands (WalkState, Op); 682 if (ACPI_FAILURE (Status)) 683 { 684 break; 685 } 686 } 687 else if (Op->Common.AmlOpcode == AML_DATA_REGION_OP) 688 { 689 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 690 "Executing DataTableRegion Strings Op=%p\n", Op)); 691 692 Status = AcpiDsEvalTableRegionOperands (WalkState, Op); 693 if (ACPI_FAILURE (Status)) 694 { 695 break; 696 } 697 } 698 else if (Op->Common.AmlOpcode == AML_BANK_FIELD_OP) 699 { 700 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 701 "Executing BankField Op=%p\n", Op)); 702 703 Status = AcpiDsEvalBankFieldOperands (WalkState, Op); 704 if (ACPI_FAILURE (Status)) 705 { 706 break; 707 } 708 } 709 break; 710 711 712 case AML_TYPE_UNDEFINED: 713 714 ACPI_ERROR ((AE_INFO, 715 "Undefined opcode type Op=%p", Op)); 716 return_ACPI_STATUS (AE_NOT_IMPLEMENTED); 717 718 719 case AML_TYPE_BOGUS: 720 721 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 722 "Internal opcode=%X type Op=%p\n", 723 WalkState->Opcode, Op)); 724 break; 725 726 727 default: 728 729 ACPI_ERROR ((AE_INFO, 730 "Unimplemented opcode, class=0x%X type=0x%X Opcode=-0x%X Op=%p", 731 OpClass, OpType, Op->Common.AmlOpcode, Op)); 732 733 Status = AE_NOT_IMPLEMENTED; 734 break; 735 } 736 } 737 738 /* 739 * ACPI 2.0 support for 64-bit integers: Truncate numeric 740 * result value if we are executing from a 32-bit ACPI table 741 */ 742 AcpiExTruncateFor32bitTable (WalkState->ResultObj); 743 744 /* 745 * Check if we just completed the evaluation of a 746 * conditional predicate 747 */ 748 if ((ACPI_SUCCESS (Status)) && 749 (WalkState->ControlState) && 750 (WalkState->ControlState->Common.State == 751 ACPI_CONTROL_PREDICATE_EXECUTING) && 752 (WalkState->ControlState->Control.PredicateOp == Op)) 753 { 754 Status = AcpiDsGetPredicateValue (WalkState, WalkState->ResultObj); 755 WalkState->ResultObj = NULL; 756 } 757 758 759Cleanup: 760 761 if (WalkState->ResultObj) 762 { 763 /* Break to debugger to display result */ 764 765 ACPI_DEBUGGER_EXEC (AcpiDbDisplayResultObject (WalkState->ResultObj, 766 WalkState)); 767 768 /* 769 * Delete the result op if and only if: 770 * Parent will not use the result -- such as any 771 * non-nested type2 op in a method (parent will be method) 772 */ 773 AcpiDsDeleteResultIfNotUsed (Op, WalkState->ResultObj, WalkState); 774 } 775 776#ifdef _UNDER_DEVELOPMENT 777 778 if (WalkState->ParserState.Aml == WalkState->ParserState.AmlEnd) 779 { 780 AcpiDbMethodEnd (WalkState); 781 } 782#endif 783 784 /* Invoke exception handler on error */ 785 786 if (ACPI_FAILURE (Status)) 787 { 788 Status = AcpiDsMethodError (Status, WalkState); 789 } 790 791 /* Always clear the object stack */ 792 793 WalkState->NumOperands = 0; 794 return_ACPI_STATUS (Status); 795} 796