1 /****************************************************************************** 2 * 3 * Module Name: dsopcode - Dispatcher Op Region support and handling of 4 * "control" opcodes 5 * $Revision: 1.115 $ 6 * 7 *****************************************************************************/ 8 9 /****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999 - 2008, Intel Corp. 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 __DSOPCODE_C__ 119 120 #include "acpi.h" 121 #include "acparser.h" 122 #include "amlcode.h" 123 #include "acdispat.h" 124 #include "acinterp.h" 125 #include "acnamesp.h" 126 #include "acevents.h" 127 #include "actables.h" 128 129 #define _COMPONENT ACPI_DISPATCHER 130 ACPI_MODULE_NAME ("dsopcode") 131 132 /* Local prototypes */ 133 134 static ACPI_STATUS 135 AcpiDsExecuteArguments ( 136 ACPI_NAMESPACE_NODE *Node, 137 ACPI_NAMESPACE_NODE *ScopeNode, 138 UINT32 AmlLength, 139 UINT8 *AmlStart); 140 141 static ACPI_STATUS 142 AcpiDsInitBufferField ( 143 UINT16 AmlOpcode, 144 ACPI_OPERAND_OBJECT *ObjDesc, 145 ACPI_OPERAND_OBJECT *BufferDesc, 146 ACPI_OPERAND_OBJECT *OffsetDesc, 147 ACPI_OPERAND_OBJECT *LengthDesc, 148 ACPI_OPERAND_OBJECT *ResultDesc); 149 150 151 /******************************************************************************* 152 * 153 * FUNCTION: AcpiDsExecuteArguments 154 * 155 * PARAMETERS: Node - Object NS node 156 * ScopeNode - Parent NS node 157 * AmlLength - Length of executable AML 158 * AmlStart - Pointer to the AML 159 * 160 * RETURN: Status. 161 * 162 * DESCRIPTION: Late (deferred) execution of region or field arguments 163 * 164 ******************************************************************************/ 165 166 static ACPI_STATUS 167 AcpiDsExecuteArguments ( 168 ACPI_NAMESPACE_NODE *Node, 169 ACPI_NAMESPACE_NODE *ScopeNode, 170 UINT32 AmlLength, 171 UINT8 *AmlStart) 172 { 173 ACPI_STATUS Status; 174 ACPI_PARSE_OBJECT *Op; 175 ACPI_WALK_STATE *WalkState; 176 177 178 ACPI_FUNCTION_TRACE (DsExecuteArguments); 179 180 181 /* 182 * Allocate a new parser op to be the root of the parsed tree 183 */ 184 Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP); 185 if (!Op) 186 { 187 return_ACPI_STATUS (AE_NO_MEMORY); 188 } 189 190 /* Save the Node for use in AcpiPsParseAml */ 191 192 Op->Common.Node = ScopeNode; 193 194 /* Create and initialize a new parser state */ 195 196 WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); 197 if (!WalkState) 198 { 199 Status = AE_NO_MEMORY; 200 goto Cleanup; 201 } 202 203 Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart, 204 AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); 205 if (ACPI_FAILURE (Status)) 206 { 207 AcpiDsDeleteWalkState (WalkState); 208 goto Cleanup; 209 } 210 211 /* Mark this parse as a deferred opcode */ 212 213 WalkState->ParseFlags = ACPI_PARSE_DEFERRED_OP; 214 WalkState->DeferredNode = Node; 215 216 /* Pass1: Parse the entire declaration */ 217 218 Status = AcpiPsParseAml (WalkState); 219 if (ACPI_FAILURE (Status)) 220 { 221 goto Cleanup; 222 } 223 224 /* Get and init the Op created above */ 225 226 Op->Common.Node = Node; 227 AcpiPsDeleteParseTree (Op); 228 229 /* Evaluate the deferred arguments */ 230 231 Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP); 232 if (!Op) 233 { 234 return_ACPI_STATUS (AE_NO_MEMORY); 235 } 236 237 Op->Common.Node = ScopeNode; 238 239 /* Create and initialize a new parser state */ 240 241 WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); 242 if (!WalkState) 243 { 244 Status = AE_NO_MEMORY; 245 goto Cleanup; 246 } 247 248 /* Execute the opcode and arguments */ 249 250 Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart, 251 AmlLength, NULL, ACPI_IMODE_EXECUTE); 252 if (ACPI_FAILURE (Status)) 253 { 254 AcpiDsDeleteWalkState (WalkState); 255 goto Cleanup; 256 } 257 258 /* Mark this execution as a deferred opcode */ 259 260 WalkState->DeferredNode = Node; 261 Status = AcpiPsParseAml (WalkState); 262 263 Cleanup: 264 AcpiPsDeleteParseTree (Op); 265 return_ACPI_STATUS (Status); 266 } 267 268 269 /******************************************************************************* 270 * 271 * FUNCTION: AcpiDsGetBufferFieldArguments 272 * 273 * PARAMETERS: ObjDesc - A valid BufferField object 274 * 275 * RETURN: Status. 276 * 277 * DESCRIPTION: Get BufferField Buffer and Index. This implements the late 278 * evaluation of these field attributes. 279 * 280 ******************************************************************************/ 281 282 ACPI_STATUS 283 AcpiDsGetBufferFieldArguments ( 284 ACPI_OPERAND_OBJECT *ObjDesc) 285 { 286 ACPI_OPERAND_OBJECT *ExtraDesc; 287 ACPI_NAMESPACE_NODE *Node; 288 ACPI_STATUS Status; 289 290 291 ACPI_FUNCTION_TRACE_PTR (DsGetBufferFieldArguments, ObjDesc); 292 293 294 if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) 295 { 296 return_ACPI_STATUS (AE_OK); 297 } 298 299 /* Get the AML pointer (method object) and BufferField node */ 300 301 ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc); 302 Node = ObjDesc->BufferField.Node; 303 304 ACPI_DEBUG_EXEC(AcpiUtDisplayInitPathname (ACPI_TYPE_BUFFER_FIELD, Node, NULL)); 305 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n", 306 AcpiUtGetNodeName (Node))); 307 308 /* Execute the AML code for the TermArg arguments */ 309 310 Status = AcpiDsExecuteArguments (Node, AcpiNsGetParentNode (Node), 311 ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart); 312 return_ACPI_STATUS (Status); 313 } 314 315 316 /******************************************************************************* 317 * 318 * FUNCTION: AcpiDsGetBankFieldArguments 319 * 320 * PARAMETERS: ObjDesc - A valid BankField object 321 * 322 * RETURN: Status. 323 * 324 * DESCRIPTION: Get BankField BankValue. This implements the late 325 * evaluation of these field attributes. 326 * 327 ******************************************************************************/ 328 329 ACPI_STATUS 330 AcpiDsGetBankFieldArguments ( 331 ACPI_OPERAND_OBJECT *ObjDesc) 332 { 333 ACPI_OPERAND_OBJECT *ExtraDesc; 334 ACPI_NAMESPACE_NODE *Node; 335 ACPI_STATUS Status; 336 337 338 ACPI_FUNCTION_TRACE_PTR (DsGetBankFieldArguments, ObjDesc); 339 340 341 if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) 342 { 343 return_ACPI_STATUS (AE_OK); 344 } 345 346 /* Get the AML pointer (method object) and BankField node */ 347 348 ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc); 349 Node = ObjDesc->BankField.Node; 350 351 ACPI_DEBUG_EXEC(AcpiUtDisplayInitPathname (ACPI_TYPE_LOCAL_BANK_FIELD, Node, NULL)); 352 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n", 353 AcpiUtGetNodeName (Node))); 354 355 /* Execute the AML code for the TermArg arguments */ 356 357 Status = AcpiDsExecuteArguments (Node, AcpiNsGetParentNode (Node), 358 ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart); 359 return_ACPI_STATUS (Status); 360 } 361 362 363 /******************************************************************************* 364 * 365 * FUNCTION: AcpiDsGetBufferArguments 366 * 367 * PARAMETERS: ObjDesc - A valid Buffer object 368 * 369 * RETURN: Status. 370 * 371 * DESCRIPTION: Get Buffer length and initializer byte list. This implements 372 * the late evaluation of these attributes. 373 * 374 ******************************************************************************/ 375 376 ACPI_STATUS 377 AcpiDsGetBufferArguments ( 378 ACPI_OPERAND_OBJECT *ObjDesc) 379 { 380 ACPI_NAMESPACE_NODE *Node; 381 ACPI_STATUS Status; 382 383 384 ACPI_FUNCTION_TRACE_PTR (DsGetBufferArguments, ObjDesc); 385 386 387 if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) 388 { 389 return_ACPI_STATUS (AE_OK); 390 } 391 392 /* Get the Buffer node */ 393 394 Node = ObjDesc->Buffer.Node; 395 if (!Node) 396 { 397 ACPI_ERROR ((AE_INFO, 398 "No pointer back to NS node in buffer obj %p", ObjDesc)); 399 return_ACPI_STATUS (AE_AML_INTERNAL); 400 } 401 402 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n")); 403 404 /* Execute the AML code for the TermArg arguments */ 405 406 Status = AcpiDsExecuteArguments (Node, Node, 407 ObjDesc->Buffer.AmlLength, ObjDesc->Buffer.AmlStart); 408 return_ACPI_STATUS (Status); 409 } 410 411 412 /******************************************************************************* 413 * 414 * FUNCTION: AcpiDsGetPackageArguments 415 * 416 * PARAMETERS: ObjDesc - A valid Package object 417 * 418 * RETURN: Status. 419 * 420 * DESCRIPTION: Get Package length and initializer byte list. This implements 421 * the late evaluation of these attributes. 422 * 423 ******************************************************************************/ 424 425 ACPI_STATUS 426 AcpiDsGetPackageArguments ( 427 ACPI_OPERAND_OBJECT *ObjDesc) 428 { 429 ACPI_NAMESPACE_NODE *Node; 430 ACPI_STATUS Status; 431 432 433 ACPI_FUNCTION_TRACE_PTR (DsGetPackageArguments, ObjDesc); 434 435 436 if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) 437 { 438 return_ACPI_STATUS (AE_OK); 439 } 440 441 /* Get the Package node */ 442 443 Node = ObjDesc->Package.Node; 444 if (!Node) 445 { 446 ACPI_ERROR ((AE_INFO, 447 "No pointer back to NS node in package %p", ObjDesc)); 448 return_ACPI_STATUS (AE_AML_INTERNAL); 449 } 450 451 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Arg Init\n")); 452 453 /* Execute the AML code for the TermArg arguments */ 454 455 Status = AcpiDsExecuteArguments (Node, Node, 456 ObjDesc->Package.AmlLength, ObjDesc->Package.AmlStart); 457 return_ACPI_STATUS (Status); 458 } 459 460 461 /***************************************************************************** 462 * 463 * FUNCTION: AcpiDsGetRegionArguments 464 * 465 * PARAMETERS: ObjDesc - A valid region object 466 * 467 * RETURN: Status. 468 * 469 * DESCRIPTION: Get region address and length. This implements the late 470 * evaluation of these region attributes. 471 * 472 ****************************************************************************/ 473 474 ACPI_STATUS 475 AcpiDsGetRegionArguments ( 476 ACPI_OPERAND_OBJECT *ObjDesc) 477 { 478 ACPI_NAMESPACE_NODE *Node; 479 ACPI_STATUS Status; 480 ACPI_OPERAND_OBJECT *ExtraDesc; 481 482 483 ACPI_FUNCTION_TRACE_PTR (DsGetRegionArguments, ObjDesc); 484 485 486 if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID) 487 { 488 return_ACPI_STATUS (AE_OK); 489 } 490 491 ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc); 492 if (!ExtraDesc) 493 { 494 return_ACPI_STATUS (AE_NOT_EXIST); 495 } 496 497 /* Get the Region node */ 498 499 Node = ObjDesc->Region.Node; 500 501 ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_REGION, Node, NULL)); 502 503 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n", 504 AcpiUtGetNodeName (Node), ExtraDesc->Extra.AmlStart)); 505 506 /* Execute the argument AML */ 507 508 Status = AcpiDsExecuteArguments (Node, AcpiNsGetParentNode (Node), 509 ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart); 510 if (ACPI_FAILURE (Status)) 511 { 512 return_ACPI_STATUS (Status); 513 } 514 515 /* Validate the region address/length via the host OS */ 516 517 Status = AcpiOsValidateAddress (ObjDesc->Region.SpaceId, 518 ObjDesc->Region.Address, (ACPI_SIZE) ObjDesc->Region.Length); 519 if (ACPI_FAILURE (Status)) 520 { 521 /* 522 * Invalid address/length. We will emit an error message and mark 523 * the region as invalid, so that it will cause an additional error if 524 * it is ever used. Then return AE_OK. 525 */ 526 ACPI_EXCEPTION ((AE_INFO, Status, 527 "During address validation of OpRegion [%4.4s]", Node->Name.Ascii)); 528 ObjDesc->Common.Flags |= AOPOBJ_INVALID; 529 Status = AE_OK; 530 } 531 532 return_ACPI_STATUS (Status); 533 } 534 535 536 /******************************************************************************* 537 * 538 * FUNCTION: AcpiDsInitializeRegion 539 * 540 * PARAMETERS: ObjHandle - Region namespace node 541 * 542 * RETURN: Status 543 * 544 * DESCRIPTION: Front end to EvInitializeRegion 545 * 546 ******************************************************************************/ 547 548 ACPI_STATUS 549 AcpiDsInitializeRegion ( 550 ACPI_HANDLE ObjHandle) 551 { 552 ACPI_OPERAND_OBJECT *ObjDesc; 553 ACPI_STATUS Status; 554 555 556 ObjDesc = AcpiNsGetAttachedObject (ObjHandle); 557 558 /* Namespace is NOT locked */ 559 560 Status = AcpiEvInitializeRegion (ObjDesc, FALSE); 561 return (Status); 562 } 563 564 565 /******************************************************************************* 566 * 567 * FUNCTION: AcpiDsInitBufferField 568 * 569 * PARAMETERS: AmlOpcode - CreateXxxField 570 * ObjDesc - BufferField object 571 * BufferDesc - Host Buffer 572 * OffsetDesc - Offset into buffer 573 * LengthDesc - Length of field (CREATE_FIELD_OP only) 574 * ResultDesc - Where to store the result 575 * 576 * RETURN: Status 577 * 578 * DESCRIPTION: Perform actual initialization of a buffer field 579 * 580 ******************************************************************************/ 581 582 static ACPI_STATUS 583 AcpiDsInitBufferField ( 584 UINT16 AmlOpcode, 585 ACPI_OPERAND_OBJECT *ObjDesc, 586 ACPI_OPERAND_OBJECT *BufferDesc, 587 ACPI_OPERAND_OBJECT *OffsetDesc, 588 ACPI_OPERAND_OBJECT *LengthDesc, 589 ACPI_OPERAND_OBJECT *ResultDesc) 590 { 591 UINT32 Offset; 592 UINT32 BitOffset; 593 UINT32 BitCount; 594 UINT8 FieldFlags; 595 ACPI_STATUS Status; 596 597 598 ACPI_FUNCTION_TRACE_PTR (DsInitBufferField, ObjDesc); 599 600 601 /* Host object must be a Buffer */ 602 603 if (ACPI_GET_OBJECT_TYPE (BufferDesc) != ACPI_TYPE_BUFFER) 604 { 605 ACPI_ERROR ((AE_INFO, 606 "Target of Create Field is not a Buffer object - %s", 607 AcpiUtGetObjectTypeName (BufferDesc))); 608 609 Status = AE_AML_OPERAND_TYPE; 610 goto Cleanup; 611 } 612 613 /* 614 * The last parameter to all of these opcodes (ResultDesc) started 615 * out as a NameString, and should therefore now be a NS node 616 * after resolution in AcpiExResolveOperands(). 617 */ 618 if (ACPI_GET_DESCRIPTOR_TYPE (ResultDesc) != ACPI_DESC_TYPE_NAMED) 619 { 620 ACPI_ERROR ((AE_INFO, 621 "(%s) destination not a NS Node [%s]", 622 AcpiPsGetOpcodeName (AmlOpcode), 623 AcpiUtGetDescriptorName (ResultDesc))); 624 625 Status = AE_AML_OPERAND_TYPE; 626 goto Cleanup; 627 } 628 629 Offset = (UINT32) OffsetDesc->Integer.Value; 630 631 /* 632 * Setup the Bit offsets and counts, according to the opcode 633 */ 634 switch (AmlOpcode) 635 { 636 case AML_CREATE_FIELD_OP: 637 638 /* Offset is in bits, count is in bits */ 639 640 FieldFlags = AML_FIELD_ACCESS_BYTE; 641 BitOffset = Offset; 642 BitCount = (UINT32) LengthDesc->Integer.Value; 643 644 /* Must have a valid (>0) bit count */ 645 646 if (BitCount == 0) 647 { 648 ACPI_ERROR ((AE_INFO, 649 "Attempt to CreateField of length zero")); 650 Status = AE_AML_OPERAND_VALUE; 651 goto Cleanup; 652 } 653 break; 654 655 case AML_CREATE_BIT_FIELD_OP: 656 657 /* Offset is in bits, Field is one bit */ 658 659 BitOffset = Offset; 660 BitCount = 1; 661 FieldFlags = AML_FIELD_ACCESS_BYTE; 662 break; 663 664 case AML_CREATE_BYTE_FIELD_OP: 665 666 /* Offset is in bytes, field is one byte */ 667 668 BitOffset = 8 * Offset; 669 BitCount = 8; 670 FieldFlags = AML_FIELD_ACCESS_BYTE; 671 break; 672 673 case AML_CREATE_WORD_FIELD_OP: 674 675 /* Offset is in bytes, field is one word */ 676 677 BitOffset = 8 * Offset; 678 BitCount = 16; 679 FieldFlags = AML_FIELD_ACCESS_WORD; 680 break; 681 682 case AML_CREATE_DWORD_FIELD_OP: 683 684 /* Offset is in bytes, field is one dword */ 685 686 BitOffset = 8 * Offset; 687 BitCount = 32; 688 FieldFlags = AML_FIELD_ACCESS_DWORD; 689 break; 690 691 case AML_CREATE_QWORD_FIELD_OP: 692 693 /* Offset is in bytes, field is one qword */ 694 695 BitOffset = 8 * Offset; 696 BitCount = 64; 697 FieldFlags = AML_FIELD_ACCESS_QWORD; 698 break; 699 700 default: 701 702 ACPI_ERROR ((AE_INFO, 703 "Unknown field creation opcode %02x", 704 AmlOpcode)); 705 Status = AE_AML_BAD_OPCODE; 706 goto Cleanup; 707 } 708 709 /* Entire field must fit within the current length of the buffer */ 710 711 if ((BitOffset + BitCount) > 712 (8 * (UINT32) BufferDesc->Buffer.Length)) 713 { 714 ACPI_ERROR ((AE_INFO, 715 "Field [%4.4s] at %d exceeds Buffer [%4.4s] size %d (bits)", 716 AcpiUtGetNodeName (ResultDesc), 717 BitOffset + BitCount, 718 AcpiUtGetNodeName (BufferDesc->Buffer.Node), 719 8 * (UINT32) BufferDesc->Buffer.Length)); 720 Status = AE_AML_BUFFER_LIMIT; 721 goto Cleanup; 722 } 723 724 /* 725 * Initialize areas of the field object that are common to all fields 726 * For FieldFlags, use LOCK_RULE = 0 (NO_LOCK), 727 * UPDATE_RULE = 0 (UPDATE_PRESERVE) 728 */ 729 Status = AcpiExPrepCommonFieldObject (ObjDesc, FieldFlags, 0, 730 BitOffset, BitCount); 731 if (ACPI_FAILURE (Status)) 732 { 733 goto Cleanup; 734 } 735 736 ObjDesc->BufferField.BufferObj = BufferDesc; 737 738 /* Reference count for BufferDesc inherits ObjDesc count */ 739 740 BufferDesc->Common.ReferenceCount = (UINT16) 741 (BufferDesc->Common.ReferenceCount + ObjDesc->Common.ReferenceCount); 742 743 744 Cleanup: 745 746 /* Always delete the operands */ 747 748 AcpiUtRemoveReference (OffsetDesc); 749 AcpiUtRemoveReference (BufferDesc); 750 751 if (AmlOpcode == AML_CREATE_FIELD_OP) 752 { 753 AcpiUtRemoveReference (LengthDesc); 754 } 755 756 /* On failure, delete the result descriptor */ 757 758 if (ACPI_FAILURE (Status)) 759 { 760 AcpiUtRemoveReference (ResultDesc); /* Result descriptor */ 761 } 762 else 763 { 764 /* Now the address and length are valid for this BufferField */ 765 766 ObjDesc->BufferField.Flags |= AOPOBJ_DATA_VALID; 767 } 768 769 return_ACPI_STATUS (Status); 770 } 771 772 773 /******************************************************************************* 774 * 775 * FUNCTION: AcpiDsEvalBufferFieldOperands 776 * 777 * PARAMETERS: WalkState - Current walk 778 * Op - A valid BufferField Op object 779 * 780 * RETURN: Status 781 * 782 * DESCRIPTION: Get BufferField Buffer and Index 783 * Called from AcpiDsExecEndOp during BufferField parse tree walk 784 * 785 ******************************************************************************/ 786 787 ACPI_STATUS 788 AcpiDsEvalBufferFieldOperands ( 789 ACPI_WALK_STATE *WalkState, 790 ACPI_PARSE_OBJECT *Op) 791 { 792 ACPI_STATUS Status; 793 ACPI_OPERAND_OBJECT *ObjDesc; 794 ACPI_NAMESPACE_NODE *Node; 795 ACPI_PARSE_OBJECT *NextOp; 796 797 798 ACPI_FUNCTION_TRACE_PTR (DsEvalBufferFieldOperands, Op); 799 800 801 /* 802 * This is where we evaluate the address and length fields of the 803 * CreateXxxField declaration 804 */ 805 Node = Op->Common.Node; 806 807 /* NextOp points to the op that holds the Buffer */ 808 809 NextOp = Op->Common.Value.Arg; 810 811 /* Evaluate/create the address and length operands */ 812 813 Status = AcpiDsCreateOperands (WalkState, NextOp); 814 if (ACPI_FAILURE (Status)) 815 { 816 return_ACPI_STATUS (Status); 817 } 818 819 ObjDesc = AcpiNsGetAttachedObject (Node); 820 if (!ObjDesc) 821 { 822 return_ACPI_STATUS (AE_NOT_EXIST); 823 } 824 825 /* Resolve the operands */ 826 827 Status = AcpiExResolveOperands (Op->Common.AmlOpcode, 828 ACPI_WALK_OPERANDS, WalkState); 829 if (ACPI_FAILURE (Status)) 830 { 831 ACPI_ERROR ((AE_INFO, "(%s) bad operand(s) (%X)", 832 AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status)); 833 834 return_ACPI_STATUS (Status); 835 } 836 837 /* Initialize the Buffer Field */ 838 839 if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP) 840 { 841 /* NOTE: Slightly different operands for this opcode */ 842 843 Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc, 844 WalkState->Operands[0], WalkState->Operands[1], 845 WalkState->Operands[2], WalkState->Operands[3]); 846 } 847 else 848 { 849 /* All other, CreateXxxField opcodes */ 850 851 Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc, 852 WalkState->Operands[0], WalkState->Operands[1], 853 NULL, WalkState->Operands[2]); 854 } 855 856 return_ACPI_STATUS (Status); 857 } 858 859 860 /******************************************************************************* 861 * 862 * FUNCTION: AcpiDsEvalRegionOperands 863 * 864 * PARAMETERS: WalkState - Current walk 865 * Op - A valid region Op object 866 * 867 * RETURN: Status 868 * 869 * DESCRIPTION: Get region address and length 870 * Called from AcpiDsExecEndOp during OpRegion parse tree walk 871 * 872 ******************************************************************************/ 873 874 ACPI_STATUS 875 AcpiDsEvalRegionOperands ( 876 ACPI_WALK_STATE *WalkState, 877 ACPI_PARSE_OBJECT *Op) 878 { 879 ACPI_STATUS Status; 880 ACPI_OPERAND_OBJECT *ObjDesc; 881 ACPI_OPERAND_OBJECT *OperandDesc; 882 ACPI_NAMESPACE_NODE *Node; 883 ACPI_PARSE_OBJECT *NextOp; 884 885 886 ACPI_FUNCTION_TRACE_PTR (DsEvalRegionOperands, Op); 887 888 889 /* 890 * This is where we evaluate the address and length fields of the 891 * OpRegion declaration 892 */ 893 Node = Op->Common.Node; 894 895 /* NextOp points to the op that holds the SpaceID */ 896 897 NextOp = Op->Common.Value.Arg; 898 899 /* NextOp points to address op */ 900 901 NextOp = NextOp->Common.Next; 902 903 /* Evaluate/create the address and length operands */ 904 905 Status = AcpiDsCreateOperands (WalkState, NextOp); 906 if (ACPI_FAILURE (Status)) 907 { 908 return_ACPI_STATUS (Status); 909 } 910 911 /* Resolve the length and address operands to numbers */ 912 913 Status = AcpiExResolveOperands (Op->Common.AmlOpcode, 914 ACPI_WALK_OPERANDS, WalkState); 915 if (ACPI_FAILURE (Status)) 916 { 917 return_ACPI_STATUS (Status); 918 } 919 920 ObjDesc = AcpiNsGetAttachedObject (Node); 921 if (!ObjDesc) 922 { 923 return_ACPI_STATUS (AE_NOT_EXIST); 924 } 925 926 /* 927 * Get the length operand and save it 928 * (at Top of stack) 929 */ 930 OperandDesc = WalkState->Operands[WalkState->NumOperands - 1]; 931 932 ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value; 933 AcpiUtRemoveReference (OperandDesc); 934 935 /* 936 * Get the address and save it 937 * (at top of stack - 1) 938 */ 939 OperandDesc = WalkState->Operands[WalkState->NumOperands - 2]; 940 941 ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS) 942 OperandDesc->Integer.Value; 943 AcpiUtRemoveReference (OperandDesc); 944 945 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", 946 ObjDesc, 947 ACPI_FORMAT_NATIVE_UINT (ObjDesc->Region.Address), 948 ObjDesc->Region.Length)); 949 950 /* Now the address and length are valid for this opregion */ 951 952 ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID; 953 954 return_ACPI_STATUS (Status); 955 } 956 957 958 /******************************************************************************* 959 * 960 * FUNCTION: AcpiDsEvalTableRegionOperands 961 * 962 * PARAMETERS: WalkState - Current walk 963 * Op - A valid region Op object 964 * 965 * RETURN: Status 966 * 967 * DESCRIPTION: Get region address and length 968 * Called from AcpiDsExecEndOp during DataTableRegion parse tree walk 969 * 970 ******************************************************************************/ 971 972 ACPI_STATUS 973 AcpiDsEvalTableRegionOperands ( 974 ACPI_WALK_STATE *WalkState, 975 ACPI_PARSE_OBJECT *Op) 976 { 977 ACPI_STATUS Status; 978 ACPI_OPERAND_OBJECT *ObjDesc; 979 ACPI_OPERAND_OBJECT **Operand; 980 ACPI_NAMESPACE_NODE *Node; 981 ACPI_PARSE_OBJECT *NextOp; 982 UINT32 TableIndex; 983 ACPI_TABLE_HEADER *Table; 984 985 986 ACPI_FUNCTION_TRACE_PTR (DsEvalTableRegionOperands, Op); 987 988 989 /* 990 * This is where we evaluate the SignatureString and OemIDString 991 * and OemTableIDString of the DataTableRegion declaration 992 */ 993 Node = Op->Common.Node; 994 995 /* NextOp points to SignatureString op */ 996 997 NextOp = Op->Common.Value.Arg; 998 999 /* 1000 * Evaluate/create the SignatureString and OemIDString 1001 * and OemTableIDString operands 1002 */ 1003 Status = AcpiDsCreateOperands (WalkState, NextOp); 1004 if (ACPI_FAILURE (Status)) 1005 { 1006 return_ACPI_STATUS (Status); 1007 } 1008 1009 /* 1010 * Resolve the SignatureString and OemIDString 1011 * and OemTableIDString operands 1012 */ 1013 Status = AcpiExResolveOperands (Op->Common.AmlOpcode, 1014 ACPI_WALK_OPERANDS, WalkState); 1015 if (ACPI_FAILURE (Status)) 1016 { 1017 return_ACPI_STATUS (Status); 1018 } 1019 1020 Operand = &WalkState->Operands[0]; 1021 1022 /* Find the ACPI table */ 1023 1024 Status = AcpiTbFindTable (Operand[0]->String.Pointer, 1025 Operand[1]->String.Pointer, Operand[2]->String.Pointer, 1026 &TableIndex); 1027 if (ACPI_FAILURE (Status)) 1028 { 1029 return_ACPI_STATUS (Status); 1030 } 1031 1032 AcpiUtRemoveReference (Operand[0]); 1033 AcpiUtRemoveReference (Operand[1]); 1034 AcpiUtRemoveReference (Operand[2]); 1035 1036 Status = AcpiGetTableByIndex (TableIndex, &Table); 1037 if (ACPI_FAILURE (Status)) 1038 { 1039 return_ACPI_STATUS (Status); 1040 } 1041 1042 ObjDesc = AcpiNsGetAttachedObject (Node); 1043 if (!ObjDesc) 1044 { 1045 return_ACPI_STATUS (AE_NOT_EXIST); 1046 } 1047 1048 ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS) ACPI_TO_INTEGER (Table); 1049 ObjDesc->Region.Length = Table->Length; 1050 1051 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", 1052 ObjDesc, 1053 ACPI_FORMAT_NATIVE_UINT (ObjDesc->Region.Address), 1054 ObjDesc->Region.Length)); 1055 1056 /* Now the address and length are valid for this opregion */ 1057 1058 ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID; 1059 1060 return_ACPI_STATUS (Status); 1061 } 1062 1063 1064 /******************************************************************************* 1065 * 1066 * FUNCTION: AcpiDsEvalDataObjectOperands 1067 * 1068 * PARAMETERS: WalkState - Current walk 1069 * Op - A valid DataObject Op object 1070 * ObjDesc - DataObject 1071 * 1072 * RETURN: Status 1073 * 1074 * DESCRIPTION: Get the operands and complete the following data object types: 1075 * Buffer, Package. 1076 * 1077 ******************************************************************************/ 1078 1079 ACPI_STATUS 1080 AcpiDsEvalDataObjectOperands ( 1081 ACPI_WALK_STATE *WalkState, 1082 ACPI_PARSE_OBJECT *Op, 1083 ACPI_OPERAND_OBJECT *ObjDesc) 1084 { 1085 ACPI_STATUS Status; 1086 ACPI_OPERAND_OBJECT *ArgDesc; 1087 UINT32 Length; 1088 1089 1090 ACPI_FUNCTION_TRACE (DsEvalDataObjectOperands); 1091 1092 1093 /* The first operand (for all of these data objects) is the length */ 1094 1095 /* 1096 * Set proper index into operand stack for AcpiDsObjStackPush 1097 * invoked inside AcpiDsCreateOperand. 1098 */ 1099 WalkState->OperandIndex = WalkState->NumOperands; 1100 1101 Status = AcpiDsCreateOperand (WalkState, Op->Common.Value.Arg, 1); 1102 if (ACPI_FAILURE (Status)) 1103 { 1104 return_ACPI_STATUS (Status); 1105 } 1106 1107 Status = AcpiExResolveOperands (WalkState->Opcode, 1108 &(WalkState->Operands [WalkState->NumOperands -1]), 1109 WalkState); 1110 if (ACPI_FAILURE (Status)) 1111 { 1112 return_ACPI_STATUS (Status); 1113 } 1114 1115 /* Extract length operand */ 1116 1117 ArgDesc = WalkState->Operands [WalkState->NumOperands - 1]; 1118 Length = (UINT32) ArgDesc->Integer.Value; 1119 1120 /* Cleanup for length operand */ 1121 1122 Status = AcpiDsObjStackPop (1, WalkState); 1123 if (ACPI_FAILURE (Status)) 1124 { 1125 return_ACPI_STATUS (Status); 1126 } 1127 1128 AcpiUtRemoveReference (ArgDesc); 1129 1130 /* 1131 * Create the actual data object 1132 */ 1133 switch (Op->Common.AmlOpcode) 1134 { 1135 case AML_BUFFER_OP: 1136 1137 Status = AcpiDsBuildInternalBufferObj (WalkState, Op, Length, &ObjDesc); 1138 break; 1139 1140 case AML_PACKAGE_OP: 1141 case AML_VAR_PACKAGE_OP: 1142 1143 Status = AcpiDsBuildInternalPackageObj (WalkState, Op, Length, &ObjDesc); 1144 break; 1145 1146 default: 1147 return_ACPI_STATUS (AE_AML_BAD_OPCODE); 1148 } 1149 1150 if (ACPI_SUCCESS (Status)) 1151 { 1152 /* 1153 * Return the object in the WalkState, unless the parent is a package - 1154 * in this case, the return object will be stored in the parse tree 1155 * for the package. 1156 */ 1157 if ((!Op->Common.Parent) || 1158 ((Op->Common.Parent->Common.AmlOpcode != AML_PACKAGE_OP) && 1159 (Op->Common.Parent->Common.AmlOpcode != AML_VAR_PACKAGE_OP) && 1160 (Op->Common.Parent->Common.AmlOpcode != AML_NAME_OP))) 1161 { 1162 WalkState->ResultObj = ObjDesc; 1163 } 1164 } 1165 1166 return_ACPI_STATUS (Status); 1167 } 1168 1169 1170 /******************************************************************************* 1171 * 1172 * FUNCTION: AcpiDsEvalBankFieldOperands 1173 * 1174 * PARAMETERS: WalkState - Current walk 1175 * Op - A valid BankField Op object 1176 * 1177 * RETURN: Status 1178 * 1179 * DESCRIPTION: Get BankField BankValue 1180 * Called from AcpiDsExecEndOp during BankField parse tree walk 1181 * 1182 ******************************************************************************/ 1183 1184 ACPI_STATUS 1185 AcpiDsEvalBankFieldOperands ( 1186 ACPI_WALK_STATE *WalkState, 1187 ACPI_PARSE_OBJECT *Op) 1188 { 1189 ACPI_STATUS Status; 1190 ACPI_OPERAND_OBJECT *ObjDesc; 1191 ACPI_OPERAND_OBJECT *OperandDesc; 1192 ACPI_NAMESPACE_NODE *Node; 1193 ACPI_PARSE_OBJECT *NextOp; 1194 ACPI_PARSE_OBJECT *Arg; 1195 1196 1197 ACPI_FUNCTION_TRACE_PTR (DsEvalBankFieldOperands, Op); 1198 1199 1200 /* 1201 * This is where we evaluate the BankValue field of the 1202 * BankField declaration 1203 */ 1204 1205 /* NextOp points to the op that holds the Region */ 1206 1207 NextOp = Op->Common.Value.Arg; 1208 1209 /* NextOp points to the op that holds the Bank Register */ 1210 1211 NextOp = NextOp->Common.Next; 1212 1213 /* NextOp points to the op that holds the Bank Value */ 1214 1215 NextOp = NextOp->Common.Next; 1216 1217 /* 1218 * Set proper index into operand stack for AcpiDsObjStackPush 1219 * invoked inside AcpiDsCreateOperand. 1220 * 1221 * We use WalkState->Operands[0] to store the evaluated BankValue 1222 */ 1223 WalkState->OperandIndex = 0; 1224 1225 Status = AcpiDsCreateOperand (WalkState, NextOp, 0); 1226 if (ACPI_FAILURE (Status)) 1227 { 1228 return_ACPI_STATUS (Status); 1229 } 1230 1231 Status = AcpiExResolveToValue (&WalkState->Operands[0], WalkState); 1232 if (ACPI_FAILURE (Status)) 1233 { 1234 return_ACPI_STATUS (Status); 1235 } 1236 1237 ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, 1238 AcpiPsGetOpcodeName (Op->Common.AmlOpcode), 1); 1239 /* 1240 * Get the BankValue operand and save it 1241 * (at Top of stack) 1242 */ 1243 OperandDesc = WalkState->Operands[0]; 1244 1245 /* Arg points to the start Bank Field */ 1246 1247 Arg = AcpiPsGetArg (Op, 4); 1248 while (Arg) 1249 { 1250 /* Ignore OFFSET and ACCESSAS terms here */ 1251 1252 if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP) 1253 { 1254 Node = Arg->Common.Node; 1255 1256 ObjDesc = AcpiNsGetAttachedObject (Node); 1257 if (!ObjDesc) 1258 { 1259 return_ACPI_STATUS (AE_NOT_EXIST); 1260 } 1261 1262 ObjDesc->BankField.Value = (UINT32) OperandDesc->Integer.Value; 1263 } 1264 1265 /* Move to next field in the list */ 1266 1267 Arg = Arg->Common.Next; 1268 } 1269 1270 AcpiUtRemoveReference (OperandDesc); 1271 return_ACPI_STATUS (Status); 1272 } 1273 1274 1275 /******************************************************************************* 1276 * 1277 * FUNCTION: AcpiDsExecBeginControlOp 1278 * 1279 * PARAMETERS: WalkList - The list that owns the walk stack 1280 * Op - The control Op 1281 * 1282 * RETURN: Status 1283 * 1284 * DESCRIPTION: Handles all control ops encountered during control method 1285 * execution. 1286 * 1287 ******************************************************************************/ 1288 1289 ACPI_STATUS 1290 AcpiDsExecBeginControlOp ( 1291 ACPI_WALK_STATE *WalkState, 1292 ACPI_PARSE_OBJECT *Op) 1293 { 1294 ACPI_STATUS Status = AE_OK; 1295 ACPI_GENERIC_STATE *ControlState; 1296 1297 1298 ACPI_FUNCTION_NAME (DsExecBeginControlOp); 1299 1300 1301 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", Op, 1302 Op->Common.AmlOpcode, WalkState)); 1303 1304 switch (Op->Common.AmlOpcode) 1305 { 1306 case AML_IF_OP: 1307 case AML_WHILE_OP: 1308 1309 /* 1310 * IF/WHILE: Create a new control state to manage these 1311 * constructs. We need to manage these as a stack, in order 1312 * to handle nesting. 1313 */ 1314 ControlState = AcpiUtCreateControlState (); 1315 if (!ControlState) 1316 { 1317 Status = AE_NO_MEMORY; 1318 break; 1319 } 1320 /* 1321 * Save a pointer to the predicate for multiple executions 1322 * of a loop 1323 */ 1324 ControlState->Control.AmlPredicateStart = WalkState->ParserState.Aml - 1; 1325 ControlState->Control.PackageEnd = WalkState->ParserState.PkgEnd; 1326 ControlState->Control.Opcode = Op->Common.AmlOpcode; 1327 1328 1329 /* Push the control state on this walk's control stack */ 1330 1331 AcpiUtPushGenericState (&WalkState->ControlState, ControlState); 1332 break; 1333 1334 case AML_ELSE_OP: 1335 1336 /* Predicate is in the state object */ 1337 /* If predicate is true, the IF was executed, ignore ELSE part */ 1338 1339 if (WalkState->LastPredicate) 1340 { 1341 Status = AE_CTRL_TRUE; 1342 } 1343 1344 break; 1345 1346 case AML_RETURN_OP: 1347 1348 break; 1349 1350 default: 1351 break; 1352 } 1353 1354 return (Status); 1355 } 1356 1357 1358 /******************************************************************************* 1359 * 1360 * FUNCTION: AcpiDsExecEndControlOp 1361 * 1362 * PARAMETERS: WalkList - The list that owns the walk stack 1363 * Op - The control Op 1364 * 1365 * RETURN: Status 1366 * 1367 * DESCRIPTION: Handles all control ops encountered during control method 1368 * execution. 1369 * 1370 ******************************************************************************/ 1371 1372 ACPI_STATUS 1373 AcpiDsExecEndControlOp ( 1374 ACPI_WALK_STATE *WalkState, 1375 ACPI_PARSE_OBJECT *Op) 1376 { 1377 ACPI_STATUS Status = AE_OK; 1378 ACPI_GENERIC_STATE *ControlState; 1379 1380 1381 ACPI_FUNCTION_NAME (DsExecEndControlOp); 1382 1383 1384 switch (Op->Common.AmlOpcode) 1385 { 1386 case AML_IF_OP: 1387 1388 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", Op)); 1389 1390 /* 1391 * Save the result of the predicate in case there is an 1392 * ELSE to come 1393 */ 1394 WalkState->LastPredicate = 1395 (BOOLEAN) WalkState->ControlState->Common.Value; 1396 1397 /* 1398 * Pop the control state that was created at the start 1399 * of the IF and free it 1400 */ 1401 ControlState = AcpiUtPopGenericState (&WalkState->ControlState); 1402 AcpiUtDeleteGenericState (ControlState); 1403 break; 1404 1405 1406 case AML_ELSE_OP: 1407 1408 break; 1409 1410 1411 case AML_WHILE_OP: 1412 1413 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", Op)); 1414 1415 if (WalkState->ControlState->Common.Value) 1416 { 1417 /* Predicate was true, go back and evaluate it again! */ 1418 1419 Status = AE_CTRL_PENDING; 1420 } 1421 1422 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 1423 "[WHILE_OP] termination! Op=%p\n",Op)); 1424 1425 /* Pop this control state and free it */ 1426 1427 ControlState = AcpiUtPopGenericState (&WalkState->ControlState); 1428 1429 WalkState->AmlLastWhile = ControlState->Control.AmlPredicateStart; 1430 AcpiUtDeleteGenericState (ControlState); 1431 break; 1432 1433 1434 case AML_RETURN_OP: 1435 1436 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 1437 "[RETURN_OP] Op=%p Arg=%p\n",Op, Op->Common.Value.Arg)); 1438 1439 /* 1440 * One optional operand -- the return value 1441 * It can be either an immediate operand or a result that 1442 * has been bubbled up the tree 1443 */ 1444 if (Op->Common.Value.Arg) 1445 { 1446 /* Since we have a real Return(), delete any implicit return */ 1447 1448 AcpiDsClearImplicitReturn (WalkState); 1449 1450 /* Return statement has an immediate operand */ 1451 1452 Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg); 1453 if (ACPI_FAILURE (Status)) 1454 { 1455 return (Status); 1456 } 1457 1458 /* 1459 * If value being returned is a Reference (such as 1460 * an arg or local), resolve it now because it may 1461 * cease to exist at the end of the method. 1462 */ 1463 Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState); 1464 if (ACPI_FAILURE (Status)) 1465 { 1466 return (Status); 1467 } 1468 1469 /* 1470 * Get the return value and save as the last result 1471 * value. This is the only place where WalkState->ReturnDesc 1472 * is set to anything other than zero! 1473 */ 1474 WalkState->ReturnDesc = WalkState->Operands[0]; 1475 } 1476 else if (WalkState->ResultCount) 1477 { 1478 /* Since we have a real Return(), delete any implicit return */ 1479 1480 AcpiDsClearImplicitReturn (WalkState); 1481 1482 /* 1483 * The return value has come from a previous calculation. 1484 * 1485 * If value being returned is a Reference (such as 1486 * an arg or local), resolve it now because it may 1487 * cease to exist at the end of the method. 1488 * 1489 * Allow references created by the Index operator to return unchanged. 1490 */ 1491 if ((ACPI_GET_DESCRIPTOR_TYPE (WalkState->Results->Results.ObjDesc[0]) == ACPI_DESC_TYPE_OPERAND) && 1492 (ACPI_GET_OBJECT_TYPE (WalkState->Results->Results.ObjDesc [0]) == ACPI_TYPE_LOCAL_REFERENCE) && 1493 ((WalkState->Results->Results.ObjDesc [0])->Reference.Class != ACPI_REFCLASS_INDEX)) 1494 { 1495 Status = AcpiExResolveToValue (&WalkState->Results->Results.ObjDesc [0], WalkState); 1496 if (ACPI_FAILURE (Status)) 1497 { 1498 return (Status); 1499 } 1500 } 1501 1502 WalkState->ReturnDesc = WalkState->Results->Results.ObjDesc [0]; 1503 } 1504 else 1505 { 1506 /* No return operand */ 1507 1508 if (WalkState->NumOperands) 1509 { 1510 AcpiUtRemoveReference (WalkState->Operands [0]); 1511 } 1512 1513 WalkState->Operands [0] = NULL; 1514 WalkState->NumOperands = 0; 1515 WalkState->ReturnDesc = NULL; 1516 } 1517 1518 1519 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 1520 "Completed RETURN_OP State=%p, RetVal=%p\n", 1521 WalkState, WalkState->ReturnDesc)); 1522 1523 /* End the control method execution right now */ 1524 1525 Status = AE_CTRL_TERMINATE; 1526 break; 1527 1528 1529 case AML_NOOP_OP: 1530 1531 /* Just do nothing! */ 1532 break; 1533 1534 1535 case AML_BREAK_POINT_OP: 1536 1537 /* Call up to the OS service layer to handle this */ 1538 1539 Status = AcpiOsSignal (ACPI_SIGNAL_BREAKPOINT, "Executed AML Breakpoint opcode"); 1540 1541 /* If and when it returns, all done. */ 1542 1543 break; 1544 1545 1546 case AML_BREAK_OP: 1547 case AML_CONTINUE_OP: /* ACPI 2.0 */ 1548 1549 1550 /* Pop and delete control states until we find a while */ 1551 1552 while (WalkState->ControlState && 1553 (WalkState->ControlState->Control.Opcode != AML_WHILE_OP)) 1554 { 1555 ControlState = AcpiUtPopGenericState (&WalkState->ControlState); 1556 AcpiUtDeleteGenericState (ControlState); 1557 } 1558 1559 /* No while found? */ 1560 1561 if (!WalkState->ControlState) 1562 { 1563 return (AE_AML_NO_WHILE); 1564 } 1565 1566 /* Was: WalkState->AmlLastWhile = WalkState->ControlState->Control.AmlPredicateStart; */ 1567 1568 WalkState->AmlLastWhile = WalkState->ControlState->Control.PackageEnd; 1569 1570 /* Return status depending on opcode */ 1571 1572 if (Op->Common.AmlOpcode == AML_BREAK_OP) 1573 { 1574 Status = AE_CTRL_BREAK; 1575 } 1576 else 1577 { 1578 Status = AE_CTRL_CONTINUE; 1579 } 1580 break; 1581 1582 1583 default: 1584 1585 ACPI_ERROR ((AE_INFO, "Unknown control opcode=%X Op=%p", 1586 Op->Common.AmlOpcode, Op)); 1587 1588 Status = AE_AML_BAD_OPCODE; 1589 break; 1590 } 1591 1592 return (Status); 1593 } 1594 1595