185754Smsmith/****************************************************************************** 285754Smsmith * 385754Smsmith * Module Name: exoparg6 - AML execution - opcodes with 6 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/acinterp.h> 47193341Sjkim#include <contrib/dev/acpica/include/acparser.h> 48193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 4985754Smsmith 5085754Smsmith 5185754Smsmith#define _COMPONENT ACPI_EXECUTER 5291116Smsmith ACPI_MODULE_NAME ("exoparg6") 5385754Smsmith 5485754Smsmith 5585754Smsmith/*! 5685754Smsmith * Naming convention for AML interpreter execution routines. 5785754Smsmith * 5885754Smsmith * The routines that begin execution of AML opcodes are named with a common 5985754Smsmith * convention based upon the number of arguments, the number of target operands, 6085754Smsmith * and whether or not a value is returned: 6185754Smsmith * 6285754Smsmith * AcpiExOpcode_xA_yT_zR 6385754Smsmith * 6487031Smsmith * Where: 6585754Smsmith * 6687031Smsmith * xA - ARGUMENTS: The number of arguments (input operands) that are 6785754Smsmith * required for this opcode type (1 through 6 args). 6887031Smsmith * yT - TARGETS: The number of targets (output operands) that are required 6985754Smsmith * for this opcode type (0, 1, or 2 targets). 7087031Smsmith * zR - RETURN VALUE: Indicates whether this opcode type returns a value 7185754Smsmith * as the function return (0 or 1). 7285754Smsmith * 7387031Smsmith * The AcpiExOpcode* functions are called via the Dispatcher component with 7485754Smsmith * fully resolved operands. 7585754Smsmith!*/ 7685754Smsmith 77151937Sjkim/* Local prototypes */ 7885754Smsmith 79151937Sjkimstatic BOOLEAN 80151937SjkimAcpiExDoMatch ( 81151937Sjkim UINT32 MatchOp, 82151937Sjkim ACPI_OPERAND_OBJECT *PackageObj, 83151937Sjkim ACPI_OPERAND_OBJECT *MatchObj); 84151937Sjkim 85151937Sjkim 8685754Smsmith/******************************************************************************* 8785754Smsmith * 8885754Smsmith * FUNCTION: AcpiExDoMatch 8985754Smsmith * 9085754Smsmith * PARAMETERS: MatchOp - The AML match operand 91151937Sjkim * PackageObj - Object from the target package 92151937Sjkim * MatchObj - Object to be matched 9385754Smsmith * 9485754Smsmith * RETURN: TRUE if the match is successful, FALSE otherwise 9585754Smsmith * 96151937Sjkim * DESCRIPTION: Implements the low-level match for the ASL Match operator. 97151937Sjkim * Package elements will be implicitly converted to the type of 98151937Sjkim * the match object (Integer/Buffer/String). 9985754Smsmith * 10085754Smsmith ******************************************************************************/ 10185754Smsmith 102151937Sjkimstatic BOOLEAN 10385754SmsmithAcpiExDoMatch ( 10485754Smsmith UINT32 MatchOp, 105151937Sjkim ACPI_OPERAND_OBJECT *PackageObj, 106151937Sjkim ACPI_OPERAND_OBJECT *MatchObj) 10785754Smsmith{ 108151937Sjkim BOOLEAN LogicalResult = TRUE; 109151937Sjkim ACPI_STATUS Status; 11085754Smsmith 111151937Sjkim 112151937Sjkim /* 113151937Sjkim * Note: Since the PackageObj/MatchObj ordering is opposite to that of 114151937Sjkim * the standard logical operators, we have to reverse them when we call 115151937Sjkim * DoLogicalOp in order to make the implicit conversion rules work 116151937Sjkim * correctly. However, this means we have to flip the entire equation 117151937Sjkim * also. A bit ugly perhaps, but overall, better than fussing the 118151937Sjkim * parameters around at runtime, over and over again. 119151937Sjkim * 120151937Sjkim * Below, P[i] refers to the package element, M refers to the Match object. 121151937Sjkim */ 12285754Smsmith switch (MatchOp) 12385754Smsmith { 124151937Sjkim case MATCH_MTR: 12585754Smsmith 126151937Sjkim /* Always true */ 127151937Sjkim 12885754Smsmith break; 12985754Smsmith 130151937Sjkim case MATCH_MEQ: 131151937Sjkim /* 132151937Sjkim * True if equal: (P[i] == M) 133151937Sjkim * Change to: (M == P[i]) 134151937Sjkim */ 135306536Sjkim Status = AcpiExDoLogicalOp ( 136306536Sjkim AML_LEQUAL_OP, MatchObj, PackageObj, &LogicalResult); 137151937Sjkim if (ACPI_FAILURE (Status)) 13885754Smsmith { 13985754Smsmith return (FALSE); 14085754Smsmith } 14185754Smsmith break; 14285754Smsmith 143151937Sjkim case MATCH_MLE: 144151937Sjkim /* 145151937Sjkim * True if less than or equal: (P[i] <= M) (P[i] NotGreater than M) 146151937Sjkim * Change to: (M >= P[i]) (M NotLess than P[i]) 147151937Sjkim */ 148306536Sjkim Status = AcpiExDoLogicalOp ( 149306536Sjkim AML_LLESS_OP, MatchObj, PackageObj, &LogicalResult); 150151937Sjkim if (ACPI_FAILURE (Status)) 15185754Smsmith { 15285754Smsmith return (FALSE); 15385754Smsmith } 154151937Sjkim LogicalResult = (BOOLEAN) !LogicalResult; 15585754Smsmith break; 15685754Smsmith 157151937Sjkim case MATCH_MLT: 158151937Sjkim /* 159151937Sjkim * True if less than: (P[i] < M) 160151937Sjkim * Change to: (M > P[i]) 161151937Sjkim */ 162306536Sjkim Status = AcpiExDoLogicalOp ( 163306536Sjkim AML_LGREATER_OP, MatchObj, PackageObj, &LogicalResult); 164151937Sjkim if (ACPI_FAILURE (Status)) 16585754Smsmith { 16685754Smsmith return (FALSE); 16785754Smsmith } 16885754Smsmith break; 16985754Smsmith 170151937Sjkim case MATCH_MGE: 171151937Sjkim /* 172151937Sjkim * True if greater than or equal: (P[i] >= M) (P[i] NotLess than M) 173151937Sjkim * Change to: (M <= P[i]) (M NotGreater than P[i]) 174151937Sjkim */ 175306536Sjkim Status = AcpiExDoLogicalOp ( 176306536Sjkim AML_LGREATER_OP, MatchObj, PackageObj, &LogicalResult); 177151937Sjkim if (ACPI_FAILURE (Status)) 17885754Smsmith { 17985754Smsmith return (FALSE); 18085754Smsmith } 181151937Sjkim LogicalResult = (BOOLEAN)!LogicalResult; 18285754Smsmith break; 18385754Smsmith 184151937Sjkim case MATCH_MGT: 185151937Sjkim /* 186151937Sjkim * True if greater than: (P[i] > M) 187151937Sjkim * Change to: (M < P[i]) 188151937Sjkim */ 189306536Sjkim Status = AcpiExDoLogicalOp ( 190306536Sjkim AML_LLESS_OP, MatchObj, PackageObj, &LogicalResult); 191151937Sjkim if (ACPI_FAILURE (Status)) 19285754Smsmith { 19385754Smsmith return (FALSE); 19485754Smsmith } 19585754Smsmith break; 19685754Smsmith 197151937Sjkim default: 19885754Smsmith 199151937Sjkim /* Undefined */ 20085754Smsmith 20185754Smsmith return (FALSE); 20285754Smsmith } 20385754Smsmith 204241973Sjkim return (LogicalResult); 20585754Smsmith} 20685754Smsmith 20785754Smsmith 20885754Smsmith/******************************************************************************* 20985754Smsmith * 21085754Smsmith * FUNCTION: AcpiExOpcode_6A_0T_1R 21185754Smsmith * 21285754Smsmith * PARAMETERS: WalkState - Current walk state 21385754Smsmith * 21485754Smsmith * RETURN: Status 21585754Smsmith * 21685754Smsmith * DESCRIPTION: Execute opcode with 6 arguments, no target, and a return value 21785754Smsmith * 21885754Smsmith ******************************************************************************/ 21985754Smsmith 22085754SmsmithACPI_STATUS 22185754SmsmithAcpiExOpcode_6A_0T_1R ( 22285754Smsmith ACPI_WALK_STATE *WalkState) 22385754Smsmith{ 22485754Smsmith ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 22585754Smsmith ACPI_OPERAND_OBJECT *ReturnDesc = NULL; 22685754Smsmith ACPI_STATUS Status = AE_OK; 227202771Sjkim UINT64 Index; 22885754Smsmith ACPI_OPERAND_OBJECT *ThisElement; 22985754Smsmith 23085754Smsmith 231167802Sjkim ACPI_FUNCTION_TRACE_STR (ExOpcode_6A_0T_1R, 232151937Sjkim AcpiPsGetOpcodeName (WalkState->Opcode)); 23385754Smsmith 23485754Smsmith 23585754Smsmith switch (WalkState->Opcode) 23685754Smsmith { 23787031Smsmith case AML_MATCH_OP: 23887031Smsmith /* 239151937Sjkim * Match (SearchPkg[0], MatchOp1[1], MatchObj1[2], 240151937Sjkim * MatchOp2[3], MatchObj2[4], StartIndex[5]) 24185754Smsmith */ 24285754Smsmith 243151937Sjkim /* Validate both Match Term Operators (MTR, MEQ, etc.) */ 24485754Smsmith 24585754Smsmith if ((Operand[1]->Integer.Value > MAX_MATCH_OPERATOR) || 24685754Smsmith (Operand[3]->Integer.Value > MAX_MATCH_OPERATOR)) 24785754Smsmith { 248167802Sjkim ACPI_ERROR ((AE_INFO, "Match operator out of range")); 24985754Smsmith Status = AE_AML_OPERAND_VALUE; 25085754Smsmith goto Cleanup; 25185754Smsmith } 25285754Smsmith 253151937Sjkim /* Get the package StartIndex, validate against the package length */ 254151937Sjkim 255151937Sjkim Index = Operand[5]->Integer.Value; 256151937Sjkim if (Index >= Operand[0]->Package.Count) 25785754Smsmith { 258167802Sjkim ACPI_ERROR ((AE_INFO, 259204773Sjkim "Index (0x%8.8X%8.8X) beyond package end (0x%X)", 260151937Sjkim ACPI_FORMAT_UINT64 (Index), Operand[0]->Package.Count)); 26185754Smsmith Status = AE_AML_PACKAGE_LIMIT; 26285754Smsmith goto Cleanup; 26385754Smsmith } 26485754Smsmith 265151937Sjkim /* Create an integer for the return value */ 266202771Sjkim /* Default return value is ACPI_UINT64_MAX if no match found */ 267151937Sjkim 268202771Sjkim ReturnDesc = AcpiUtCreateIntegerObject (ACPI_UINT64_MAX); 26985754Smsmith if (!ReturnDesc) 27085754Smsmith { 27185754Smsmith Status = AE_NO_MEMORY; 27285754Smsmith goto Cleanup; 27385754Smsmith 27485754Smsmith } 27585754Smsmith 27685754Smsmith /* 277151937Sjkim * Examine each element until a match is found. Both match conditions 278151937Sjkim * must be satisfied for a match to occur. Within the loop, 27985754Smsmith * "continue" signifies that the current element does not match 28085754Smsmith * and the next should be examined. 28187031Smsmith * 28285754Smsmith * Upon finding a match, the loop will terminate via "break" at 283241973Sjkim * the bottom. If it terminates "normally", MatchValue will be 284202771Sjkim * ACPI_UINT64_MAX (Ones) (its initial value) indicating that no 285151937Sjkim * match was found. 28685754Smsmith */ 28785754Smsmith for ( ; Index < Operand[0]->Package.Count; Index++) 28885754Smsmith { 289151937Sjkim /* Get the current package element */ 290151937Sjkim 29185754Smsmith ThisElement = Operand[0]->Package.Elements[Index]; 29285754Smsmith 293151937Sjkim /* Treat any uninitialized (NULL) elements as non-matching */ 294151937Sjkim 295151937Sjkim if (!ThisElement) 29685754Smsmith { 29785754Smsmith continue; 29885754Smsmith } 29985754Smsmith 30085754Smsmith /* 301151937Sjkim * Both match conditions must be satisfied. Execution of a continue 302151937Sjkim * (proceed to next iteration of enclosing for loop) signifies a 303151937Sjkim * non-match. 30485754Smsmith */ 30587031Smsmith if (!AcpiExDoMatch ((UINT32) Operand[1]->Integer.Value, 306306536Sjkim ThisElement, Operand[2])) 30785754Smsmith { 30885754Smsmith continue; 30985754Smsmith } 31085754Smsmith 31187031Smsmith if (!AcpiExDoMatch ((UINT32) Operand[3]->Integer.Value, 312306536Sjkim ThisElement, Operand[4])) 31385754Smsmith { 31485754Smsmith continue; 31585754Smsmith } 31685754Smsmith 31785754Smsmith /* Match found: Index is the return value */ 31885754Smsmith 31985754Smsmith ReturnDesc->Integer.Value = Index; 32085754Smsmith break; 32185754Smsmith } 32285754Smsmith break; 32385754Smsmith 32485754Smsmith case AML_LOAD_TABLE_OP: 32585754Smsmith 32691116Smsmith Status = AcpiExLoadTableOp (WalkState, &ReturnDesc); 32785754Smsmith break; 32885754Smsmith 32985754Smsmith default: 33085754Smsmith 331204773Sjkim ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X", 332167802Sjkim WalkState->Opcode)); 333306536Sjkim 33485754Smsmith Status = AE_AML_BAD_OPCODE; 33585754Smsmith goto Cleanup; 33685754Smsmith } 33785754Smsmith 33885754Smsmith 33985754SmsmithCleanup: 34085754Smsmith 34185754Smsmith /* Delete return object on error */ 34285754Smsmith 34385754Smsmith if (ACPI_FAILURE (Status)) 34485754Smsmith { 34585754Smsmith AcpiUtRemoveReference (ReturnDesc); 34685754Smsmith } 34785754Smsmith 348167802Sjkim /* Save return object on success */ 349167802Sjkim 350167802Sjkim else 351167802Sjkim { 352167802Sjkim WalkState->ResultObj = ReturnDesc; 353167802Sjkim } 354167802Sjkim 35585754Smsmith return_ACPI_STATUS (Status); 35685754Smsmith} 357