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

exmisc.c
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003  *
00004  * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes
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 
00088  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
00089  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
00090  * PARTICULAR PURPOSE.
00091  *
00092  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
00093  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
00094  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
00095  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
00096  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
00097  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
00098  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
00099  * LIMITED REMEDY.
00100  *
00101  * 4.3. Licensee shall not export, either directly or indirectly, any of this
00102  * software or system incorporating such software without first obtaining any
00103  * required license or other approval from the U. S. Department of Commerce or
00104  * any other agency or department of the United States Government.  In the
00105  * event Licensee exports any such software from the United States or
00106  * re-exports any such software from a foreign destination, Licensee shall
00107  * ensure that the distribution and export/re-export of the software is in
00108  * compliance with all laws, regulations, orders, or other restrictions of the
00109  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
00110  * any of its subsidiaries will export/re-export any technical data, process,
00111  * software, or service, directly or indirectly, to any country for which the
00112  * United States government or any agency thereof requires an export license,
00113  * other governmental approval, or letter of assurance, without first obtaining
00114  * such license, approval or letter.
00115  *
00116  *****************************************************************************/
00117 
00118 #define __EXMISC_C__
00119 
00120 #include "acpi.h"
00121 #include "accommon.h"
00122 #include "acinterp.h"
00123 #include "amlcode.h"
00124 #include "amlresrc.h"
00125 
00126 
00127 #define _COMPONENT          ACPI_EXECUTER
00128         ACPI_MODULE_NAME    ("exmisc")
00129 
00130 
00131 /*******************************************************************************
00132  *
00133  * FUNCTION:    AcpiExGetObjectReference
00134  *
00135  * PARAMETERS:  ObjDesc             - Create a reference to this object
00136  *              ReturnDesc          - Where to store the reference
00137  *              WalkState           - Current state
00138  *
00139  * RETURN:      Status
00140  *
00141  * DESCRIPTION: Obtain and return a "reference" to the target object
00142  *              Common code for the RefOfOp and the CondRefOfOp.
00143  *
00144  ******************************************************************************/
00145 
00146 ACPI_STATUS
00147 AcpiExGetObjectReference (
00148     ACPI_OPERAND_OBJECT     *ObjDesc,
00149     ACPI_OPERAND_OBJECT     **ReturnDesc,
00150     ACPI_WALK_STATE         *WalkState)
00151 {
00152     ACPI_OPERAND_OBJECT     *ReferenceObj;
00153     ACPI_OPERAND_OBJECT     *ReferencedObj;
00154 
00155 
00156     ACPI_FUNCTION_TRACE_PTR (ExGetObjectReference, ObjDesc);
00157 
00158 
00159     *ReturnDesc = NULL;
00160 
00161     switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
00162     {
00163     case ACPI_DESC_TYPE_OPERAND:
00164 
00165         if (ObjDesc->Common.Type != ACPI_TYPE_LOCAL_REFERENCE)
00166         {
00167             return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
00168         }
00169 
00170         /*
00171          * Must be a reference to a Local or Arg
00172          */
00173         switch (ObjDesc->Reference.Class)
00174         {
00175         case ACPI_REFCLASS_LOCAL:
00176         case ACPI_REFCLASS_ARG:
00177         case ACPI_REFCLASS_DEBUG:
00178 
00179             /* The referenced object is the pseudo-node for the local/arg */
00180 
00181             ReferencedObj = ObjDesc->Reference.Object;
00182             break;
00183 
00184         default:
00185 
00186             ACPI_ERROR ((AE_INFO, "Unknown Reference Class 0x%2.2X",
00187                 ObjDesc->Reference.Class));
00188             return_ACPI_STATUS (AE_AML_INTERNAL);
00189         }
00190         break;
00191 
00192 
00193     case ACPI_DESC_TYPE_NAMED:
00194 
00195         /*
00196          * A named reference that has already been resolved to a Node
00197          */
00198         ReferencedObj = ObjDesc;
00199         break;
00200 
00201 
00202     default:
00203 
00204         ACPI_ERROR ((AE_INFO, "Invalid descriptor type 0x%X",
00205             ACPI_GET_DESCRIPTOR_TYPE (ObjDesc)));
00206         return_ACPI_STATUS (AE_TYPE);
00207     }
00208 
00209 
00210     /* Create a new reference object */
00211 
00212     ReferenceObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_REFERENCE);
00213     if (!ReferenceObj)
00214     {
00215         return_ACPI_STATUS (AE_NO_MEMORY);
00216     }
00217 
00218     ReferenceObj->Reference.Class = ACPI_REFCLASS_REFOF;
00219     ReferenceObj->Reference.Object = ReferencedObj;
00220     *ReturnDesc = ReferenceObj;
00221 
00222     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
00223         "Object %p Type [%s], returning Reference %p\n",
00224         ObjDesc, AcpiUtGetObjectTypeName (ObjDesc), *ReturnDesc));
00225 
00226     return_ACPI_STATUS (AE_OK);
00227 }
00228 
00229 
00230 /*******************************************************************************
00231  *
00232  * FUNCTION:    AcpiExConcatTemplate
00233  *
00234  * PARAMETERS:  Operand0            - First source object
00235  *              Operand1            - Second source object
00236  *              ActualReturnDesc    - Where to place the return object
00237  *              WalkState           - Current walk state
00238  *
00239  * RETURN:      Status
00240  *
00241  * DESCRIPTION: Concatenate two resource templates
00242  *
00243  ******************************************************************************/
00244 
00245 ACPI_STATUS
00246 AcpiExConcatTemplate (
00247     ACPI_OPERAND_OBJECT     *Operand0,
00248     ACPI_OPERAND_OBJECT     *Operand1,
00249     ACPI_OPERAND_OBJECT     **ActualReturnDesc,
00250     ACPI_WALK_STATE         *WalkState)
00251 {
00252     ACPI_STATUS             Status;
00253     ACPI_OPERAND_OBJECT     *ReturnDesc;
00254     UINT8                   *NewBuf;
00255     UINT8                   *EndTag;
00256     ACPI_SIZE               Length0;
00257     ACPI_SIZE               Length1;
00258     ACPI_SIZE               NewLength;
00259 
00260 
00261     ACPI_FUNCTION_TRACE (ExConcatTemplate);
00262 
00263 
00264     /*
00265      * Find the EndTag descriptor in each resource template.
00266      * Note1: returned pointers point TO the EndTag, not past it.
00267      * Note2: zero-length buffers are allowed; treated like one EndTag
00268      */
00269 
00270     /* Get the length of the first resource template */
00271 
00272     Status = AcpiUtGetResourceEndTag (Operand0, &EndTag);
00273     if (ACPI_FAILURE (Status))
00274     {
00275         return_ACPI_STATUS (Status);
00276     }
00277 
00278     Length0 = ACPI_PTR_DIFF (EndTag, Operand0->Buffer.Pointer);
00279 
00280     /* Get the length of the second resource template */
00281 
00282     Status = AcpiUtGetResourceEndTag (Operand1, &EndTag);
00283     if (ACPI_FAILURE (Status))
00284     {
00285         return_ACPI_STATUS (Status);
00286     }
00287 
00288     Length1 = ACPI_PTR_DIFF (EndTag, Operand1->Buffer.Pointer);
00289 
00290     /* Combine both lengths, minimum size will be 2 for EndTag */
00291 
00292     NewLength = Length0 + Length1 + sizeof (AML_RESOURCE_END_TAG);
00293 
00294     /* Create a new buffer object for the result (with one EndTag) */
00295 
00296     ReturnDesc = AcpiUtCreateBufferObject (NewLength);
00297     if (!ReturnDesc)
00298     {
00299         return_ACPI_STATUS (AE_NO_MEMORY);
00300     }
00301 
00302     /*
00303      * Copy the templates to the new buffer, 0 first, then 1 follows. One
00304      * EndTag descriptor is copied from Operand1.
00305      */
00306     NewBuf = ReturnDesc->Buffer.Pointer;
00307     ACPI_MEMCPY (NewBuf, Operand0->Buffer.Pointer, Length0);
00308     ACPI_MEMCPY (NewBuf + Length0, Operand1->Buffer.Pointer, Length1);
00309 
00310     /* Insert EndTag and set the checksum to zero, means "ignore checksum" */
00311 
00312     NewBuf[NewLength - 1] = 0;
00313     NewBuf[NewLength - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;
00314 
00315     /* Return the completed resource template */
00316 
00317     *ActualReturnDesc = ReturnDesc;
00318     return_ACPI_STATUS (AE_OK);
00319 }
00320 
00321 
00322 /*******************************************************************************
00323  *
00324  * FUNCTION:    AcpiExDoConcatenate
00325  *
00326  * PARAMETERS:  Operand0            - First source object
00327  *              Operand1            - Second source object
00328  *              ActualReturnDesc    - Where to place the return object
00329  *              WalkState           - Current walk state
00330  *
00331  * RETURN:      Status
00332  *
00333  * DESCRIPTION: Concatenate two objects OF THE SAME TYPE.
00334  *
00335  ******************************************************************************/
00336 
00337 ACPI_STATUS
00338 AcpiExDoConcatenate (
00339     ACPI_OPERAND_OBJECT     *Operand0,
00340     ACPI_OPERAND_OBJECT     *Operand1,
00341     ACPI_OPERAND_OBJECT     **ActualReturnDesc,
00342     ACPI_WALK_STATE         *WalkState)
00343 {
00344     ACPI_OPERAND_OBJECT     *LocalOperand1 = Operand1;
00345     ACPI_OPERAND_OBJECT     *ReturnDesc;
00346     char                    *NewBuf;
00347     ACPI_STATUS             Status;
00348 
00349 
00350     ACPI_FUNCTION_TRACE (ExDoConcatenate);
00351 
00352 
00353     /*
00354      * Convert the second operand if necessary.  The first operand
00355      * determines the type of the second operand, (See the Data Types
00356      * section of the ACPI specification.)  Both object types are
00357      * guaranteed to be either Integer/String/Buffer by the operand
00358      * resolution mechanism.
00359      */
00360     switch (Operand0->Common.Type)
00361     {
00362     case ACPI_TYPE_INTEGER:
00363         Status = AcpiExConvertToInteger (Operand1, &LocalOperand1, 16);
00364         break;
00365 
00366     case ACPI_TYPE_STRING:
00367         Status = AcpiExConvertToString (Operand1, &LocalOperand1,
00368                     ACPI_IMPLICIT_CONVERT_HEX);
00369         break;
00370 
00371     case ACPI_TYPE_BUFFER:
00372         Status = AcpiExConvertToBuffer (Operand1, &LocalOperand1);
00373         break;
00374 
00375     default:
00376         ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
00377             Operand0->Common.Type));
00378         Status = AE_AML_INTERNAL;
00379     }
00380 
00381     if (ACPI_FAILURE (Status))
00382     {
00383         goto Cleanup;
00384     }
00385 
00386     /*
00387      * Both operands are now known to be the same object type
00388      * (Both are Integer, String, or Buffer), and we can now perform the
00389      * concatenation.
00390      */
00391 
00392     /*
00393      * There are three cases to handle:
00394      *
00395      * 1) Two Integers concatenated to produce a new Buffer
00396      * 2) Two Strings concatenated to produce a new String
00397      * 3) Two Buffers concatenated to produce a new Buffer
00398      */
00399     switch (Operand0->Common.Type)
00400     {
00401     case ACPI_TYPE_INTEGER:
00402 
00403         /* Result of two Integers is a Buffer */
00404         /* Need enough buffer space for two integers */
00405 
00406         ReturnDesc = AcpiUtCreateBufferObject ((ACPI_SIZE)
00407                             ACPI_MUL_2 (AcpiGbl_IntegerByteWidth));
00408         if (!ReturnDesc)
00409         {
00410             Status = AE_NO_MEMORY;
00411             goto Cleanup;
00412         }
00413 
00414         NewBuf = (char *) ReturnDesc->Buffer.Pointer;
00415 
00416         /* Copy the first integer, LSB first */
00417 
00418         ACPI_MEMCPY (NewBuf, &Operand0->Integer.Value,
00419                         AcpiGbl_IntegerByteWidth);
00420 
00421         /* Copy the second integer (LSB first) after the first */
00422 
00423         ACPI_MEMCPY (NewBuf + AcpiGbl_IntegerByteWidth,
00424                         &LocalOperand1->Integer.Value,
00425                         AcpiGbl_IntegerByteWidth);
00426         break;
00427 
00428     case ACPI_TYPE_STRING:
00429 
00430         /* Result of two Strings is a String */
00431 
00432         ReturnDesc = AcpiUtCreateStringObject (
00433                         ((ACPI_SIZE) Operand0->String.Length +
00434                         LocalOperand1->String.Length));
00435         if (!ReturnDesc)
00436         {
00437             Status = AE_NO_MEMORY;
00438             goto Cleanup;
00439         }
00440 
00441         NewBuf = ReturnDesc->String.Pointer;
00442 
00443         /* Concatenate the strings */
00444 
00445         ACPI_STRCPY (NewBuf, Operand0->String.Pointer);
00446         ACPI_STRCPY (NewBuf + Operand0->String.Length,
00447                         LocalOperand1->String.Pointer);
00448         break;
00449 
00450     case ACPI_TYPE_BUFFER:
00451 
00452         /* Result of two Buffers is a Buffer */
00453 
00454         ReturnDesc = AcpiUtCreateBufferObject (
00455                         ((ACPI_SIZE) Operand0->Buffer.Length +
00456                         LocalOperand1->Buffer.Length));
00457         if (!ReturnDesc)
00458         {
00459             Status = AE_NO_MEMORY;
00460             goto Cleanup;
00461         }
00462 
00463         NewBuf = (char *) ReturnDesc->Buffer.Pointer;
00464 
00465         /* Concatenate the buffers */
00466 
00467         ACPI_MEMCPY (NewBuf, Operand0->Buffer.Pointer,
00468                         Operand0->Buffer.Length);
00469         ACPI_MEMCPY (NewBuf + Operand0->Buffer.Length,
00470                         LocalOperand1->Buffer.Pointer,
00471                         LocalOperand1->Buffer.Length);
00472         break;
00473 
00474     default:
00475 
00476         /* Invalid object type, should not happen here */
00477 
00478         ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
00479             Operand0->Common.Type));
00480         Status =AE_AML_INTERNAL;
00481         goto Cleanup;
00482     }
00483 
00484     *ActualReturnDesc = ReturnDesc;
00485 
00486 Cleanup:
00487     if (LocalOperand1 != Operand1)
00488     {
00489         AcpiUtRemoveReference (LocalOperand1);
00490     }
00491     return_ACPI_STATUS (Status);
00492 }
00493 
00494 
00495 /*******************************************************************************
00496  *
00497  * FUNCTION:    AcpiExDoMathOp
00498  *
00499  * PARAMETERS:  Opcode              - AML opcode
00500  *              Integer0            - Integer operand #0
00501  *              Integer1            - Integer operand #1
00502  *
00503  * RETURN:      Integer result of the operation
00504  *
00505  * DESCRIPTION: Execute a math AML opcode. The purpose of having all of the
00506  *              math functions here is to prevent a lot of pointer dereferencing
00507  *              to obtain the operands.
00508  *
00509  ******************************************************************************/
00510 
00511 UINT64
00512 AcpiExDoMathOp (
00513     UINT16                  Opcode,
00514     UINT64                  Integer0,
00515     UINT64                  Integer1)
00516 {
00517 
00518     ACPI_FUNCTION_ENTRY ();
00519 
00520 
00521     switch (Opcode)
00522     {
00523     case AML_ADD_OP:                /* Add (Integer0, Integer1, Result) */
00524 
00525         return (Integer0 + Integer1);
00526 
00527 
00528     case AML_BIT_AND_OP:            /* And (Integer0, Integer1, Result) */
00529 
00530         return (Integer0 & Integer1);
00531 
00532 
00533     case AML_BIT_NAND_OP:           /* NAnd (Integer0, Integer1, Result) */
00534 
00535         return (~(Integer0 & Integer1));
00536 
00537 
00538     case AML_BIT_OR_OP:             /* Or (Integer0, Integer1, Result) */
00539 
00540         return (Integer0 | Integer1);
00541 
00542 
00543     case AML_BIT_NOR_OP:            /* NOr (Integer0, Integer1, Result) */
00544 
00545         return (~(Integer0 | Integer1));
00546 
00547 
00548     case AML_BIT_XOR_OP:            /* XOr (Integer0, Integer1, Result) */
00549 
00550         return (Integer0 ^ Integer1);
00551 
00552 
00553     case AML_MULTIPLY_OP:           /* Multiply (Integer0, Integer1, Result) */
00554 
00555         return (Integer0 * Integer1);
00556 
00557 
00558     case AML_SHIFT_LEFT_OP:         /* ShiftLeft (Operand, ShiftCount, Result)*/
00559 
00560         /*
00561          * We need to check if the shiftcount is larger than the integer bit
00562          * width since the behavior of this is not well-defined in the C language.
00563          */
00564         if (Integer1 >= AcpiGbl_IntegerBitWidth)
00565         {
00566             return (0);
00567         }
00568         return (Integer0 << Integer1);
00569 
00570 
00571     case AML_SHIFT_RIGHT_OP:        /* ShiftRight (Operand, ShiftCount, Result) */
00572 
00573         /*
00574          * We need to check if the shiftcount is larger than the integer bit
00575          * width since the behavior of this is not well-defined in the C language.
00576          */
00577         if (Integer1 >= AcpiGbl_IntegerBitWidth)
00578         {
00579             return (0);
00580         }
00581         return (Integer0 >> Integer1);
00582 
00583 
00584     case AML_SUBTRACT_OP:           /* Subtract (Integer0, Integer1, Result) */
00585 
00586         return (Integer0 - Integer1);
00587 
00588     default:
00589 
00590         return (0);
00591     }
00592 }
00593 
00594 
00595 /*******************************************************************************
00596  *
00597  * FUNCTION:    AcpiExDoLogicalNumericOp
00598  *
00599  * PARAMETERS:  Opcode              - AML opcode
00600  *              Integer0            - Integer operand #0
00601  *              Integer1            - Integer operand #1
00602  *              LogicalResult       - TRUE/FALSE result of the operation
00603  *
00604  * RETURN:      Status
00605  *
00606  * DESCRIPTION: Execute a logical "Numeric" AML opcode. For these Numeric
00607  *              operators (LAnd and LOr), both operands must be integers.
00608  *
00609  *              Note: cleanest machine code seems to be produced by the code
00610  *              below, rather than using statements of the form:
00611  *                  Result = (Integer0 && Integer1);
00612  *
00613  ******************************************************************************/
00614 
00615 ACPI_STATUS
00616 AcpiExDoLogicalNumericOp (
00617     UINT16                  Opcode,
00618     UINT64                  Integer0,
00619     UINT64                  Integer1,
00620     BOOLEAN                 *LogicalResult)
00621 {
00622     ACPI_STATUS             Status = AE_OK;
00623     BOOLEAN                 LocalResult = FALSE;
00624 
00625 
00626     ACPI_FUNCTION_TRACE (ExDoLogicalNumericOp);
00627 
00628 
00629     switch (Opcode)
00630     {
00631     case AML_LAND_OP:               /* LAnd (Integer0, Integer1) */
00632 
00633         if (Integer0 && Integer1)
00634         {
00635             LocalResult = TRUE;
00636         }
00637         break;
00638 
00639     case AML_LOR_OP:                /* LOr (Integer0, Integer1) */
00640 
00641         if (Integer0 || Integer1)
00642         {
00643             LocalResult = TRUE;
00644         }
00645         break;
00646 
00647     default:
00648         Status = AE_AML_INTERNAL;
00649         break;
00650     }
00651 
00652     /* Return the logical result and status */
00653 
00654     *LogicalResult = LocalResult;
00655     return_ACPI_STATUS (Status);
00656 }
00657 
00658 
00659 /*******************************************************************************
00660  *
00661  * FUNCTION:    AcpiExDoLogicalOp
00662  *
00663  * PARAMETERS:  Opcode              - AML opcode
00664  *              Operand0            - operand #0
00665  *              Operand1            - operand #1
00666  *              LogicalResult       - TRUE/FALSE result of the operation
00667  *
00668  * RETURN:      Status
00669  *
00670  * DESCRIPTION: Execute a logical AML opcode. The purpose of having all of the
00671  *              functions here is to prevent a lot of pointer dereferencing
00672  *              to obtain the operands and to simplify the generation of the
00673  *              logical value. For the Numeric operators (LAnd and LOr), both
00674  *              operands must be integers. For the other logical operators,
00675  *              operands can be any combination of Integer/String/Buffer. The
00676  *              first operand determines the type to which the second operand
00677  *              will be converted.
00678  *
00679  *              Note: cleanest machine code seems to be produced by the code
00680  *              below, rather than using statements of the form:
00681  *                  Result = (Operand0 == Operand1);
00682  *
00683  ******************************************************************************/
00684 
00685 ACPI_STATUS
00686 AcpiExDoLogicalOp (
00687     UINT16                  Opcode,
00688     ACPI_OPERAND_OBJECT     *Operand0,
00689     ACPI_OPERAND_OBJECT     *Operand1,
00690     BOOLEAN                 *LogicalResult)
00691 {
00692     ACPI_OPERAND_OBJECT     *LocalOperand1 = Operand1;
00693     UINT64                  Integer0;
00694     UINT64                  Integer1;
00695     UINT32                  Length0;
00696     UINT32                  Length1;
00697     ACPI_STATUS             Status = AE_OK;
00698     BOOLEAN                 LocalResult = FALSE;
00699     int                     Compare;
00700 
00701 
00702     ACPI_FUNCTION_TRACE (ExDoLogicalOp);
00703 
00704 
00705     /*
00706      * Convert the second operand if necessary.  The first operand
00707      * determines the type of the second operand, (See the Data Types
00708      * section of the ACPI 3.0+ specification.)  Both object types are
00709      * guaranteed to be either Integer/String/Buffer by the operand
00710      * resolution mechanism.
00711      */
00712     switch (Operand0->Common.Type)
00713     {
00714     case ACPI_TYPE_INTEGER:
00715         Status = AcpiExConvertToInteger (Operand1, &LocalOperand1, 16);
00716         break;
00717 
00718     case ACPI_TYPE_STRING:
00719         Status = AcpiExConvertToString (Operand1, &LocalOperand1,
00720                     ACPI_IMPLICIT_CONVERT_HEX);
00721         break;
00722 
00723     case ACPI_TYPE_BUFFER:
00724         Status = AcpiExConvertToBuffer (Operand1, &LocalOperand1);
00725         break;
00726 
00727     default:
00728         Status = AE_AML_INTERNAL;
00729         break;
00730     }
00731 
00732     if (ACPI_FAILURE (Status))
00733     {
00734         goto Cleanup;
00735     }
00736 
00737     /*
00738      * Two cases: 1) Both Integers, 2) Both Strings or Buffers
00739      */
00740     if (Operand0->Common.Type == ACPI_TYPE_INTEGER)
00741     {
00742         /*
00743          * 1) Both operands are of type integer
00744          *    Note: LocalOperand1 may have changed above
00745          */
00746         Integer0 = Operand0->Integer.Value;
00747         Integer1 = LocalOperand1->Integer.Value;
00748 
00749         switch (Opcode)
00750         {
00751         case AML_LEQUAL_OP:             /* LEqual (Operand0, Operand1) */
00752 
00753             if (Integer0 == Integer1)
00754             {
00755                 LocalResult = TRUE;
00756             }
00757             break;
00758 
00759         case AML_LGREATER_OP:           /* LGreater (Operand0, Operand1) */
00760 
00761             if (Integer0 > Integer1)
00762             {
00763                 LocalResult = TRUE;
00764             }
00765             break;
00766 
00767         case AML_LLESS_OP:              /* LLess (Operand0, Operand1) */
00768 
00769             if (Integer0 < Integer1)
00770             {
00771                 LocalResult = TRUE;
00772             }
00773             break;
00774 
00775         default:
00776             Status = AE_AML_INTERNAL;
00777             break;
00778         }
00779     }
00780     else
00781     {
00782         /*
00783          * 2) Both operands are Strings or both are Buffers
00784          *    Note: Code below takes advantage of common Buffer/String
00785          *          object fields. LocalOperand1 may have changed above. Use
00786          *          memcmp to handle nulls in buffers.
00787          */
00788         Length0 = Operand0->Buffer.Length;
00789         Length1 = LocalOperand1->Buffer.Length;
00790 
00791         /* Lexicographic compare: compare the data bytes */
00792 
00793         Compare = ACPI_MEMCMP (Operand0->Buffer.Pointer,
00794                     LocalOperand1->Buffer.Pointer,
00795                     (Length0 > Length1) ? Length1 : Length0);
00796 
00797         switch (Opcode)
00798         {
00799         case AML_LEQUAL_OP:             /* LEqual (Operand0, Operand1) */
00800 
00801             /* Length and all bytes must be equal */
00802 
00803             if ((Length0 == Length1) &&
00804                 (Compare == 0))
00805             {
00806                 /* Length and all bytes match ==> TRUE */
00807 
00808                 LocalResult = TRUE;
00809             }
00810             break;
00811 
00812         case AML_LGREATER_OP:           /* LGreater (Operand0, Operand1) */
00813 
00814             if (Compare > 0)
00815             {
00816                 LocalResult = TRUE;
00817                 goto Cleanup;   /* TRUE */
00818             }
00819             if (Compare < 0)
00820             {
00821                 goto Cleanup;   /* FALSE */
00822             }
00823 
00824             /* Bytes match (to shortest length), compare lengths */
00825 
00826             if (Length0 > Length1)
00827             {
00828                 LocalResult = TRUE;
00829             }
00830             break;
00831 
00832         case AML_LLESS_OP:              /* LLess (Operand0, Operand1) */
00833 
00834             if (Compare > 0)
00835             {
00836                 goto Cleanup;   /* FALSE */
00837             }
00838             if (Compare < 0)
00839             {
00840                 LocalResult = TRUE;
00841                 goto Cleanup;   /* TRUE */
00842             }
00843 
00844             /* Bytes match (to shortest length), compare lengths */
00845 
00846             if (Length0 < Length1)
00847             {
00848                 LocalResult = TRUE;
00849             }
00850             break;
00851 
00852         default:
00853             Status = AE_AML_INTERNAL;
00854             break;
00855         }
00856     }
00857 
00858 Cleanup:
00859 
00860     /* New object was created if implicit conversion performed - delete */
00861 
00862     if (LocalOperand1 != Operand1)
00863     {
00864         AcpiUtRemoveReference (LocalOperand1);
00865     }
00866 
00867     /* Return the logical result and status */
00868 
00869     *LogicalResult = LocalResult;
00870     return_ACPI_STATUS (Status);
00871 }
00872 
00873 

Generated on Wed May 23 2012 04:25:09 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.