1*7851SDana.Myers@Sun.COM 2*7851SDana.Myers@Sun.COM /****************************************************************************** 3*7851SDana.Myers@Sun.COM * 4*7851SDana.Myers@Sun.COM * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes 5*7851SDana.Myers@Sun.COM * $Revision: 1.145 $ 6*7851SDana.Myers@Sun.COM * 7*7851SDana.Myers@Sun.COM *****************************************************************************/ 8*7851SDana.Myers@Sun.COM 9*7851SDana.Myers@Sun.COM /****************************************************************************** 10*7851SDana.Myers@Sun.COM * 11*7851SDana.Myers@Sun.COM * 1. Copyright Notice 12*7851SDana.Myers@Sun.COM * 13*7851SDana.Myers@Sun.COM * Some or all of this work - Copyright (c) 1999 - 2008, Intel Corp. 14*7851SDana.Myers@Sun.COM * All rights reserved. 15*7851SDana.Myers@Sun.COM * 16*7851SDana.Myers@Sun.COM * 2. License 17*7851SDana.Myers@Sun.COM * 18*7851SDana.Myers@Sun.COM * 2.1. This is your license from Intel Corp. under its intellectual property 19*7851SDana.Myers@Sun.COM * rights. You may have additional license terms from the party that provided 20*7851SDana.Myers@Sun.COM * you this software, covering your right to use that party's intellectual 21*7851SDana.Myers@Sun.COM * property rights. 22*7851SDana.Myers@Sun.COM * 23*7851SDana.Myers@Sun.COM * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24*7851SDana.Myers@Sun.COM * copy of the source code appearing in this file ("Covered Code") an 25*7851SDana.Myers@Sun.COM * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26*7851SDana.Myers@Sun.COM * base code distributed originally by Intel ("Original Intel Code") to copy, 27*7851SDana.Myers@Sun.COM * make derivatives, distribute, use and display any portion of the Covered 28*7851SDana.Myers@Sun.COM * Code in any form, with the right to sublicense such rights; and 29*7851SDana.Myers@Sun.COM * 30*7851SDana.Myers@Sun.COM * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31*7851SDana.Myers@Sun.COM * license (with the right to sublicense), under only those claims of Intel 32*7851SDana.Myers@Sun.COM * patents that are infringed by the Original Intel Code, to make, use, sell, 33*7851SDana.Myers@Sun.COM * offer to sell, and import the Covered Code and derivative works thereof 34*7851SDana.Myers@Sun.COM * solely to the minimum extent necessary to exercise the above copyright 35*7851SDana.Myers@Sun.COM * license, and in no event shall the patent license extend to any additions 36*7851SDana.Myers@Sun.COM * to or modifications of the Original Intel Code. No other license or right 37*7851SDana.Myers@Sun.COM * is granted directly or by implication, estoppel or otherwise; 38*7851SDana.Myers@Sun.COM * 39*7851SDana.Myers@Sun.COM * The above copyright and patent license is granted only if the following 40*7851SDana.Myers@Sun.COM * conditions are met: 41*7851SDana.Myers@Sun.COM * 42*7851SDana.Myers@Sun.COM * 3. Conditions 43*7851SDana.Myers@Sun.COM * 44*7851SDana.Myers@Sun.COM * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45*7851SDana.Myers@Sun.COM * Redistribution of source code of any substantial portion of the Covered 46*7851SDana.Myers@Sun.COM * Code or modification with rights to further distribute source must include 47*7851SDana.Myers@Sun.COM * the above Copyright Notice, the above License, this list of Conditions, 48*7851SDana.Myers@Sun.COM * and the following Disclaimer and Export Compliance provision. In addition, 49*7851SDana.Myers@Sun.COM * Licensee must cause all Covered Code to which Licensee contributes to 50*7851SDana.Myers@Sun.COM * contain a file documenting the changes Licensee made to create that Covered 51*7851SDana.Myers@Sun.COM * Code and the date of any change. Licensee must include in that file the 52*7851SDana.Myers@Sun.COM * documentation of any changes made by any predecessor Licensee. Licensee 53*7851SDana.Myers@Sun.COM * must include a prominent statement that the modification is derived, 54*7851SDana.Myers@Sun.COM * directly or indirectly, from Original Intel Code. 55*7851SDana.Myers@Sun.COM * 56*7851SDana.Myers@Sun.COM * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57*7851SDana.Myers@Sun.COM * Redistribution of source code of any substantial portion of the Covered 58*7851SDana.Myers@Sun.COM * Code or modification without rights to further distribute source must 59*7851SDana.Myers@Sun.COM * include the following Disclaimer and Export Compliance provision in the 60*7851SDana.Myers@Sun.COM * documentation and/or other materials provided with distribution. In 61*7851SDana.Myers@Sun.COM * addition, Licensee may not authorize further sublicense of source of any 62*7851SDana.Myers@Sun.COM * portion of the Covered Code, and must include terms to the effect that the 63*7851SDana.Myers@Sun.COM * license from Licensee to its licensee is limited to the intellectual 64*7851SDana.Myers@Sun.COM * property embodied in the software Licensee provides to its licensee, and 65*7851SDana.Myers@Sun.COM * not to intellectual property embodied in modifications its licensee may 66*7851SDana.Myers@Sun.COM * make. 67*7851SDana.Myers@Sun.COM * 68*7851SDana.Myers@Sun.COM * 3.3. Redistribution of Executable. Redistribution in executable form of any 69*7851SDana.Myers@Sun.COM * substantial portion of the Covered Code or modification must reproduce the 70*7851SDana.Myers@Sun.COM * above Copyright Notice, and the following Disclaimer and Export Compliance 71*7851SDana.Myers@Sun.COM * provision in the documentation and/or other materials provided with the 72*7851SDana.Myers@Sun.COM * distribution. 73*7851SDana.Myers@Sun.COM * 74*7851SDana.Myers@Sun.COM * 3.4. Intel retains all right, title, and interest in and to the Original 75*7851SDana.Myers@Sun.COM * Intel Code. 76*7851SDana.Myers@Sun.COM * 77*7851SDana.Myers@Sun.COM * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78*7851SDana.Myers@Sun.COM * Intel shall be used in advertising or otherwise to promote the sale, use or 79*7851SDana.Myers@Sun.COM * other dealings in products derived from or relating to the Covered Code 80*7851SDana.Myers@Sun.COM * without prior written authorization from Intel. 81*7851SDana.Myers@Sun.COM * 82*7851SDana.Myers@Sun.COM * 4. Disclaimer and Export Compliance 83*7851SDana.Myers@Sun.COM * 84*7851SDana.Myers@Sun.COM * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85*7851SDana.Myers@Sun.COM * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86*7851SDana.Myers@Sun.COM * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87*7851SDana.Myers@Sun.COM * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88*7851SDana.Myers@Sun.COM 89*7851SDana.Myers@Sun.COM * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 90*7851SDana.Myers@Sun.COM * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 91*7851SDana.Myers@Sun.COM * PARTICULAR PURPOSE. 92*7851SDana.Myers@Sun.COM * 93*7851SDana.Myers@Sun.COM * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 94*7851SDana.Myers@Sun.COM * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 95*7851SDana.Myers@Sun.COM * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 96*7851SDana.Myers@Sun.COM * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 97*7851SDana.Myers@Sun.COM * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 98*7851SDana.Myers@Sun.COM * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 99*7851SDana.Myers@Sun.COM * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 100*7851SDana.Myers@Sun.COM * LIMITED REMEDY. 101*7851SDana.Myers@Sun.COM * 102*7851SDana.Myers@Sun.COM * 4.3. Licensee shall not export, either directly or indirectly, any of this 103*7851SDana.Myers@Sun.COM * software or system incorporating such software without first obtaining any 104*7851SDana.Myers@Sun.COM * required license or other approval from the U. S. Department of Commerce or 105*7851SDana.Myers@Sun.COM * any other agency or department of the United States Government. In the 106*7851SDana.Myers@Sun.COM * event Licensee exports any such software from the United States or 107*7851SDana.Myers@Sun.COM * re-exports any such software from a foreign destination, Licensee shall 108*7851SDana.Myers@Sun.COM * ensure that the distribution and export/re-export of the software is in 109*7851SDana.Myers@Sun.COM * compliance with all laws, regulations, orders, or other restrictions of the 110*7851SDana.Myers@Sun.COM * U.S. Export Administration Regulations. Licensee agrees that neither it nor 111*7851SDana.Myers@Sun.COM * any of its subsidiaries will export/re-export any technical data, process, 112*7851SDana.Myers@Sun.COM * software, or service, directly or indirectly, to any country for which the 113*7851SDana.Myers@Sun.COM * United States government or any agency thereof requires an export license, 114*7851SDana.Myers@Sun.COM * other governmental approval, or letter of assurance, without first obtaining 115*7851SDana.Myers@Sun.COM * such license, approval or letter. 116*7851SDana.Myers@Sun.COM * 117*7851SDana.Myers@Sun.COM *****************************************************************************/ 118*7851SDana.Myers@Sun.COM 119*7851SDana.Myers@Sun.COM #define __EXMISC_C__ 120*7851SDana.Myers@Sun.COM 121*7851SDana.Myers@Sun.COM #include "acpi.h" 122*7851SDana.Myers@Sun.COM #include "acinterp.h" 123*7851SDana.Myers@Sun.COM #include "amlcode.h" 124*7851SDana.Myers@Sun.COM #include "amlresrc.h" 125*7851SDana.Myers@Sun.COM 126*7851SDana.Myers@Sun.COM 127*7851SDana.Myers@Sun.COM #define _COMPONENT ACPI_EXECUTER 128*7851SDana.Myers@Sun.COM ACPI_MODULE_NAME ("exmisc") 129*7851SDana.Myers@Sun.COM 130*7851SDana.Myers@Sun.COM 131*7851SDana.Myers@Sun.COM /******************************************************************************* 132*7851SDana.Myers@Sun.COM * 133*7851SDana.Myers@Sun.COM * FUNCTION: AcpiExGetObjectReference 134*7851SDana.Myers@Sun.COM * 135*7851SDana.Myers@Sun.COM * PARAMETERS: ObjDesc - Create a reference to this object 136*7851SDana.Myers@Sun.COM * ReturnDesc - Where to store the reference 137*7851SDana.Myers@Sun.COM * WalkState - Current state 138*7851SDana.Myers@Sun.COM * 139*7851SDana.Myers@Sun.COM * RETURN: Status 140*7851SDana.Myers@Sun.COM * 141*7851SDana.Myers@Sun.COM * DESCRIPTION: Obtain and return a "reference" to the target object 142*7851SDana.Myers@Sun.COM * Common code for the RefOfOp and the CondRefOfOp. 143*7851SDana.Myers@Sun.COM * 144*7851SDana.Myers@Sun.COM ******************************************************************************/ 145*7851SDana.Myers@Sun.COM 146*7851SDana.Myers@Sun.COM ACPI_STATUS 147*7851SDana.Myers@Sun.COM AcpiExGetObjectReference ( 148*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *ObjDesc, 149*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT **ReturnDesc, 150*7851SDana.Myers@Sun.COM ACPI_WALK_STATE *WalkState) 151*7851SDana.Myers@Sun.COM { 152*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *ReferenceObj; 153*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *ReferencedObj; 154*7851SDana.Myers@Sun.COM 155*7851SDana.Myers@Sun.COM 156*7851SDana.Myers@Sun.COM ACPI_FUNCTION_TRACE_PTR (ExGetObjectReference, ObjDesc); 157*7851SDana.Myers@Sun.COM 158*7851SDana.Myers@Sun.COM 159*7851SDana.Myers@Sun.COM *ReturnDesc = NULL; 160*7851SDana.Myers@Sun.COM 161*7851SDana.Myers@Sun.COM switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc)) 162*7851SDana.Myers@Sun.COM { 163*7851SDana.Myers@Sun.COM case ACPI_DESC_TYPE_OPERAND: 164*7851SDana.Myers@Sun.COM 165*7851SDana.Myers@Sun.COM if (ACPI_GET_OBJECT_TYPE (ObjDesc) != ACPI_TYPE_LOCAL_REFERENCE) 166*7851SDana.Myers@Sun.COM { 167*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 168*7851SDana.Myers@Sun.COM } 169*7851SDana.Myers@Sun.COM 170*7851SDana.Myers@Sun.COM /* 171*7851SDana.Myers@Sun.COM * Must be a reference to a Local or Arg 172*7851SDana.Myers@Sun.COM */ 173*7851SDana.Myers@Sun.COM switch (ObjDesc->Reference.Class) 174*7851SDana.Myers@Sun.COM { 175*7851SDana.Myers@Sun.COM case ACPI_REFCLASS_LOCAL: 176*7851SDana.Myers@Sun.COM case ACPI_REFCLASS_ARG: 177*7851SDana.Myers@Sun.COM case ACPI_REFCLASS_DEBUG: 178*7851SDana.Myers@Sun.COM 179*7851SDana.Myers@Sun.COM /* The referenced object is the pseudo-node for the local/arg */ 180*7851SDana.Myers@Sun.COM 181*7851SDana.Myers@Sun.COM ReferencedObj = ObjDesc->Reference.Object; 182*7851SDana.Myers@Sun.COM break; 183*7851SDana.Myers@Sun.COM 184*7851SDana.Myers@Sun.COM default: 185*7851SDana.Myers@Sun.COM 186*7851SDana.Myers@Sun.COM ACPI_ERROR ((AE_INFO, "Unknown Reference Class %2.2X", 187*7851SDana.Myers@Sun.COM ObjDesc->Reference.Class)); 188*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_AML_INTERNAL); 189*7851SDana.Myers@Sun.COM } 190*7851SDana.Myers@Sun.COM break; 191*7851SDana.Myers@Sun.COM 192*7851SDana.Myers@Sun.COM 193*7851SDana.Myers@Sun.COM case ACPI_DESC_TYPE_NAMED: 194*7851SDana.Myers@Sun.COM 195*7851SDana.Myers@Sun.COM /* 196*7851SDana.Myers@Sun.COM * A named reference that has already been resolved to a Node 197*7851SDana.Myers@Sun.COM */ 198*7851SDana.Myers@Sun.COM ReferencedObj = ObjDesc; 199*7851SDana.Myers@Sun.COM break; 200*7851SDana.Myers@Sun.COM 201*7851SDana.Myers@Sun.COM 202*7851SDana.Myers@Sun.COM default: 203*7851SDana.Myers@Sun.COM 204*7851SDana.Myers@Sun.COM ACPI_ERROR ((AE_INFO, "Invalid descriptor type %X", 205*7851SDana.Myers@Sun.COM ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))); 206*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_TYPE); 207*7851SDana.Myers@Sun.COM } 208*7851SDana.Myers@Sun.COM 209*7851SDana.Myers@Sun.COM 210*7851SDana.Myers@Sun.COM /* Create a new reference object */ 211*7851SDana.Myers@Sun.COM 212*7851SDana.Myers@Sun.COM ReferenceObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_REFERENCE); 213*7851SDana.Myers@Sun.COM if (!ReferenceObj) 214*7851SDana.Myers@Sun.COM { 215*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_NO_MEMORY); 216*7851SDana.Myers@Sun.COM } 217*7851SDana.Myers@Sun.COM 218*7851SDana.Myers@Sun.COM ReferenceObj->Reference.Class = ACPI_REFCLASS_REFOF; 219*7851SDana.Myers@Sun.COM ReferenceObj->Reference.Object = ReferencedObj; 220*7851SDana.Myers@Sun.COM *ReturnDesc = ReferenceObj; 221*7851SDana.Myers@Sun.COM 222*7851SDana.Myers@Sun.COM ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 223*7851SDana.Myers@Sun.COM "Object %p Type [%s], returning Reference %p\n", 224*7851SDana.Myers@Sun.COM ObjDesc, AcpiUtGetObjectTypeName (ObjDesc), *ReturnDesc)); 225*7851SDana.Myers@Sun.COM 226*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_OK); 227*7851SDana.Myers@Sun.COM } 228*7851SDana.Myers@Sun.COM 229*7851SDana.Myers@Sun.COM 230*7851SDana.Myers@Sun.COM /******************************************************************************* 231*7851SDana.Myers@Sun.COM * 232*7851SDana.Myers@Sun.COM * FUNCTION: AcpiExConcatTemplate 233*7851SDana.Myers@Sun.COM * 234*7851SDana.Myers@Sun.COM * PARAMETERS: Operand0 - First source object 235*7851SDana.Myers@Sun.COM * Operand1 - Second source object 236*7851SDana.Myers@Sun.COM * ActualReturnDesc - Where to place the return object 237*7851SDana.Myers@Sun.COM * WalkState - Current walk state 238*7851SDana.Myers@Sun.COM * 239*7851SDana.Myers@Sun.COM * RETURN: Status 240*7851SDana.Myers@Sun.COM * 241*7851SDana.Myers@Sun.COM * DESCRIPTION: Concatenate two resource templates 242*7851SDana.Myers@Sun.COM * 243*7851SDana.Myers@Sun.COM ******************************************************************************/ 244*7851SDana.Myers@Sun.COM 245*7851SDana.Myers@Sun.COM ACPI_STATUS 246*7851SDana.Myers@Sun.COM AcpiExConcatTemplate ( 247*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *Operand0, 248*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *Operand1, 249*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT **ActualReturnDesc, 250*7851SDana.Myers@Sun.COM ACPI_WALK_STATE *WalkState) 251*7851SDana.Myers@Sun.COM { 252*7851SDana.Myers@Sun.COM ACPI_STATUS Status; 253*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *ReturnDesc; 254*7851SDana.Myers@Sun.COM UINT8 *NewBuf; 255*7851SDana.Myers@Sun.COM UINT8 *EndTag; 256*7851SDana.Myers@Sun.COM ACPI_SIZE Length0; 257*7851SDana.Myers@Sun.COM ACPI_SIZE Length1; 258*7851SDana.Myers@Sun.COM ACPI_SIZE NewLength; 259*7851SDana.Myers@Sun.COM 260*7851SDana.Myers@Sun.COM 261*7851SDana.Myers@Sun.COM ACPI_FUNCTION_TRACE (ExConcatTemplate); 262*7851SDana.Myers@Sun.COM 263*7851SDana.Myers@Sun.COM 264*7851SDana.Myers@Sun.COM /* 265*7851SDana.Myers@Sun.COM * Find the EndTag descriptor in each resource template. 266*7851SDana.Myers@Sun.COM * Note1: returned pointers point TO the EndTag, not past it. 267*7851SDana.Myers@Sun.COM * Note2: zero-length buffers are allowed; treated like one EndTag 268*7851SDana.Myers@Sun.COM */ 269*7851SDana.Myers@Sun.COM 270*7851SDana.Myers@Sun.COM /* Get the length of the first resource template */ 271*7851SDana.Myers@Sun.COM 272*7851SDana.Myers@Sun.COM Status = AcpiUtGetResourceEndTag (Operand0, &EndTag); 273*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 274*7851SDana.Myers@Sun.COM { 275*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 276*7851SDana.Myers@Sun.COM } 277*7851SDana.Myers@Sun.COM 278*7851SDana.Myers@Sun.COM Length0 = ACPI_PTR_DIFF (EndTag, Operand0->Buffer.Pointer); 279*7851SDana.Myers@Sun.COM 280*7851SDana.Myers@Sun.COM /* Get the length of the second resource template */ 281*7851SDana.Myers@Sun.COM 282*7851SDana.Myers@Sun.COM Status = AcpiUtGetResourceEndTag (Operand1, &EndTag); 283*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 284*7851SDana.Myers@Sun.COM { 285*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 286*7851SDana.Myers@Sun.COM } 287*7851SDana.Myers@Sun.COM 288*7851SDana.Myers@Sun.COM Length1 = ACPI_PTR_DIFF (EndTag, Operand1->Buffer.Pointer); 289*7851SDana.Myers@Sun.COM 290*7851SDana.Myers@Sun.COM /* Combine both lengths, minimum size will be 2 for EndTag */ 291*7851SDana.Myers@Sun.COM 292*7851SDana.Myers@Sun.COM NewLength = Length0 + Length1 + sizeof (AML_RESOURCE_END_TAG); 293*7851SDana.Myers@Sun.COM 294*7851SDana.Myers@Sun.COM /* Create a new buffer object for the result (with one EndTag) */ 295*7851SDana.Myers@Sun.COM 296*7851SDana.Myers@Sun.COM ReturnDesc = AcpiUtCreateBufferObject (NewLength); 297*7851SDana.Myers@Sun.COM if (!ReturnDesc) 298*7851SDana.Myers@Sun.COM { 299*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_NO_MEMORY); 300*7851SDana.Myers@Sun.COM } 301*7851SDana.Myers@Sun.COM 302*7851SDana.Myers@Sun.COM /* 303*7851SDana.Myers@Sun.COM * Copy the templates to the new buffer, 0 first, then 1 follows. One 304*7851SDana.Myers@Sun.COM * EndTag descriptor is copied from Operand1. 305*7851SDana.Myers@Sun.COM */ 306*7851SDana.Myers@Sun.COM NewBuf = ReturnDesc->Buffer.Pointer; 307*7851SDana.Myers@Sun.COM ACPI_MEMCPY (NewBuf, Operand0->Buffer.Pointer, Length0); 308*7851SDana.Myers@Sun.COM ACPI_MEMCPY (NewBuf + Length0, Operand1->Buffer.Pointer, Length1); 309*7851SDana.Myers@Sun.COM 310*7851SDana.Myers@Sun.COM /* Insert EndTag and set the checksum to zero, means "ignore checksum" */ 311*7851SDana.Myers@Sun.COM 312*7851SDana.Myers@Sun.COM NewBuf[NewLength - 1] = 0; 313*7851SDana.Myers@Sun.COM NewBuf[NewLength - 2] = ACPI_RESOURCE_NAME_END_TAG | 1; 314*7851SDana.Myers@Sun.COM 315*7851SDana.Myers@Sun.COM /* Return the completed resource template */ 316*7851SDana.Myers@Sun.COM 317*7851SDana.Myers@Sun.COM *ActualReturnDesc = ReturnDesc; 318*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_OK); 319*7851SDana.Myers@Sun.COM } 320*7851SDana.Myers@Sun.COM 321*7851SDana.Myers@Sun.COM 322*7851SDana.Myers@Sun.COM /******************************************************************************* 323*7851SDana.Myers@Sun.COM * 324*7851SDana.Myers@Sun.COM * FUNCTION: AcpiExDoConcatenate 325*7851SDana.Myers@Sun.COM * 326*7851SDana.Myers@Sun.COM * PARAMETERS: Operand0 - First source object 327*7851SDana.Myers@Sun.COM * Operand1 - Second source object 328*7851SDana.Myers@Sun.COM * ActualReturnDesc - Where to place the return object 329*7851SDana.Myers@Sun.COM * WalkState - Current walk state 330*7851SDana.Myers@Sun.COM * 331*7851SDana.Myers@Sun.COM * RETURN: Status 332*7851SDana.Myers@Sun.COM * 333*7851SDana.Myers@Sun.COM * DESCRIPTION: Concatenate two objects OF THE SAME TYPE. 334*7851SDana.Myers@Sun.COM * 335*7851SDana.Myers@Sun.COM ******************************************************************************/ 336*7851SDana.Myers@Sun.COM 337*7851SDana.Myers@Sun.COM ACPI_STATUS 338*7851SDana.Myers@Sun.COM AcpiExDoConcatenate ( 339*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *Operand0, 340*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *Operand1, 341*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT **ActualReturnDesc, 342*7851SDana.Myers@Sun.COM ACPI_WALK_STATE *WalkState) 343*7851SDana.Myers@Sun.COM { 344*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *LocalOperand1 = Operand1; 345*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *ReturnDesc; 346*7851SDana.Myers@Sun.COM char *NewBuf; 347*7851SDana.Myers@Sun.COM ACPI_STATUS Status; 348*7851SDana.Myers@Sun.COM 349*7851SDana.Myers@Sun.COM 350*7851SDana.Myers@Sun.COM ACPI_FUNCTION_TRACE (ExDoConcatenate); 351*7851SDana.Myers@Sun.COM 352*7851SDana.Myers@Sun.COM 353*7851SDana.Myers@Sun.COM /* 354*7851SDana.Myers@Sun.COM * Convert the second operand if necessary. The first operand 355*7851SDana.Myers@Sun.COM * determines the type of the second operand, (See the Data Types 356*7851SDana.Myers@Sun.COM * section of the ACPI specification.) Both object types are 357*7851SDana.Myers@Sun.COM * guaranteed to be either Integer/String/Buffer by the operand 358*7851SDana.Myers@Sun.COM * resolution mechanism. 359*7851SDana.Myers@Sun.COM */ 360*7851SDana.Myers@Sun.COM switch (ACPI_GET_OBJECT_TYPE (Operand0)) 361*7851SDana.Myers@Sun.COM { 362*7851SDana.Myers@Sun.COM case ACPI_TYPE_INTEGER: 363*7851SDana.Myers@Sun.COM Status = AcpiExConvertToInteger (Operand1, &LocalOperand1, 16); 364*7851SDana.Myers@Sun.COM break; 365*7851SDana.Myers@Sun.COM 366*7851SDana.Myers@Sun.COM case ACPI_TYPE_STRING: 367*7851SDana.Myers@Sun.COM Status = AcpiExConvertToString (Operand1, &LocalOperand1, 368*7851SDana.Myers@Sun.COM ACPI_IMPLICIT_CONVERT_HEX); 369*7851SDana.Myers@Sun.COM break; 370*7851SDana.Myers@Sun.COM 371*7851SDana.Myers@Sun.COM case ACPI_TYPE_BUFFER: 372*7851SDana.Myers@Sun.COM Status = AcpiExConvertToBuffer (Operand1, &LocalOperand1); 373*7851SDana.Myers@Sun.COM break; 374*7851SDana.Myers@Sun.COM 375*7851SDana.Myers@Sun.COM default: 376*7851SDana.Myers@Sun.COM ACPI_ERROR ((AE_INFO, "Invalid object type: %X", 377*7851SDana.Myers@Sun.COM ACPI_GET_OBJECT_TYPE (Operand0))); 378*7851SDana.Myers@Sun.COM Status = AE_AML_INTERNAL; 379*7851SDana.Myers@Sun.COM } 380*7851SDana.Myers@Sun.COM 381*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 382*7851SDana.Myers@Sun.COM { 383*7851SDana.Myers@Sun.COM goto Cleanup; 384*7851SDana.Myers@Sun.COM } 385*7851SDana.Myers@Sun.COM 386*7851SDana.Myers@Sun.COM /* 387*7851SDana.Myers@Sun.COM * Both operands are now known to be the same object type 388*7851SDana.Myers@Sun.COM * (Both are Integer, String, or Buffer), and we can now perform the 389*7851SDana.Myers@Sun.COM * concatenation. 390*7851SDana.Myers@Sun.COM */ 391*7851SDana.Myers@Sun.COM 392*7851SDana.Myers@Sun.COM /* 393*7851SDana.Myers@Sun.COM * There are three cases to handle: 394*7851SDana.Myers@Sun.COM * 395*7851SDana.Myers@Sun.COM * 1) Two Integers concatenated to produce a new Buffer 396*7851SDana.Myers@Sun.COM * 2) Two Strings concatenated to produce a new String 397*7851SDana.Myers@Sun.COM * 3) Two Buffers concatenated to produce a new Buffer 398*7851SDana.Myers@Sun.COM */ 399*7851SDana.Myers@Sun.COM switch (ACPI_GET_OBJECT_TYPE (Operand0)) 400*7851SDana.Myers@Sun.COM { 401*7851SDana.Myers@Sun.COM case ACPI_TYPE_INTEGER: 402*7851SDana.Myers@Sun.COM 403*7851SDana.Myers@Sun.COM /* Result of two Integers is a Buffer */ 404*7851SDana.Myers@Sun.COM /* Need enough buffer space for two integers */ 405*7851SDana.Myers@Sun.COM 406*7851SDana.Myers@Sun.COM ReturnDesc = AcpiUtCreateBufferObject ((ACPI_SIZE) 407*7851SDana.Myers@Sun.COM ACPI_MUL_2 (AcpiGbl_IntegerByteWidth)); 408*7851SDana.Myers@Sun.COM if (!ReturnDesc) 409*7851SDana.Myers@Sun.COM { 410*7851SDana.Myers@Sun.COM Status = AE_NO_MEMORY; 411*7851SDana.Myers@Sun.COM goto Cleanup; 412*7851SDana.Myers@Sun.COM } 413*7851SDana.Myers@Sun.COM 414*7851SDana.Myers@Sun.COM NewBuf = (char *) ReturnDesc->Buffer.Pointer; 415*7851SDana.Myers@Sun.COM 416*7851SDana.Myers@Sun.COM /* Copy the first integer, LSB first */ 417*7851SDana.Myers@Sun.COM 418*7851SDana.Myers@Sun.COM ACPI_MEMCPY (NewBuf, &Operand0->Integer.Value, 419*7851SDana.Myers@Sun.COM AcpiGbl_IntegerByteWidth); 420*7851SDana.Myers@Sun.COM 421*7851SDana.Myers@Sun.COM /* Copy the second integer (LSB first) after the first */ 422*7851SDana.Myers@Sun.COM 423*7851SDana.Myers@Sun.COM ACPI_MEMCPY (NewBuf + AcpiGbl_IntegerByteWidth, 424*7851SDana.Myers@Sun.COM &LocalOperand1->Integer.Value, 425*7851SDana.Myers@Sun.COM AcpiGbl_IntegerByteWidth); 426*7851SDana.Myers@Sun.COM break; 427*7851SDana.Myers@Sun.COM 428*7851SDana.Myers@Sun.COM case ACPI_TYPE_STRING: 429*7851SDana.Myers@Sun.COM 430*7851SDana.Myers@Sun.COM /* Result of two Strings is a String */ 431*7851SDana.Myers@Sun.COM 432*7851SDana.Myers@Sun.COM ReturnDesc = AcpiUtCreateStringObject ( 433*7851SDana.Myers@Sun.COM ((ACPI_SIZE) Operand0->String.Length + 434*7851SDana.Myers@Sun.COM LocalOperand1->String.Length)); 435*7851SDana.Myers@Sun.COM if (!ReturnDesc) 436*7851SDana.Myers@Sun.COM { 437*7851SDana.Myers@Sun.COM Status = AE_NO_MEMORY; 438*7851SDana.Myers@Sun.COM goto Cleanup; 439*7851SDana.Myers@Sun.COM } 440*7851SDana.Myers@Sun.COM 441*7851SDana.Myers@Sun.COM NewBuf = ReturnDesc->String.Pointer; 442*7851SDana.Myers@Sun.COM 443*7851SDana.Myers@Sun.COM /* Concatenate the strings */ 444*7851SDana.Myers@Sun.COM 445*7851SDana.Myers@Sun.COM ACPI_STRCPY (NewBuf, Operand0->String.Pointer); 446*7851SDana.Myers@Sun.COM ACPI_STRCPY (NewBuf + Operand0->String.Length, 447*7851SDana.Myers@Sun.COM LocalOperand1->String.Pointer); 448*7851SDana.Myers@Sun.COM break; 449*7851SDana.Myers@Sun.COM 450*7851SDana.Myers@Sun.COM case ACPI_TYPE_BUFFER: 451*7851SDana.Myers@Sun.COM 452*7851SDana.Myers@Sun.COM /* Result of two Buffers is a Buffer */ 453*7851SDana.Myers@Sun.COM 454*7851SDana.Myers@Sun.COM ReturnDesc = AcpiUtCreateBufferObject ( 455*7851SDana.Myers@Sun.COM ((ACPI_SIZE) Operand0->Buffer.Length + 456*7851SDana.Myers@Sun.COM LocalOperand1->Buffer.Length)); 457*7851SDana.Myers@Sun.COM if (!ReturnDesc) 458*7851SDana.Myers@Sun.COM { 459*7851SDana.Myers@Sun.COM Status = AE_NO_MEMORY; 460*7851SDana.Myers@Sun.COM goto Cleanup; 461*7851SDana.Myers@Sun.COM } 462*7851SDana.Myers@Sun.COM 463*7851SDana.Myers@Sun.COM NewBuf = (char *) ReturnDesc->Buffer.Pointer; 464*7851SDana.Myers@Sun.COM 465*7851SDana.Myers@Sun.COM /* Concatenate the buffers */ 466*7851SDana.Myers@Sun.COM 467*7851SDana.Myers@Sun.COM ACPI_MEMCPY (NewBuf, Operand0->Buffer.Pointer, 468*7851SDana.Myers@Sun.COM Operand0->Buffer.Length); 469*7851SDana.Myers@Sun.COM ACPI_MEMCPY (NewBuf + Operand0->Buffer.Length, 470*7851SDana.Myers@Sun.COM LocalOperand1->Buffer.Pointer, 471*7851SDana.Myers@Sun.COM LocalOperand1->Buffer.Length); 472*7851SDana.Myers@Sun.COM break; 473*7851SDana.Myers@Sun.COM 474*7851SDana.Myers@Sun.COM default: 475*7851SDana.Myers@Sun.COM 476*7851SDana.Myers@Sun.COM /* Invalid object type, should not happen here */ 477*7851SDana.Myers@Sun.COM 478*7851SDana.Myers@Sun.COM ACPI_ERROR ((AE_INFO, "Invalid object type: %X", 479*7851SDana.Myers@Sun.COM ACPI_GET_OBJECT_TYPE (Operand0))); 480*7851SDana.Myers@Sun.COM Status =AE_AML_INTERNAL; 481*7851SDana.Myers@Sun.COM goto Cleanup; 482*7851SDana.Myers@Sun.COM } 483*7851SDana.Myers@Sun.COM 484*7851SDana.Myers@Sun.COM *ActualReturnDesc = ReturnDesc; 485*7851SDana.Myers@Sun.COM 486*7851SDana.Myers@Sun.COM Cleanup: 487*7851SDana.Myers@Sun.COM if (LocalOperand1 != Operand1) 488*7851SDana.Myers@Sun.COM { 489*7851SDana.Myers@Sun.COM AcpiUtRemoveReference (LocalOperand1); 490*7851SDana.Myers@Sun.COM } 491*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 492*7851SDana.Myers@Sun.COM } 493*7851SDana.Myers@Sun.COM 494*7851SDana.Myers@Sun.COM 495*7851SDana.Myers@Sun.COM /******************************************************************************* 496*7851SDana.Myers@Sun.COM * 497*7851SDana.Myers@Sun.COM * FUNCTION: AcpiExDoMathOp 498*7851SDana.Myers@Sun.COM * 499*7851SDana.Myers@Sun.COM * PARAMETERS: Opcode - AML opcode 500*7851SDana.Myers@Sun.COM * Integer0 - Integer operand #0 501*7851SDana.Myers@Sun.COM * Integer1 - Integer operand #1 502*7851SDana.Myers@Sun.COM * 503*7851SDana.Myers@Sun.COM * RETURN: Integer result of the operation 504*7851SDana.Myers@Sun.COM * 505*7851SDana.Myers@Sun.COM * DESCRIPTION: Execute a math AML opcode. The purpose of having all of the 506*7851SDana.Myers@Sun.COM * math functions here is to prevent a lot of pointer dereferencing 507*7851SDana.Myers@Sun.COM * to obtain the operands. 508*7851SDana.Myers@Sun.COM * 509*7851SDana.Myers@Sun.COM ******************************************************************************/ 510*7851SDana.Myers@Sun.COM 511*7851SDana.Myers@Sun.COM ACPI_INTEGER 512*7851SDana.Myers@Sun.COM AcpiExDoMathOp ( 513*7851SDana.Myers@Sun.COM UINT16 Opcode, 514*7851SDana.Myers@Sun.COM ACPI_INTEGER Integer0, 515*7851SDana.Myers@Sun.COM ACPI_INTEGER Integer1) 516*7851SDana.Myers@Sun.COM { 517*7851SDana.Myers@Sun.COM 518*7851SDana.Myers@Sun.COM ACPI_FUNCTION_ENTRY (); 519*7851SDana.Myers@Sun.COM 520*7851SDana.Myers@Sun.COM 521*7851SDana.Myers@Sun.COM switch (Opcode) 522*7851SDana.Myers@Sun.COM { 523*7851SDana.Myers@Sun.COM case AML_ADD_OP: /* Add (Integer0, Integer1, Result) */ 524*7851SDana.Myers@Sun.COM 525*7851SDana.Myers@Sun.COM return (Integer0 + Integer1); 526*7851SDana.Myers@Sun.COM 527*7851SDana.Myers@Sun.COM 528*7851SDana.Myers@Sun.COM case AML_BIT_AND_OP: /* And (Integer0, Integer1, Result) */ 529*7851SDana.Myers@Sun.COM 530*7851SDana.Myers@Sun.COM return (Integer0 & Integer1); 531*7851SDana.Myers@Sun.COM 532*7851SDana.Myers@Sun.COM 533*7851SDana.Myers@Sun.COM case AML_BIT_NAND_OP: /* NAnd (Integer0, Integer1, Result) */ 534*7851SDana.Myers@Sun.COM 535*7851SDana.Myers@Sun.COM return (~(Integer0 & Integer1)); 536*7851SDana.Myers@Sun.COM 537*7851SDana.Myers@Sun.COM 538*7851SDana.Myers@Sun.COM case AML_BIT_OR_OP: /* Or (Integer0, Integer1, Result) */ 539*7851SDana.Myers@Sun.COM 540*7851SDana.Myers@Sun.COM return (Integer0 | Integer1); 541*7851SDana.Myers@Sun.COM 542*7851SDana.Myers@Sun.COM 543*7851SDana.Myers@Sun.COM case AML_BIT_NOR_OP: /* NOr (Integer0, Integer1, Result) */ 544*7851SDana.Myers@Sun.COM 545*7851SDana.Myers@Sun.COM return (~(Integer0 | Integer1)); 546*7851SDana.Myers@Sun.COM 547*7851SDana.Myers@Sun.COM 548*7851SDana.Myers@Sun.COM case AML_BIT_XOR_OP: /* XOr (Integer0, Integer1, Result) */ 549*7851SDana.Myers@Sun.COM 550*7851SDana.Myers@Sun.COM return (Integer0 ^ Integer1); 551*7851SDana.Myers@Sun.COM 552*7851SDana.Myers@Sun.COM 553*7851SDana.Myers@Sun.COM case AML_MULTIPLY_OP: /* Multiply (Integer0, Integer1, Result) */ 554*7851SDana.Myers@Sun.COM 555*7851SDana.Myers@Sun.COM return (Integer0 * Integer1); 556*7851SDana.Myers@Sun.COM 557*7851SDana.Myers@Sun.COM 558*7851SDana.Myers@Sun.COM case AML_SHIFT_LEFT_OP: /* ShiftLeft (Operand, ShiftCount, Result)*/ 559*7851SDana.Myers@Sun.COM 560*7851SDana.Myers@Sun.COM /* 561*7851SDana.Myers@Sun.COM * We need to check if the shiftcount is larger than the integer bit 562*7851SDana.Myers@Sun.COM * width since the behavior of this is not well-defined in the C language. 563*7851SDana.Myers@Sun.COM */ 564*7851SDana.Myers@Sun.COM if (Integer1 >= AcpiGbl_IntegerBitWidth) 565*7851SDana.Myers@Sun.COM { 566*7851SDana.Myers@Sun.COM return (0); 567*7851SDana.Myers@Sun.COM } 568*7851SDana.Myers@Sun.COM return (Integer0 << Integer1); 569*7851SDana.Myers@Sun.COM 570*7851SDana.Myers@Sun.COM 571*7851SDana.Myers@Sun.COM case AML_SHIFT_RIGHT_OP: /* ShiftRight (Operand, ShiftCount, Result) */ 572*7851SDana.Myers@Sun.COM 573*7851SDana.Myers@Sun.COM /* 574*7851SDana.Myers@Sun.COM * We need to check if the shiftcount is larger than the integer bit 575*7851SDana.Myers@Sun.COM * width since the behavior of this is not well-defined in the C language. 576*7851SDana.Myers@Sun.COM */ 577*7851SDana.Myers@Sun.COM if (Integer1 >= AcpiGbl_IntegerBitWidth) 578*7851SDana.Myers@Sun.COM { 579*7851SDana.Myers@Sun.COM return (0); 580*7851SDana.Myers@Sun.COM } 581*7851SDana.Myers@Sun.COM return (Integer0 >> Integer1); 582*7851SDana.Myers@Sun.COM 583*7851SDana.Myers@Sun.COM 584*7851SDana.Myers@Sun.COM case AML_SUBTRACT_OP: /* Subtract (Integer0, Integer1, Result) */ 585*7851SDana.Myers@Sun.COM 586*7851SDana.Myers@Sun.COM return (Integer0 - Integer1); 587*7851SDana.Myers@Sun.COM 588*7851SDana.Myers@Sun.COM default: 589*7851SDana.Myers@Sun.COM 590*7851SDana.Myers@Sun.COM return (0); 591*7851SDana.Myers@Sun.COM } 592*7851SDana.Myers@Sun.COM } 593*7851SDana.Myers@Sun.COM 594*7851SDana.Myers@Sun.COM 595*7851SDana.Myers@Sun.COM /******************************************************************************* 596*7851SDana.Myers@Sun.COM * 597*7851SDana.Myers@Sun.COM * FUNCTION: AcpiExDoLogicalNumericOp 598*7851SDana.Myers@Sun.COM * 599*7851SDana.Myers@Sun.COM * PARAMETERS: Opcode - AML opcode 600*7851SDana.Myers@Sun.COM * Integer0 - Integer operand #0 601*7851SDana.Myers@Sun.COM * Integer1 - Integer operand #1 602*7851SDana.Myers@Sun.COM * LogicalResult - TRUE/FALSE result of the operation 603*7851SDana.Myers@Sun.COM * 604*7851SDana.Myers@Sun.COM * RETURN: Status 605*7851SDana.Myers@Sun.COM * 606*7851SDana.Myers@Sun.COM * DESCRIPTION: Execute a logical "Numeric" AML opcode. For these Numeric 607*7851SDana.Myers@Sun.COM * operators (LAnd and LOr), both operands must be integers. 608*7851SDana.Myers@Sun.COM * 609*7851SDana.Myers@Sun.COM * Note: cleanest machine code seems to be produced by the code 610*7851SDana.Myers@Sun.COM * below, rather than using statements of the form: 611*7851SDana.Myers@Sun.COM * Result = (Integer0 && Integer1); 612*7851SDana.Myers@Sun.COM * 613*7851SDana.Myers@Sun.COM ******************************************************************************/ 614*7851SDana.Myers@Sun.COM 615*7851SDana.Myers@Sun.COM ACPI_STATUS 616*7851SDana.Myers@Sun.COM AcpiExDoLogicalNumericOp ( 617*7851SDana.Myers@Sun.COM UINT16 Opcode, 618*7851SDana.Myers@Sun.COM ACPI_INTEGER Integer0, 619*7851SDana.Myers@Sun.COM ACPI_INTEGER Integer1, 620*7851SDana.Myers@Sun.COM BOOLEAN *LogicalResult) 621*7851SDana.Myers@Sun.COM { 622*7851SDana.Myers@Sun.COM ACPI_STATUS Status = AE_OK; 623*7851SDana.Myers@Sun.COM BOOLEAN LocalResult = FALSE; 624*7851SDana.Myers@Sun.COM 625*7851SDana.Myers@Sun.COM 626*7851SDana.Myers@Sun.COM ACPI_FUNCTION_TRACE (ExDoLogicalNumericOp); 627*7851SDana.Myers@Sun.COM 628*7851SDana.Myers@Sun.COM 629*7851SDana.Myers@Sun.COM switch (Opcode) 630*7851SDana.Myers@Sun.COM { 631*7851SDana.Myers@Sun.COM case AML_LAND_OP: /* LAnd (Integer0, Integer1) */ 632*7851SDana.Myers@Sun.COM 633*7851SDana.Myers@Sun.COM if (Integer0 && Integer1) 634*7851SDana.Myers@Sun.COM { 635*7851SDana.Myers@Sun.COM LocalResult = TRUE; 636*7851SDana.Myers@Sun.COM } 637*7851SDana.Myers@Sun.COM break; 638*7851SDana.Myers@Sun.COM 639*7851SDana.Myers@Sun.COM case AML_LOR_OP: /* LOr (Integer0, Integer1) */ 640*7851SDana.Myers@Sun.COM 641*7851SDana.Myers@Sun.COM if (Integer0 || Integer1) 642*7851SDana.Myers@Sun.COM { 643*7851SDana.Myers@Sun.COM LocalResult = TRUE; 644*7851SDana.Myers@Sun.COM } 645*7851SDana.Myers@Sun.COM break; 646*7851SDana.Myers@Sun.COM 647*7851SDana.Myers@Sun.COM default: 648*7851SDana.Myers@Sun.COM Status = AE_AML_INTERNAL; 649*7851SDana.Myers@Sun.COM break; 650*7851SDana.Myers@Sun.COM } 651*7851SDana.Myers@Sun.COM 652*7851SDana.Myers@Sun.COM /* Return the logical result and status */ 653*7851SDana.Myers@Sun.COM 654*7851SDana.Myers@Sun.COM *LogicalResult = LocalResult; 655*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 656*7851SDana.Myers@Sun.COM } 657*7851SDana.Myers@Sun.COM 658*7851SDana.Myers@Sun.COM 659*7851SDana.Myers@Sun.COM /******************************************************************************* 660*7851SDana.Myers@Sun.COM * 661*7851SDana.Myers@Sun.COM * FUNCTION: AcpiExDoLogicalOp 662*7851SDana.Myers@Sun.COM * 663*7851SDana.Myers@Sun.COM * PARAMETERS: Opcode - AML opcode 664*7851SDana.Myers@Sun.COM * Operand0 - operand #0 665*7851SDana.Myers@Sun.COM * Operand1 - operand #1 666*7851SDana.Myers@Sun.COM * LogicalResult - TRUE/FALSE result of the operation 667*7851SDana.Myers@Sun.COM * 668*7851SDana.Myers@Sun.COM * RETURN: Status 669*7851SDana.Myers@Sun.COM * 670*7851SDana.Myers@Sun.COM * DESCRIPTION: Execute a logical AML opcode. The purpose of having all of the 671*7851SDana.Myers@Sun.COM * functions here is to prevent a lot of pointer dereferencing 672*7851SDana.Myers@Sun.COM * to obtain the operands and to simplify the generation of the 673*7851SDana.Myers@Sun.COM * logical value. For the Numeric operators (LAnd and LOr), both 674*7851SDana.Myers@Sun.COM * operands must be integers. For the other logical operators, 675*7851SDana.Myers@Sun.COM * operands can be any combination of Integer/String/Buffer. The 676*7851SDana.Myers@Sun.COM * first operand determines the type to which the second operand 677*7851SDana.Myers@Sun.COM * will be converted. 678*7851SDana.Myers@Sun.COM * 679*7851SDana.Myers@Sun.COM * Note: cleanest machine code seems to be produced by the code 680*7851SDana.Myers@Sun.COM * below, rather than using statements of the form: 681*7851SDana.Myers@Sun.COM * Result = (Operand0 == Operand1); 682*7851SDana.Myers@Sun.COM * 683*7851SDana.Myers@Sun.COM ******************************************************************************/ 684*7851SDana.Myers@Sun.COM 685*7851SDana.Myers@Sun.COM ACPI_STATUS 686*7851SDana.Myers@Sun.COM AcpiExDoLogicalOp ( 687*7851SDana.Myers@Sun.COM UINT16 Opcode, 688*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *Operand0, 689*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *Operand1, 690*7851SDana.Myers@Sun.COM BOOLEAN *LogicalResult) 691*7851SDana.Myers@Sun.COM { 692*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *LocalOperand1 = Operand1; 693*7851SDana.Myers@Sun.COM ACPI_INTEGER Integer0; 694*7851SDana.Myers@Sun.COM ACPI_INTEGER Integer1; 695*7851SDana.Myers@Sun.COM UINT32 Length0; 696*7851SDana.Myers@Sun.COM UINT32 Length1; 697*7851SDana.Myers@Sun.COM ACPI_STATUS Status = AE_OK; 698*7851SDana.Myers@Sun.COM BOOLEAN LocalResult = FALSE; 699*7851SDana.Myers@Sun.COM int Compare; 700*7851SDana.Myers@Sun.COM 701*7851SDana.Myers@Sun.COM 702*7851SDana.Myers@Sun.COM ACPI_FUNCTION_TRACE (ExDoLogicalOp); 703*7851SDana.Myers@Sun.COM 704*7851SDana.Myers@Sun.COM 705*7851SDana.Myers@Sun.COM /* 706*7851SDana.Myers@Sun.COM * Convert the second operand if necessary. The first operand 707*7851SDana.Myers@Sun.COM * determines the type of the second operand, (See the Data Types 708*7851SDana.Myers@Sun.COM * section of the ACPI 3.0+ specification.) Both object types are 709*7851SDana.Myers@Sun.COM * guaranteed to be either Integer/String/Buffer by the operand 710*7851SDana.Myers@Sun.COM * resolution mechanism. 711*7851SDana.Myers@Sun.COM */ 712*7851SDana.Myers@Sun.COM switch (ACPI_GET_OBJECT_TYPE (Operand0)) 713*7851SDana.Myers@Sun.COM { 714*7851SDana.Myers@Sun.COM case ACPI_TYPE_INTEGER: 715*7851SDana.Myers@Sun.COM Status = AcpiExConvertToInteger (Operand1, &LocalOperand1, 16); 716*7851SDana.Myers@Sun.COM break; 717*7851SDana.Myers@Sun.COM 718*7851SDana.Myers@Sun.COM case ACPI_TYPE_STRING: 719*7851SDana.Myers@Sun.COM Status = AcpiExConvertToString (Operand1, &LocalOperand1, 720*7851SDana.Myers@Sun.COM ACPI_IMPLICIT_CONVERT_HEX); 721*7851SDana.Myers@Sun.COM break; 722*7851SDana.Myers@Sun.COM 723*7851SDana.Myers@Sun.COM case ACPI_TYPE_BUFFER: 724*7851SDana.Myers@Sun.COM Status = AcpiExConvertToBuffer (Operand1, &LocalOperand1); 725*7851SDana.Myers@Sun.COM break; 726*7851SDana.Myers@Sun.COM 727*7851SDana.Myers@Sun.COM default: 728*7851SDana.Myers@Sun.COM Status = AE_AML_INTERNAL; 729*7851SDana.Myers@Sun.COM break; 730*7851SDana.Myers@Sun.COM } 731*7851SDana.Myers@Sun.COM 732*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 733*7851SDana.Myers@Sun.COM { 734*7851SDana.Myers@Sun.COM goto Cleanup; 735*7851SDana.Myers@Sun.COM } 736*7851SDana.Myers@Sun.COM 737*7851SDana.Myers@Sun.COM /* 738*7851SDana.Myers@Sun.COM * Two cases: 1) Both Integers, 2) Both Strings or Buffers 739*7851SDana.Myers@Sun.COM */ 740*7851SDana.Myers@Sun.COM if (ACPI_GET_OBJECT_TYPE (Operand0) == ACPI_TYPE_INTEGER) 741*7851SDana.Myers@Sun.COM { 742*7851SDana.Myers@Sun.COM /* 743*7851SDana.Myers@Sun.COM * 1) Both operands are of type integer 744*7851SDana.Myers@Sun.COM * Note: LocalOperand1 may have changed above 745*7851SDana.Myers@Sun.COM */ 746*7851SDana.Myers@Sun.COM Integer0 = Operand0->Integer.Value; 747*7851SDana.Myers@Sun.COM Integer1 = LocalOperand1->Integer.Value; 748*7851SDana.Myers@Sun.COM 749*7851SDana.Myers@Sun.COM switch (Opcode) 750*7851SDana.Myers@Sun.COM { 751*7851SDana.Myers@Sun.COM case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */ 752*7851SDana.Myers@Sun.COM 753*7851SDana.Myers@Sun.COM if (Integer0 == Integer1) 754*7851SDana.Myers@Sun.COM { 755*7851SDana.Myers@Sun.COM LocalResult = TRUE; 756*7851SDana.Myers@Sun.COM } 757*7851SDana.Myers@Sun.COM break; 758*7851SDana.Myers@Sun.COM 759*7851SDana.Myers@Sun.COM case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */ 760*7851SDana.Myers@Sun.COM 761*7851SDana.Myers@Sun.COM if (Integer0 > Integer1) 762*7851SDana.Myers@Sun.COM { 763*7851SDana.Myers@Sun.COM LocalResult = TRUE; 764*7851SDana.Myers@Sun.COM } 765*7851SDana.Myers@Sun.COM break; 766*7851SDana.Myers@Sun.COM 767*7851SDana.Myers@Sun.COM case AML_LLESS_OP: /* LLess (Operand0, Operand1) */ 768*7851SDana.Myers@Sun.COM 769*7851SDana.Myers@Sun.COM if (Integer0 < Integer1) 770*7851SDana.Myers@Sun.COM { 771*7851SDana.Myers@Sun.COM LocalResult = TRUE; 772*7851SDana.Myers@Sun.COM } 773*7851SDana.Myers@Sun.COM break; 774*7851SDana.Myers@Sun.COM 775*7851SDana.Myers@Sun.COM default: 776*7851SDana.Myers@Sun.COM Status = AE_AML_INTERNAL; 777*7851SDana.Myers@Sun.COM break; 778*7851SDana.Myers@Sun.COM } 779*7851SDana.Myers@Sun.COM } 780*7851SDana.Myers@Sun.COM else 781*7851SDana.Myers@Sun.COM { 782*7851SDana.Myers@Sun.COM /* 783*7851SDana.Myers@Sun.COM * 2) Both operands are Strings or both are Buffers 784*7851SDana.Myers@Sun.COM * Note: Code below takes advantage of common Buffer/String 785*7851SDana.Myers@Sun.COM * object fields. LocalOperand1 may have changed above. Use 786*7851SDana.Myers@Sun.COM * memcmp to handle nulls in buffers. 787*7851SDana.Myers@Sun.COM */ 788*7851SDana.Myers@Sun.COM Length0 = Operand0->Buffer.Length; 789*7851SDana.Myers@Sun.COM Length1 = LocalOperand1->Buffer.Length; 790*7851SDana.Myers@Sun.COM 791*7851SDana.Myers@Sun.COM /* Lexicographic compare: compare the data bytes */ 792*7851SDana.Myers@Sun.COM 793*7851SDana.Myers@Sun.COM Compare = ACPI_MEMCMP (Operand0->Buffer.Pointer, 794*7851SDana.Myers@Sun.COM LocalOperand1->Buffer.Pointer, 795*7851SDana.Myers@Sun.COM (Length0 > Length1) ? Length1 : Length0); 796*7851SDana.Myers@Sun.COM 797*7851SDana.Myers@Sun.COM switch (Opcode) 798*7851SDana.Myers@Sun.COM { 799*7851SDana.Myers@Sun.COM case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */ 800*7851SDana.Myers@Sun.COM 801*7851SDana.Myers@Sun.COM /* Length and all bytes must be equal */ 802*7851SDana.Myers@Sun.COM 803*7851SDana.Myers@Sun.COM if ((Length0 == Length1) && 804*7851SDana.Myers@Sun.COM (Compare == 0)) 805*7851SDana.Myers@Sun.COM { 806*7851SDana.Myers@Sun.COM /* Length and all bytes match ==> TRUE */ 807*7851SDana.Myers@Sun.COM 808*7851SDana.Myers@Sun.COM LocalResult = TRUE; 809*7851SDana.Myers@Sun.COM } 810*7851SDana.Myers@Sun.COM break; 811*7851SDana.Myers@Sun.COM 812*7851SDana.Myers@Sun.COM case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */ 813*7851SDana.Myers@Sun.COM 814*7851SDana.Myers@Sun.COM if (Compare > 0) 815*7851SDana.Myers@Sun.COM { 816*7851SDana.Myers@Sun.COM LocalResult = TRUE; 817*7851SDana.Myers@Sun.COM goto Cleanup; /* TRUE */ 818*7851SDana.Myers@Sun.COM } 819*7851SDana.Myers@Sun.COM if (Compare < 0) 820*7851SDana.Myers@Sun.COM { 821*7851SDana.Myers@Sun.COM goto Cleanup; /* FALSE */ 822*7851SDana.Myers@Sun.COM } 823*7851SDana.Myers@Sun.COM 824*7851SDana.Myers@Sun.COM /* Bytes match (to shortest length), compare lengths */ 825*7851SDana.Myers@Sun.COM 826*7851SDana.Myers@Sun.COM if (Length0 > Length1) 827*7851SDana.Myers@Sun.COM { 828*7851SDana.Myers@Sun.COM LocalResult = TRUE; 829*7851SDana.Myers@Sun.COM } 830*7851SDana.Myers@Sun.COM break; 831*7851SDana.Myers@Sun.COM 832*7851SDana.Myers@Sun.COM case AML_LLESS_OP: /* LLess (Operand0, Operand1) */ 833*7851SDana.Myers@Sun.COM 834*7851SDana.Myers@Sun.COM if (Compare > 0) 835*7851SDana.Myers@Sun.COM { 836*7851SDana.Myers@Sun.COM goto Cleanup; /* FALSE */ 837*7851SDana.Myers@Sun.COM } 838*7851SDana.Myers@Sun.COM if (Compare < 0) 839*7851SDana.Myers@Sun.COM { 840*7851SDana.Myers@Sun.COM LocalResult = TRUE; 841*7851SDana.Myers@Sun.COM goto Cleanup; /* TRUE */ 842*7851SDana.Myers@Sun.COM } 843*7851SDana.Myers@Sun.COM 844*7851SDana.Myers@Sun.COM /* Bytes match (to shortest length), compare lengths */ 845*7851SDana.Myers@Sun.COM 846*7851SDana.Myers@Sun.COM if (Length0 < Length1) 847*7851SDana.Myers@Sun.COM { 848*7851SDana.Myers@Sun.COM LocalResult = TRUE; 849*7851SDana.Myers@Sun.COM } 850*7851SDana.Myers@Sun.COM break; 851*7851SDana.Myers@Sun.COM 852*7851SDana.Myers@Sun.COM default: 853*7851SDana.Myers@Sun.COM Status = AE_AML_INTERNAL; 854*7851SDana.Myers@Sun.COM break; 855*7851SDana.Myers@Sun.COM } 856*7851SDana.Myers@Sun.COM } 857*7851SDana.Myers@Sun.COM 858*7851SDana.Myers@Sun.COM Cleanup: 859*7851SDana.Myers@Sun.COM 860*7851SDana.Myers@Sun.COM /* New object was created if implicit conversion performed - delete */ 861*7851SDana.Myers@Sun.COM 862*7851SDana.Myers@Sun.COM if (LocalOperand1 != Operand1) 863*7851SDana.Myers@Sun.COM { 864*7851SDana.Myers@Sun.COM AcpiUtRemoveReference (LocalOperand1); 865*7851SDana.Myers@Sun.COM } 866*7851SDana.Myers@Sun.COM 867*7851SDana.Myers@Sun.COM /* Return the logical result and status */ 868*7851SDana.Myers@Sun.COM 869*7851SDana.Myers@Sun.COM *LogicalResult = LocalResult; 870*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 871*7851SDana.Myers@Sun.COM } 872*7851SDana.Myers@Sun.COM 873*7851SDana.Myers@Sun.COM 874