exoparg6.c revision 306536
136285Sbrian/****************************************************************************** 236285Sbrian * 336285Sbrian * Module Name: exoparg6 - AML execution - opcodes with 6 arguments 436285Sbrian * 536285Sbrian *****************************************************************************/ 636285Sbrian 736285Sbrian/* 836285Sbrian * Copyright (C) 2000 - 2016, Intel Corp. 936285Sbrian * All rights reserved. 1036285Sbrian * 1136285Sbrian * Redistribution and use in source and binary forms, with or without 1236285Sbrian * modification, are permitted provided that the following conditions 1336285Sbrian * are met: 1436285Sbrian * 1. Redistributions of source code must retain the above copyright 1536285Sbrian * notice, this list of conditions, and the following disclaimer, 1636285Sbrian * without modification. 1736285Sbrian * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1836285Sbrian * substantially similar to the "NO WARRANTY" disclaimer below 1936285Sbrian * ("Disclaimer") and any redistribution must be conditioned upon 2036285Sbrian * including a substantially similar Disclaimer requirement for further 2136285Sbrian * binary redistribution. 2236285Sbrian * 3. Neither the names of the above-listed copyright holders nor the names 2336285Sbrian * of any contributors may be used to endorse or promote products derived 2436285Sbrian * from this software without specific prior written permission. 2536285Sbrian * 2650479Speter * Alternatively, this software may be distributed under the terms of the 2736285Sbrian * GNU General Public License ("GPL") version 2 as published by the Free 2836285Sbrian * Software Foundation. 2936285Sbrian * 3036285Sbrian * NO WARRANTY 3146686Sbrian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3281634Sbrian * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3346686Sbrian * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3446686Sbrian * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3546686Sbrian * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3636285Sbrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37102500Sbrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3836285Sbrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3945193Sbrian * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4036285Sbrian * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4136285Sbrian * POSSIBILITY OF SUCH DAMAGES. 4238174Sbrian */ 4346686Sbrian 4436285Sbrian#include <contrib/dev/acpica/include/acpi.h> 4536285Sbrian#include <contrib/dev/acpica/include/accommon.h> 4636285Sbrian#include <contrib/dev/acpica/include/acinterp.h> 4736285Sbrian#include <contrib/dev/acpica/include/acparser.h> 4836285Sbrian#include <contrib/dev/acpica/include/amlcode.h> 4936285Sbrian 5046686Sbrian 5136285Sbrian#define _COMPONENT ACPI_EXECUTER 5236285Sbrian ACPI_MODULE_NAME ("exoparg6") 5336285Sbrian 5436285Sbrian 5536285Sbrian/*! 5636285Sbrian * Naming convention for AML interpreter execution routines. 5746686Sbrian * 5846686Sbrian * The routines that begin execution of AML opcodes are named with a common 5946686Sbrian * convention based upon the number of arguments, the number of target operands, 6046686Sbrian * and whether or not a value is returned: 6146686Sbrian * 6281634Sbrian * AcpiExOpcode_xA_yT_zR 6381634Sbrian * 6446686Sbrian * Where: 6581634Sbrian * 6646686Sbrian * xA - ARGUMENTS: The number of arguments (input operands) that are 6746686Sbrian * required for this opcode type (1 through 6 args). 6846686Sbrian * yT - TARGETS: The number of targets (output operands) that are required 6946686Sbrian * for this opcode type (0, 1, or 2 targets). 7047211Sbrian * zR - RETURN VALUE: Indicates whether this opcode type returns a value 7136285Sbrian * as the function return (0 or 1). 7246686Sbrian * 7346686Sbrian * The AcpiExOpcode* functions are called via the Dispatcher component with 7464652Sbrian * fully resolved operands. 7536285Sbrian!*/ 7636285Sbrian 7764652Sbrian/* Local prototypes */ 7864652Sbrian 7964652Sbrianstatic BOOLEAN 8064652SbrianAcpiExDoMatch ( 8164652Sbrian UINT32 MatchOp, 8236285Sbrian ACPI_OPERAND_OBJECT *PackageObj, 8336285Sbrian ACPI_OPERAND_OBJECT *MatchObj); 8464652Sbrian 8536285Sbrian 8636285Sbrian/******************************************************************************* 8764652Sbrian * 8864652Sbrian * FUNCTION: AcpiExDoMatch 8964652Sbrian * 9064652Sbrian * PARAMETERS: MatchOp - The AML match operand 9164652Sbrian * PackageObj - Object from the target package 9236285Sbrian * MatchObj - Object to be matched 9336285Sbrian * 9436285Sbrian * RETURN: TRUE if the match is successful, FALSE otherwise 9536285Sbrian * 9636285Sbrian * DESCRIPTION: Implements the low-level match for the ASL Match operator. 9750867Sbrian * Package elements will be implicitly converted to the type of 9850867Sbrian * the match object (Integer/Buffer/String). 9936285Sbrian * 10050867Sbrian ******************************************************************************/ 10150867Sbrian 10250867Sbrianstatic BOOLEAN 10354912SbrianAcpiExDoMatch ( 10454912Sbrian UINT32 MatchOp, 10536285Sbrian ACPI_OPERAND_OBJECT *PackageObj, 10636285Sbrian ACPI_OPERAND_OBJECT *MatchObj) 10738544Sbrian{ 10838544Sbrian BOOLEAN LogicalResult = TRUE; 10938544Sbrian ACPI_STATUS Status; 11050867Sbrian 11138544Sbrian 11250867Sbrian /* 11350867Sbrian * Note: Since the PackageObj/MatchObj ordering is opposite to that of 11438544Sbrian * the standard logical operators, we have to reverse them when we call 11554912Sbrian * DoLogicalOp in order to make the implicit conversion rules work 11638544Sbrian * correctly. However, this means we have to flip the entire equation 11738544Sbrian * also. A bit ugly perhaps, but overall, better than fussing the 11854912Sbrian * parameters around at runtime, over and over again. 11936285Sbrian * 12036285Sbrian * Below, P[i] refers to the package element, M refers to the Match object. 121134789Sbrian */ 12254912Sbrian switch (MatchOp) 12336285Sbrian { 12450867Sbrian case MATCH_MTR: 12554912Sbrian 12636285Sbrian /* Always true */ 12736285Sbrian 12836285Sbrian break; 12936285Sbrian 13054912Sbrian case MATCH_MEQ: 13136285Sbrian /* 13236285Sbrian * True if equal: (P[i] == M) 133134789Sbrian * Change to: (M == P[i]) 13454912Sbrian */ 13536285Sbrian Status = AcpiExDoLogicalOp ( 13636285Sbrian AML_LEQUAL_OP, MatchObj, PackageObj, &LogicalResult); 13736285Sbrian if (ACPI_FAILURE (Status)) 13850867Sbrian { 13954912Sbrian return (FALSE); 14036285Sbrian } 14136285Sbrian break; 14254912Sbrian 14354912Sbrian case MATCH_MLE: 14436285Sbrian /* 14536285Sbrian * True if less than or equal: (P[i] <= M) (P[i] NotGreater than M) 14636285Sbrian * Change to: (M >= P[i]) (M NotLess than P[i]) 14736285Sbrian */ 14836285Sbrian Status = AcpiExDoLogicalOp ( 14936285Sbrian AML_LLESS_OP, MatchObj, PackageObj, &LogicalResult); 150131327Sbrian if (ACPI_FAILURE (Status)) 151131327Sbrian { 152131327Sbrian return (FALSE); 153131327Sbrian } 154131327Sbrian LogicalResult = (BOOLEAN) !LogicalResult; 155131327Sbrian break; 156131327Sbrian 157131327Sbrian case MATCH_MLT: 158131327Sbrian /* 159131327Sbrian * True if less than: (P[i] < M) 160131327Sbrian * Change to: (M > P[i]) 161131327Sbrian */ 162131327Sbrian Status = AcpiExDoLogicalOp ( 163131327Sbrian AML_LGREATER_OP, MatchObj, PackageObj, &LogicalResult); 164131327Sbrian if (ACPI_FAILURE (Status)) 165131327Sbrian { 166131327Sbrian return (FALSE); 167131327Sbrian } 168131327Sbrian break; 169131327Sbrian 170131327Sbrian case MATCH_MGE: 171131327Sbrian /* 172131327Sbrian * True if greater than or equal: (P[i] >= M) (P[i] NotLess than M) 173131327Sbrian * Change to: (M <= P[i]) (M NotGreater than P[i]) 174131327Sbrian */ 175131327Sbrian Status = AcpiExDoLogicalOp ( 176131327Sbrian AML_LGREATER_OP, MatchObj, PackageObj, &LogicalResult); 177131327Sbrian if (ACPI_FAILURE (Status)) 17836285Sbrian { 17936285Sbrian return (FALSE); 18036285Sbrian } 18136285Sbrian LogicalResult = (BOOLEAN)!LogicalResult; 18236285Sbrian break; 18336285Sbrian 18450867Sbrian case MATCH_MGT: 18554912Sbrian /* 18654912Sbrian * True if greater than: (P[i] > M) 18736285Sbrian * Change to: (M < P[i]) 18854912Sbrian */ 18954912Sbrian Status = AcpiExDoLogicalOp ( 19036285Sbrian AML_LLESS_OP, MatchObj, PackageObj, &LogicalResult); 19136285Sbrian if (ACPI_FAILURE (Status)) 19236285Sbrian { 19336285Sbrian return (FALSE); 19436285Sbrian } 19536285Sbrian break; 19636285Sbrian 19736285Sbrian default: 19836285Sbrian 19936285Sbrian /* Undefined */ 20036285Sbrian 20136285Sbrian return (FALSE); 20236285Sbrian } 20336285Sbrian 20436285Sbrian return (LogicalResult); 20536285Sbrian} 20636285Sbrian 20736285Sbrian 20836285Sbrian/******************************************************************************* 20936285Sbrian * 21036285Sbrian * FUNCTION: AcpiExOpcode_6A_0T_1R 21136285Sbrian * 212300470Struckman * PARAMETERS: WalkState - Current walk state 21336285Sbrian * 21436285Sbrian * RETURN: Status 21536285Sbrian * 21636285Sbrian * DESCRIPTION: Execute opcode with 6 arguments, no target, and a return value 21736285Sbrian * 21836285Sbrian ******************************************************************************/ 21936285Sbrian 22036285SbrianACPI_STATUS 221300470StruckmanAcpiExOpcode_6A_0T_1R ( 222300470Struckman ACPI_WALK_STATE *WalkState) 223300470Struckman{ 224300470Struckman ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 225300470Struckman ACPI_OPERAND_OBJECT *ReturnDesc = NULL; 22636285Sbrian ACPI_STATUS Status = AE_OK; 227300470Struckman UINT64 Index; 22836285Sbrian ACPI_OPERAND_OBJECT *ThisElement; 22936285Sbrian 23036285Sbrian 23136285Sbrian ACPI_FUNCTION_TRACE_STR (ExOpcode_6A_0T_1R, 23236285Sbrian AcpiPsGetOpcodeName (WalkState->Opcode)); 23336285Sbrian 23436285Sbrian 23536285Sbrian switch (WalkState->Opcode) 23636285Sbrian { 23736285Sbrian case AML_MATCH_OP: 23836285Sbrian /* 23936285Sbrian * Match (SearchPkg[0], MatchOp1[1], MatchObj1[2], 24036285Sbrian * MatchOp2[3], MatchObj2[4], StartIndex[5]) 24136285Sbrian */ 24236285Sbrian 24336285Sbrian /* Validate both Match Term Operators (MTR, MEQ, etc.) */ 24436285Sbrian 24536285Sbrian if ((Operand[1]->Integer.Value > MAX_MATCH_OPERATOR) || 24646686Sbrian (Operand[3]->Integer.Value > MAX_MATCH_OPERATOR)) 24746686Sbrian { 24846686Sbrian ACPI_ERROR ((AE_INFO, "Match operator out of range")); 24946686Sbrian Status = AE_AML_OPERAND_VALUE; 25046686Sbrian goto Cleanup; 25146686Sbrian } 25246686Sbrian 25346686Sbrian /* Get the package StartIndex, validate against the package length */ 25446686Sbrian 25546686Sbrian Index = Operand[5]->Integer.Value; 25646686Sbrian if (Index >= Operand[0]->Package.Count) 25746686Sbrian { 25846686Sbrian ACPI_ERROR ((AE_INFO, 25946686Sbrian "Index (0x%8.8X%8.8X) beyond package end (0x%X)", 260134789Sbrian ACPI_FORMAT_UINT64 (Index), Operand[0]->Package.Count)); 26146686Sbrian Status = AE_AML_PACKAGE_LIMIT; 26246686Sbrian goto Cleanup; 263131327Sbrian } 26446686Sbrian 26546686Sbrian /* Create an integer for the return value */ 26646686Sbrian /* Default return value is ACPI_UINT64_MAX if no match found */ 26746686Sbrian 26846686Sbrian ReturnDesc = AcpiUtCreateIntegerObject (ACPI_UINT64_MAX); 26954912Sbrian if (!ReturnDesc) 27047061Sbrian { 27154912Sbrian Status = AE_NO_MEMORY; 27246686Sbrian goto Cleanup; 27346686Sbrian 27446686Sbrian } 27546686Sbrian 27646686Sbrian /* 27746686Sbrian * Examine each element until a match is found. Both match conditions 27846686Sbrian * must be satisfied for a match to occur. Within the loop, 27946686Sbrian * "continue" signifies that the current element does not match 28046686Sbrian * and the next should be examined. 28146686Sbrian * 28246686Sbrian * Upon finding a match, the loop will terminate via "break" at 28346686Sbrian * the bottom. If it terminates "normally", MatchValue will be 28446686Sbrian * ACPI_UINT64_MAX (Ones) (its initial value) indicating that no 28546686Sbrian * match was found. 28654912Sbrian */ 28746686Sbrian for ( ; Index < Operand[0]->Package.Count; Index++) 28846686Sbrian { 28946686Sbrian /* Get the current package element */ 29046686Sbrian 29146686Sbrian ThisElement = Operand[0]->Package.Elements[Index]; 29246686Sbrian 29346686Sbrian /* Treat any uninitialized (NULL) elements as non-matching */ 29446686Sbrian 29546686Sbrian if (!ThisElement) 29646686Sbrian { 29754912Sbrian continue; 29846686Sbrian } 29946686Sbrian 30046686Sbrian /* 30146686Sbrian * Both match conditions must be satisfied. Execution of a continue 30246686Sbrian * (proceed to next iteration of enclosing for loop) signifies a 30346686Sbrian * non-match. 30446686Sbrian */ 30546686Sbrian if (!AcpiExDoMatch ((UINT32) Operand[1]->Integer.Value, 30646686Sbrian ThisElement, Operand[2])) 30746686Sbrian { 30854912Sbrian continue; 30954912Sbrian } 31046686Sbrian 31146686Sbrian if (!AcpiExDoMatch ((UINT32) Operand[3]->Integer.Value, 31246686Sbrian ThisElement, Operand[4])) 31346686Sbrian { 31446686Sbrian continue; 31546686Sbrian } 31646686Sbrian 31746686Sbrian /* Match found: Index is the return value */ 31854912Sbrian 31954912Sbrian ReturnDesc->Integer.Value = Index; 32047061Sbrian break; 32146686Sbrian } 32246686Sbrian break; 32346686Sbrian 32446686Sbrian case AML_LOAD_TABLE_OP: 32546686Sbrian 32646686Sbrian Status = AcpiExLoadTableOp (WalkState, &ReturnDesc); 32746686Sbrian break; 32846686Sbrian 32946686Sbrian default: 33046686Sbrian 33146686Sbrian ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X", 33246686Sbrian WalkState->Opcode)); 33346686Sbrian 33446686Sbrian Status = AE_AML_BAD_OPCODE; 33546686Sbrian goto Cleanup; 33646686Sbrian } 33746686Sbrian 33846686Sbrian 33946686SbrianCleanup: 34046686Sbrian 34146686Sbrian /* Delete return object on error */ 34246686Sbrian 34346686Sbrian if (ACPI_FAILURE (Status)) 34446686Sbrian { 34546686Sbrian AcpiUtRemoveReference (ReturnDesc); 34646686Sbrian } 34746686Sbrian 34846686Sbrian /* Save return object on success */ 34946686Sbrian 35046686Sbrian else 35146686Sbrian { 35246686Sbrian WalkState->ResultObj = ReturnDesc; 35381634Sbrian } 35481634Sbrian 35581634Sbrian return_ACPI_STATUS (Status); 35681634Sbrian} 35746686Sbrian