Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenexmisc.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
1.7.6.1
|