Subversion Repositories Kolibri OS

Rev

Rev 1498 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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