ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

exoparg1.c
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003  *
00004  * Module Name: exoparg1 - AML execution - opcodes with 1 argument
00005  *
00006  *****************************************************************************/
00007 
00008 /******************************************************************************
00009  *
00010  * 1. Copyright Notice
00011  *
00012  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
00013  * All rights reserved.
00014  *
00015  * 2. License
00016  *
00017  * 2.1. This is your license from Intel Corp. under its intellectual property
00018  * rights.  You may have additional license terms from the party that provided
00019  * you this software, covering your right to use that party's intellectual
00020  * property rights.
00021  *
00022  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
00023  * copy of the source code appearing in this file ("Covered Code") an
00024  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
00025  * base code distributed originally by Intel ("Original Intel Code") to copy,
00026  * make derivatives, distribute, use and display any portion of the Covered
00027  * Code in any form, with the right to sublicense such rights; and
00028  *
00029  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
00030  * license (with the right to sublicense), under only those claims of Intel
00031  * patents that are infringed by the Original Intel Code, to make, use, sell,
00032  * offer to sell, and import the Covered Code and derivative works thereof
00033  * solely to the minimum extent necessary to exercise the above copyright
00034  * license, and in no event shall the patent license extend to any additions
00035  * to or modifications of the Original Intel Code.  No other license or right
00036  * is granted directly or by implication, estoppel or otherwise;
00037  *
00038  * The above copyright and patent license is granted only if the following
00039  * conditions are met:
00040  *
00041  * 3. Conditions
00042  *
00043  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
00044  * Redistribution of source code of any substantial portion of the Covered
00045  * Code or modification with rights to further distribute source must include
00046  * the above Copyright Notice, the above License, this list of Conditions,
00047  * and the following Disclaimer and Export Compliance provision.  In addition,
00048  * Licensee must cause all Covered Code to which Licensee contributes to
00049  * contain a file documenting the changes Licensee made to create that Covered
00050  * Code and the date of any change.  Licensee must include in that file the
00051  * documentation of any changes made by any predecessor Licensee.  Licensee
00052  * must include a prominent statement that the modification is derived,
00053  * directly or indirectly, from Original Intel Code.
00054  *
00055  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
00056  * Redistribution of source code of any substantial portion of the Covered
00057  * Code or modification without rights to further distribute source must
00058  * include the following Disclaimer and Export Compliance provision in the
00059  * documentation and/or other materials provided with distribution.  In
00060  * addition, Licensee may not authorize further sublicense of source of any
00061  * portion of the Covered Code, and must include terms to the effect that the
00062  * license from Licensee to its licensee is limited to the intellectual
00063  * property embodied in the software Licensee provides to its licensee, and
00064  * not to intellectual property embodied in modifications its licensee may
00065  * make.
00066  *
00067  * 3.3. Redistribution of Executable. Redistribution in executable form of any
00068  * substantial portion of the Covered Code or modification must reproduce the
00069  * above Copyright Notice, and the following Disclaimer and Export Compliance
00070  * provision in the documentation and/or other materials provided with the
00071  * distribution.
00072  *
00073  * 3.4. Intel retains all right, title, and interest in and to the Original
00074  * Intel Code.
00075  *
00076  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
00077  * Intel shall be used in advertising or otherwise to promote the sale, use or
00078  * other dealings in products derived from or relating to the Covered Code
00079  * without prior written authorization from Intel.
00080  *
00081  * 4. Disclaimer and Export Compliance
00082  *
00083  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
00084  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
00085  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
00086  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
00087  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
00088  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
00089  * PARTICULAR PURPOSE.
00090  *
00091  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
00092  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
00093  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
00094  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
00095  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
00096  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
00097  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
00098  * LIMITED REMEDY.
00099  *
00100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
00101  * software or system incorporating such software without first obtaining any
00102  * required license or other approval from the U. S. Department of Commerce or
00103  * any other agency or department of the United States Government.  In the
00104  * event Licensee exports any such software from the United States or
00105  * re-exports any such software from a foreign destination, Licensee shall
00106  * ensure that the distribution and export/re-export of the software is in
00107  * compliance with all laws, regulations, orders, or other restrictions of the
00108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
00109  * any of its subsidiaries will export/re-export any technical data, process,
00110  * software, or service, directly or indirectly, to any country for which the
00111  * United States government or any agency thereof requires an export license,
00112  * other governmental approval, or letter of assurance, without first obtaining
00113  * such license, approval or letter.
00114  *
00115  *****************************************************************************/
00116 
00117 #define __EXOPARG1_C__
00118 
00119 #include "acpi.h"
00120 #include "accommon.h"
00121 #include "acparser.h"
00122 #include "acdispat.h"
00123 #include "acinterp.h"
00124 #include "amlcode.h"
00125 #include "acnamesp.h"
00126 
00127 
00128 #define _COMPONENT          ACPI_EXECUTER
00129         ACPI_MODULE_NAME    ("exoparg1")
00130 
00131 
00132 
00154 /*******************************************************************************
00155  *
00156  * FUNCTION:    AcpiExOpcode_0A_0T_1R
00157  *
00158  * PARAMETERS:  WalkState           - Current state (contains AML opcode)
00159  *
00160  * RETURN:      Status
00161  *
00162  * DESCRIPTION: Execute operator with no operands, one return value
00163  *
00164  ******************************************************************************/
00165 
00166 ACPI_STATUS
00167 AcpiExOpcode_0A_0T_1R (
00168     ACPI_WALK_STATE         *WalkState)
00169 {
00170     ACPI_STATUS             Status = AE_OK;
00171     ACPI_OPERAND_OBJECT     *ReturnDesc = NULL;
00172 
00173 
00174     ACPI_FUNCTION_TRACE_STR (ExOpcode_0A_0T_1R,
00175         AcpiPsGetOpcodeName (WalkState->Opcode));
00176 
00177 
00178     /* Examine the AML opcode */
00179 
00180     switch (WalkState->Opcode)
00181     {
00182     case AML_TIMER_OP:      /*  Timer () */
00183 
00184         /* Create a return object of type Integer */
00185 
00186         ReturnDesc = AcpiUtCreateIntegerObject (AcpiOsGetTimer ());
00187         if (!ReturnDesc)
00188         {
00189             Status = AE_NO_MEMORY;
00190             goto Cleanup;
00191         }
00192         break;
00193 
00194     default:                /*  Unknown opcode  */
00195 
00196         ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
00197             WalkState->Opcode));
00198         Status = AE_AML_BAD_OPCODE;
00199         break;
00200     }
00201 
00202 Cleanup:
00203 
00204     /* Delete return object on error */
00205 
00206     if ((ACPI_FAILURE (Status)) || WalkState->ResultObj)
00207     {
00208         AcpiUtRemoveReference (ReturnDesc);
00209         WalkState->ResultObj = NULL;
00210     }
00211     else
00212     {
00213         /* Save the return value */
00214 
00215         WalkState->ResultObj = ReturnDesc;
00216     }
00217 
00218     return_ACPI_STATUS (Status);
00219 }
00220 
00221 
00222 /*******************************************************************************
00223  *
00224  * FUNCTION:    AcpiExOpcode_1A_0T_0R
00225  *
00226  * PARAMETERS:  WalkState           - Current state (contains AML opcode)
00227  *
00228  * RETURN:      Status
00229  *
00230  * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on
00231  *              object stack
00232  *
00233  ******************************************************************************/
00234 
00235 ACPI_STATUS
00236 AcpiExOpcode_1A_0T_0R (
00237     ACPI_WALK_STATE         *WalkState)
00238 {
00239     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
00240     ACPI_STATUS             Status = AE_OK;
00241 
00242 
00243     ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_0T_0R,
00244         AcpiPsGetOpcodeName (WalkState->Opcode));
00245 
00246 
00247     /* Examine the AML opcode */
00248 
00249     switch (WalkState->Opcode)
00250     {
00251     case AML_RELEASE_OP:    /*  Release (MutexObject) */
00252 
00253         Status = AcpiExReleaseMutex (Operand[0], WalkState);
00254         break;
00255 
00256 
00257     case AML_RESET_OP:      /*  Reset (EventObject) */
00258 
00259         Status = AcpiExSystemResetEvent (Operand[0]);
00260         break;
00261 
00262 
00263     case AML_SIGNAL_OP:     /*  Signal (EventObject) */
00264 
00265         Status = AcpiExSystemSignalEvent (Operand[0]);
00266         break;
00267 
00268 
00269     case AML_SLEEP_OP:      /*  Sleep (MsecTime) */
00270 
00271         Status = AcpiExSystemDoSleep (Operand[0]->Integer.Value);
00272         break;
00273 
00274 
00275     case AML_STALL_OP:      /*  Stall (UsecTime) */
00276 
00277         Status = AcpiExSystemDoStall ((UINT32) Operand[0]->Integer.Value);
00278         break;
00279 
00280 
00281     case AML_UNLOAD_OP:     /*  Unload (Handle) */
00282 
00283         Status = AcpiExUnloadTable (Operand[0]);
00284         break;
00285 
00286 
00287     default:                /*  Unknown opcode  */
00288 
00289         ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
00290             WalkState->Opcode));
00291         Status = AE_AML_BAD_OPCODE;
00292         break;
00293     }
00294 
00295     return_ACPI_STATUS (Status);
00296 }
00297 
00298 
00299 /*******************************************************************************
00300  *
00301  * FUNCTION:    AcpiExOpcode_1A_1T_0R
00302  *
00303  * PARAMETERS:  WalkState           - Current state (contains AML opcode)
00304  *
00305  * RETURN:      Status
00306  *
00307  * DESCRIPTION: Execute opcode with one argument, one target, and no
00308  *              return value.
00309  *
00310  ******************************************************************************/
00311 
00312 ACPI_STATUS
00313 AcpiExOpcode_1A_1T_0R (
00314     ACPI_WALK_STATE         *WalkState)
00315 {
00316     ACPI_STATUS             Status = AE_OK;
00317     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
00318 
00319 
00320     ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_1T_0R,
00321         AcpiPsGetOpcodeName (WalkState->Opcode));
00322 
00323 
00324     /* Examine the AML opcode */
00325 
00326     switch (WalkState->Opcode)
00327     {
00328     case AML_LOAD_OP:
00329 
00330         Status = AcpiExLoadOp (Operand[0], Operand[1], WalkState);
00331         break;
00332 
00333     default:                        /* Unknown opcode */
00334 
00335         ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
00336             WalkState->Opcode));
00337         Status = AE_AML_BAD_OPCODE;
00338         goto Cleanup;
00339     }
00340 
00341 
00342 Cleanup:
00343 
00344     return_ACPI_STATUS (Status);
00345 }
00346 
00347 
00348 /*******************************************************************************
00349  *
00350  * FUNCTION:    AcpiExOpcode_1A_1T_1R
00351  *
00352  * PARAMETERS:  WalkState           - Current state (contains AML opcode)
00353  *
00354  * RETURN:      Status
00355  *
00356  * DESCRIPTION: Execute opcode with one argument, one target, and a
00357  *              return value.
00358  *
00359  ******************************************************************************/
00360 
00361 ACPI_STATUS
00362 AcpiExOpcode_1A_1T_1R (
00363     ACPI_WALK_STATE         *WalkState)
00364 {
00365     ACPI_STATUS             Status = AE_OK;
00366     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
00367     ACPI_OPERAND_OBJECT     *ReturnDesc = NULL;
00368     ACPI_OPERAND_OBJECT     *ReturnDesc2 = NULL;
00369     UINT32                  Temp32;
00370     UINT32                  i;
00371     UINT64                  PowerOfTen;
00372     UINT64                  Digit;
00373 
00374 
00375     ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_1T_1R,
00376         AcpiPsGetOpcodeName (WalkState->Opcode));
00377 
00378 
00379     /* Examine the AML opcode */
00380 
00381     switch (WalkState->Opcode)
00382     {
00383     case AML_BIT_NOT_OP:
00384     case AML_FIND_SET_LEFT_BIT_OP:
00385     case AML_FIND_SET_RIGHT_BIT_OP:
00386     case AML_FROM_BCD_OP:
00387     case AML_TO_BCD_OP:
00388     case AML_COND_REF_OF_OP:
00389 
00390         /* Create a return object of type Integer for these opcodes */
00391 
00392         ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
00393         if (!ReturnDesc)
00394         {
00395             Status = AE_NO_MEMORY;
00396             goto Cleanup;
00397         }
00398 
00399         switch (WalkState->Opcode)
00400         {
00401         case AML_BIT_NOT_OP:            /* Not (Operand, Result)  */
00402 
00403             ReturnDesc->Integer.Value = ~Operand[0]->Integer.Value;
00404             break;
00405 
00406 
00407         case AML_FIND_SET_LEFT_BIT_OP:  /* FindSetLeftBit (Operand, Result) */
00408 
00409             ReturnDesc->Integer.Value = Operand[0]->Integer.Value;
00410 
00411             /*
00412              * Acpi specification describes Integer type as a little
00413              * endian unsigned value, so this boundary condition is valid.
00414              */
00415             for (Temp32 = 0; ReturnDesc->Integer.Value &&
00416                              Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32)
00417             {
00418                 ReturnDesc->Integer.Value >>= 1;
00419             }
00420 
00421             ReturnDesc->Integer.Value = Temp32;
00422             break;
00423 
00424 
00425         case AML_FIND_SET_RIGHT_BIT_OP: /* FindSetRightBit (Operand, Result) */
00426 
00427             ReturnDesc->Integer.Value = Operand[0]->Integer.Value;
00428 
00429             /*
00430              * The Acpi specification describes Integer type as a little
00431              * endian unsigned value, so this boundary condition is valid.
00432              */
00433             for (Temp32 = 0; ReturnDesc->Integer.Value &&
00434                              Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32)
00435             {
00436                 ReturnDesc->Integer.Value <<= 1;
00437             }
00438 
00439             /* Since the bit position is one-based, subtract from 33 (65) */
00440 
00441             ReturnDesc->Integer.Value =
00442                 Temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - Temp32;
00443             break;
00444 
00445 
00446         case AML_FROM_BCD_OP:           /* FromBcd (BCDValue, Result)  */
00447 
00448             /*
00449              * The 64-bit ACPI integer can hold 16 4-bit BCD characters
00450              * (if table is 32-bit, integer can hold 8 BCD characters)
00451              * Convert each 4-bit BCD value
00452              */
00453             PowerOfTen = 1;
00454             ReturnDesc->Integer.Value = 0;
00455             Digit = Operand[0]->Integer.Value;
00456 
00457             /* Convert each BCD digit (each is one nybble wide) */
00458 
00459             for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++)
00460             {
00461                 /* Get the least significant 4-bit BCD digit */
00462 
00463                 Temp32 = ((UINT32) Digit) & 0xF;
00464 
00465                 /* Check the range of the digit */
00466 
00467                 if (Temp32 > 9)
00468                 {
00469                     ACPI_ERROR ((AE_INFO,
00470                         "BCD digit too large (not decimal): 0x%X",
00471                         Temp32));
00472 
00473                     Status = AE_AML_NUMERIC_OVERFLOW;
00474                     goto Cleanup;
00475                 }
00476 
00477                 /* Sum the digit into the result with the current power of 10 */
00478 
00479                 ReturnDesc->Integer.Value +=
00480                     (((UINT64) Temp32) * PowerOfTen);
00481 
00482                 /* Shift to next BCD digit */
00483 
00484                 Digit >>= 4;
00485 
00486                 /* Next power of 10 */
00487 
00488                 PowerOfTen *= 10;
00489             }
00490             break;
00491 
00492 
00493         case AML_TO_BCD_OP:             /* ToBcd (Operand, Result)  */
00494 
00495             ReturnDesc->Integer.Value = 0;
00496             Digit = Operand[0]->Integer.Value;
00497 
00498             /* Each BCD digit is one nybble wide */
00499 
00500             for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++)
00501             {
00502                 (void) AcpiUtShortDivide (Digit, 10, &Digit, &Temp32);
00503 
00504                 /*
00505                  * Insert the BCD digit that resides in the
00506                  * remainder from above
00507                  */
00508                 ReturnDesc->Integer.Value |=
00509                     (((UINT64) Temp32) << ACPI_MUL_4 (i));
00510             }
00511 
00512             /* Overflow if there is any data left in Digit */
00513 
00514             if (Digit > 0)
00515             {
00516                 ACPI_ERROR ((AE_INFO,
00517                     "Integer too large to convert to BCD: 0x%8.8X%8.8X",
00518                     ACPI_FORMAT_UINT64 (Operand[0]->Integer.Value)));
00519                 Status = AE_AML_NUMERIC_OVERFLOW;
00520                 goto Cleanup;
00521             }
00522             break;
00523 
00524 
00525         case AML_COND_REF_OF_OP:        /* CondRefOf (SourceObject, Result)  */
00526 
00527             /*
00528              * This op is a little strange because the internal return value is
00529              * different than the return value stored in the result descriptor
00530              * (There are really two return values)
00531              */
00532             if ((ACPI_NAMESPACE_NODE *) Operand[0] == AcpiGbl_RootNode)
00533             {
00534                 /*
00535                  * This means that the object does not exist in the namespace,
00536                  * return FALSE
00537                  */
00538                 ReturnDesc->Integer.Value = 0;
00539                 goto Cleanup;
00540             }
00541 
00542             /* Get the object reference, store it, and remove our reference */
00543 
00544             Status = AcpiExGetObjectReference (Operand[0],
00545                         &ReturnDesc2, WalkState);
00546             if (ACPI_FAILURE (Status))
00547             {
00548                 goto Cleanup;
00549             }
00550 
00551             Status = AcpiExStore (ReturnDesc2, Operand[1], WalkState);
00552             AcpiUtRemoveReference (ReturnDesc2);
00553 
00554             /* The object exists in the namespace, return TRUE */
00555 
00556             ReturnDesc->Integer.Value = ACPI_UINT64_MAX;
00557             goto Cleanup;
00558 
00559 
00560         default:
00561             /* No other opcodes get here */
00562             break;
00563         }
00564         break;
00565 
00566 
00567     case AML_STORE_OP:              /* Store (Source, Target) */
00568 
00569         /*
00570          * A store operand is typically a number, string, buffer or lvalue
00571          * Be careful about deleting the source object,
00572          * since the object itself may have been stored.
00573          */
00574         Status = AcpiExStore (Operand[0], Operand[1], WalkState);
00575         if (ACPI_FAILURE (Status))
00576         {
00577             return_ACPI_STATUS (Status);
00578         }
00579 
00580         /* It is possible that the Store already produced a return object */
00581 
00582         if (!WalkState->ResultObj)
00583         {
00584             /*
00585              * Normally, we would remove a reference on the Operand[0]
00586              * parameter; But since it is being used as the internal return
00587              * object (meaning we would normally increment it), the two
00588              * cancel out, and we simply don't do anything.
00589              */
00590             WalkState->ResultObj = Operand[0];
00591             WalkState->Operands[0] = NULL;  /* Prevent deletion */
00592         }
00593         return_ACPI_STATUS (Status);
00594 
00595 
00596     /*
00597      * ACPI 2.0 Opcodes
00598      */
00599     case AML_COPY_OP:               /* Copy (Source, Target) */
00600 
00601         Status = AcpiUtCopyIobjectToIobject (Operand[0], &ReturnDesc,
00602                     WalkState);
00603         break;
00604 
00605 
00606     case AML_TO_DECSTRING_OP:       /* ToDecimalString (Data, Result) */
00607 
00608         Status = AcpiExConvertToString (Operand[0], &ReturnDesc,
00609                     ACPI_EXPLICIT_CONVERT_DECIMAL);
00610         if (ReturnDesc == Operand[0])
00611         {
00612             /* No conversion performed, add ref to handle return value */
00613             AcpiUtAddReference (ReturnDesc);
00614         }
00615         break;
00616 
00617 
00618     case AML_TO_HEXSTRING_OP:       /* ToHexString (Data, Result) */
00619 
00620         Status = AcpiExConvertToString (Operand[0], &ReturnDesc,
00621                     ACPI_EXPLICIT_CONVERT_HEX);
00622         if (ReturnDesc == Operand[0])
00623         {
00624             /* No conversion performed, add ref to handle return value */
00625             AcpiUtAddReference (ReturnDesc);
00626         }
00627         break;
00628 
00629 
00630     case AML_TO_BUFFER_OP:          /* ToBuffer (Data, Result) */
00631 
00632         Status = AcpiExConvertToBuffer (Operand[0], &ReturnDesc);
00633         if (ReturnDesc == Operand[0])
00634         {
00635             /* No conversion performed, add ref to handle return value */
00636             AcpiUtAddReference (ReturnDesc);
00637         }
00638         break;
00639 
00640 
00641     case AML_TO_INTEGER_OP:         /* ToInteger (Data, Result) */
00642 
00643         Status = AcpiExConvertToInteger (Operand[0], &ReturnDesc,
00644                     ACPI_ANY_BASE);
00645         if (ReturnDesc == Operand[0])
00646         {
00647             /* No conversion performed, add ref to handle return value */
00648             AcpiUtAddReference (ReturnDesc);
00649         }
00650         break;
00651 
00652 
00653     case AML_SHIFT_LEFT_BIT_OP:     /* ShiftLeftBit (Source, BitNum)  */
00654     case AML_SHIFT_RIGHT_BIT_OP:    /* ShiftRightBit (Source, BitNum) */
00655 
00656         /* These are two obsolete opcodes */
00657 
00658         ACPI_ERROR ((AE_INFO,
00659             "%s is obsolete and not implemented",
00660             AcpiPsGetOpcodeName (WalkState->Opcode)));
00661         Status = AE_SUPPORT;
00662         goto Cleanup;
00663 
00664 
00665     default:                        /* Unknown opcode */
00666 
00667         ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
00668             WalkState->Opcode));
00669         Status = AE_AML_BAD_OPCODE;
00670         goto Cleanup;
00671     }
00672 
00673     if (ACPI_SUCCESS (Status))
00674     {
00675         /* Store the return value computed above into the target object */
00676 
00677         Status = AcpiExStore (ReturnDesc, Operand[1], WalkState);
00678     }
00679 
00680 
00681 Cleanup:
00682 
00683     /* Delete return object on error */
00684 
00685     if (ACPI_FAILURE (Status))
00686     {
00687         AcpiUtRemoveReference (ReturnDesc);
00688     }
00689 
00690     /* Save return object on success */
00691 
00692     else if (!WalkState->ResultObj)
00693     {
00694         WalkState->ResultObj = ReturnDesc;
00695     }
00696 
00697     return_ACPI_STATUS (Status);
00698 }
00699 
00700 
00701 /*******************************************************************************
00702  *
00703  * FUNCTION:    AcpiExOpcode_1A_0T_1R
00704  *
00705  * PARAMETERS:  WalkState           - Current state (contains AML opcode)
00706  *
00707  * RETURN:      Status
00708  *
00709  * DESCRIPTION: Execute opcode with one argument, no target, and a return value
00710  *
00711  ******************************************************************************/
00712 
00713 ACPI_STATUS
00714 AcpiExOpcode_1A_0T_1R (
00715     ACPI_WALK_STATE         *WalkState)
00716 {
00717     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
00718     ACPI_OPERAND_OBJECT     *TempDesc;
00719     ACPI_OPERAND_OBJECT     *ReturnDesc = NULL;
00720     ACPI_STATUS             Status = AE_OK;
00721     UINT32                  Type;
00722     UINT64                  Value;
00723 
00724 
00725     ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_0T_1R,
00726         AcpiPsGetOpcodeName (WalkState->Opcode));
00727 
00728 
00729     /* Examine the AML opcode */
00730 
00731     switch (WalkState->Opcode)
00732     {
00733     case AML_LNOT_OP:               /* LNot (Operand) */
00734 
00735         ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) 0);
00736         if (!ReturnDesc)
00737         {
00738             Status = AE_NO_MEMORY;
00739             goto Cleanup;
00740         }
00741 
00742         /*
00743          * Set result to ONES (TRUE) if Value == 0.  Note:
00744          * ReturnDesc->Integer.Value is initially == 0 (FALSE) from above.
00745          */
00746         if (!Operand[0]->Integer.Value)
00747         {
00748             ReturnDesc->Integer.Value = ACPI_UINT64_MAX;
00749         }
00750         break;
00751 
00752 
00753     case AML_DECREMENT_OP:          /* Decrement (Operand)  */
00754     case AML_INCREMENT_OP:          /* Increment (Operand)  */
00755 
00756         /*
00757          * Create a new integer.  Can't just get the base integer and
00758          * increment it because it may be an Arg or Field.
00759          */
00760         ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
00761         if (!ReturnDesc)
00762         {
00763             Status = AE_NO_MEMORY;
00764             goto Cleanup;
00765         }
00766 
00767         /*
00768          * Since we are expecting a Reference operand, it can be either a
00769          * NS Node or an internal object.
00770          */
00771         TempDesc = Operand[0];
00772         if (ACPI_GET_DESCRIPTOR_TYPE (TempDesc) == ACPI_DESC_TYPE_OPERAND)
00773         {
00774             /* Internal reference object - prevent deletion */
00775 
00776             AcpiUtAddReference (TempDesc);
00777         }
00778 
00779         /*
00780          * Convert the Reference operand to an Integer (This removes a
00781          * reference on the Operand[0] object)
00782          *
00783          * NOTE:  We use LNOT_OP here in order to force resolution of the
00784          * reference operand to an actual integer.
00785          */
00786         Status = AcpiExResolveOperands (AML_LNOT_OP, &TempDesc, WalkState);
00787         if (ACPI_FAILURE (Status))
00788         {
00789             ACPI_EXCEPTION ((AE_INFO, Status,
00790                 "While resolving operands for [%s]",
00791                 AcpiPsGetOpcodeName (WalkState->Opcode)));
00792 
00793             goto Cleanup;
00794         }
00795 
00796         /*
00797          * TempDesc is now guaranteed to be an Integer object --
00798          * Perform the actual increment or decrement
00799          */
00800         if (WalkState->Opcode == AML_INCREMENT_OP)
00801         {
00802             ReturnDesc->Integer.Value = TempDesc->Integer.Value +1;
00803         }
00804         else
00805         {
00806             ReturnDesc->Integer.Value = TempDesc->Integer.Value -1;
00807         }
00808 
00809         /* Finished with this Integer object */
00810 
00811         AcpiUtRemoveReference (TempDesc);
00812 
00813         /*
00814          * Store the result back (indirectly) through the original
00815          * Reference object
00816          */
00817         Status = AcpiExStore (ReturnDesc, Operand[0], WalkState);
00818         break;
00819 
00820 
00821     case AML_TYPE_OP:               /* ObjectType (SourceObject) */
00822 
00823         /*
00824          * Note: The operand is not resolved at this point because we want to
00825          * get the associated object, not its value.  For example, we don't
00826          * want to resolve a FieldUnit to its value, we want the actual
00827          * FieldUnit object.
00828          */
00829 
00830         /* Get the type of the base object */
00831 
00832         Status = AcpiExResolveMultiple (WalkState, Operand[0], &Type, NULL);
00833         if (ACPI_FAILURE (Status))
00834         {
00835             goto Cleanup;
00836         }
00837 
00838         /* Allocate a descriptor to hold the type. */
00839 
00840         ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) Type);
00841         if (!ReturnDesc)
00842         {
00843             Status = AE_NO_MEMORY;
00844             goto Cleanup;
00845         }
00846         break;
00847 
00848 
00849     case AML_SIZE_OF_OP:            /* SizeOf (SourceObject)  */
00850 
00851         /*
00852          * Note: The operand is not resolved at this point because we want to
00853          * get the associated object, not its value.
00854          */
00855 
00856         /* Get the base object */
00857 
00858         Status = AcpiExResolveMultiple (WalkState,
00859                     Operand[0], &Type, &TempDesc);
00860         if (ACPI_FAILURE (Status))
00861         {
00862             goto Cleanup;
00863         }
00864 
00865         /*
00866          * The type of the base object must be integer, buffer, string, or
00867          * package.  All others are not supported.
00868          *
00869          * NOTE: Integer is not specifically supported by the ACPI spec,
00870          * but is supported implicitly via implicit operand conversion.
00871          * rather than bother with conversion, we just use the byte width
00872          * global (4 or 8 bytes).
00873          */
00874         switch (Type)
00875         {
00876         case ACPI_TYPE_INTEGER:
00877             Value = AcpiGbl_IntegerByteWidth;
00878             break;
00879 
00880         case ACPI_TYPE_STRING:
00881             Value = TempDesc->String.Length;
00882             break;
00883 
00884         case ACPI_TYPE_BUFFER:
00885 
00886             /* Buffer arguments may not be evaluated at this point */
00887 
00888             Status = AcpiDsGetBufferArguments (TempDesc);
00889             Value = TempDesc->Buffer.Length;
00890             break;
00891 
00892         case ACPI_TYPE_PACKAGE:
00893 
00894             /* Package arguments may not be evaluated at this point */
00895 
00896             Status = AcpiDsGetPackageArguments (TempDesc);
00897             Value = TempDesc->Package.Count;
00898             break;
00899 
00900         default:
00901             ACPI_ERROR ((AE_INFO,
00902                 "Operand must be Buffer/Integer/String/Package - found type %s",
00903                 AcpiUtGetTypeName (Type)));
00904             Status = AE_AML_OPERAND_TYPE;
00905             goto Cleanup;
00906         }
00907 
00908         if (ACPI_FAILURE (Status))
00909         {
00910             goto Cleanup;
00911         }
00912 
00913         /*
00914          * Now that we have the size of the object, create a result
00915          * object to hold the value
00916          */
00917         ReturnDesc = AcpiUtCreateIntegerObject (Value);
00918         if (!ReturnDesc)
00919         {
00920             Status = AE_NO_MEMORY;
00921             goto Cleanup;
00922         }
00923         break;
00924 
00925 
00926     case AML_REF_OF_OP:             /* RefOf (SourceObject) */
00927 
00928         Status = AcpiExGetObjectReference (Operand[0], &ReturnDesc, WalkState);
00929         if (ACPI_FAILURE (Status))
00930         {
00931             goto Cleanup;
00932         }
00933         break;
00934 
00935 
00936     case AML_DEREF_OF_OP:           /* DerefOf (ObjReference | String) */
00937 
00938         /* Check for a method local or argument, or standalone String */
00939 
00940         if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_NAMED)
00941         {
00942             TempDesc = AcpiNsGetAttachedObject (
00943                            (ACPI_NAMESPACE_NODE *) Operand[0]);
00944             if (TempDesc &&
00945                  ((TempDesc->Common.Type == ACPI_TYPE_STRING) ||
00946                   (TempDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)))
00947             {
00948                 Operand[0] = TempDesc;
00949                 AcpiUtAddReference (TempDesc);
00950             }
00951             else
00952             {
00953                 Status = AE_AML_OPERAND_TYPE;
00954                 goto Cleanup;
00955             }
00956         }
00957         else
00958         {
00959             switch ((Operand[0])->Common.Type)
00960             {
00961             case ACPI_TYPE_LOCAL_REFERENCE:
00962                 /*
00963                  * This is a DerefOf (LocalX | ArgX)
00964                  *
00965                  * Must resolve/dereference the local/arg reference first
00966                  */
00967                 switch (Operand[0]->Reference.Class)
00968                 {
00969                 case ACPI_REFCLASS_LOCAL:
00970                 case ACPI_REFCLASS_ARG:
00971 
00972                     /* Set Operand[0] to the value of the local/arg */
00973 
00974                     Status = AcpiDsMethodDataGetValue (
00975                                 Operand[0]->Reference.Class,
00976                                 Operand[0]->Reference.Value,
00977                                 WalkState, &TempDesc);
00978                     if (ACPI_FAILURE (Status))
00979                     {
00980                         goto Cleanup;
00981                     }
00982 
00983                     /*
00984                      * Delete our reference to the input object and
00985                      * point to the object just retrieved
00986                      */
00987                     AcpiUtRemoveReference (Operand[0]);
00988                     Operand[0] = TempDesc;
00989                     break;
00990 
00991                 case ACPI_REFCLASS_REFOF:
00992 
00993                     /* Get the object to which the reference refers */
00994 
00995                     TempDesc = Operand[0]->Reference.Object;
00996                     AcpiUtRemoveReference (Operand[0]);
00997                     Operand[0] = TempDesc;
00998                     break;
00999 
01000                 default:
01001 
01002                     /* Must be an Index op - handled below */
01003                     break;
01004                 }
01005                 break;
01006 
01007             case ACPI_TYPE_STRING:
01008                 break;
01009 
01010             default:
01011                 Status = AE_AML_OPERAND_TYPE;
01012                 goto Cleanup;
01013             }
01014         }
01015 
01016         if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) != ACPI_DESC_TYPE_NAMED)
01017         {
01018             if ((Operand[0])->Common.Type == ACPI_TYPE_STRING)
01019             {
01020                 /*
01021                  * This is a DerefOf (String). The string is a reference
01022                  * to a named ACPI object.
01023                  *
01024                  * 1) Find the owning Node
01025                  * 2) Dereference the node to an actual object. Could be a
01026                  *    Field, so we need to resolve the node to a value.
01027                  */
01028                 Status = AcpiNsGetNode (WalkState->ScopeInfo->Scope.Node,
01029                             Operand[0]->String.Pointer,
01030                             ACPI_NS_SEARCH_PARENT,
01031                             ACPI_CAST_INDIRECT_PTR (
01032                                 ACPI_NAMESPACE_NODE, &ReturnDesc));
01033                 if (ACPI_FAILURE (Status))
01034                 {
01035                     goto Cleanup;
01036                 }
01037 
01038                 Status = AcpiExResolveNodeToValue (
01039                             ACPI_CAST_INDIRECT_PTR (
01040                                 ACPI_NAMESPACE_NODE, &ReturnDesc),
01041                             WalkState);
01042                 goto Cleanup;
01043             }
01044         }
01045 
01046         /* Operand[0] may have changed from the code above */
01047 
01048         if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_NAMED)
01049         {
01050             /*
01051              * This is a DerefOf (ObjectReference)
01052              * Get the actual object from the Node (This is the dereference).
01053              * This case may only happen when a LocalX or ArgX is
01054              * dereferenced above.
01055              */
01056             ReturnDesc = AcpiNsGetAttachedObject (
01057                             (ACPI_NAMESPACE_NODE *) Operand[0]);
01058             AcpiUtAddReference (ReturnDesc);
01059         }
01060         else
01061         {
01062             /*
01063              * This must be a reference object produced by either the
01064              * Index() or RefOf() operator
01065              */
01066             switch (Operand[0]->Reference.Class)
01067             {
01068             case ACPI_REFCLASS_INDEX:
01069 
01070                 /*
01071                  * The target type for the Index operator must be
01072                  * either a Buffer or a Package
01073                  */
01074                 switch (Operand[0]->Reference.TargetType)
01075                 {
01076                 case ACPI_TYPE_BUFFER_FIELD:
01077 
01078                     TempDesc = Operand[0]->Reference.Object;
01079 
01080                     /*
01081                      * Create a new object that contains one element of the
01082                      * buffer -- the element pointed to by the index.
01083                      *
01084                      * NOTE: index into a buffer is NOT a pointer to a
01085                      * sub-buffer of the main buffer, it is only a pointer to a
01086                      * single element (byte) of the buffer!
01087                      *
01088                      * Since we are returning the value of the buffer at the
01089                      * indexed location, we don't need to add an additional
01090                      * reference to the buffer itself.
01091                      */
01092                     ReturnDesc = AcpiUtCreateIntegerObject ((UINT64)
01093                         TempDesc->Buffer.Pointer[Operand[0]->Reference.Value]);
01094                     if (!ReturnDesc)
01095                     {
01096                         Status = AE_NO_MEMORY;
01097                         goto Cleanup;
01098                     }
01099                     break;
01100 
01101 
01102                 case ACPI_TYPE_PACKAGE:
01103 
01104                     /*
01105                      * Return the referenced element of the package.  We must
01106                      * add another reference to the referenced object, however.
01107                      */
01108                     ReturnDesc = *(Operand[0]->Reference.Where);
01109                     if (ReturnDesc)
01110                     {
01111                         AcpiUtAddReference (ReturnDesc);
01112                     }
01113                     break;
01114 
01115 
01116                 default:
01117 
01118                     ACPI_ERROR ((AE_INFO,
01119                         "Unknown Index TargetType 0x%X in reference object %p",
01120                         Operand[0]->Reference.TargetType, Operand[0]));
01121                     Status = AE_AML_OPERAND_TYPE;
01122                     goto Cleanup;
01123                 }
01124                 break;
01125 
01126 
01127             case ACPI_REFCLASS_REFOF:
01128 
01129                 ReturnDesc = Operand[0]->Reference.Object;
01130 
01131                 if (ACPI_GET_DESCRIPTOR_TYPE (ReturnDesc) ==
01132                         ACPI_DESC_TYPE_NAMED)
01133                 {
01134                     ReturnDesc = AcpiNsGetAttachedObject (
01135                                     (ACPI_NAMESPACE_NODE *) ReturnDesc);
01136                 }
01137 
01138                 /* Add another reference to the object! */
01139 
01140                 AcpiUtAddReference (ReturnDesc);
01141                 break;
01142 
01143 
01144             default:
01145                 ACPI_ERROR ((AE_INFO,
01146                     "Unknown class in reference(%p) - 0x%2.2X",
01147                     Operand[0], Operand[0]->Reference.Class));
01148 
01149                 Status = AE_TYPE;
01150                 goto Cleanup;
01151             }
01152         }
01153         break;
01154 
01155 
01156     default:
01157 
01158         ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
01159             WalkState->Opcode));
01160         Status = AE_AML_BAD_OPCODE;
01161         goto Cleanup;
01162     }
01163 
01164 
01165 Cleanup:
01166 
01167     /* Delete return object on error */
01168 
01169     if (ACPI_FAILURE (Status))
01170     {
01171         AcpiUtRemoveReference (ReturnDesc);
01172     }
01173 
01174     /* Save return object on success */
01175 
01176     else
01177     {
01178         WalkState->ResultObj = ReturnDesc;
01179     }
01180 
01181     return_ACPI_STATUS (Status);
01182 }
01183 

Generated on Fri May 25 2012 04:25:31 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.