185754Smsmith/****************************************************************************** 285754Smsmith * 385754Smsmith * Module Name: exoparg2 - AML execution - opcodes with 2 arguments 485754Smsmith * 585754Smsmith *****************************************************************************/ 685754Smsmith 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 985754Smsmith * All rights reserved. 1085754Smsmith * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 2585754Smsmith * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 2985754Smsmith * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 4385754Smsmith 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46193341Sjkim#include <contrib/dev/acpica/include/acparser.h> 47193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 48193341Sjkim#include <contrib/dev/acpica/include/acevents.h> 49193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 5085754Smsmith 5185754Smsmith 5285754Smsmith#define _COMPONENT ACPI_EXECUTER 5391116Smsmith ACPI_MODULE_NAME ("exoparg2") 5485754Smsmith 5585754Smsmith 5685754Smsmith/*! 5785754Smsmith * Naming convention for AML interpreter execution routines. 5885754Smsmith * 5985754Smsmith * The routines that begin execution of AML opcodes are named with a common 6085754Smsmith * convention based upon the number of arguments, the number of target operands, 6185754Smsmith * and whether or not a value is returned: 6285754Smsmith * 6385754Smsmith * AcpiExOpcode_xA_yT_zR 6485754Smsmith * 6587031Smsmith * Where: 6685754Smsmith * 6787031Smsmith * xA - ARGUMENTS: The number of arguments (input operands) that are 6885754Smsmith * required for this opcode type (1 through 6 args). 6987031Smsmith * yT - TARGETS: The number of targets (output operands) that are required 7085754Smsmith * for this opcode type (0, 1, or 2 targets). 7187031Smsmith * zR - RETURN VALUE: Indicates whether this opcode type returns a value 7285754Smsmith * as the function return (0 or 1). 7385754Smsmith * 7487031Smsmith * The AcpiExOpcode* functions are called via the Dispatcher component with 7585754Smsmith * fully resolved operands. 7685754Smsmith!*/ 7785754Smsmith 7885754Smsmith 7985754Smsmith/******************************************************************************* 8085754Smsmith * 8185754Smsmith * FUNCTION: AcpiExOpcode_2A_0T_0R 8285754Smsmith * 8385754Smsmith * PARAMETERS: WalkState - Current walk state 8485754Smsmith * 8585754Smsmith * RETURN: Status 8685754Smsmith * 8785754Smsmith * DESCRIPTION: Execute opcode with two arguments, no target, and no return 8885754Smsmith * value. 8985754Smsmith * 9085754Smsmith * ALLOCATION: Deletes both operands 9185754Smsmith * 9285754Smsmith ******************************************************************************/ 9385754Smsmith 9485754SmsmithACPI_STATUS 9585754SmsmithAcpiExOpcode_2A_0T_0R ( 9685754Smsmith ACPI_WALK_STATE *WalkState) 9785754Smsmith{ 9885754Smsmith ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 9985754Smsmith ACPI_NAMESPACE_NODE *Node; 100129684Snjl UINT32 Value; 10185754Smsmith ACPI_STATUS Status = AE_OK; 10285754Smsmith 10385754Smsmith 104167802Sjkim ACPI_FUNCTION_TRACE_STR (ExOpcode_2A_0T_0R, 10599146Siwasaki AcpiPsGetOpcodeName (WalkState->Opcode)); 10685754Smsmith 10785754Smsmith 10885754Smsmith /* Examine the opcode */ 10985754Smsmith 11085754Smsmith switch (WalkState->Opcode) 11185754Smsmith { 11285754Smsmith case AML_NOTIFY_OP: /* Notify (NotifyObject, NotifyValue) */ 11385754Smsmith 11485754Smsmith /* The first operand is a namespace node */ 11585754Smsmith 11685754Smsmith Node = (ACPI_NAMESPACE_NODE *) Operand[0]; 11785754Smsmith 118129684Snjl /* Second value is the notify value */ 119129684Snjl 120129684Snjl Value = (UINT32) Operand[1]->Integer.Value; 121129684Snjl 122151937Sjkim /* Are notifies allowed on this object? */ 12385754Smsmith 12499146Siwasaki if (!AcpiEvIsNotifyObject (Node)) 12585754Smsmith { 126167802Sjkim ACPI_ERROR ((AE_INFO, 127167802Sjkim "Unexpected notify object type [%s]", 128167802Sjkim AcpiUtGetTypeName (Node->Type))); 12985754Smsmith 13091116Smsmith Status = AE_AML_OPERAND_TYPE; 13191116Smsmith break; 13285754Smsmith } 13399146Siwasaki 13499146Siwasaki /* 13599146Siwasaki * Dispatch the notify to the appropriate handler 13699146Siwasaki * NOTE: the request is queued for execution after this method 137241973Sjkim * completes. The notify handlers are NOT invoked synchronously 13899146Siwasaki * from this thread -- because handlers may in turn run other 13999146Siwasaki * control methods. 14099146Siwasaki */ 141129684Snjl Status = AcpiEvQueueNotifyRequest (Node, Value); 14285754Smsmith break; 14385754Smsmith 14485754Smsmith default: 14585754Smsmith 146204773Sjkim ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X", 147167802Sjkim WalkState->Opcode)); 14885754Smsmith Status = AE_AML_BAD_OPCODE; 14985754Smsmith } 15085754Smsmith 15185754Smsmith return_ACPI_STATUS (Status); 15285754Smsmith} 15385754Smsmith 15485754Smsmith 15585754Smsmith/******************************************************************************* 15685754Smsmith * 15785754Smsmith * FUNCTION: AcpiExOpcode_2A_2T_1R 15885754Smsmith * 15985754Smsmith * PARAMETERS: WalkState - Current walk state 16085754Smsmith * 16185754Smsmith * RETURN: Status 16285754Smsmith * 16385754Smsmith * DESCRIPTION: Execute a dyadic operator (2 operands) with 2 output targets 16485754Smsmith * and one implicit return value. 16585754Smsmith * 16685754Smsmith ******************************************************************************/ 16785754Smsmith 16885754SmsmithACPI_STATUS 16985754SmsmithAcpiExOpcode_2A_2T_1R ( 17085754Smsmith ACPI_WALK_STATE *WalkState) 17185754Smsmith{ 17285754Smsmith ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 17385754Smsmith ACPI_OPERAND_OBJECT *ReturnDesc1 = NULL; 17485754Smsmith ACPI_OPERAND_OBJECT *ReturnDesc2 = NULL; 17585754Smsmith ACPI_STATUS Status; 17685754Smsmith 17785754Smsmith 178167802Sjkim ACPI_FUNCTION_TRACE_STR (ExOpcode_2A_2T_1R, 179138287Smarks AcpiPsGetOpcodeName (WalkState->Opcode)); 18085754Smsmith 18185754Smsmith 182151937Sjkim /* Execute the opcode */ 183151937Sjkim 18485754Smsmith switch (WalkState->Opcode) 18585754Smsmith { 186151937Sjkim case AML_DIVIDE_OP: 18785754Smsmith 188151937Sjkim /* Divide (Dividend, Divisor, RemainderResult QuotientResult) */ 189151937Sjkim 19085754Smsmith ReturnDesc1 = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 19185754Smsmith if (!ReturnDesc1) 19285754Smsmith { 19385754Smsmith Status = AE_NO_MEMORY; 19485754Smsmith goto Cleanup; 19585754Smsmith } 19685754Smsmith 19785754Smsmith ReturnDesc2 = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 19885754Smsmith if (!ReturnDesc2) 19985754Smsmith { 20085754Smsmith Status = AE_NO_MEMORY; 20185754Smsmith goto Cleanup; 20285754Smsmith } 20385754Smsmith 20485754Smsmith /* Quotient to ReturnDesc1, remainder to ReturnDesc2 */ 20585754Smsmith 206306536Sjkim Status = AcpiUtDivide ( 207306536Sjkim Operand[0]->Integer.Value, 208306536Sjkim Operand[1]->Integer.Value, 209306536Sjkim &ReturnDesc1->Integer.Value, 210306536Sjkim &ReturnDesc2->Integer.Value); 21185754Smsmith if (ACPI_FAILURE (Status)) 21285754Smsmith { 21385754Smsmith goto Cleanup; 21485754Smsmith } 21585754Smsmith break; 21685754Smsmith 21785754Smsmith default: 21885754Smsmith 219204773Sjkim ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X", 220167802Sjkim WalkState->Opcode)); 221306536Sjkim 22285754Smsmith Status = AE_AML_BAD_OPCODE; 22385754Smsmith goto Cleanup; 22485754Smsmith } 22585754Smsmith 22685754Smsmith /* Store the results to the target reference operands */ 22785754Smsmith 22885754Smsmith Status = AcpiExStore (ReturnDesc2, Operand[2], WalkState); 22985754Smsmith if (ACPI_FAILURE (Status)) 23085754Smsmith { 23185754Smsmith goto Cleanup; 23285754Smsmith } 23385754Smsmith 23485754Smsmith Status = AcpiExStore (ReturnDesc1, Operand[3], WalkState); 23585754Smsmith if (ACPI_FAILURE (Status)) 23685754Smsmith { 23785754Smsmith goto Cleanup; 23885754Smsmith } 23985754Smsmith 24085754SmsmithCleanup: 24185754Smsmith /* 24285754Smsmith * Since the remainder is not returned indirectly, remove a reference to 24385754Smsmith * it. Only the quotient is returned indirectly. 24485754Smsmith */ 24585754Smsmith AcpiUtRemoveReference (ReturnDesc2); 24685754Smsmith 24785754Smsmith if (ACPI_FAILURE (Status)) 24885754Smsmith { 24985754Smsmith /* Delete the return object */ 25085754Smsmith 25185754Smsmith AcpiUtRemoveReference (ReturnDesc1); 25285754Smsmith } 25385754Smsmith 254167802Sjkim /* Save return object (the remainder) on success */ 255167802Sjkim 256167802Sjkim else 257167802Sjkim { 258167802Sjkim WalkState->ResultObj = ReturnDesc1; 259167802Sjkim } 260167802Sjkim 26185754Smsmith return_ACPI_STATUS (Status); 26285754Smsmith} 26385754Smsmith 26485754Smsmith 26585754Smsmith/******************************************************************************* 26685754Smsmith * 26785754Smsmith * FUNCTION: AcpiExOpcode_2A_1T_1R 26885754Smsmith * 26985754Smsmith * PARAMETERS: WalkState - Current walk state 27085754Smsmith * 27185754Smsmith * RETURN: Status 27285754Smsmith * 27385754Smsmith * DESCRIPTION: Execute opcode with two arguments, one target, and a return 27485754Smsmith * value. 27585754Smsmith * 27685754Smsmith ******************************************************************************/ 27785754Smsmith 27885754SmsmithACPI_STATUS 27985754SmsmithAcpiExOpcode_2A_1T_1R ( 28085754Smsmith ACPI_WALK_STATE *WalkState) 28185754Smsmith{ 282107325Siwasaki ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 28385754Smsmith ACPI_OPERAND_OBJECT *ReturnDesc = NULL; 284202771Sjkim UINT64 Index; 285107325Siwasaki ACPI_STATUS Status = AE_OK; 286249112Sjkim ACPI_SIZE Length = 0; 28785754Smsmith 28885754Smsmith 289167802Sjkim ACPI_FUNCTION_TRACE_STR (ExOpcode_2A_1T_1R, 290138287Smarks AcpiPsGetOpcodeName (WalkState->Opcode)); 29185754Smsmith 29285754Smsmith 293151937Sjkim /* Execute the opcode */ 294151937Sjkim 29585754Smsmith if (WalkState->OpInfo->Flags & AML_MATH) 29685754Smsmith { 29785754Smsmith /* All simple math opcodes (add, etc.) */ 29885754Smsmith 29985754Smsmith ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 30085754Smsmith if (!ReturnDesc) 30185754Smsmith { 30285754Smsmith Status = AE_NO_MEMORY; 30385754Smsmith goto Cleanup; 30485754Smsmith } 30585754Smsmith 306306536Sjkim ReturnDesc->Integer.Value = AcpiExDoMathOp ( 307306536Sjkim WalkState->Opcode, 308306536Sjkim Operand[0]->Integer.Value, 309306536Sjkim Operand[1]->Integer.Value); 31085754Smsmith goto StoreResultToTarget; 31185754Smsmith } 31285754Smsmith 31385754Smsmith switch (WalkState->Opcode) 31485754Smsmith { 315151937Sjkim case AML_MOD_OP: /* Mod (Dividend, Divisor, RemainderResult (ACPI 2.0) */ 31685754Smsmith 31785754Smsmith ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 31885754Smsmith if (!ReturnDesc) 31985754Smsmith { 32085754Smsmith Status = AE_NO_MEMORY; 32185754Smsmith goto Cleanup; 32285754Smsmith } 32385754Smsmith 32485754Smsmith /* ReturnDesc will contain the remainder */ 32585754Smsmith 326306536Sjkim Status = AcpiUtDivide ( 327306536Sjkim Operand[0]->Integer.Value, 328306536Sjkim Operand[1]->Integer.Value, 329306536Sjkim NULL, 330306536Sjkim &ReturnDesc->Integer.Value); 33185754Smsmith break; 33285754Smsmith 333151937Sjkim case AML_CONCAT_OP: /* Concatenate (Data1, Data2, Result) */ 33485754Smsmith 335306536Sjkim Status = AcpiExDoConcatenate ( 336306536Sjkim Operand[0], Operand[1], &ReturnDesc, WalkState); 33785754Smsmith break; 33885754Smsmith 339151937Sjkim case AML_TO_STRING_OP: /* ToString (Buffer, Length, Result) (ACPI 2.0) */ 340104470Siwasaki /* 341104470Siwasaki * Input object is guaranteed to be a buffer at this point (it may have 342151937Sjkim * been converted.) Copy the raw buffer data to a new object of 343151937Sjkim * type String. 344104470Siwasaki */ 345104470Siwasaki 346138287Smarks /* 347138287Smarks * Get the length of the new string. It is the smallest of: 348138287Smarks * 1) Length of the input buffer 349138287Smarks * 2) Max length as specified in the ToString operator 350138287Smarks * 3) Length of input buffer up to a zero byte (null terminator) 351138287Smarks * 352138287Smarks * NOTE: A length of zero is ok, and will create a zero-length, null 353138287Smarks * terminated string. 354138287Smarks */ 355104470Siwasaki while ((Length < Operand[0]->Buffer.Length) && 356104470Siwasaki (Length < Operand[1]->Integer.Value) && 357104470Siwasaki (Operand[0]->Buffer.Pointer[Length])) 358104470Siwasaki { 359104470Siwasaki Length++; 360104470Siwasaki } 361104470Siwasaki 362138287Smarks /* Allocate a new string object */ 363104470Siwasaki 364138287Smarks ReturnDesc = AcpiUtCreateStringObject (Length); 365104470Siwasaki if (!ReturnDesc) 366104470Siwasaki { 367104470Siwasaki Status = AE_NO_MEMORY; 368104470Siwasaki goto Cleanup; 369104470Siwasaki } 370114237Snjl 371167802Sjkim /* 372167802Sjkim * Copy the raw buffer data with no transform. 373167802Sjkim * (NULL terminated already) 374167802Sjkim */ 375306536Sjkim memcpy (ReturnDesc->String.Pointer, 376138287Smarks Operand[0]->Buffer.Pointer, Length); 37785754Smsmith break; 37885754Smsmith 379151937Sjkim case AML_CONCAT_RES_OP: 38085754Smsmith 381151937Sjkim /* ConcatenateResTemplate (Buffer, Buffer, Result) (ACPI 2.0) */ 382151937Sjkim 383306536Sjkim Status = AcpiExConcatTemplate ( 384306536Sjkim Operand[0], Operand[1], &ReturnDesc, WalkState); 38585754Smsmith break; 38685754Smsmith 38785754Smsmith case AML_INDEX_OP: /* Index (Source Index Result) */ 38885754Smsmith 38985754Smsmith /* Create the internal return object */ 39085754Smsmith 391107325Siwasaki ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_REFERENCE); 39285754Smsmith if (!ReturnDesc) 39385754Smsmith { 39485754Smsmith Status = AE_NO_MEMORY; 39585754Smsmith goto Cleanup; 39685754Smsmith } 39785754Smsmith 398167802Sjkim /* Initialize the Index reference object */ 399167802Sjkim 400151937Sjkim Index = Operand[1]->Integer.Value; 401193267Sjkim ReturnDesc->Reference.Value = (UINT32) Index; 402193267Sjkim ReturnDesc->Reference.Class = ACPI_REFCLASS_INDEX; 40385754Smsmith 404167802Sjkim /* 405167802Sjkim * At this point, the Source operand is a String, Buffer, or Package. 406167802Sjkim * Verify that the index is within range. 407167802Sjkim */ 408193267Sjkim switch ((Operand[0])->Common.Type) 40985754Smsmith { 410167802Sjkim case ACPI_TYPE_STRING: 41185754Smsmith 412167802Sjkim if (Index >= Operand[0]->String.Length) 41385754Smsmith { 414249112Sjkim Length = Operand[0]->String.Length; 415167802Sjkim Status = AE_AML_STRING_LIMIT; 41685754Smsmith } 41785754Smsmith 418167802Sjkim ReturnDesc->Reference.TargetType = ACPI_TYPE_BUFFER_FIELD; 419306536Sjkim ReturnDesc->Reference.IndexPointer = 420306536Sjkim &(Operand[0]->Buffer.Pointer [Index]); 421167802Sjkim break; 42285754Smsmith 423167802Sjkim case ACPI_TYPE_BUFFER: 424167802Sjkim 42585754Smsmith if (Index >= Operand[0]->Buffer.Length) 42685754Smsmith { 427249112Sjkim Length = Operand[0]->Buffer.Length; 42885754Smsmith Status = AE_AML_BUFFER_LIMIT; 42985754Smsmith } 43085754Smsmith 431107325Siwasaki ReturnDesc->Reference.TargetType = ACPI_TYPE_BUFFER_FIELD; 432306536Sjkim ReturnDesc->Reference.IndexPointer = 433306536Sjkim &(Operand[0]->Buffer.Pointer [Index]); 434167802Sjkim break; 435167802Sjkim 436167802Sjkim case ACPI_TYPE_PACKAGE: 437167802Sjkim 438167802Sjkim if (Index >= Operand[0]->Package.Count) 439167802Sjkim { 440249112Sjkim Length = Operand[0]->Package.Count; 441167802Sjkim Status = AE_AML_PACKAGE_LIMIT; 442167802Sjkim } 443167802Sjkim 444167802Sjkim ReturnDesc->Reference.TargetType = ACPI_TYPE_PACKAGE; 445306536Sjkim ReturnDesc->Reference.Where = 446306536Sjkim &Operand[0]->Package.Elements [Index]; 447167802Sjkim break; 448167802Sjkim 449167802Sjkim default: 450167802Sjkim 451167802Sjkim Status = AE_AML_INTERNAL; 452167802Sjkim goto Cleanup; 45385754Smsmith } 45485754Smsmith 455167802Sjkim /* Failure means that the Index was beyond the end of the object */ 456167802Sjkim 457167802Sjkim if (ACPI_FAILURE (Status)) 458167802Sjkim { 459167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 460249112Sjkim "Index (0x%X%8.8X) is beyond end of object (length 0x%X)", 461249112Sjkim ACPI_FORMAT_UINT64 (Index), (UINT32) Length)); 462167802Sjkim goto Cleanup; 463167802Sjkim } 464167802Sjkim 465151937Sjkim /* 466167802Sjkim * Save the target object and add a reference to it for the life 467167802Sjkim * of the index 468151937Sjkim */ 469167802Sjkim ReturnDesc->Reference.Object = Operand[0]; 470151937Sjkim AcpiUtAddReference (Operand[0]); 471151937Sjkim 472107325Siwasaki /* Store the reference to the Target */ 473107325Siwasaki 474107325Siwasaki Status = AcpiExStore (ReturnDesc, Operand[2], WalkState); 475107325Siwasaki 476107325Siwasaki /* Return the reference */ 477107325Siwasaki 47885754Smsmith WalkState->ResultObj = ReturnDesc; 47985754Smsmith goto Cleanup; 48085754Smsmith 48185754Smsmith default: 48285754Smsmith 483204773Sjkim ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X", 484167802Sjkim WalkState->Opcode)); 48585754Smsmith Status = AE_AML_BAD_OPCODE; 48685754Smsmith break; 48785754Smsmith } 48885754Smsmith 48985754Smsmith 49085754SmsmithStoreResultToTarget: 49185754Smsmith 49285754Smsmith if (ACPI_SUCCESS (Status)) 49385754Smsmith { 49485754Smsmith /* 49585754Smsmith * Store the result of the operation (which is now in ReturnDesc) into 49685754Smsmith * the Target descriptor. 49785754Smsmith */ 49885754Smsmith Status = AcpiExStore (ReturnDesc, Operand[2], WalkState); 49985754Smsmith if (ACPI_FAILURE (Status)) 50085754Smsmith { 50185754Smsmith goto Cleanup; 50285754Smsmith } 50385754Smsmith 504107325Siwasaki if (!WalkState->ResultObj) 505107325Siwasaki { 506107325Siwasaki WalkState->ResultObj = ReturnDesc; 507107325Siwasaki } 50885754Smsmith } 50985754Smsmith 51085754Smsmith 51185754SmsmithCleanup: 51285754Smsmith 51385754Smsmith /* Delete return object on error */ 51485754Smsmith 51585754Smsmith if (ACPI_FAILURE (Status)) 51685754Smsmith { 51785754Smsmith AcpiUtRemoveReference (ReturnDesc); 518167802Sjkim WalkState->ResultObj = NULL; 51985754Smsmith } 52085754Smsmith 52185754Smsmith return_ACPI_STATUS (Status); 52285754Smsmith} 52385754Smsmith 52485754Smsmith 52585754Smsmith/******************************************************************************* 52685754Smsmith * 52785754Smsmith * FUNCTION: AcpiExOpcode_2A_0T_1R 52885754Smsmith * 52985754Smsmith * PARAMETERS: WalkState - Current walk state 53085754Smsmith * 53185754Smsmith * RETURN: Status 53285754Smsmith * 53385754Smsmith * DESCRIPTION: Execute opcode with 2 arguments, no target, and a return value 53485754Smsmith * 53585754Smsmith ******************************************************************************/ 53685754Smsmith 53785754SmsmithACPI_STATUS 53885754SmsmithAcpiExOpcode_2A_0T_1R ( 53985754Smsmith ACPI_WALK_STATE *WalkState) 54085754Smsmith{ 54185754Smsmith ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 54285754Smsmith ACPI_OPERAND_OBJECT *ReturnDesc = NULL; 54385754Smsmith ACPI_STATUS Status = AE_OK; 54485754Smsmith BOOLEAN LogicalResult = FALSE; 54585754Smsmith 54685754Smsmith 547167802Sjkim ACPI_FUNCTION_TRACE_STR (ExOpcode_2A_0T_1R, 548138287Smarks AcpiPsGetOpcodeName (WalkState->Opcode)); 54985754Smsmith 55085754Smsmith 55185754Smsmith /* Create the internal return object */ 55285754Smsmith 55385754Smsmith ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 55485754Smsmith if (!ReturnDesc) 55585754Smsmith { 55685754Smsmith Status = AE_NO_MEMORY; 55785754Smsmith goto Cleanup; 55885754Smsmith } 55985754Smsmith 560151937Sjkim /* Execute the Opcode */ 561151937Sjkim 562151937Sjkim if (WalkState->OpInfo->Flags & AML_LOGICAL_NUMERIC) 56385754Smsmith { 564151937Sjkim /* LogicalOp (Operand0, Operand1) */ 565151937Sjkim 566138287Smarks Status = AcpiExDoLogicalNumericOp (WalkState->Opcode, 567306536Sjkim Operand[0]->Integer.Value, Operand[1]->Integer.Value, 568306536Sjkim &LogicalResult); 56985754Smsmith goto StoreLogicalResult; 57085754Smsmith } 571151937Sjkim else if (WalkState->OpInfo->Flags & AML_LOGICAL) 572138287Smarks { 573151937Sjkim /* LogicalOp (Operand0, Operand1) */ 574151937Sjkim 575138287Smarks Status = AcpiExDoLogicalOp (WalkState->Opcode, Operand[0], 576306536Sjkim Operand[1], &LogicalResult); 577138287Smarks goto StoreLogicalResult; 578138287Smarks } 57985754Smsmith 58085754Smsmith switch (WalkState->Opcode) 58185754Smsmith { 58285754Smsmith case AML_ACQUIRE_OP: /* Acquire (MutexObject, Timeout) */ 58385754Smsmith 58485754Smsmith Status = AcpiExAcquireMutex (Operand[1], Operand[0], WalkState); 58585754Smsmith if (Status == AE_TIME) 58685754Smsmith { 58785754Smsmith LogicalResult = TRUE; /* TRUE = Acquire timed out */ 58885754Smsmith Status = AE_OK; 58985754Smsmith } 59085754Smsmith break; 59185754Smsmith 59285754Smsmith 59385754Smsmith case AML_WAIT_OP: /* Wait (EventObject, Timeout) */ 59485754Smsmith 59585754Smsmith Status = AcpiExSystemWaitEvent (Operand[1], Operand[0]); 59685754Smsmith if (Status == AE_TIME) 59785754Smsmith { 59885754Smsmith LogicalResult = TRUE; /* TRUE, Wait timed out */ 59985754Smsmith Status = AE_OK; 60085754Smsmith } 60185754Smsmith break; 60285754Smsmith 60385754Smsmith default: 60485754Smsmith 605204773Sjkim ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X", 606100966Siwasaki WalkState->Opcode)); 607306536Sjkim 60885754Smsmith Status = AE_AML_BAD_OPCODE; 60985754Smsmith goto Cleanup; 61085754Smsmith } 61185754Smsmith 61285754Smsmith 61385754SmsmithStoreLogicalResult: 61487031Smsmith /* 61585754Smsmith * Set return value to according to LogicalResult. logical TRUE (all ones) 61687031Smsmith * Default is FALSE (zero) 61785754Smsmith */ 61885754Smsmith if (LogicalResult) 61985754Smsmith { 620202771Sjkim ReturnDesc->Integer.Value = ACPI_UINT64_MAX; 62185754Smsmith } 62285754Smsmith 62385754SmsmithCleanup: 62485754Smsmith 62585754Smsmith /* Delete return object on error */ 62685754Smsmith 62785754Smsmith if (ACPI_FAILURE (Status)) 62885754Smsmith { 62985754Smsmith AcpiUtRemoveReference (ReturnDesc); 63085754Smsmith } 63185754Smsmith 632167802Sjkim /* Save return object on success */ 633167802Sjkim 634167802Sjkim else 635167802Sjkim { 636167802Sjkim WalkState->ResultObj = ReturnDesc; 637167802Sjkim } 638167802Sjkim 63985754Smsmith return_ACPI_STATUS (Status); 64085754Smsmith} 641