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