1db2bae30SDana Myers /****************************************************************************** 2db2bae30SDana Myers * 3db2bae30SDana Myers * Module Name: exoparg6 - AML execution - opcodes with 6 arguments 4db2bae30SDana Myers * 5db2bae30SDana Myers *****************************************************************************/ 6db2bae30SDana Myers 726f3cdf0SGordon Ross /* 8*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp. 9db2bae30SDana Myers * All rights reserved. 10db2bae30SDana Myers * 1126f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without 1226f3cdf0SGordon Ross * modification, are permitted provided that the following conditions 1326f3cdf0SGordon Ross * are met: 1426f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright 1526f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer, 1626f3cdf0SGordon Ross * without modification. 1726f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1826f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below 1926f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon 2026f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further 2126f3cdf0SGordon Ross * binary redistribution. 2226f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names 2326f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived 2426f3cdf0SGordon Ross * from this software without specific prior written permission. 25db2bae30SDana Myers * 2626f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the 2726f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free 2826f3cdf0SGordon Ross * Software Foundation. 29db2bae30SDana Myers * 3026f3cdf0SGordon Ross * NO WARRANTY 3126f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3226f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3326f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3426f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3526f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3626f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3726f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3826f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3926f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4026f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4126f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES. 4226f3cdf0SGordon Ross */ 43db2bae30SDana Myers 44db2bae30SDana Myers #include "acpi.h" 45aa2aa9a6SDana Myers #include "accommon.h" 46db2bae30SDana Myers #include "acinterp.h" 47db2bae30SDana Myers #include "acparser.h" 48db2bae30SDana Myers #include "amlcode.h" 49db2bae30SDana Myers 50db2bae30SDana Myers 51db2bae30SDana Myers #define _COMPONENT ACPI_EXECUTER 52db2bae30SDana Myers ACPI_MODULE_NAME ("exoparg6") 53db2bae30SDana Myers 54db2bae30SDana Myers 55db2bae30SDana Myers /*! 56db2bae30SDana Myers * Naming convention for AML interpreter execution routines. 57db2bae30SDana Myers * 58db2bae30SDana Myers * The routines that begin execution of AML opcodes are named with a common 59db2bae30SDana Myers * convention based upon the number of arguments, the number of target operands, 60db2bae30SDana Myers * and whether or not a value is returned: 61db2bae30SDana Myers * 62db2bae30SDana Myers * AcpiExOpcode_xA_yT_zR 63db2bae30SDana Myers * 64db2bae30SDana Myers * Where: 65db2bae30SDana Myers * 66db2bae30SDana Myers * xA - ARGUMENTS: The number of arguments (input operands) that are 67db2bae30SDana Myers * required for this opcode type (1 through 6 args). 68db2bae30SDana Myers * yT - TARGETS: The number of targets (output operands) that are required 69db2bae30SDana Myers * for this opcode type (0, 1, or 2 targets). 70db2bae30SDana Myers * zR - RETURN VALUE: Indicates whether this opcode type returns a value 71db2bae30SDana Myers * as the function return (0 or 1). 72db2bae30SDana Myers * 73db2bae30SDana Myers * The AcpiExOpcode* functions are called via the Dispatcher component with 74db2bae30SDana Myers * fully resolved operands. 75db2bae30SDana Myers !*/ 76db2bae30SDana Myers 77db2bae30SDana Myers /* Local prototypes */ 78db2bae30SDana Myers 79db2bae30SDana Myers static BOOLEAN 80db2bae30SDana Myers AcpiExDoMatch ( 81db2bae30SDana Myers UINT32 MatchOp, 82db2bae30SDana Myers ACPI_OPERAND_OBJECT *PackageObj, 83db2bae30SDana Myers ACPI_OPERAND_OBJECT *MatchObj); 84db2bae30SDana Myers 85db2bae30SDana Myers 86db2bae30SDana Myers /******************************************************************************* 87db2bae30SDana Myers * 88db2bae30SDana Myers * FUNCTION: AcpiExDoMatch 89db2bae30SDana Myers * 90db2bae30SDana Myers * PARAMETERS: MatchOp - The AML match operand 91db2bae30SDana Myers * PackageObj - Object from the target package 92db2bae30SDana Myers * MatchObj - Object to be matched 93db2bae30SDana Myers * 94db2bae30SDana Myers * RETURN: TRUE if the match is successful, FALSE otherwise 95db2bae30SDana Myers * 96db2bae30SDana Myers * DESCRIPTION: Implements the low-level match for the ASL Match operator. 97db2bae30SDana Myers * Package elements will be implicitly converted to the type of 98db2bae30SDana Myers * the match object (Integer/Buffer/String). 99db2bae30SDana Myers * 100db2bae30SDana Myers ******************************************************************************/ 101db2bae30SDana Myers 102db2bae30SDana Myers static BOOLEAN 103db2bae30SDana Myers AcpiExDoMatch ( 104db2bae30SDana Myers UINT32 MatchOp, 105db2bae30SDana Myers ACPI_OPERAND_OBJECT *PackageObj, 106db2bae30SDana Myers ACPI_OPERAND_OBJECT *MatchObj) 107db2bae30SDana Myers { 108db2bae30SDana Myers BOOLEAN LogicalResult = TRUE; 109db2bae30SDana Myers ACPI_STATUS Status; 110db2bae30SDana Myers 111db2bae30SDana Myers 112db2bae30SDana Myers /* 113db2bae30SDana Myers * Note: Since the PackageObj/MatchObj ordering is opposite to that of 114db2bae30SDana Myers * the standard logical operators, we have to reverse them when we call 115db2bae30SDana Myers * DoLogicalOp in order to make the implicit conversion rules work 116db2bae30SDana Myers * correctly. However, this means we have to flip the entire equation 117db2bae30SDana Myers * also. A bit ugly perhaps, but overall, better than fussing the 118db2bae30SDana Myers * parameters around at runtime, over and over again. 119db2bae30SDana Myers * 120db2bae30SDana Myers * Below, P[i] refers to the package element, M refers to the Match object. 121db2bae30SDana Myers */ 122db2bae30SDana Myers switch (MatchOp) 123db2bae30SDana Myers { 124db2bae30SDana Myers case MATCH_MTR: 125db2bae30SDana Myers 126db2bae30SDana Myers /* Always true */ 127db2bae30SDana Myers 128db2bae30SDana Myers break; 129db2bae30SDana Myers 130db2bae30SDana Myers case MATCH_MEQ: 131db2bae30SDana Myers /* 132db2bae30SDana Myers * True if equal: (P[i] == M) 133db2bae30SDana Myers * Change to: (M == P[i]) 134db2bae30SDana Myers */ 135*385cc6b4SJerry Jelinek Status = AcpiExDoLogicalOp ( 136*385cc6b4SJerry Jelinek AML_LEQUAL_OP, MatchObj, PackageObj, &LogicalResult); 137db2bae30SDana Myers if (ACPI_FAILURE (Status)) 138db2bae30SDana Myers { 139db2bae30SDana Myers return (FALSE); 140db2bae30SDana Myers } 141db2bae30SDana Myers break; 142db2bae30SDana Myers 143db2bae30SDana Myers case MATCH_MLE: 144db2bae30SDana Myers /* 145db2bae30SDana Myers * True if less than or equal: (P[i] <= M) (P[i] NotGreater than M) 146db2bae30SDana Myers * Change to: (M >= P[i]) (M NotLess than P[i]) 147db2bae30SDana Myers */ 148*385cc6b4SJerry Jelinek Status = AcpiExDoLogicalOp ( 149*385cc6b4SJerry Jelinek AML_LLESS_OP, MatchObj, PackageObj, &LogicalResult); 150db2bae30SDana Myers if (ACPI_FAILURE (Status)) 151db2bae30SDana Myers { 152db2bae30SDana Myers return (FALSE); 153db2bae30SDana Myers } 154db2bae30SDana Myers LogicalResult = (BOOLEAN) !LogicalResult; 155db2bae30SDana Myers break; 156db2bae30SDana Myers 157db2bae30SDana Myers case MATCH_MLT: 158db2bae30SDana Myers /* 159db2bae30SDana Myers * True if less than: (P[i] < M) 160db2bae30SDana Myers * Change to: (M > P[i]) 161db2bae30SDana Myers */ 162*385cc6b4SJerry Jelinek Status = AcpiExDoLogicalOp ( 163*385cc6b4SJerry Jelinek AML_LGREATER_OP, MatchObj, PackageObj, &LogicalResult); 164db2bae30SDana Myers if (ACPI_FAILURE (Status)) 165db2bae30SDana Myers { 166db2bae30SDana Myers return (FALSE); 167db2bae30SDana Myers } 168db2bae30SDana Myers break; 169db2bae30SDana Myers 170db2bae30SDana Myers case MATCH_MGE: 171db2bae30SDana Myers /* 172db2bae30SDana Myers * True if greater than or equal: (P[i] >= M) (P[i] NotLess than M) 173db2bae30SDana Myers * Change to: (M <= P[i]) (M NotGreater than P[i]) 174db2bae30SDana Myers */ 175*385cc6b4SJerry Jelinek Status = AcpiExDoLogicalOp ( 176*385cc6b4SJerry Jelinek AML_LGREATER_OP, MatchObj, PackageObj, &LogicalResult); 177db2bae30SDana Myers if (ACPI_FAILURE (Status)) 178db2bae30SDana Myers { 179db2bae30SDana Myers return (FALSE); 180db2bae30SDana Myers } 181db2bae30SDana Myers LogicalResult = (BOOLEAN)!LogicalResult; 182db2bae30SDana Myers break; 183db2bae30SDana Myers 184db2bae30SDana Myers case MATCH_MGT: 185db2bae30SDana Myers /* 186db2bae30SDana Myers * True if greater than: (P[i] > M) 187db2bae30SDana Myers * Change to: (M < P[i]) 188db2bae30SDana Myers */ 189*385cc6b4SJerry Jelinek Status = AcpiExDoLogicalOp ( 190*385cc6b4SJerry Jelinek AML_LLESS_OP, MatchObj, PackageObj, &LogicalResult); 191db2bae30SDana Myers if (ACPI_FAILURE (Status)) 192db2bae30SDana Myers { 193db2bae30SDana Myers return (FALSE); 194db2bae30SDana Myers } 195db2bae30SDana Myers break; 196db2bae30SDana Myers 197db2bae30SDana Myers default: 198db2bae30SDana Myers 199db2bae30SDana Myers /* Undefined */ 200db2bae30SDana Myers 201db2bae30SDana Myers return (FALSE); 202db2bae30SDana Myers } 203db2bae30SDana Myers 204*385cc6b4SJerry Jelinek return (LogicalResult); 205db2bae30SDana Myers } 206db2bae30SDana Myers 207db2bae30SDana Myers 208db2bae30SDana Myers /******************************************************************************* 209db2bae30SDana Myers * 210db2bae30SDana Myers * FUNCTION: AcpiExOpcode_6A_0T_1R 211db2bae30SDana Myers * 212db2bae30SDana Myers * PARAMETERS: WalkState - Current walk state 213db2bae30SDana Myers * 214db2bae30SDana Myers * RETURN: Status 215db2bae30SDana Myers * 216db2bae30SDana Myers * DESCRIPTION: Execute opcode with 6 arguments, no target, and a return value 217db2bae30SDana Myers * 218db2bae30SDana Myers ******************************************************************************/ 219db2bae30SDana Myers 220db2bae30SDana Myers ACPI_STATUS 221db2bae30SDana Myers AcpiExOpcode_6A_0T_1R ( 222db2bae30SDana Myers ACPI_WALK_STATE *WalkState) 223db2bae30SDana Myers { 224db2bae30SDana Myers ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 225db2bae30SDana Myers ACPI_OPERAND_OBJECT *ReturnDesc = NULL; 226db2bae30SDana Myers ACPI_STATUS Status = AE_OK; 22726f3cdf0SGordon Ross UINT64 Index; 228db2bae30SDana Myers ACPI_OPERAND_OBJECT *ThisElement; 229db2bae30SDana Myers 230db2bae30SDana Myers 231db2bae30SDana Myers ACPI_FUNCTION_TRACE_STR (ExOpcode_6A_0T_1R, 232db2bae30SDana Myers AcpiPsGetOpcodeName (WalkState->Opcode)); 233db2bae30SDana Myers 234db2bae30SDana Myers 235db2bae30SDana Myers switch (WalkState->Opcode) 236db2bae30SDana Myers { 237db2bae30SDana Myers case AML_MATCH_OP: 238db2bae30SDana Myers /* 239db2bae30SDana Myers * Match (SearchPkg[0], MatchOp1[1], MatchObj1[2], 240db2bae30SDana Myers * MatchOp2[3], MatchObj2[4], StartIndex[5]) 241db2bae30SDana Myers */ 242db2bae30SDana Myers 243db2bae30SDana Myers /* Validate both Match Term Operators (MTR, MEQ, etc.) */ 244db2bae30SDana Myers 245db2bae30SDana Myers if ((Operand[1]->Integer.Value > MAX_MATCH_OPERATOR) || 246db2bae30SDana Myers (Operand[3]->Integer.Value > MAX_MATCH_OPERATOR)) 247db2bae30SDana Myers { 248db2bae30SDana Myers ACPI_ERROR ((AE_INFO, "Match operator out of range")); 249db2bae30SDana Myers Status = AE_AML_OPERAND_VALUE; 250db2bae30SDana Myers goto Cleanup; 251db2bae30SDana Myers } 252db2bae30SDana Myers 253db2bae30SDana Myers /* Get the package StartIndex, validate against the package length */ 254db2bae30SDana Myers 255db2bae30SDana Myers Index = Operand[5]->Integer.Value; 256db2bae30SDana Myers if (Index >= Operand[0]->Package.Count) 257db2bae30SDana Myers { 258db2bae30SDana Myers ACPI_ERROR ((AE_INFO, 25926f3cdf0SGordon Ross "Index (0x%8.8X%8.8X) beyond package end (0x%X)", 260db2bae30SDana Myers ACPI_FORMAT_UINT64 (Index), Operand[0]->Package.Count)); 261db2bae30SDana Myers Status = AE_AML_PACKAGE_LIMIT; 262db2bae30SDana Myers goto Cleanup; 263db2bae30SDana Myers } 264db2bae30SDana Myers 265db2bae30SDana Myers /* Create an integer for the return value */ 26626f3cdf0SGordon Ross /* Default return value is ACPI_UINT64_MAX if no match found */ 267db2bae30SDana Myers 26826f3cdf0SGordon Ross ReturnDesc = AcpiUtCreateIntegerObject (ACPI_UINT64_MAX); 269db2bae30SDana Myers if (!ReturnDesc) 270db2bae30SDana Myers { 271db2bae30SDana Myers Status = AE_NO_MEMORY; 272db2bae30SDana Myers goto Cleanup; 273db2bae30SDana Myers 274db2bae30SDana Myers } 275db2bae30SDana Myers 276db2bae30SDana Myers /* 277db2bae30SDana Myers * Examine each element until a match is found. Both match conditions 278db2bae30SDana Myers * must be satisfied for a match to occur. Within the loop, 279db2bae30SDana Myers * "continue" signifies that the current element does not match 280db2bae30SDana Myers * and the next should be examined. 281db2bae30SDana Myers * 282db2bae30SDana Myers * Upon finding a match, the loop will terminate via "break" at 283db2bae30SDana Myers * the bottom. If it terminates "normally", MatchValue will be 28426f3cdf0SGordon Ross * ACPI_UINT64_MAX (Ones) (its initial value) indicating that no 285db2bae30SDana Myers * match was found. 286db2bae30SDana Myers */ 287db2bae30SDana Myers for ( ; Index < Operand[0]->Package.Count; Index++) 288db2bae30SDana Myers { 289db2bae30SDana Myers /* Get the current package element */ 290db2bae30SDana Myers 291db2bae30SDana Myers ThisElement = Operand[0]->Package.Elements[Index]; 292db2bae30SDana Myers 293db2bae30SDana Myers /* Treat any uninitialized (NULL) elements as non-matching */ 294db2bae30SDana Myers 295db2bae30SDana Myers if (!ThisElement) 296db2bae30SDana Myers { 297db2bae30SDana Myers continue; 298db2bae30SDana Myers } 299db2bae30SDana Myers 300db2bae30SDana Myers /* 301db2bae30SDana Myers * Both match conditions must be satisfied. Execution of a continue 302db2bae30SDana Myers * (proceed to next iteration of enclosing for loop) signifies a 303db2bae30SDana Myers * non-match. 304db2bae30SDana Myers */ 305db2bae30SDana Myers if (!AcpiExDoMatch ((UINT32) Operand[1]->Integer.Value, 306db2bae30SDana Myers ThisElement, Operand[2])) 307db2bae30SDana Myers { 308db2bae30SDana Myers continue; 309db2bae30SDana Myers } 310db2bae30SDana Myers 311db2bae30SDana Myers if (!AcpiExDoMatch ((UINT32) Operand[3]->Integer.Value, 312db2bae30SDana Myers ThisElement, Operand[4])) 313db2bae30SDana Myers { 314db2bae30SDana Myers continue; 315db2bae30SDana Myers } 316db2bae30SDana Myers 317db2bae30SDana Myers /* Match found: Index is the return value */ 318db2bae30SDana Myers 319db2bae30SDana Myers ReturnDesc->Integer.Value = Index; 320db2bae30SDana Myers break; 321db2bae30SDana Myers } 322db2bae30SDana Myers break; 323db2bae30SDana Myers 324db2bae30SDana Myers case AML_LOAD_TABLE_OP: 325db2bae30SDana Myers 326db2bae30SDana Myers Status = AcpiExLoadTableOp (WalkState, &ReturnDesc); 327db2bae30SDana Myers break; 328db2bae30SDana Myers 329db2bae30SDana Myers default: 330db2bae30SDana Myers 33126f3cdf0SGordon Ross ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X", 332db2bae30SDana Myers WalkState->Opcode)); 333*385cc6b4SJerry Jelinek 334db2bae30SDana Myers Status = AE_AML_BAD_OPCODE; 335db2bae30SDana Myers goto Cleanup; 336db2bae30SDana Myers } 337db2bae30SDana Myers 338db2bae30SDana Myers 339db2bae30SDana Myers Cleanup: 340db2bae30SDana Myers 341db2bae30SDana Myers /* Delete return object on error */ 342db2bae30SDana Myers 343db2bae30SDana Myers if (ACPI_FAILURE (Status)) 344db2bae30SDana Myers { 345db2bae30SDana Myers AcpiUtRemoveReference (ReturnDesc); 346db2bae30SDana Myers } 347db2bae30SDana Myers 348db2bae30SDana Myers /* Save return object on success */ 349db2bae30SDana Myers 350db2bae30SDana Myers else 351db2bae30SDana Myers { 352db2bae30SDana Myers WalkState->ResultObj = ReturnDesc; 353db2bae30SDana Myers } 354db2bae30SDana Myers 355db2bae30SDana Myers return_ACPI_STATUS (Status); 356db2bae30SDana Myers } 357