Home | History | Annotate | Line # | Download | only in executer
exoparg1.c revision 1.1
      1 
      2 /******************************************************************************
      3  *
      4  * Module Name: exoparg1 - AML execution - opcodes with 1 argument
      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  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
     88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
     89  * PARTICULAR PURPOSE.
     90  *
     91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
     92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
     93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
     94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
     95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
     96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
     97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
     98  * LIMITED REMEDY.
     99  *
    100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
    101  * software or system incorporating such software without first obtaining any
    102  * required license or other approval from the U. S. Department of Commerce or
    103  * any other agency or department of the United States Government.  In the
    104  * event Licensee exports any such software from the United States or
    105  * re-exports any such software from a foreign destination, Licensee shall
    106  * ensure that the distribution and export/re-export of the software is in
    107  * compliance with all laws, regulations, orders, or other restrictions of the
    108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
    109  * any of its subsidiaries will export/re-export any technical data, process,
    110  * software, or service, directly or indirectly, to any country for which the
    111  * United States government or any agency thereof requires an export license,
    112  * other governmental approval, or letter of assurance, without first obtaining
    113  * such license, approval or letter.
    114  *
    115  *****************************************************************************/
    116 
    117 #define __EXOPARG1_C__
    118 
    119 #include "acpi.h"
    120 #include "accommon.h"
    121 #include "acparser.h"
    122 #include "acdispat.h"
    123 #include "acinterp.h"
    124 #include "amlcode.h"
    125 #include "acnamesp.h"
    126 
    127 
    128 #define _COMPONENT          ACPI_EXECUTER
    129         ACPI_MODULE_NAME    ("exoparg1")
    130 
    131 
    132 /*!
    133  * Naming convention for AML interpreter execution routines.
    134  *
    135  * The routines that begin execution of AML opcodes are named with a common
    136  * convention based upon the number of arguments, the number of target operands,
    137  * and whether or not a value is returned:
    138  *
    139  *      AcpiExOpcode_xA_yT_zR
    140  *
    141  * Where:
    142  *
    143  * xA - ARGUMENTS:    The number of arguments (input operands) that are
    144  *                    required for this opcode type (0 through 6 args).
    145  * yT - TARGETS:      The number of targets (output operands) that are required
    146  *                    for this opcode type (0, 1, or 2 targets).
    147  * zR - RETURN VALUE: Indicates whether this opcode type returns a value
    148  *                    as the function return (0 or 1).
    149  *
    150  * The AcpiExOpcode* functions are called via the Dispatcher component with
    151  * fully resolved operands.
    152 !*/
    153 
    154 /*******************************************************************************
    155  *
    156  * FUNCTION:    AcpiExOpcode_0A_0T_1R
    157  *
    158  * PARAMETERS:  WalkState           - Current state (contains AML opcode)
    159  *
    160  * RETURN:      Status
    161  *
    162  * DESCRIPTION: Execute operator with no operands, one return value
    163  *
    164  ******************************************************************************/
    165 
    166 ACPI_STATUS
    167 AcpiExOpcode_0A_0T_1R (
    168     ACPI_WALK_STATE         *WalkState)
    169 {
    170     ACPI_STATUS             Status = AE_OK;
    171     ACPI_OPERAND_OBJECT     *ReturnDesc = NULL;
    172 
    173 
    174     ACPI_FUNCTION_TRACE_STR (ExOpcode_0A_0T_1R,
    175         AcpiPsGetOpcodeName (WalkState->Opcode));
    176 
    177 
    178     /* Examine the AML opcode */
    179 
    180     switch (WalkState->Opcode)
    181     {
    182     case AML_TIMER_OP:      /*  Timer () */
    183 
    184         /* Create a return object of type Integer */
    185 
    186         ReturnDesc = AcpiUtCreateIntegerObject (AcpiOsGetTimer ());
    187         if (!ReturnDesc)
    188         {
    189             Status = AE_NO_MEMORY;
    190             goto Cleanup;
    191         }
    192         break;
    193 
    194     default:                /*  Unknown opcode  */
    195 
    196         ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
    197             WalkState->Opcode));
    198         Status = AE_AML_BAD_OPCODE;
    199         break;
    200     }
    201 
    202 Cleanup:
    203 
    204     /* Delete return object on error */
    205 
    206     if ((ACPI_FAILURE (Status)) || WalkState->ResultObj)
    207     {
    208         AcpiUtRemoveReference (ReturnDesc);
    209         WalkState->ResultObj = NULL;
    210     }
    211     else
    212     {
    213         /* Save the return value */
    214 
    215         WalkState->ResultObj = ReturnDesc;
    216     }
    217 
    218     return_ACPI_STATUS (Status);
    219 }
    220 
    221 
    222 /*******************************************************************************
    223  *
    224  * FUNCTION:    AcpiExOpcode_1A_0T_0R
    225  *
    226  * PARAMETERS:  WalkState           - Current state (contains AML opcode)
    227  *
    228  * RETURN:      Status
    229  *
    230  * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on
    231  *              object stack
    232  *
    233  ******************************************************************************/
    234 
    235 ACPI_STATUS
    236 AcpiExOpcode_1A_0T_0R (
    237     ACPI_WALK_STATE         *WalkState)
    238 {
    239     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
    240     ACPI_STATUS             Status = AE_OK;
    241 
    242 
    243     ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_0T_0R,
    244         AcpiPsGetOpcodeName (WalkState->Opcode));
    245 
    246 
    247     /* Examine the AML opcode */
    248 
    249     switch (WalkState->Opcode)
    250     {
    251     case AML_RELEASE_OP:    /*  Release (MutexObject) */
    252 
    253         Status = AcpiExReleaseMutex (Operand[0], WalkState);
    254         break;
    255 
    256 
    257     case AML_RESET_OP:      /*  Reset (EventObject) */
    258 
    259         Status = AcpiExSystemResetEvent (Operand[0]);
    260         break;
    261 
    262 
    263     case AML_SIGNAL_OP:     /*  Signal (EventObject) */
    264 
    265         Status = AcpiExSystemSignalEvent (Operand[0]);
    266         break;
    267 
    268 
    269     case AML_SLEEP_OP:      /*  Sleep (MsecTime) */
    270 
    271         Status = AcpiExSystemDoSleep (Operand[0]->Integer.Value);
    272         break;
    273 
    274 
    275     case AML_STALL_OP:      /*  Stall (UsecTime) */
    276 
    277         Status = AcpiExSystemDoStall ((UINT32) Operand[0]->Integer.Value);
    278         break;
    279 
    280 
    281     case AML_UNLOAD_OP:     /*  Unload (Handle) */
    282 
    283         Status = AcpiExUnloadTable (Operand[0]);
    284         break;
    285 
    286 
    287     default:                /*  Unknown opcode  */
    288 
    289         ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
    290             WalkState->Opcode));
    291         Status = AE_AML_BAD_OPCODE;
    292         break;
    293     }
    294 
    295     return_ACPI_STATUS (Status);
    296 }
    297 
    298 
    299 /*******************************************************************************
    300  *
    301  * FUNCTION:    AcpiExOpcode_1A_1T_0R
    302  *
    303  * PARAMETERS:  WalkState           - Current state (contains AML opcode)
    304  *
    305  * RETURN:      Status
    306  *
    307  * DESCRIPTION: Execute opcode with one argument, one target, and no
    308  *              return value.
    309  *
    310  ******************************************************************************/
    311 
    312 ACPI_STATUS
    313 AcpiExOpcode_1A_1T_0R (
    314     ACPI_WALK_STATE         *WalkState)
    315 {
    316     ACPI_STATUS             Status = AE_OK;
    317     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
    318 
    319 
    320     ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_1T_0R,
    321         AcpiPsGetOpcodeName (WalkState->Opcode));
    322 
    323 
    324     /* Examine the AML opcode */
    325 
    326     switch (WalkState->Opcode)
    327     {
    328     case AML_LOAD_OP:
    329 
    330         Status = AcpiExLoadOp (Operand[0], Operand[1], WalkState);
    331         break;
    332 
    333     default:                        /* Unknown opcode */
    334 
    335         ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
    336             WalkState->Opcode));
    337         Status = AE_AML_BAD_OPCODE;
    338         goto Cleanup;
    339     }
    340 
    341 
    342 Cleanup:
    343 
    344     return_ACPI_STATUS (Status);
    345 }
    346 
    347 
    348 /*******************************************************************************
    349  *
    350  * FUNCTION:    AcpiExOpcode_1A_1T_1R
    351  *
    352  * PARAMETERS:  WalkState           - Current state (contains AML opcode)
    353  *
    354  * RETURN:      Status
    355  *
    356  * DESCRIPTION: Execute opcode with one argument, one target, and a
    357  *              return value.
    358  *
    359  ******************************************************************************/
    360 
    361 ACPI_STATUS
    362 AcpiExOpcode_1A_1T_1R (
    363     ACPI_WALK_STATE         *WalkState)
    364 {
    365     ACPI_STATUS             Status = AE_OK;
    366     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
    367     ACPI_OPERAND_OBJECT     *ReturnDesc = NULL;
    368     ACPI_OPERAND_OBJECT     *ReturnDesc2 = NULL;
    369     UINT32                  Temp32;
    370     UINT32                  i;
    371     UINT64                  PowerOfTen;
    372     UINT64                  Digit;
    373 
    374 
    375     ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_1T_1R,
    376         AcpiPsGetOpcodeName (WalkState->Opcode));
    377 
    378 
    379     /* Examine the AML opcode */
    380 
    381     switch (WalkState->Opcode)
    382     {
    383     case AML_BIT_NOT_OP:
    384     case AML_FIND_SET_LEFT_BIT_OP:
    385     case AML_FIND_SET_RIGHT_BIT_OP:
    386     case AML_FROM_BCD_OP:
    387     case AML_TO_BCD_OP:
    388     case AML_COND_REF_OF_OP:
    389 
    390         /* Create a return object of type Integer for these opcodes */
    391 
    392         ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
    393         if (!ReturnDesc)
    394         {
    395             Status = AE_NO_MEMORY;
    396             goto Cleanup;
    397         }
    398 
    399         switch (WalkState->Opcode)
    400         {
    401         case AML_BIT_NOT_OP:            /* Not (Operand, Result)  */
    402 
    403             ReturnDesc->Integer.Value = ~Operand[0]->Integer.Value;
    404             break;
    405 
    406 
    407         case AML_FIND_SET_LEFT_BIT_OP:  /* FindSetLeftBit (Operand, Result) */
    408 
    409             ReturnDesc->Integer.Value = Operand[0]->Integer.Value;
    410 
    411             /*
    412              * Acpi specification describes Integer type as a little
    413              * endian unsigned value, so this boundary condition is valid.
    414              */
    415             for (Temp32 = 0; ReturnDesc->Integer.Value &&
    416                              Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32)
    417             {
    418                 ReturnDesc->Integer.Value >>= 1;
    419             }
    420 
    421             ReturnDesc->Integer.Value = Temp32;
    422             break;
    423 
    424 
    425         case AML_FIND_SET_RIGHT_BIT_OP: /* FindSetRightBit (Operand, Result) */
    426 
    427             ReturnDesc->Integer.Value = Operand[0]->Integer.Value;
    428 
    429             /*
    430              * The Acpi specification describes Integer type as a little
    431              * endian unsigned value, so this boundary condition is valid.
    432              */
    433             for (Temp32 = 0; ReturnDesc->Integer.Value &&
    434                              Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32)
    435             {
    436                 ReturnDesc->Integer.Value <<= 1;
    437             }
    438 
    439             /* Since the bit position is one-based, subtract from 33 (65) */
    440 
    441             ReturnDesc->Integer.Value =
    442                 Temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - Temp32;
    443             break;
    444 
    445 
    446         case AML_FROM_BCD_OP:           /* FromBcd (BCDValue, Result)  */
    447 
    448             /*
    449              * The 64-bit ACPI integer can hold 16 4-bit BCD characters
    450              * (if table is 32-bit, integer can hold 8 BCD characters)
    451              * Convert each 4-bit BCD value
    452              */
    453             PowerOfTen = 1;
    454             ReturnDesc->Integer.Value = 0;
    455             Digit = Operand[0]->Integer.Value;
    456 
    457             /* Convert each BCD digit (each is one nybble wide) */
    458 
    459             for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++)
    460             {
    461                 /* Get the least significant 4-bit BCD digit */
    462 
    463                 Temp32 = ((UINT32) Digit) & 0xF;
    464 
    465                 /* Check the range of the digit */
    466 
    467                 if (Temp32 > 9)
    468                 {
    469                     ACPI_ERROR ((AE_INFO,
    470                         "BCD digit too large (not decimal): 0x%X",
    471                         Temp32));
    472 
    473                     Status = AE_AML_NUMERIC_OVERFLOW;
    474                     goto Cleanup;
    475                 }
    476 
    477                 /* Sum the digit into the result with the current power of 10 */
    478 
    479                 ReturnDesc->Integer.Value +=
    480                     (((UINT64) Temp32) * PowerOfTen);
    481 
    482                 /* Shift to next BCD digit */
    483 
    484                 Digit >>= 4;
    485 
    486                 /* Next power of 10 */
    487 
    488                 PowerOfTen *= 10;
    489             }
    490             break;
    491 
    492 
    493         case AML_TO_BCD_OP:             /* ToBcd (Operand, Result)  */
    494 
    495             ReturnDesc->Integer.Value = 0;
    496             Digit = Operand[0]->Integer.Value;
    497 
    498             /* Each BCD digit is one nybble wide */
    499 
    500             for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++)
    501             {
    502                 (void) AcpiUtShortDivide (Digit, 10, &Digit, &Temp32);
    503 
    504                 /*
    505                  * Insert the BCD digit that resides in the
    506                  * remainder from above
    507                  */
    508                 ReturnDesc->Integer.Value |=
    509                     (((UINT64) Temp32) << ACPI_MUL_4 (i));
    510             }
    511 
    512             /* Overflow if there is any data left in Digit */
    513 
    514             if (Digit > 0)
    515             {
    516                 ACPI_ERROR ((AE_INFO,
    517                     "Integer too large to convert to BCD: 0x%8.8X%8.8X",
    518                     ACPI_FORMAT_UINT64 (Operand[0]->Integer.Value)));
    519                 Status = AE_AML_NUMERIC_OVERFLOW;
    520                 goto Cleanup;
    521             }
    522             break;
    523 
    524 
    525         case AML_COND_REF_OF_OP:        /* CondRefOf (SourceObject, Result)  */
    526 
    527             /*
    528              * This op is a little strange because the internal return value is
    529              * different than the return value stored in the result descriptor
    530              * (There are really two return values)
    531              */
    532             if ((ACPI_NAMESPACE_NODE *) Operand[0] == AcpiGbl_RootNode)
    533             {
    534                 /*
    535                  * This means that the object does not exist in the namespace,
    536                  * return FALSE
    537                  */
    538                 ReturnDesc->Integer.Value = 0;
    539                 goto Cleanup;
    540             }
    541 
    542             /* Get the object reference, store it, and remove our reference */
    543 
    544             Status = AcpiExGetObjectReference (Operand[0],
    545                         &ReturnDesc2, WalkState);
    546             if (ACPI_FAILURE (Status))
    547             {
    548                 goto Cleanup;
    549             }
    550 
    551             Status = AcpiExStore (ReturnDesc2, Operand[1], WalkState);
    552             AcpiUtRemoveReference (ReturnDesc2);
    553 
    554             /* The object exists in the namespace, return TRUE */
    555 
    556             ReturnDesc->Integer.Value = ACPI_UINT64_MAX;
    557             goto Cleanup;
    558 
    559 
    560         default:
    561             /* No other opcodes get here */
    562             break;
    563         }
    564         break;
    565 
    566 
    567     case AML_STORE_OP:              /* Store (Source, Target) */
    568 
    569         /*
    570          * A store operand is typically a number, string, buffer or lvalue
    571          * Be careful about deleting the source object,
    572          * since the object itself may have been stored.
    573          */
    574         Status = AcpiExStore (Operand[0], Operand[1], WalkState);
    575         if (ACPI_FAILURE (Status))
    576         {
    577             return_ACPI_STATUS (Status);
    578         }
    579 
    580         /* It is possible that the Store already produced a return object */
    581 
    582         if (!WalkState->ResultObj)
    583         {
    584             /*
    585              * Normally, we would remove a reference on the Operand[0]
    586              * parameter; But since it is being used as the internal return
    587              * object (meaning we would normally increment it), the two
    588              * cancel out, and we simply don't do anything.
    589              */
    590             WalkState->ResultObj = Operand[0];
    591             WalkState->Operands[0] = NULL;  /* Prevent deletion */
    592         }
    593         return_ACPI_STATUS (Status);
    594 
    595 
    596     /*
    597      * ACPI 2.0 Opcodes
    598      */
    599     case AML_COPY_OP:               /* Copy (Source, Target) */
    600 
    601         Status = AcpiUtCopyIobjectToIobject (Operand[0], &ReturnDesc,
    602                     WalkState);
    603         break;
    604 
    605 
    606     case AML_TO_DECSTRING_OP:       /* ToDecimalString (Data, Result) */
    607 
    608         Status = AcpiExConvertToString (Operand[0], &ReturnDesc,
    609                     ACPI_EXPLICIT_CONVERT_DECIMAL);
    610         if (ReturnDesc == Operand[0])
    611         {
    612             /* No conversion performed, add ref to handle return value */
    613             AcpiUtAddReference (ReturnDesc);
    614         }
    615         break;
    616 
    617 
    618     case AML_TO_HEXSTRING_OP:       /* ToHexString (Data, Result) */
    619 
    620         Status = AcpiExConvertToString (Operand[0], &ReturnDesc,
    621                     ACPI_EXPLICIT_CONVERT_HEX);
    622         if (ReturnDesc == Operand[0])
    623         {
    624             /* No conversion performed, add ref to handle return value */
    625             AcpiUtAddReference (ReturnDesc);
    626         }
    627         break;
    628 
    629 
    630     case AML_TO_BUFFER_OP:          /* ToBuffer (Data, Result) */
    631 
    632         Status = AcpiExConvertToBuffer (Operand[0], &ReturnDesc);
    633         if (ReturnDesc == Operand[0])
    634         {
    635             /* No conversion performed, add ref to handle return value */
    636             AcpiUtAddReference (ReturnDesc);
    637         }
    638         break;
    639 
    640 
    641     case AML_TO_INTEGER_OP:         /* ToInteger (Data, Result) */
    642 
    643         Status = AcpiExConvertToInteger (Operand[0], &ReturnDesc,
    644                     ACPI_ANY_BASE);
    645         if (ReturnDesc == Operand[0])
    646         {
    647             /* No conversion performed, add ref to handle return value */
    648             AcpiUtAddReference (ReturnDesc);
    649         }
    650         break;
    651 
    652 
    653     case AML_SHIFT_LEFT_BIT_OP:     /* ShiftLeftBit (Source, BitNum)  */
    654     case AML_SHIFT_RIGHT_BIT_OP:    /* ShiftRightBit (Source, BitNum) */
    655 
    656         /* These are two obsolete opcodes */
    657 
    658         ACPI_ERROR ((AE_INFO,
    659             "%s is obsolete and not implemented",
    660             AcpiPsGetOpcodeName (WalkState->Opcode)));
    661         Status = AE_SUPPORT;
    662         goto Cleanup;
    663 
    664 
    665     default:                        /* Unknown opcode */
    666 
    667         ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
    668             WalkState->Opcode));
    669         Status = AE_AML_BAD_OPCODE;
    670         goto Cleanup;
    671     }
    672 
    673     if (ACPI_SUCCESS (Status))
    674     {
    675         /* Store the return value computed above into the target object */
    676 
    677         Status = AcpiExStore (ReturnDesc, Operand[1], WalkState);
    678     }
    679 
    680 
    681 Cleanup:
    682 
    683     /* Delete return object on error */
    684 
    685     if (ACPI_FAILURE (Status))
    686     {
    687         AcpiUtRemoveReference (ReturnDesc);
    688     }
    689 
    690     /* Save return object on success */
    691 
    692     else if (!WalkState->ResultObj)
    693     {
    694         WalkState->ResultObj = ReturnDesc;
    695     }
    696 
    697     return_ACPI_STATUS (Status);
    698 }
    699 
    700 
    701 /*******************************************************************************
    702  *
    703  * FUNCTION:    AcpiExOpcode_1A_0T_1R
    704  *
    705  * PARAMETERS:  WalkState           - Current state (contains AML opcode)
    706  *
    707  * RETURN:      Status
    708  *
    709  * DESCRIPTION: Execute opcode with one argument, no target, and a return value
    710  *
    711  ******************************************************************************/
    712 
    713 ACPI_STATUS
    714 AcpiExOpcode_1A_0T_1R (
    715     ACPI_WALK_STATE         *WalkState)
    716 {
    717     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
    718     ACPI_OPERAND_OBJECT     *TempDesc;
    719     ACPI_OPERAND_OBJECT     *ReturnDesc = NULL;
    720     ACPI_STATUS             Status = AE_OK;
    721     UINT32                  Type;
    722     UINT64                  Value;
    723 
    724 
    725     ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_0T_1R,
    726         AcpiPsGetOpcodeName (WalkState->Opcode));
    727 
    728 
    729     /* Examine the AML opcode */
    730 
    731     switch (WalkState->Opcode)
    732     {
    733     case AML_LNOT_OP:               /* LNot (Operand) */
    734 
    735         ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) 0);
    736         if (!ReturnDesc)
    737         {
    738             Status = AE_NO_MEMORY;
    739             goto Cleanup;
    740         }
    741 
    742         /*
    743          * Set result to ONES (TRUE) if Value == 0.  Note:
    744          * ReturnDesc->Integer.Value is initially == 0 (FALSE) from above.
    745          */
    746         if (!Operand[0]->Integer.Value)
    747         {
    748             ReturnDesc->Integer.Value = ACPI_UINT64_MAX;
    749         }
    750         break;
    751 
    752 
    753     case AML_DECREMENT_OP:          /* Decrement (Operand)  */
    754     case AML_INCREMENT_OP:          /* Increment (Operand)  */
    755 
    756         /*
    757          * Create a new integer.  Can't just get the base integer and
    758          * increment it because it may be an Arg or Field.
    759          */
    760         ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
    761         if (!ReturnDesc)
    762         {
    763             Status = AE_NO_MEMORY;
    764             goto Cleanup;
    765         }
    766 
    767         /*
    768          * Since we are expecting a Reference operand, it can be either a
    769          * NS Node or an internal object.
    770          */
    771         TempDesc = Operand[0];
    772         if (ACPI_GET_DESCRIPTOR_TYPE (TempDesc) == ACPI_DESC_TYPE_OPERAND)
    773         {
    774             /* Internal reference object - prevent deletion */
    775 
    776             AcpiUtAddReference (TempDesc);
    777         }
    778 
    779         /*
    780          * Convert the Reference operand to an Integer (This removes a
    781          * reference on the Operand[0] object)
    782          *
    783          * NOTE:  We use LNOT_OP here in order to force resolution of the
    784          * reference operand to an actual integer.
    785          */
    786         Status = AcpiExResolveOperands (AML_LNOT_OP, &TempDesc, WalkState);
    787         if (ACPI_FAILURE (Status))
    788         {
    789             ACPI_EXCEPTION ((AE_INFO, Status,
    790                 "While resolving operands for [%s]",
    791                 AcpiPsGetOpcodeName (WalkState->Opcode)));
    792 
    793             goto Cleanup;
    794         }
    795 
    796         /*
    797          * TempDesc is now guaranteed to be an Integer object --
    798          * Perform the actual increment or decrement
    799          */
    800         if (WalkState->Opcode == AML_INCREMENT_OP)
    801         {
    802             ReturnDesc->Integer.Value = TempDesc->Integer.Value +1;
    803         }
    804         else
    805         {
    806             ReturnDesc->Integer.Value = TempDesc->Integer.Value -1;
    807         }
    808 
    809         /* Finished with this Integer object */
    810 
    811         AcpiUtRemoveReference (TempDesc);
    812 
    813         /*
    814          * Store the result back (indirectly) through the original
    815          * Reference object
    816          */
    817         Status = AcpiExStore (ReturnDesc, Operand[0], WalkState);
    818         break;
    819 
    820 
    821     case AML_TYPE_OP:               /* ObjectType (SourceObject) */
    822 
    823         /*
    824          * Note: The operand is not resolved at this point because we want to
    825          * get the associated object, not its value.  For example, we don't
    826          * want to resolve a FieldUnit to its value, we want the actual
    827          * FieldUnit object.
    828          */
    829 
    830         /* Get the type of the base object */
    831 
    832         Status = AcpiExResolveMultiple (WalkState, Operand[0], &Type, NULL);
    833         if (ACPI_FAILURE (Status))
    834         {
    835             goto Cleanup;
    836         }
    837 
    838         /* Allocate a descriptor to hold the type. */
    839 
    840         ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) Type);
    841         if (!ReturnDesc)
    842         {
    843             Status = AE_NO_MEMORY;
    844             goto Cleanup;
    845         }
    846         break;
    847 
    848 
    849     case AML_SIZE_OF_OP:            /* SizeOf (SourceObject)  */
    850 
    851         /*
    852          * Note: The operand is not resolved at this point because we want to
    853          * get the associated object, not its value.
    854          */
    855 
    856         /* Get the base object */
    857 
    858         Status = AcpiExResolveMultiple (WalkState,
    859                     Operand[0], &Type, &TempDesc);
    860         if (ACPI_FAILURE (Status))
    861         {
    862             goto Cleanup;
    863         }
    864 
    865         /*
    866          * The type of the base object must be integer, buffer, string, or
    867          * package.  All others are not supported.
    868          *
    869          * NOTE: Integer is not specifically supported by the ACPI spec,
    870          * but is supported implicitly via implicit operand conversion.
    871          * rather than bother with conversion, we just use the byte width
    872          * global (4 or 8 bytes).
    873          */
    874         switch (Type)
    875         {
    876         case ACPI_TYPE_INTEGER:
    877             Value = AcpiGbl_IntegerByteWidth;
    878             break;
    879 
    880         case ACPI_TYPE_STRING:
    881             Value = TempDesc->String.Length;
    882             break;
    883 
    884         case ACPI_TYPE_BUFFER:
    885 
    886             /* Buffer arguments may not be evaluated at this point */
    887 
    888             Status = AcpiDsGetBufferArguments (TempDesc);
    889             Value = TempDesc->Buffer.Length;
    890             break;
    891 
    892         case ACPI_TYPE_PACKAGE:
    893 
    894             /* Package arguments may not be evaluated at this point */
    895 
    896             Status = AcpiDsGetPackageArguments (TempDesc);
    897             Value = TempDesc->Package.Count;
    898             break;
    899 
    900         default:
    901             ACPI_ERROR ((AE_INFO,
    902                 "Operand must be Buffer/Integer/String/Package - found type %s",
    903                 AcpiUtGetTypeName (Type)));
    904             Status = AE_AML_OPERAND_TYPE;
    905             goto Cleanup;
    906         }
    907 
    908         if (ACPI_FAILURE (Status))
    909         {
    910             goto Cleanup;
    911         }
    912 
    913         /*
    914          * Now that we have the size of the object, create a result
    915          * object to hold the value
    916          */
    917         ReturnDesc = AcpiUtCreateIntegerObject (Value);
    918         if (!ReturnDesc)
    919         {
    920             Status = AE_NO_MEMORY;
    921             goto Cleanup;
    922         }
    923         break;
    924 
    925 
    926     case AML_REF_OF_OP:             /* RefOf (SourceObject) */
    927 
    928         Status = AcpiExGetObjectReference (Operand[0], &ReturnDesc, WalkState);
    929         if (ACPI_FAILURE (Status))
    930         {
    931             goto Cleanup;
    932         }
    933         break;
    934 
    935 
    936     case AML_DEREF_OF_OP:           /* DerefOf (ObjReference | String) */
    937 
    938         /* Check for a method local or argument, or standalone String */
    939 
    940         if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_NAMED)
    941         {
    942             TempDesc = AcpiNsGetAttachedObject (
    943                            (ACPI_NAMESPACE_NODE *) Operand[0]);
    944             if (TempDesc &&
    945                  ((TempDesc->Common.Type == ACPI_TYPE_STRING) ||
    946                   (TempDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)))
    947             {
    948                 Operand[0] = TempDesc;
    949                 AcpiUtAddReference (TempDesc);
    950             }
    951             else
    952             {
    953                 Status = AE_AML_OPERAND_TYPE;
    954                 goto Cleanup;
    955             }
    956         }
    957         else
    958         {
    959             switch ((Operand[0])->Common.Type)
    960             {
    961             case ACPI_TYPE_LOCAL_REFERENCE:
    962                 /*
    963                  * This is a DerefOf (LocalX | ArgX)
    964                  *
    965                  * Must resolve/dereference the local/arg reference first
    966                  */
    967                 switch (Operand[0]->Reference.Class)
    968                 {
    969                 case ACPI_REFCLASS_LOCAL:
    970                 case ACPI_REFCLASS_ARG:
    971 
    972                     /* Set Operand[0] to the value of the local/arg */
    973 
    974                     Status = AcpiDsMethodDataGetValue (
    975                                 Operand[0]->Reference.Class,
    976                                 Operand[0]->Reference.Value,
    977                                 WalkState, &TempDesc);
    978                     if (ACPI_FAILURE (Status))
    979                     {
    980                         goto Cleanup;
    981                     }
    982 
    983                     /*
    984                      * Delete our reference to the input object and
    985                      * point to the object just retrieved
    986                      */
    987                     AcpiUtRemoveReference (Operand[0]);
    988                     Operand[0] = TempDesc;
    989                     break;
    990 
    991                 case ACPI_REFCLASS_REFOF:
    992 
    993                     /* Get the object to which the reference refers */
    994 
    995                     TempDesc = Operand[0]->Reference.Object;
    996                     AcpiUtRemoveReference (Operand[0]);
    997                     Operand[0] = TempDesc;
    998                     break;
    999 
   1000                 default:
   1001 
   1002                     /* Must be an Index op - handled below */
   1003                     break;
   1004                 }
   1005                 break;
   1006 
   1007             case ACPI_TYPE_STRING:
   1008                 break;
   1009 
   1010             default:
   1011                 Status = AE_AML_OPERAND_TYPE;
   1012                 goto Cleanup;
   1013             }
   1014         }
   1015 
   1016         if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) != ACPI_DESC_TYPE_NAMED)
   1017         {
   1018             if ((Operand[0])->Common.Type == ACPI_TYPE_STRING)
   1019             {
   1020                 /*
   1021                  * This is a DerefOf (String). The string is a reference
   1022                  * to a named ACPI object.
   1023                  *
   1024                  * 1) Find the owning Node
   1025                  * 2) Dereference the node to an actual object. Could be a
   1026                  *    Field, so we need to resolve the node to a value.
   1027                  */
   1028                 Status = AcpiNsGetNode (WalkState->ScopeInfo->Scope.Node,
   1029                             Operand[0]->String.Pointer,
   1030                             ACPI_NS_SEARCH_PARENT,
   1031                             ACPI_CAST_INDIRECT_PTR (
   1032                                 ACPI_NAMESPACE_NODE, &ReturnDesc));
   1033                 if (ACPI_FAILURE (Status))
   1034                 {
   1035                     goto Cleanup;
   1036                 }
   1037 
   1038                 Status = AcpiExResolveNodeToValue (
   1039                             ACPI_CAST_INDIRECT_PTR (
   1040                                 ACPI_NAMESPACE_NODE, &ReturnDesc),
   1041                             WalkState);
   1042                 goto Cleanup;
   1043             }
   1044         }
   1045 
   1046         /* Operand[0] may have changed from the code above */
   1047 
   1048         if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_NAMED)
   1049         {
   1050             /*
   1051              * This is a DerefOf (ObjectReference)
   1052              * Get the actual object from the Node (This is the dereference).
   1053              * This case may only happen when a LocalX or ArgX is
   1054              * dereferenced above.
   1055              */
   1056             ReturnDesc = AcpiNsGetAttachedObject (
   1057                             (ACPI_NAMESPACE_NODE *) Operand[0]);
   1058             AcpiUtAddReference (ReturnDesc);
   1059         }
   1060         else
   1061         {
   1062             /*
   1063              * This must be a reference object produced by either the
   1064              * Index() or RefOf() operator
   1065              */
   1066             switch (Operand[0]->Reference.Class)
   1067             {
   1068             case ACPI_REFCLASS_INDEX:
   1069 
   1070                 /*
   1071                  * The target type for the Index operator must be
   1072                  * either a Buffer or a Package
   1073                  */
   1074                 switch (Operand[0]->Reference.TargetType)
   1075                 {
   1076                 case ACPI_TYPE_BUFFER_FIELD:
   1077 
   1078                     TempDesc = Operand[0]->Reference.Object;
   1079 
   1080                     /*
   1081                      * Create a new object that contains one element of the
   1082                      * buffer -- the element pointed to by the index.
   1083                      *
   1084                      * NOTE: index into a buffer is NOT a pointer to a
   1085                      * sub-buffer of the main buffer, it is only a pointer to a
   1086                      * single element (byte) of the buffer!
   1087                      *
   1088                      * Since we are returning the value of the buffer at the
   1089                      * indexed location, we don't need to add an additional
   1090                      * reference to the buffer itself.
   1091                      */
   1092                     ReturnDesc = AcpiUtCreateIntegerObject ((UINT64)
   1093                         TempDesc->Buffer.Pointer[Operand[0]->Reference.Value]);
   1094                     if (!ReturnDesc)
   1095                     {
   1096                         Status = AE_NO_MEMORY;
   1097                         goto Cleanup;
   1098                     }
   1099                     break;
   1100 
   1101 
   1102                 case ACPI_TYPE_PACKAGE:
   1103 
   1104                     /*
   1105                      * Return the referenced element of the package.  We must
   1106                      * add another reference to the referenced object, however.
   1107                      */
   1108                     ReturnDesc = *(Operand[0]->Reference.Where);
   1109                     if (ReturnDesc)
   1110                     {
   1111                         AcpiUtAddReference (ReturnDesc);
   1112                     }
   1113                     break;
   1114 
   1115 
   1116                 default:
   1117 
   1118                     ACPI_ERROR ((AE_INFO,
   1119                         "Unknown Index TargetType 0x%X in reference object %p",
   1120                         Operand[0]->Reference.TargetType, Operand[0]));
   1121                     Status = AE_AML_OPERAND_TYPE;
   1122                     goto Cleanup;
   1123                 }
   1124                 break;
   1125 
   1126 
   1127             case ACPI_REFCLASS_REFOF:
   1128 
   1129                 ReturnDesc = Operand[0]->Reference.Object;
   1130 
   1131                 if (ACPI_GET_DESCRIPTOR_TYPE (ReturnDesc) ==
   1132                         ACPI_DESC_TYPE_NAMED)
   1133                 {
   1134                     ReturnDesc = AcpiNsGetAttachedObject (
   1135                                     (ACPI_NAMESPACE_NODE *) ReturnDesc);
   1136                 }
   1137 
   1138                 /* Add another reference to the object! */
   1139 
   1140                 AcpiUtAddReference (ReturnDesc);
   1141                 break;
   1142 
   1143 
   1144             default:
   1145                 ACPI_ERROR ((AE_INFO,
   1146                     "Unknown class in reference(%p) - 0x%2.2X",
   1147                     Operand[0], Operand[0]->Reference.Class));
   1148 
   1149                 Status = AE_TYPE;
   1150                 goto Cleanup;
   1151             }
   1152         }
   1153         break;
   1154 
   1155 
   1156     default:
   1157 
   1158         ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
   1159             WalkState->Opcode));
   1160         Status = AE_AML_BAD_OPCODE;
   1161         goto Cleanup;
   1162     }
   1163 
   1164 
   1165 Cleanup:
   1166 
   1167     /* Delete return object on error */
   1168 
   1169     if (ACPI_FAILURE (Status))
   1170     {
   1171         AcpiUtRemoveReference (ReturnDesc);
   1172     }
   1173 
   1174     /* Save return object on success */
   1175 
   1176     else
   1177     {
   1178         WalkState->ResultObj = ReturnDesc;
   1179     }
   1180 
   1181     return_ACPI_STATUS (Status);
   1182 }
   1183 
   1184