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