14 * All rights reserved. 15 * 16 * 2. License 17 * 18 * 2.1. This is your license from Intel Corp. under its intellectual property 19 * rights. You may have additional license terms from the party that provided 20 * you this software, covering your right to use that party's intellectual 21 * property rights. 22 * 23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24 * copy of the source code appearing in this file ("Covered Code") an 25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26 * base code distributed originally by Intel ("Original Intel Code") to copy, 27 * make derivatives, distribute, use and display any portion of the Covered 28 * Code in any form, with the right to sublicense such rights; and 29 * 30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31 * license (with the right to sublicense), under only those claims of Intel 32 * patents that are infringed by the Original Intel Code, to make, use, sell, 33 * offer to sell, and import the Covered Code and derivative works thereof 34 * solely to the minimum extent necessary to exercise the above copyright 35 * license, and in no event shall the patent license extend to any additions 36 * to or modifications of the Original Intel Code. No other license or right 37 * is granted directly or by implication, estoppel or otherwise; 38 * 39 * The above copyright and patent license is granted only if the following 40 * conditions are met: 41 * 42 * 3. Conditions 43 * 44 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45 * Redistribution of source code of any substantial portion of the Covered 46 * Code or modification with rights to further distribute source must include 47 * the above Copyright Notice, the above License, this list of Conditions, 48 * and the following Disclaimer and Export Compliance provision. In addition, 49 * Licensee must cause all Covered Code to which Licensee contributes to 50 * contain a file documenting the changes Licensee made to create that Covered 51 * Code and the date of any change. Licensee must include in that file the 52 * documentation of any changes made by any predecessor Licensee. Licensee 53 * must include a prominent statement that the modification is derived, 54 * directly or indirectly, from Original Intel Code. 55 * 56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57 * Redistribution of source code of any substantial portion of the Covered 58 * Code or modification without rights to further distribute source must 59 * include the following Disclaimer and Export Compliance provision in the 60 * documentation and/or other materials provided with distribution. In 61 * addition, Licensee may not authorize further sublicense of source of any 62 * portion of the Covered Code, and must include terms to the effect that the 63 * license from Licensee to its licensee is limited to the intellectual 64 * property embodied in the software Licensee provides to its licensee, and 65 * not to intellectual property embodied in modifications its licensee may 66 * make. 67 * 68 * 3.3. Redistribution of Executable. Redistribution in executable form of any 69 * substantial portion of the Covered Code or modification must reproduce the 70 * above Copyright Notice, and the following Disclaimer and Export Compliance 71 * provision in the documentation and/or other materials provided with the 72 * distribution. 73 * 74 * 3.4. Intel retains all right, title, and interest in and to the Original 75 * Intel Code. 76 * 77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78 * Intel shall be used in advertising or otherwise to promote the sale, use or 79 * other dealings in products derived from or relating to the Covered Code 80 * without prior written authorization from Intel. 81 * 82 * 4. Disclaimer and Export Compliance 83 * 84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 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 __EXOPARG1_C__ 119 120#include "acpi.h" 121#include "acparser.h" 122#include "acdispat.h" 123#include "acinterp.h" 124#include "amlcode.h" 125#include "acnamesp.h" 126 127 128#define _COMPONENT ACPI_EXECUTER 129 ACPI_MODULE_NAME ("exoparg1") 130 131 132/*! 133 * Naming convention for AML interpreter execution routines. 134 * 135 * The routines that begin execution of AML opcodes are named with a common 136 * convention based upon the number of arguments, the number of target operands, 137 * and whether or not a value is returned: 138 * 139 * AcpiExOpcode_xA_yT_zR 140 * 141 * Where: 142 * 143 * xA - ARGUMENTS: The number of arguments (input operands) that are 144 * required for this opcode type (1 through 6 args). 145 * yT - TARGETS: The number of targets (output operands) that are required 146 * for this opcode type (0, 1, or 2 targets). 147 * zR - RETURN VALUE: Indicates whether this opcode type returns a value 148 * as the function return (0 or 1). 149 * 150 * The AcpiExOpcode* functions are called via the Dispatcher component with 151 * fully resolved operands. 152!*/ 153 154/******************************************************************************* 155 * 156 * FUNCTION: AcpiExOpcode_1A_0T_0R 157 * 158 * PARAMETERS: WalkState - Current state (contains AML opcode) 159 * 160 * RETURN: Status 161 * 162 * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on 163 * object stack 164 * 165 ******************************************************************************/ 166 167ACPI_STATUS 168AcpiExOpcode_1A_0T_0R ( 169 ACPI_WALK_STATE *WalkState) 170{ 171 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 172 ACPI_STATUS Status = AE_OK; 173 174 175 ACPI_FUNCTION_TRACE_STR ("ExOpcode_1A_0T_0R", AcpiPsGetOpcodeName (WalkState->Opcode)); 176 177 178 /* Examine the AML opcode */ 179 180 switch (WalkState->Opcode) 181 { 182 case AML_RELEASE_OP: /* Release (MutexObject) */ 183 184 Status = AcpiExReleaseMutex (Operand[0], WalkState); 185 break; 186 187 188 case AML_RESET_OP: /* Reset (EventObject) */ 189 190 Status = AcpiExSystemResetEvent (Operand[0]); 191 break; 192 193 194 case AML_SIGNAL_OP: /* Signal (EventObject) */ 195 196 Status = AcpiExSystemSignalEvent (Operand[0]); 197 break; 198 199 200 case AML_SLEEP_OP: /* Sleep (MsecTime) */ 201 202 Status = AcpiExSystemDoSuspend ((UINT32) Operand[0]->Integer.Value); 203 break; 204 205 206 case AML_STALL_OP: /* Stall (UsecTime) */ 207 208 Status = AcpiExSystemDoStall ((UINT32) Operand[0]->Integer.Value); 209 break; 210 211 212 case AML_UNLOAD_OP: /* Unload (Handle) */ 213 214 Status = AcpiExUnloadTable (Operand[0]); 215 break; 216 217 218 default: /* Unknown opcode */ 219 220 ACPI_REPORT_ERROR (("AcpiExOpcode_1A_0T_0R: Unknown opcode %X\n", 221 WalkState->Opcode)); 222 Status = AE_AML_BAD_OPCODE; 223 break; 224 } 225 226 return_ACPI_STATUS (Status); 227} 228 229 230/******************************************************************************* 231 * 232 * FUNCTION: AcpiExOpcode_1A_1T_0R 233 * 234 * PARAMETERS: WalkState - Current state (contains AML opcode) 235 * 236 * RETURN: Status 237 * 238 * DESCRIPTION: Execute opcode with one argument, one target, and no 239 * return value. 240 * 241 ******************************************************************************/ 242 243ACPI_STATUS 244AcpiExOpcode_1A_1T_0R ( 245 ACPI_WALK_STATE *WalkState) 246{ 247 ACPI_STATUS Status = AE_OK; 248 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 249 250 251 ACPI_FUNCTION_TRACE_STR ("ExOpcode_1A_1T_0R", AcpiPsGetOpcodeName (WalkState->Opcode)); 252 253 254 /* Examine the AML opcode */ 255 256 switch (WalkState->Opcode) 257 { 258 case AML_LOAD_OP: 259 260 Status = AcpiExLoadOp (Operand[0], Operand[1], WalkState); 261 break; 262 263 default: /* Unknown opcode */ 264 265 ACPI_REPORT_ERROR (("AcpiExOpcode_1A_1T_0R: Unknown opcode %X\n", 266 WalkState->Opcode)); 267 Status = AE_AML_BAD_OPCODE; 268 goto Cleanup; 269 } 270 271 272Cleanup: 273 274 return_ACPI_STATUS (Status); 275} 276 277 278/******************************************************************************* 279 * 280 * FUNCTION: AcpiExOpcode_1A_1T_1R 281 * 282 * PARAMETERS: WalkState - Current state (contains AML opcode) 283 * 284 * RETURN: Status 285 * 286 * DESCRIPTION: Execute opcode with one argument, one target, and a 287 * return value. 288 * 289 ******************************************************************************/ 290 291ACPI_STATUS 292AcpiExOpcode_1A_1T_1R ( 293 ACPI_WALK_STATE *WalkState) 294{ 295 ACPI_STATUS Status = AE_OK; 296 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 297 ACPI_OPERAND_OBJECT *ReturnDesc = NULL; 298 ACPI_OPERAND_OBJECT *ReturnDesc2 = NULL; 299 UINT32 Temp32; 300 UINT32 i; 301 UINT32 PowerOfTen; 302 ACPI_INTEGER Digit; 303 304 305 ACPI_FUNCTION_TRACE_STR ("ExOpcode_1A_1T_1R", AcpiPsGetOpcodeName (WalkState->Opcode)); 306 307 308 /* Examine the AML opcode */ 309 310 switch (WalkState->Opcode) 311 { 312 case AML_BIT_NOT_OP: 313 case AML_FIND_SET_LEFT_BIT_OP: 314 case AML_FIND_SET_RIGHT_BIT_OP: 315 case AML_FROM_BCD_OP: 316 case AML_TO_BCD_OP: 317 case AML_COND_REF_OF_OP: 318 319 /* Create a return object of type Integer for these opcodes */ 320 321 ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 322 if (!ReturnDesc) 323 { 324 Status = AE_NO_MEMORY; 325 goto Cleanup; 326 } 327 328 switch (WalkState->Opcode) 329 { 330 case AML_BIT_NOT_OP: /* Not (Operand, Result) */ 331 332 ReturnDesc->Integer.Value = ~Operand[0]->Integer.Value; 333 break; 334 335 336 case AML_FIND_SET_LEFT_BIT_OP: /* FindSetLeftBit (Operand, Result) */ 337 338 ReturnDesc->Integer.Value = Operand[0]->Integer.Value; 339 340 /* 341 * Acpi specification describes Integer type as a little 342 * endian unsigned value, so this boundary condition is valid. 343 */ 344 for (Temp32 = 0; ReturnDesc->Integer.Value && Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32) 345 { 346 ReturnDesc->Integer.Value >>= 1; 347 } 348 349 ReturnDesc->Integer.Value = Temp32; 350 break; 351 352 353 case AML_FIND_SET_RIGHT_BIT_OP: /* FindSetRightBit (Operand, Result) */ 354 355 ReturnDesc->Integer.Value = Operand[0]->Integer.Value; 356 357 /* 358 * The Acpi specification describes Integer type as a little 359 * endian unsigned value, so this boundary condition is valid. 360 */ 361 for (Temp32 = 0; ReturnDesc->Integer.Value && Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32) 362 { 363 ReturnDesc->Integer.Value <<= 1; 364 } 365 366 /* Since the bit position is one-based, subtract from 33 (65) */ 367 368 ReturnDesc->Integer.Value = Temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - Temp32; 369 break; 370 371 372 case AML_FROM_BCD_OP: /* FromBcd (BCDValue, Result) */ 373 374 /* 375 * The 64-bit ACPI integer can hold 16 4-bit BCD characters 376 * (if table is 32-bit, integer can hold 8 BCD characters) 377 * Convert each 4-bit BCD value 378 */ 379 PowerOfTen = 1; 380 ReturnDesc->Integer.Value = 0; 381 Digit = Operand[0]->Integer.Value; 382 383 /* Convert each BCD digit (each is one nybble wide) */ 384 385 for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++) 386 { 387 /* Get the least significant 4-bit BCD digit */ 388 389 Temp32 = ((UINT32) Digit) & 0xF; 390 391 /* Check the range of the digit */ 392 393 if (Temp32 > 9) 394 { 395 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 396 "BCD digit too large (not decimal): 0x%X\n", 397 Temp32)); 398 399 Status = AE_AML_NUMERIC_OVERFLOW; 400 goto Cleanup; 401 } 402 403 /* Sum the digit into the result with the current power of 10 */ 404 405 ReturnDesc->Integer.Value += (((ACPI_INTEGER) Temp32) * PowerOfTen); 406 407 /* Shift to next BCD digit */ 408 409 Digit >>= 4; 410 411 /* Next power of 10 */ 412 413 PowerOfTen *= 10; 414 } 415 break; 416 417 418 case AML_TO_BCD_OP: /* ToBcd (Operand, Result) */ 419 420 ReturnDesc->Integer.Value = 0; 421 Digit = Operand[0]->Integer.Value; 422 423 /* Each BCD digit is one nybble wide */ 424 425 for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++) 426 { 427 (void) AcpiUtShortDivide (&Digit, 10, &Digit, &Temp32); 428 429 /* Insert the BCD digit that resides in the remainder from above */ 430 431 ReturnDesc->Integer.Value |= (((ACPI_INTEGER) Temp32) << (i * 4)); 432 } 433 434 /* Overflow if there is any data left in Digit */ 435 436 if (Digit > 0) 437 { 438 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Integer too large to convert to BCD: %8.8X%8.8X\n", 439 ACPI_FORMAT_UINT64 (Operand[0]->Integer.Value))); 440 Status = AE_AML_NUMERIC_OVERFLOW; 441 goto Cleanup; 442 } 443 break; 444 445 446 case AML_COND_REF_OF_OP: /* CondRefOf (SourceObject, Result) */ 447 448 /* 449 * This op is a little strange because the internal return value is 450 * different than the return value stored in the result descriptor 451 * (There are really two return values) 452 */ 453 if ((ACPI_NAMESPACE_NODE *) Operand[0] == AcpiGbl_RootNode) 454 { 455 /* 456 * This means that the object does not exist in the namespace, 457 * return FALSE 458 */ 459 ReturnDesc->Integer.Value = 0; 460 goto Cleanup; 461 } 462 463 /* Get the object reference, store it, and remove our reference */ 464 465 Status = AcpiExGetObjectReference (Operand[0], &ReturnDesc2, WalkState); 466 if (ACPI_FAILURE (Status)) 467 { 468 goto Cleanup; 469 } 470 471 Status = AcpiExStore (ReturnDesc2, Operand[1], WalkState); 472 AcpiUtRemoveReference (ReturnDesc2); 473 474 /* The object exists in the namespace, return TRUE */ 475 476 ReturnDesc->Integer.Value = ACPI_INTEGER_MAX; 477 goto Cleanup; 478 479 480 default: 481 /* No other opcodes get here */ 482 break; 483 } 484 break; 485 486 487 case AML_STORE_OP: /* Store (Source, Target) */ 488 489 /* 490 * A store operand is typically a number, string, buffer or lvalue 491 * Be careful about deleting the source object, 492 * since the object itself may have been stored. 493 */ 494 Status = AcpiExStore (Operand[0], Operand[1], WalkState); 495 if (ACPI_FAILURE (Status)) 496 { 497 return_ACPI_STATUS (Status); 498 } 499 500 /* It is possible that the Store already produced a return object */ 501 502 if (!WalkState->ResultObj) 503 { 504 /* 505 * Normally, we would remove a reference on the Operand[0] parameter; 506 * But since it is being used as the internal return object 507 * (meaning we would normally increment it), the two cancel out, 508 * and we simply don't do anything. 509 */ 510 WalkState->ResultObj = Operand[0]; 511 WalkState->Operands[0] = NULL; /* Prevent deletion */ 512 } 513 return_ACPI_STATUS (Status); 514 515 516 /* 517 * ACPI 2.0 Opcodes 518 */ 519 case AML_COPY_OP: /* Copy (Source, Target) */ 520 521 Status = AcpiUtCopyIobjectToIobject (Operand[0], &ReturnDesc, WalkState); 522 break; 523 524 525 case AML_TO_DECSTRING_OP: /* ToDecimalString (Data, Result) */ 526 527 Status = AcpiExConvertToString (Operand[0], &ReturnDesc, 10, ACPI_UINT32_MAX, WalkState); 528 break; 529 530 531 case AML_TO_HEXSTRING_OP: /* ToHexString (Data, Result) */ 532 533 Status = AcpiExConvertToString (Operand[0], &ReturnDesc, 16, ACPI_UINT32_MAX, WalkState); 534 break; 535 536 537 case AML_TO_BUFFER_OP: /* ToBuffer (Data, Result) */ 538 539 Status = AcpiExConvertToBuffer (Operand[0], &ReturnDesc, WalkState); 540 break; 541 542 543 case AML_TO_INTEGER_OP: /* ToInteger (Data, Result) */ 544 545 Status = AcpiExConvertToInteger (Operand[0], &ReturnDesc, WalkState); 546 break; 547 548 549 case AML_SHIFT_LEFT_BIT_OP: /* ShiftLeftBit (Source, BitNum) */ 550 case AML_SHIFT_RIGHT_BIT_OP: /* ShiftRightBit (Source, BitNum) */ 551 552 /* 553 * These are two obsolete opcodes 554 */ 555 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s is obsolete and not implemented\n", 556 AcpiPsGetOpcodeName (WalkState->Opcode))); 557 Status = AE_SUPPORT; 558 goto Cleanup; 559 560 561 default: /* Unknown opcode */ 562 563 ACPI_REPORT_ERROR (("AcpiExOpcode_1A_1T_1R: Unknown opcode %X\n", 564 WalkState->Opcode)); 565 Status = AE_AML_BAD_OPCODE; 566 goto Cleanup; 567 } 568 569 /* 570 * Store the return value computed above into the target object 571 */ 572 Status = AcpiExStore (ReturnDesc, Operand[1], WalkState); 573 574 575Cleanup: 576 577 if (!WalkState->ResultObj) 578 { 579 WalkState->ResultObj = ReturnDesc; 580 } 581 582 /* Delete return object on error */ 583 584 if (ACPI_FAILURE (Status)) 585 { 586 AcpiUtRemoveReference (ReturnDesc); 587 } 588 589 return_ACPI_STATUS (Status); 590} 591 592 593/******************************************************************************* 594 * 595 * FUNCTION: AcpiExOpcode_1A_0T_1R 596 * 597 * PARAMETERS: WalkState - Current state (contains AML opcode) 598 * 599 * RETURN: Status 600 * 601 * DESCRIPTION: Execute opcode with one argument, no target, and a return value 602 * 603 ******************************************************************************/ 604 605ACPI_STATUS 606AcpiExOpcode_1A_0T_1R ( 607 ACPI_WALK_STATE *WalkState) 608{ 609 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 610 ACPI_OPERAND_OBJECT *TempDesc; 611 ACPI_OPERAND_OBJECT *ReturnDesc = NULL; 612 ACPI_STATUS Status = AE_OK; 613 UINT32 Type; 614 ACPI_INTEGER Value; 615 616 617 ACPI_FUNCTION_TRACE_STR ("ExOpcode_1A_0T_1R", AcpiPsGetOpcodeName (WalkState->Opcode)); 618 619 620 /* Examine the AML opcode */ 621 622 switch (WalkState->Opcode) 623 { 624 case AML_LNOT_OP: /* LNot (Operand) */ 625 626 ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 627 if (!ReturnDesc) 628 { 629 Status = AE_NO_MEMORY; 630 goto Cleanup; 631 } 632 633 ReturnDesc->Integer.Value = !Operand[0]->Integer.Value; 634 break; 635 636 637 case AML_DECREMENT_OP: /* Decrement (Operand) */ 638 case AML_INCREMENT_OP: /* Increment (Operand) */ 639 640 /* 641 * Since we are expecting a Reference operand, it 642 * can be either a NS Node or an internal object. 643 */ 644 ReturnDesc = Operand[0]; 645 if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_OPERAND) 646 { 647 /* Internal reference object - prevent deletion */ 648 649 AcpiUtAddReference (ReturnDesc); 650 } 651 652 /* 653 * Convert the ReturnDesc Reference to a Number 654 * (This removes a reference on the ReturnDesc object) 655 */ 656 Status = AcpiExResolveOperands (AML_LNOT_OP, &ReturnDesc, WalkState); 657 if (ACPI_FAILURE (Status)) 658 { 659 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s: bad operand(s) %s\n", 660 AcpiPsGetOpcodeName (WalkState->Opcode), AcpiFormatException(Status))); 661 662 goto Cleanup; 663 } 664 665 /* 666 * ReturnDesc is now guaranteed to be an Integer object 667 * Do the actual increment or decrement 668 */ 669 if (AML_INCREMENT_OP == WalkState->Opcode) 670 { 671 ReturnDesc->Integer.Value++; 672 } 673 else 674 { 675 ReturnDesc->Integer.Value--; 676 } 677 678 /* Store the result back in the original descriptor */ 679 680 Status = AcpiExStore (ReturnDesc, Operand[0], WalkState); 681 break; 682 683 684 case AML_TYPE_OP: /* ObjectType (SourceObject) */ 685 686 /* Get the type of the base object */ 687 688 Status = AcpiExResolveMultiple (WalkState, Operand[0], &Type, NULL); 689 if (ACPI_FAILURE (Status)) 690 { 691 goto Cleanup; 692 } 693 694 /* Allocate a descriptor to hold the type. */ 695 696 ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 697 if (!ReturnDesc) 698 { 699 Status = AE_NO_MEMORY; 700 goto Cleanup; 701 } 702 703 ReturnDesc->Integer.Value = Type; 704 break; 705 706 707 case AML_SIZE_OF_OP: /* SizeOf (SourceObject) */ 708 709 /* Get the base object */ 710 711 Status = AcpiExResolveMultiple (WalkState, Operand[0], &Type, &TempDesc); 712 if (ACPI_FAILURE (Status)) 713 { 714 goto Cleanup; 715 } 716 717 /* 718 * Type is guaranteed to be a buffer, string, or package at this 719 * point (even if the original operand was an object reference, it 720 * will be resolved and typechecked during operand resolution.) 721 */ 722 switch (Type) 723 { 724 case ACPI_TYPE_BUFFER: 725 Value = TempDesc->Buffer.Length; 726 break; 727 728 case ACPI_TYPE_STRING: 729 Value = TempDesc->String.Length; 730 break; 731 732 case ACPI_TYPE_PACKAGE: 733 Value = TempDesc->Package.Count; 734 break; 735 736 default: 737 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "SizeOf, Not Buf/Str/Pkg - found type %s\n", 738 AcpiUtGetTypeName (Type))); 739 Status = AE_AML_OPERAND_TYPE; 740 goto Cleanup; 741 } 742 743 /* 744 * Now that we have the size of the object, create a result 745 * object to hold the value 746 */ 747 ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 748 if (!ReturnDesc) 749 { 750 Status = AE_NO_MEMORY; 751 goto Cleanup; 752 } 753 754 ReturnDesc->Integer.Value = Value; 755 break; 756 757 758 case AML_REF_OF_OP: /* RefOf (SourceObject) */ 759 760 Status = AcpiExGetObjectReference (Operand[0], &ReturnDesc, WalkState); 761 if (ACPI_FAILURE (Status)) 762 { 763 goto Cleanup; 764 } 765 break; 766 767 768 case AML_DEREF_OF_OP: /* DerefOf (ObjReference | String) */ 769 770 /* Check for a method local or argument, or standalone String */ 771 772 if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) != ACPI_DESC_TYPE_NAMED) 773 { 774 switch (ACPI_GET_OBJECT_TYPE (Operand[0])) 775 { 776 case ACPI_TYPE_LOCAL_REFERENCE: 777 /* 778 * This is a DerefOf (LocalX | ArgX) 779 * 780 * Must resolve/dereference the local/arg reference first 781 */ 782 switch (Operand[0]->Reference.Opcode) 783 { 784 case AML_LOCAL_OP: 785 case AML_ARG_OP: 786 787 /* Set Operand[0] to the value of the local/arg */ 788 789 Status = AcpiDsMethodDataGetValue (Operand[0]->Reference.Opcode, 790 Operand[0]->Reference.Offset, WalkState, &TempDesc); 791 if (ACPI_FAILURE (Status)) 792 { 793 goto Cleanup; 794 } 795 796 /* 797 * Delete our reference to the input object and 798 * point to the object just retrieved 799 */ 800 AcpiUtRemoveReference (Operand[0]); 801 Operand[0] = TempDesc; 802 break; 803 804 case AML_REF_OF_OP: 805 806 /* Get the object to which the reference refers */ 807 808 TempDesc = Operand[0]->Reference.Object; 809 AcpiUtRemoveReference (Operand[0]); 810 Operand[0] = TempDesc; 811 break; 812 813 default: 814 815 /* Must be an Index op - handled below */ 816 break; 817 } 818 break; 819 820 821 case ACPI_TYPE_STRING: 822 823 /* 824 * This is a DerefOf (String). The string is a reference to a named ACPI object. 825 * 826 * 1) Find the owning Node 827 * 2) Dereference the node to an actual object. Could be a Field, so we nee 828 * to resolve the node to a value. 829 */ 830 Status = AcpiNsGetNodeByPath (Operand[0]->String.Pointer, 831 WalkState->ScopeInfo->Scope.Node, ACPI_NS_SEARCH_PARENT, 832 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ReturnDesc)); 833 if (ACPI_FAILURE (Status)) 834 { 835 goto Cleanup; 836 } 837 838 Status = AcpiExResolveNodeToValue ( 839 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ReturnDesc), WalkState); 840 goto Cleanup; 841 842 843 default: 844 845 Status = AE_AML_OPERAND_TYPE; 846 goto Cleanup; 847 } 848 } 849 850 /* Operand[0] may have changed from the code above */ 851 852 if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_NAMED) 853 { 854 /* 855 * This is a DerefOf (ObjectReference) 856 * Get the actual object from the Node (This is the dereference). 857 * -- This case may only happen when a LocalX or ArgX is dereferenced above. 858 */ 859 ReturnDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) Operand[0]); 860 } 861 else 862 { 863 /* 864 * This must be a reference object produced by either the Index() or 865 * RefOf() operator 866 */ 867 switch (Operand[0]->Reference.Opcode) 868 { 869 case AML_INDEX_OP: 870 871 /* 872 * The target type for the Index operator must be 873 * either a Buffer or a Package 874 */ 875 switch (Operand[0]->Reference.TargetType) 876 { 877 case ACPI_TYPE_BUFFER_FIELD: 878 879 TempDesc = Operand[0]->Reference.Object; 880 881 /* 882 * Create a new object that contains one element of the 883 * buffer -- the element pointed to by the index. 884 * 885 * NOTE: index into a buffer is NOT a pointer to a 886 * sub-buffer of the main buffer, it is only a pointer to a 887 * single element (byte) of the buffer! 888 */ 889 ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 890 if (!ReturnDesc) 891 { 892 Status = AE_NO_MEMORY; 893 goto Cleanup; 894 } 895 896 /* 897 * Since we are returning the value of the buffer at the 898 * indexed location, we don't need to add an additional 899 * reference to the buffer itself. 900 */ 901 ReturnDesc->Integer.Value = 902 TempDesc->Buffer.Pointer[Operand[0]->Reference.Offset]; 903 break; 904 905 906 case ACPI_TYPE_PACKAGE: 907 908 /* 909 * Return the referenced element of the package. We must add 910 * another reference to the referenced object, however. 911 */ 912 ReturnDesc = *(Operand[0]->Reference.Where); 913 if (!ReturnDesc) 914 { 915 /* 916 * We can't return a NULL dereferenced value. This is 917 * an uninitialized package element and is thus a 918 * severe error. 919 */ 920 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "NULL package element obj %p\n", 921 Operand[0])); 922 Status = AE_AML_UNINITIALIZED_ELEMENT; 923 goto Cleanup; 924 } 925 926 AcpiUtAddReference (ReturnDesc); 927 break; 928 929 930 default: 931 932 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Index TargetType %X in obj %p\n", 933 Operand[0]->Reference.TargetType, Operand[0])); 934 Status = AE_AML_OPERAND_TYPE; 935 goto Cleanup; 936 } 937 break; 938 939 940 case AML_REF_OF_OP: 941 942 ReturnDesc = Operand[0]->Reference.Object; 943 944 if (ACPI_GET_DESCRIPTOR_TYPE (ReturnDesc) == ACPI_DESC_TYPE_NAMED) 945 { 946 947 ReturnDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) ReturnDesc); 948 } 949 950 /* Add another reference to the object! */ 951 952 AcpiUtAddReference (ReturnDesc); 953 break; 954 955 956 default: 957 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode in ref(%p) - %X\n", 958 Operand[0], Operand[0]->Reference.Opcode)); 959 960 Status = AE_TYPE; 961 goto Cleanup; 962 } 963 } 964 break; 965 966 967 default: 968 969 ACPI_REPORT_ERROR (("AcpiExOpcode_1A_0T_1R: Unknown opcode %X\n", 970 WalkState->Opcode)); 971 Status = AE_AML_BAD_OPCODE; 972 goto Cleanup; 973 } 974 975 976Cleanup: 977 978 /* Delete return object on error */ 979 980 if (ACPI_FAILURE (Status)) 981 { 982 AcpiUtRemoveReference (ReturnDesc); 983 } 984 985 WalkState->ResultObj = ReturnDesc; 986 return_ACPI_STATUS (Status); 987} 988
| 14 * All rights reserved. 15 * 16 * 2. License 17 * 18 * 2.1. This is your license from Intel Corp. under its intellectual property 19 * rights. You may have additional license terms from the party that provided 20 * you this software, covering your right to use that party's intellectual 21 * property rights. 22 * 23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24 * copy of the source code appearing in this file ("Covered Code") an 25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26 * base code distributed originally by Intel ("Original Intel Code") to copy, 27 * make derivatives, distribute, use and display any portion of the Covered 28 * Code in any form, with the right to sublicense such rights; and 29 * 30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31 * license (with the right to sublicense), under only those claims of Intel 32 * patents that are infringed by the Original Intel Code, to make, use, sell, 33 * offer to sell, and import the Covered Code and derivative works thereof 34 * solely to the minimum extent necessary to exercise the above copyright 35 * license, and in no event shall the patent license extend to any additions 36 * to or modifications of the Original Intel Code. No other license or right 37 * is granted directly or by implication, estoppel or otherwise; 38 * 39 * The above copyright and patent license is granted only if the following 40 * conditions are met: 41 * 42 * 3. Conditions 43 * 44 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45 * Redistribution of source code of any substantial portion of the Covered 46 * Code or modification with rights to further distribute source must include 47 * the above Copyright Notice, the above License, this list of Conditions, 48 * and the following Disclaimer and Export Compliance provision. In addition, 49 * Licensee must cause all Covered Code to which Licensee contributes to 50 * contain a file documenting the changes Licensee made to create that Covered 51 * Code and the date of any change. Licensee must include in that file the 52 * documentation of any changes made by any predecessor Licensee. Licensee 53 * must include a prominent statement that the modification is derived, 54 * directly or indirectly, from Original Intel Code. 55 * 56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57 * Redistribution of source code of any substantial portion of the Covered 58 * Code or modification without rights to further distribute source must 59 * include the following Disclaimer and Export Compliance provision in the 60 * documentation and/or other materials provided with distribution. In 61 * addition, Licensee may not authorize further sublicense of source of any 62 * portion of the Covered Code, and must include terms to the effect that the 63 * license from Licensee to its licensee is limited to the intellectual 64 * property embodied in the software Licensee provides to its licensee, and 65 * not to intellectual property embodied in modifications its licensee may 66 * make. 67 * 68 * 3.3. Redistribution of Executable. Redistribution in executable form of any 69 * substantial portion of the Covered Code or modification must reproduce the 70 * above Copyright Notice, and the following Disclaimer and Export Compliance 71 * provision in the documentation and/or other materials provided with the 72 * distribution. 73 * 74 * 3.4. Intel retains all right, title, and interest in and to the Original 75 * Intel Code. 76 * 77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78 * Intel shall be used in advertising or otherwise to promote the sale, use or 79 * other dealings in products derived from or relating to the Covered Code 80 * without prior written authorization from Intel. 81 * 82 * 4. Disclaimer and Export Compliance 83 * 84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 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 __EXOPARG1_C__ 119 120#include "acpi.h" 121#include "acparser.h" 122#include "acdispat.h" 123#include "acinterp.h" 124#include "amlcode.h" 125#include "acnamesp.h" 126 127 128#define _COMPONENT ACPI_EXECUTER 129 ACPI_MODULE_NAME ("exoparg1") 130 131 132/*! 133 * Naming convention for AML interpreter execution routines. 134 * 135 * The routines that begin execution of AML opcodes are named with a common 136 * convention based upon the number of arguments, the number of target operands, 137 * and whether or not a value is returned: 138 * 139 * AcpiExOpcode_xA_yT_zR 140 * 141 * Where: 142 * 143 * xA - ARGUMENTS: The number of arguments (input operands) that are 144 * required for this opcode type (1 through 6 args). 145 * yT - TARGETS: The number of targets (output operands) that are required 146 * for this opcode type (0, 1, or 2 targets). 147 * zR - RETURN VALUE: Indicates whether this opcode type returns a value 148 * as the function return (0 or 1). 149 * 150 * The AcpiExOpcode* functions are called via the Dispatcher component with 151 * fully resolved operands. 152!*/ 153 154/******************************************************************************* 155 * 156 * FUNCTION: AcpiExOpcode_1A_0T_0R 157 * 158 * PARAMETERS: WalkState - Current state (contains AML opcode) 159 * 160 * RETURN: Status 161 * 162 * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on 163 * object stack 164 * 165 ******************************************************************************/ 166 167ACPI_STATUS 168AcpiExOpcode_1A_0T_0R ( 169 ACPI_WALK_STATE *WalkState) 170{ 171 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 172 ACPI_STATUS Status = AE_OK; 173 174 175 ACPI_FUNCTION_TRACE_STR ("ExOpcode_1A_0T_0R", AcpiPsGetOpcodeName (WalkState->Opcode)); 176 177 178 /* Examine the AML opcode */ 179 180 switch (WalkState->Opcode) 181 { 182 case AML_RELEASE_OP: /* Release (MutexObject) */ 183 184 Status = AcpiExReleaseMutex (Operand[0], WalkState); 185 break; 186 187 188 case AML_RESET_OP: /* Reset (EventObject) */ 189 190 Status = AcpiExSystemResetEvent (Operand[0]); 191 break; 192 193 194 case AML_SIGNAL_OP: /* Signal (EventObject) */ 195 196 Status = AcpiExSystemSignalEvent (Operand[0]); 197 break; 198 199 200 case AML_SLEEP_OP: /* Sleep (MsecTime) */ 201 202 Status = AcpiExSystemDoSuspend ((UINT32) Operand[0]->Integer.Value); 203 break; 204 205 206 case AML_STALL_OP: /* Stall (UsecTime) */ 207 208 Status = AcpiExSystemDoStall ((UINT32) Operand[0]->Integer.Value); 209 break; 210 211 212 case AML_UNLOAD_OP: /* Unload (Handle) */ 213 214 Status = AcpiExUnloadTable (Operand[0]); 215 break; 216 217 218 default: /* Unknown opcode */ 219 220 ACPI_REPORT_ERROR (("AcpiExOpcode_1A_0T_0R: Unknown opcode %X\n", 221 WalkState->Opcode)); 222 Status = AE_AML_BAD_OPCODE; 223 break; 224 } 225 226 return_ACPI_STATUS (Status); 227} 228 229 230/******************************************************************************* 231 * 232 * FUNCTION: AcpiExOpcode_1A_1T_0R 233 * 234 * PARAMETERS: WalkState - Current state (contains AML opcode) 235 * 236 * RETURN: Status 237 * 238 * DESCRIPTION: Execute opcode with one argument, one target, and no 239 * return value. 240 * 241 ******************************************************************************/ 242 243ACPI_STATUS 244AcpiExOpcode_1A_1T_0R ( 245 ACPI_WALK_STATE *WalkState) 246{ 247 ACPI_STATUS Status = AE_OK; 248 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 249 250 251 ACPI_FUNCTION_TRACE_STR ("ExOpcode_1A_1T_0R", AcpiPsGetOpcodeName (WalkState->Opcode)); 252 253 254 /* Examine the AML opcode */ 255 256 switch (WalkState->Opcode) 257 { 258 case AML_LOAD_OP: 259 260 Status = AcpiExLoadOp (Operand[0], Operand[1], WalkState); 261 break; 262 263 default: /* Unknown opcode */ 264 265 ACPI_REPORT_ERROR (("AcpiExOpcode_1A_1T_0R: Unknown opcode %X\n", 266 WalkState->Opcode)); 267 Status = AE_AML_BAD_OPCODE; 268 goto Cleanup; 269 } 270 271 272Cleanup: 273 274 return_ACPI_STATUS (Status); 275} 276 277 278/******************************************************************************* 279 * 280 * FUNCTION: AcpiExOpcode_1A_1T_1R 281 * 282 * PARAMETERS: WalkState - Current state (contains AML opcode) 283 * 284 * RETURN: Status 285 * 286 * DESCRIPTION: Execute opcode with one argument, one target, and a 287 * return value. 288 * 289 ******************************************************************************/ 290 291ACPI_STATUS 292AcpiExOpcode_1A_1T_1R ( 293 ACPI_WALK_STATE *WalkState) 294{ 295 ACPI_STATUS Status = AE_OK; 296 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 297 ACPI_OPERAND_OBJECT *ReturnDesc = NULL; 298 ACPI_OPERAND_OBJECT *ReturnDesc2 = NULL; 299 UINT32 Temp32; 300 UINT32 i; 301 UINT32 PowerOfTen; 302 ACPI_INTEGER Digit; 303 304 305 ACPI_FUNCTION_TRACE_STR ("ExOpcode_1A_1T_1R", AcpiPsGetOpcodeName (WalkState->Opcode)); 306 307 308 /* Examine the AML opcode */ 309 310 switch (WalkState->Opcode) 311 { 312 case AML_BIT_NOT_OP: 313 case AML_FIND_SET_LEFT_BIT_OP: 314 case AML_FIND_SET_RIGHT_BIT_OP: 315 case AML_FROM_BCD_OP: 316 case AML_TO_BCD_OP: 317 case AML_COND_REF_OF_OP: 318 319 /* Create a return object of type Integer for these opcodes */ 320 321 ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 322 if (!ReturnDesc) 323 { 324 Status = AE_NO_MEMORY; 325 goto Cleanup; 326 } 327 328 switch (WalkState->Opcode) 329 { 330 case AML_BIT_NOT_OP: /* Not (Operand, Result) */ 331 332 ReturnDesc->Integer.Value = ~Operand[0]->Integer.Value; 333 break; 334 335 336 case AML_FIND_SET_LEFT_BIT_OP: /* FindSetLeftBit (Operand, Result) */ 337 338 ReturnDesc->Integer.Value = Operand[0]->Integer.Value; 339 340 /* 341 * Acpi specification describes Integer type as a little 342 * endian unsigned value, so this boundary condition is valid. 343 */ 344 for (Temp32 = 0; ReturnDesc->Integer.Value && Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32) 345 { 346 ReturnDesc->Integer.Value >>= 1; 347 } 348 349 ReturnDesc->Integer.Value = Temp32; 350 break; 351 352 353 case AML_FIND_SET_RIGHT_BIT_OP: /* FindSetRightBit (Operand, Result) */ 354 355 ReturnDesc->Integer.Value = Operand[0]->Integer.Value; 356 357 /* 358 * The Acpi specification describes Integer type as a little 359 * endian unsigned value, so this boundary condition is valid. 360 */ 361 for (Temp32 = 0; ReturnDesc->Integer.Value && Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32) 362 { 363 ReturnDesc->Integer.Value <<= 1; 364 } 365 366 /* Since the bit position is one-based, subtract from 33 (65) */ 367 368 ReturnDesc->Integer.Value = Temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - Temp32; 369 break; 370 371 372 case AML_FROM_BCD_OP: /* FromBcd (BCDValue, Result) */ 373 374 /* 375 * The 64-bit ACPI integer can hold 16 4-bit BCD characters 376 * (if table is 32-bit, integer can hold 8 BCD characters) 377 * Convert each 4-bit BCD value 378 */ 379 PowerOfTen = 1; 380 ReturnDesc->Integer.Value = 0; 381 Digit = Operand[0]->Integer.Value; 382 383 /* Convert each BCD digit (each is one nybble wide) */ 384 385 for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++) 386 { 387 /* Get the least significant 4-bit BCD digit */ 388 389 Temp32 = ((UINT32) Digit) & 0xF; 390 391 /* Check the range of the digit */ 392 393 if (Temp32 > 9) 394 { 395 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 396 "BCD digit too large (not decimal): 0x%X\n", 397 Temp32)); 398 399 Status = AE_AML_NUMERIC_OVERFLOW; 400 goto Cleanup; 401 } 402 403 /* Sum the digit into the result with the current power of 10 */ 404 405 ReturnDesc->Integer.Value += (((ACPI_INTEGER) Temp32) * PowerOfTen); 406 407 /* Shift to next BCD digit */ 408 409 Digit >>= 4; 410 411 /* Next power of 10 */ 412 413 PowerOfTen *= 10; 414 } 415 break; 416 417 418 case AML_TO_BCD_OP: /* ToBcd (Operand, Result) */ 419 420 ReturnDesc->Integer.Value = 0; 421 Digit = Operand[0]->Integer.Value; 422 423 /* Each BCD digit is one nybble wide */ 424 425 for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++) 426 { 427 (void) AcpiUtShortDivide (&Digit, 10, &Digit, &Temp32); 428 429 /* Insert the BCD digit that resides in the remainder from above */ 430 431 ReturnDesc->Integer.Value |= (((ACPI_INTEGER) Temp32) << (i * 4)); 432 } 433 434 /* Overflow if there is any data left in Digit */ 435 436 if (Digit > 0) 437 { 438 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Integer too large to convert to BCD: %8.8X%8.8X\n", 439 ACPI_FORMAT_UINT64 (Operand[0]->Integer.Value))); 440 Status = AE_AML_NUMERIC_OVERFLOW; 441 goto Cleanup; 442 } 443 break; 444 445 446 case AML_COND_REF_OF_OP: /* CondRefOf (SourceObject, Result) */ 447 448 /* 449 * This op is a little strange because the internal return value is 450 * different than the return value stored in the result descriptor 451 * (There are really two return values) 452 */ 453 if ((ACPI_NAMESPACE_NODE *) Operand[0] == AcpiGbl_RootNode) 454 { 455 /* 456 * This means that the object does not exist in the namespace, 457 * return FALSE 458 */ 459 ReturnDesc->Integer.Value = 0; 460 goto Cleanup; 461 } 462 463 /* Get the object reference, store it, and remove our reference */ 464 465 Status = AcpiExGetObjectReference (Operand[0], &ReturnDesc2, WalkState); 466 if (ACPI_FAILURE (Status)) 467 { 468 goto Cleanup; 469 } 470 471 Status = AcpiExStore (ReturnDesc2, Operand[1], WalkState); 472 AcpiUtRemoveReference (ReturnDesc2); 473 474 /* The object exists in the namespace, return TRUE */ 475 476 ReturnDesc->Integer.Value = ACPI_INTEGER_MAX; 477 goto Cleanup; 478 479 480 default: 481 /* No other opcodes get here */ 482 break; 483 } 484 break; 485 486 487 case AML_STORE_OP: /* Store (Source, Target) */ 488 489 /* 490 * A store operand is typically a number, string, buffer or lvalue 491 * Be careful about deleting the source object, 492 * since the object itself may have been stored. 493 */ 494 Status = AcpiExStore (Operand[0], Operand[1], WalkState); 495 if (ACPI_FAILURE (Status)) 496 { 497 return_ACPI_STATUS (Status); 498 } 499 500 /* It is possible that the Store already produced a return object */ 501 502 if (!WalkState->ResultObj) 503 { 504 /* 505 * Normally, we would remove a reference on the Operand[0] parameter; 506 * But since it is being used as the internal return object 507 * (meaning we would normally increment it), the two cancel out, 508 * and we simply don't do anything. 509 */ 510 WalkState->ResultObj = Operand[0]; 511 WalkState->Operands[0] = NULL; /* Prevent deletion */ 512 } 513 return_ACPI_STATUS (Status); 514 515 516 /* 517 * ACPI 2.0 Opcodes 518 */ 519 case AML_COPY_OP: /* Copy (Source, Target) */ 520 521 Status = AcpiUtCopyIobjectToIobject (Operand[0], &ReturnDesc, WalkState); 522 break; 523 524 525 case AML_TO_DECSTRING_OP: /* ToDecimalString (Data, Result) */ 526 527 Status = AcpiExConvertToString (Operand[0], &ReturnDesc, 10, ACPI_UINT32_MAX, WalkState); 528 break; 529 530 531 case AML_TO_HEXSTRING_OP: /* ToHexString (Data, Result) */ 532 533 Status = AcpiExConvertToString (Operand[0], &ReturnDesc, 16, ACPI_UINT32_MAX, WalkState); 534 break; 535 536 537 case AML_TO_BUFFER_OP: /* ToBuffer (Data, Result) */ 538 539 Status = AcpiExConvertToBuffer (Operand[0], &ReturnDesc, WalkState); 540 break; 541 542 543 case AML_TO_INTEGER_OP: /* ToInteger (Data, Result) */ 544 545 Status = AcpiExConvertToInteger (Operand[0], &ReturnDesc, WalkState); 546 break; 547 548 549 case AML_SHIFT_LEFT_BIT_OP: /* ShiftLeftBit (Source, BitNum) */ 550 case AML_SHIFT_RIGHT_BIT_OP: /* ShiftRightBit (Source, BitNum) */ 551 552 /* 553 * These are two obsolete opcodes 554 */ 555 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s is obsolete and not implemented\n", 556 AcpiPsGetOpcodeName (WalkState->Opcode))); 557 Status = AE_SUPPORT; 558 goto Cleanup; 559 560 561 default: /* Unknown opcode */ 562 563 ACPI_REPORT_ERROR (("AcpiExOpcode_1A_1T_1R: Unknown opcode %X\n", 564 WalkState->Opcode)); 565 Status = AE_AML_BAD_OPCODE; 566 goto Cleanup; 567 } 568 569 /* 570 * Store the return value computed above into the target object 571 */ 572 Status = AcpiExStore (ReturnDesc, Operand[1], WalkState); 573 574 575Cleanup: 576 577 if (!WalkState->ResultObj) 578 { 579 WalkState->ResultObj = ReturnDesc; 580 } 581 582 /* Delete return object on error */ 583 584 if (ACPI_FAILURE (Status)) 585 { 586 AcpiUtRemoveReference (ReturnDesc); 587 } 588 589 return_ACPI_STATUS (Status); 590} 591 592 593/******************************************************************************* 594 * 595 * FUNCTION: AcpiExOpcode_1A_0T_1R 596 * 597 * PARAMETERS: WalkState - Current state (contains AML opcode) 598 * 599 * RETURN: Status 600 * 601 * DESCRIPTION: Execute opcode with one argument, no target, and a return value 602 * 603 ******************************************************************************/ 604 605ACPI_STATUS 606AcpiExOpcode_1A_0T_1R ( 607 ACPI_WALK_STATE *WalkState) 608{ 609 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 610 ACPI_OPERAND_OBJECT *TempDesc; 611 ACPI_OPERAND_OBJECT *ReturnDesc = NULL; 612 ACPI_STATUS Status = AE_OK; 613 UINT32 Type; 614 ACPI_INTEGER Value; 615 616 617 ACPI_FUNCTION_TRACE_STR ("ExOpcode_1A_0T_1R", AcpiPsGetOpcodeName (WalkState->Opcode)); 618 619 620 /* Examine the AML opcode */ 621 622 switch (WalkState->Opcode) 623 { 624 case AML_LNOT_OP: /* LNot (Operand) */ 625 626 ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 627 if (!ReturnDesc) 628 { 629 Status = AE_NO_MEMORY; 630 goto Cleanup; 631 } 632 633 ReturnDesc->Integer.Value = !Operand[0]->Integer.Value; 634 break; 635 636 637 case AML_DECREMENT_OP: /* Decrement (Operand) */ 638 case AML_INCREMENT_OP: /* Increment (Operand) */ 639 640 /* 641 * Since we are expecting a Reference operand, it 642 * can be either a NS Node or an internal object. 643 */ 644 ReturnDesc = Operand[0]; 645 if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_OPERAND) 646 { 647 /* Internal reference object - prevent deletion */ 648 649 AcpiUtAddReference (ReturnDesc); 650 } 651 652 /* 653 * Convert the ReturnDesc Reference to a Number 654 * (This removes a reference on the ReturnDesc object) 655 */ 656 Status = AcpiExResolveOperands (AML_LNOT_OP, &ReturnDesc, WalkState); 657 if (ACPI_FAILURE (Status)) 658 { 659 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s: bad operand(s) %s\n", 660 AcpiPsGetOpcodeName (WalkState->Opcode), AcpiFormatException(Status))); 661 662 goto Cleanup; 663 } 664 665 /* 666 * ReturnDesc is now guaranteed to be an Integer object 667 * Do the actual increment or decrement 668 */ 669 if (AML_INCREMENT_OP == WalkState->Opcode) 670 { 671 ReturnDesc->Integer.Value++; 672 } 673 else 674 { 675 ReturnDesc->Integer.Value--; 676 } 677 678 /* Store the result back in the original descriptor */ 679 680 Status = AcpiExStore (ReturnDesc, Operand[0], WalkState); 681 break; 682 683 684 case AML_TYPE_OP: /* ObjectType (SourceObject) */ 685 686 /* Get the type of the base object */ 687 688 Status = AcpiExResolveMultiple (WalkState, Operand[0], &Type, NULL); 689 if (ACPI_FAILURE (Status)) 690 { 691 goto Cleanup; 692 } 693 694 /* Allocate a descriptor to hold the type. */ 695 696 ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 697 if (!ReturnDesc) 698 { 699 Status = AE_NO_MEMORY; 700 goto Cleanup; 701 } 702 703 ReturnDesc->Integer.Value = Type; 704 break; 705 706 707 case AML_SIZE_OF_OP: /* SizeOf (SourceObject) */ 708 709 /* Get the base object */ 710 711 Status = AcpiExResolveMultiple (WalkState, Operand[0], &Type, &TempDesc); 712 if (ACPI_FAILURE (Status)) 713 { 714 goto Cleanup; 715 } 716 717 /* 718 * Type is guaranteed to be a buffer, string, or package at this 719 * point (even if the original operand was an object reference, it 720 * will be resolved and typechecked during operand resolution.) 721 */ 722 switch (Type) 723 { 724 case ACPI_TYPE_BUFFER: 725 Value = TempDesc->Buffer.Length; 726 break; 727 728 case ACPI_TYPE_STRING: 729 Value = TempDesc->String.Length; 730 break; 731 732 case ACPI_TYPE_PACKAGE: 733 Value = TempDesc->Package.Count; 734 break; 735 736 default: 737 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "SizeOf, Not Buf/Str/Pkg - found type %s\n", 738 AcpiUtGetTypeName (Type))); 739 Status = AE_AML_OPERAND_TYPE; 740 goto Cleanup; 741 } 742 743 /* 744 * Now that we have the size of the object, create a result 745 * object to hold the value 746 */ 747 ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 748 if (!ReturnDesc) 749 { 750 Status = AE_NO_MEMORY; 751 goto Cleanup; 752 } 753 754 ReturnDesc->Integer.Value = Value; 755 break; 756 757 758 case AML_REF_OF_OP: /* RefOf (SourceObject) */ 759 760 Status = AcpiExGetObjectReference (Operand[0], &ReturnDesc, WalkState); 761 if (ACPI_FAILURE (Status)) 762 { 763 goto Cleanup; 764 } 765 break; 766 767 768 case AML_DEREF_OF_OP: /* DerefOf (ObjReference | String) */ 769 770 /* Check for a method local or argument, or standalone String */ 771 772 if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) != ACPI_DESC_TYPE_NAMED) 773 { 774 switch (ACPI_GET_OBJECT_TYPE (Operand[0])) 775 { 776 case ACPI_TYPE_LOCAL_REFERENCE: 777 /* 778 * This is a DerefOf (LocalX | ArgX) 779 * 780 * Must resolve/dereference the local/arg reference first 781 */ 782 switch (Operand[0]->Reference.Opcode) 783 { 784 case AML_LOCAL_OP: 785 case AML_ARG_OP: 786 787 /* Set Operand[0] to the value of the local/arg */ 788 789 Status = AcpiDsMethodDataGetValue (Operand[0]->Reference.Opcode, 790 Operand[0]->Reference.Offset, WalkState, &TempDesc); 791 if (ACPI_FAILURE (Status)) 792 { 793 goto Cleanup; 794 } 795 796 /* 797 * Delete our reference to the input object and 798 * point to the object just retrieved 799 */ 800 AcpiUtRemoveReference (Operand[0]); 801 Operand[0] = TempDesc; 802 break; 803 804 case AML_REF_OF_OP: 805 806 /* Get the object to which the reference refers */ 807 808 TempDesc = Operand[0]->Reference.Object; 809 AcpiUtRemoveReference (Operand[0]); 810 Operand[0] = TempDesc; 811 break; 812 813 default: 814 815 /* Must be an Index op - handled below */ 816 break; 817 } 818 break; 819 820 821 case ACPI_TYPE_STRING: 822 823 /* 824 * This is a DerefOf (String). The string is a reference to a named ACPI object. 825 * 826 * 1) Find the owning Node 827 * 2) Dereference the node to an actual object. Could be a Field, so we nee 828 * to resolve the node to a value. 829 */ 830 Status = AcpiNsGetNodeByPath (Operand[0]->String.Pointer, 831 WalkState->ScopeInfo->Scope.Node, ACPI_NS_SEARCH_PARENT, 832 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ReturnDesc)); 833 if (ACPI_FAILURE (Status)) 834 { 835 goto Cleanup; 836 } 837 838 Status = AcpiExResolveNodeToValue ( 839 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ReturnDesc), WalkState); 840 goto Cleanup; 841 842 843 default: 844 845 Status = AE_AML_OPERAND_TYPE; 846 goto Cleanup; 847 } 848 } 849 850 /* Operand[0] may have changed from the code above */ 851 852 if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_NAMED) 853 { 854 /* 855 * This is a DerefOf (ObjectReference) 856 * Get the actual object from the Node (This is the dereference). 857 * -- This case may only happen when a LocalX or ArgX is dereferenced above. 858 */ 859 ReturnDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) Operand[0]); 860 } 861 else 862 { 863 /* 864 * This must be a reference object produced by either the Index() or 865 * RefOf() operator 866 */ 867 switch (Operand[0]->Reference.Opcode) 868 { 869 case AML_INDEX_OP: 870 871 /* 872 * The target type for the Index operator must be 873 * either a Buffer or a Package 874 */ 875 switch (Operand[0]->Reference.TargetType) 876 { 877 case ACPI_TYPE_BUFFER_FIELD: 878 879 TempDesc = Operand[0]->Reference.Object; 880 881 /* 882 * Create a new object that contains one element of the 883 * buffer -- the element pointed to by the index. 884 * 885 * NOTE: index into a buffer is NOT a pointer to a 886 * sub-buffer of the main buffer, it is only a pointer to a 887 * single element (byte) of the buffer! 888 */ 889 ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 890 if (!ReturnDesc) 891 { 892 Status = AE_NO_MEMORY; 893 goto Cleanup; 894 } 895 896 /* 897 * Since we are returning the value of the buffer at the 898 * indexed location, we don't need to add an additional 899 * reference to the buffer itself. 900 */ 901 ReturnDesc->Integer.Value = 902 TempDesc->Buffer.Pointer[Operand[0]->Reference.Offset]; 903 break; 904 905 906 case ACPI_TYPE_PACKAGE: 907 908 /* 909 * Return the referenced element of the package. We must add 910 * another reference to the referenced object, however. 911 */ 912 ReturnDesc = *(Operand[0]->Reference.Where); 913 if (!ReturnDesc) 914 { 915 /* 916 * We can't return a NULL dereferenced value. This is 917 * an uninitialized package element and is thus a 918 * severe error. 919 */ 920 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "NULL package element obj %p\n", 921 Operand[0])); 922 Status = AE_AML_UNINITIALIZED_ELEMENT; 923 goto Cleanup; 924 } 925 926 AcpiUtAddReference (ReturnDesc); 927 break; 928 929 930 default: 931 932 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Index TargetType %X in obj %p\n", 933 Operand[0]->Reference.TargetType, Operand[0])); 934 Status = AE_AML_OPERAND_TYPE; 935 goto Cleanup; 936 } 937 break; 938 939 940 case AML_REF_OF_OP: 941 942 ReturnDesc = Operand[0]->Reference.Object; 943 944 if (ACPI_GET_DESCRIPTOR_TYPE (ReturnDesc) == ACPI_DESC_TYPE_NAMED) 945 { 946 947 ReturnDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) ReturnDesc); 948 } 949 950 /* Add another reference to the object! */ 951 952 AcpiUtAddReference (ReturnDesc); 953 break; 954 955 956 default: 957 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode in ref(%p) - %X\n", 958 Operand[0], Operand[0]->Reference.Opcode)); 959 960 Status = AE_TYPE; 961 goto Cleanup; 962 } 963 } 964 break; 965 966 967 default: 968 969 ACPI_REPORT_ERROR (("AcpiExOpcode_1A_0T_1R: Unknown opcode %X\n", 970 WalkState->Opcode)); 971 Status = AE_AML_BAD_OPCODE; 972 goto Cleanup; 973 } 974 975 976Cleanup: 977 978 /* Delete return object on error */ 979 980 if (ACPI_FAILURE (Status)) 981 { 982 AcpiUtRemoveReference (ReturnDesc); 983 } 984 985 WalkState->ResultObj = ReturnDesc; 986 return_ACPI_STATUS (Status); 987} 988
|