1 /****************************************************************************** 2 * 3 * Module Name: aslfold - Constant folding 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include <contrib/dev/acpica/compiler/aslcompiler.h> 45 #include "aslcompiler.y.h" 46 #include <contrib/dev/acpica/include/amlcode.h> 47 48 #include <contrib/dev/acpica/include/acdispat.h> 49 #include <contrib/dev/acpica/include/acparser.h> 50 51 #define _COMPONENT ACPI_COMPILER 52 ACPI_MODULE_NAME ("aslfold") 53 54 /* Local prototypes */ 55 56 static ACPI_STATUS 57 OpcAmlEvaluationWalk1 ( 58 ACPI_PARSE_OBJECT *Op, 59 UINT32 Level, 60 void *Context); 61 62 static ACPI_STATUS 63 OpcAmlEvaluationWalk2 ( 64 ACPI_PARSE_OBJECT *Op, 65 UINT32 Level, 66 void *Context); 67 68 static ACPI_STATUS 69 OpcAmlCheckForConstant ( 70 ACPI_PARSE_OBJECT *Op, 71 UINT32 Level, 72 void *Context); 73 74 static void 75 OpcUpdateIntegerNode ( 76 ACPI_PARSE_OBJECT *Op, 77 UINT64 Value); 78 79 static ACPI_STATUS 80 TrTransformToStoreOp ( 81 ACPI_PARSE_OBJECT *Op, 82 ACPI_WALK_STATE *WalkState); 83 84 static ACPI_STATUS 85 TrSimpleConstantReduction ( 86 ACPI_PARSE_OBJECT *Op, 87 ACPI_WALK_STATE *WalkState); 88 89 static void 90 TrInstallReducedConstant ( 91 ACPI_PARSE_OBJECT *Op, 92 ACPI_OPERAND_OBJECT *ObjDesc); 93 94 95 /******************************************************************************* 96 * 97 * FUNCTION: OpcAmlConstantWalk 98 * 99 * PARAMETERS: ASL_WALK_CALLBACK 100 * 101 * RETURN: Status 102 * 103 * DESCRIPTION: Reduce an Op and its subtree to a constant if possible 104 * 105 ******************************************************************************/ 106 107 ACPI_STATUS 108 OpcAmlConstantWalk ( 109 ACPI_PARSE_OBJECT *Op, 110 UINT32 Level, 111 void *Context) 112 { 113 ACPI_WALK_STATE *WalkState; 114 ACPI_STATUS Status = AE_OK; 115 116 117 if (Op->Asl.CompileFlags == 0) 118 { 119 return (AE_OK); 120 } 121 122 /* 123 * Only interested in subtrees that could possibly contain 124 * expressions that can be evaluated at this time 125 */ 126 if ((!(Op->Asl.CompileFlags & NODE_COMPILE_TIME_CONST)) || 127 (Op->Asl.CompileFlags & NODE_IS_TARGET)) 128 { 129 return (AE_OK); 130 } 131 132 /* Create a new walk state */ 133 134 WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); 135 if (!WalkState) 136 { 137 return (AE_NO_MEMORY); 138 } 139 140 WalkState->NextOp = NULL; 141 WalkState->Params = NULL; 142 143 /* 144 * Examine the entire subtree -- all nodes must be constants 145 * or type 3/4/5 opcodes 146 */ 147 Status = TrWalkParseTree (Op, ASL_WALK_VISIT_DOWNWARD, 148 OpcAmlCheckForConstant, NULL, WalkState); 149 150 /* 151 * Did we find an entire subtree that contains all constants 152 * and type 3/4/5 opcodes? 153 */ 154 switch (Status) 155 { 156 case AE_OK: 157 158 /* Simple case, like Add(3,4) -> 7 */ 159 160 Status = TrSimpleConstantReduction (Op, WalkState); 161 break; 162 163 case AE_CTRL_RETURN_VALUE: 164 165 /* More complex case, like Add(3,4,Local0) -> Store(7,Local0) */ 166 167 Status = TrTransformToStoreOp (Op, WalkState); 168 break; 169 170 case AE_TYPE: 171 172 AcpiDsDeleteWalkState (WalkState); 173 return (AE_OK); 174 175 default: 176 AcpiDsDeleteWalkState (WalkState); 177 break; 178 } 179 180 if (ACPI_FAILURE (Status)) 181 { 182 DbgPrint (ASL_PARSE_OUTPUT, "Cannot resolve, %s\n", 183 AcpiFormatException (Status)); 184 185 /* We could not resolve the subtree for some reason */ 186 187 AslError (ASL_ERROR, ASL_MSG_CONSTANT_EVALUATION, Op, 188 (char *) AcpiFormatException (Status)); 189 190 /* Set the subtree value to ZERO anyway. Eliminates further errors */ 191 192 OpcUpdateIntegerNode (Op, 0); 193 } 194 195 /* Abort the walk of this subtree, we are done with it */ 196 197 return (AE_CTRL_DEPTH); 198 } 199 200 201 /******************************************************************************* 202 * 203 * FUNCTION: OpcAmlCheckForConstant 204 * 205 * PARAMETERS: ASL_WALK_CALLBACK 206 * 207 * RETURN: Status 208 * 209 * DESCRIPTION: Check one Op for a type 3/4/5 AML opcode 210 * 211 ******************************************************************************/ 212 213 static ACPI_STATUS 214 OpcAmlCheckForConstant ( 215 ACPI_PARSE_OBJECT *Op, 216 UINT32 Level, 217 void *Context) 218 { 219 ACPI_WALK_STATE *WalkState = Context; 220 ACPI_STATUS Status = AE_OK; 221 222 223 WalkState->Op = Op; 224 WalkState->Opcode = Op->Common.AmlOpcode; 225 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 226 227 DbgPrint (ASL_PARSE_OUTPUT, "[%.4d] Opcode: %12.12s ", 228 Op->Asl.LogicalLineNumber, Op->Asl.ParseOpName); 229 230 /* 231 * TBD: Ignore buffer constants for now. The problem is that these 232 * constants have been transformed into RAW_DATA at this point, from 233 * the parse tree transform process which currently happens before 234 * the constant folding process. We may need to defer this transform 235 * for buffer until after the constant folding. 236 */ 237 if (WalkState->Opcode == AML_BUFFER_OP) 238 { 239 Status = AE_TYPE; 240 goto CleanupAndExit; 241 } 242 243 /* 244 * These opcodes do not appear in the OpcodeInfo table, but 245 * they represent constants, so abort the constant walk now. 246 */ 247 if ((WalkState->Opcode == AML_RAW_DATA_BYTE) || 248 (WalkState->Opcode == AML_RAW_DATA_WORD) || 249 (WalkState->Opcode == AML_RAW_DATA_DWORD) || 250 (WalkState->Opcode == AML_RAW_DATA_QWORD)) 251 { 252 DbgPrint (ASL_PARSE_OUTPUT, "RAW DATA"); 253 Status = AE_TYPE; 254 goto CleanupAndExit; 255 } 256 257 /* Type 3/4/5 opcodes have the AML_CONSTANT flag set */ 258 259 if (!(WalkState->OpInfo->Flags & AML_CONSTANT)) 260 { 261 /* Not 3/4/5 opcode, but maybe can convert to STORE */ 262 263 if (Op->Asl.CompileFlags & NODE_IS_TARGET) 264 { 265 DbgPrint (ASL_PARSE_OUTPUT, 266 "**** Valid Target, transform to Store ****\n"); 267 return (AE_CTRL_RETURN_VALUE); 268 } 269 270 /* Expression cannot be reduced */ 271 272 DbgPrint (ASL_PARSE_OUTPUT, 273 "**** Not a Type 3/4/5 opcode (%s) ****", 274 Op->Asl.ParseOpName); 275 276 Status = AE_TYPE; 277 goto CleanupAndExit; 278 } 279 280 /* Debug output */ 281 282 DbgPrint (ASL_PARSE_OUTPUT, "TYPE_345"); 283 284 if (Op->Asl.CompileFlags & NODE_IS_TARGET) 285 { 286 if (Op->Asl.ParseOpcode == PARSEOP_ZERO) 287 { 288 DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " NULL TARGET"); 289 } 290 else 291 { 292 DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " VALID TARGET"); 293 } 294 } 295 if (Op->Asl.CompileFlags & NODE_IS_TERM_ARG) 296 { 297 DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " TERMARG"); 298 } 299 300 CleanupAndExit: 301 302 /* Dump the node compile flags also */ 303 304 TrPrintNodeCompileFlags (Op->Asl.CompileFlags); 305 DbgPrint (ASL_PARSE_OUTPUT, "\n"); 306 return (Status); 307 } 308 309 310 /******************************************************************************* 311 * 312 * FUNCTION: TrSimpleConstantReduction 313 * 314 * PARAMETERS: Op - Parent operator to be transformed 315 * WalkState - Current walk state 316 * 317 * RETURN: Status 318 * 319 * DESCRIPTION: Reduce an entire AML operation to a single constant. The 320 * operation must not have a target operand. 321 * 322 * Add (32,64) --> 96 323 * 324 ******************************************************************************/ 325 326 static ACPI_STATUS 327 TrSimpleConstantReduction ( 328 ACPI_PARSE_OBJECT *Op, 329 ACPI_WALK_STATE *WalkState) 330 { 331 ACPI_PARSE_OBJECT *RootOp; 332 ACPI_PARSE_OBJECT *OriginalParentOp; 333 ACPI_OPERAND_OBJECT *ObjDesc; 334 ACPI_STATUS Status; 335 336 337 DbgPrint (ASL_PARSE_OUTPUT, 338 "Simple subtree constant reduction, operator to constant\n"); 339 340 /* Allocate a new temporary root for this subtree */ 341 342 RootOp = TrAllocateNode (PARSEOP_INTEGER); 343 if (!RootOp) 344 { 345 return (AE_NO_MEMORY); 346 } 347 348 RootOp->Common.AmlOpcode = AML_INT_EVAL_SUBTREE_OP; 349 350 OriginalParentOp = Op->Common.Parent; 351 Op->Common.Parent = RootOp; 352 353 /* Hand off the subtree to the AML interpreter */ 354 355 WalkState->CallerReturnDesc = &ObjDesc; 356 357 Status = TrWalkParseTree (Op, ASL_WALK_VISIT_TWICE, 358 OpcAmlEvaluationWalk1, OpcAmlEvaluationWalk2, WalkState); 359 360 /* Restore original parse tree */ 361 362 Op->Common.Parent = OriginalParentOp; 363 364 if (ACPI_FAILURE (Status)) 365 { 366 DbgPrint (ASL_PARSE_OUTPUT, 367 "Constant Subtree evaluation(1), %s\n", 368 AcpiFormatException (Status)); 369 return (Status); 370 } 371 372 /* Get the final result */ 373 374 Status = AcpiDsResultPop (&ObjDesc, WalkState); 375 if (ACPI_FAILURE (Status)) 376 { 377 DbgPrint (ASL_PARSE_OUTPUT, 378 "Constant Subtree evaluation(2), %s\n", 379 AcpiFormatException (Status)); 380 return (Status); 381 } 382 383 TrInstallReducedConstant (Op, ObjDesc); 384 385 UtSetParseOpName (Op); 386 Op->Asl.Child = NULL; 387 return (AE_OK); 388 } 389 390 391 /******************************************************************************* 392 * 393 * FUNCTION: TrTransformToStoreOp 394 * 395 * PARAMETERS: Op - Parent operator to be transformed 396 * WalkState - Current walk state 397 * 398 * RETURN: Status 399 * 400 * DESCRIPTION: Transforms a single AML operation with a constant and target 401 * to a simple store operation: 402 * 403 * Add (32,64,DATA) --> Store (96,DATA) 404 * 405 ******************************************************************************/ 406 407 static ACPI_STATUS 408 TrTransformToStoreOp ( 409 ACPI_PARSE_OBJECT *Op, 410 ACPI_WALK_STATE *WalkState) 411 { 412 ACPI_PARSE_OBJECT *OriginalTarget; 413 ACPI_PARSE_OBJECT *NewTarget; 414 ACPI_PARSE_OBJECT *Child1; 415 ACPI_PARSE_OBJECT *Child2; 416 ACPI_OPERAND_OBJECT *ObjDesc; 417 ACPI_PARSE_OBJECT *NewParent; 418 ACPI_PARSE_OBJECT *OriginalParent; 419 ACPI_STATUS Status; 420 421 422 DbgPrint (ASL_PARSE_OUTPUT, 423 "Reduction/Transform to StoreOp: Store(Constant, Target)\n"); 424 425 /* Extract the operands */ 426 427 Child1 = Op->Asl.Child; 428 Child2 = Child1->Asl.Next; 429 430 /* 431 * Special case for DIVIDE -- it has two targets. The first 432 * is for the remainder and if present, we will not attempt 433 * to reduce the expression. 434 */ 435 if (Op->Asl.ParseOpcode == PARSEOP_DIVIDE) 436 { 437 Child2 = Child2->Asl.Next; 438 if (Child2->Asl.ParseOpcode != PARSEOP_ZERO) 439 { 440 DbgPrint (ASL_PARSE_OUTPUT, 441 "Cannot reduce DIVIDE - has two targets\n\n"); 442 return (AE_OK); 443 } 444 } 445 446 /* 447 * Create a NULL (zero) target so that we can use the 448 * interpreter to evaluate the expression. 449 */ 450 NewTarget = TrCreateNullTarget (); 451 NewTarget->Common.AmlOpcode = AML_INT_NAMEPATH_OP; 452 453 /* Handle one-operand cases (NOT, TOBCD, etc.) */ 454 455 if (!Child2->Asl.Next) 456 { 457 Child2 = Child1; 458 } 459 460 /* Link in new NULL target as the last operand */ 461 462 OriginalTarget = Child2->Asl.Next; 463 Child2->Asl.Next = NewTarget; 464 NewTarget->Asl.Parent = OriginalTarget->Asl.Parent; 465 466 NewParent = TrAllocateNode (PARSEOP_INTEGER); 467 NewParent->Common.AmlOpcode = AML_INT_EVAL_SUBTREE_OP; 468 469 OriginalParent = Op->Common.Parent; 470 Op->Common.Parent = NewParent; 471 472 /* Hand off the subtree to the AML interpreter */ 473 474 WalkState->CallerReturnDesc = &ObjDesc; 475 476 Status = TrWalkParseTree (Op, ASL_WALK_VISIT_TWICE, 477 OpcAmlEvaluationWalk1, OpcAmlEvaluationWalk2, WalkState); 478 if (ACPI_FAILURE (Status)) 479 { 480 DbgPrint (ASL_PARSE_OUTPUT, 481 "Constant Subtree evaluation(3), %s\n", 482 AcpiFormatException (Status)); 483 goto EvalError; 484 } 485 486 /* Get the final result */ 487 488 Status = AcpiDsResultPop (&ObjDesc, WalkState); 489 if (ACPI_FAILURE (Status)) 490 { 491 DbgPrint (ASL_PARSE_OUTPUT, 492 "Constant Subtree evaluation(4), %s\n", 493 AcpiFormatException (Status)); 494 goto EvalError; 495 } 496 497 /* Folded constant is in ObjDesc, store into Child1 */ 498 499 TrInstallReducedConstant (Child1, ObjDesc); 500 501 /* Convert operator to STORE */ 502 503 Op->Asl.ParseOpcode = PARSEOP_STORE; 504 Op->Asl.AmlOpcode = AML_STORE_OP; 505 UtSetParseOpName (Op); 506 Op->Common.Parent = OriginalParent; 507 508 /* Truncate any subtree expressions, they have been evaluated */ 509 510 Child1->Asl.Child = NULL; 511 Child2->Asl.Child = NULL; 512 513 /* First child is the folded constant */ 514 515 /* Second child will be the target */ 516 517 Child1->Asl.Next = OriginalTarget; 518 return (AE_OK); 519 520 521 EvalError: 522 523 /* Restore original links */ 524 525 Op->Common.Parent = OriginalParent; 526 Child2->Asl.Next = OriginalTarget; 527 return (Status); 528 } 529 530 531 /******************************************************************************* 532 * 533 * FUNCTION: TrInstallReducedConstant 534 * 535 * PARAMETERS: Op - Parent operator to be transformed 536 * ObjDesc - Reduced constant to be installed 537 * 538 * RETURN: None 539 * 540 * DESCRIPTION: Transform the original operator to a simple constant. 541 * Handles Integers, Strings, and Buffers. 542 * 543 ******************************************************************************/ 544 545 static void 546 TrInstallReducedConstant ( 547 ACPI_PARSE_OBJECT *Op, 548 ACPI_OPERAND_OBJECT *ObjDesc) 549 { 550 ACPI_PARSE_OBJECT *RootOp; 551 552 553 TotalFolds++; 554 AslError (ASL_OPTIMIZATION, ASL_MSG_CONSTANT_FOLDED, Op, 555 Op->Asl.ParseOpName); 556 557 /* 558 * Because we know we executed type 3/4/5 opcodes above, we know that 559 * the result must be either an Integer, String, or Buffer. 560 */ 561 switch (ObjDesc->Common.Type) 562 { 563 case ACPI_TYPE_INTEGER: 564 565 OpcUpdateIntegerNode (Op, ObjDesc->Integer.Value); 566 567 DbgPrint (ASL_PARSE_OUTPUT, 568 "Constant expression reduced to (%s) %8.8X%8.8X\n\n", 569 Op->Asl.ParseOpName, 570 ACPI_FORMAT_UINT64 (Op->Common.Value.Integer)); 571 break; 572 573 case ACPI_TYPE_STRING: 574 575 Op->Asl.ParseOpcode = PARSEOP_STRING_LITERAL; 576 Op->Common.AmlOpcode = AML_STRING_OP; 577 Op->Asl.AmlLength = ACPI_STRLEN (ObjDesc->String.Pointer) + 1; 578 Op->Common.Value.String = ObjDesc->String.Pointer; 579 580 DbgPrint (ASL_PARSE_OUTPUT, 581 "Constant expression reduced to (STRING) %s\n\n", 582 Op->Common.Value.String); 583 584 break; 585 586 case ACPI_TYPE_BUFFER: 587 588 Op->Asl.ParseOpcode = PARSEOP_BUFFER; 589 Op->Common.AmlOpcode = AML_BUFFER_OP; 590 Op->Asl.CompileFlags = NODE_AML_PACKAGE; 591 UtSetParseOpName (Op); 592 593 /* Child node is the buffer length */ 594 595 RootOp = TrAllocateNode (PARSEOP_INTEGER); 596 597 RootOp->Asl.AmlOpcode = AML_DWORD_OP; 598 RootOp->Asl.Value.Integer = ObjDesc->Buffer.Length; 599 RootOp->Asl.Parent = Op; 600 601 (void) OpcSetOptimalIntegerSize (RootOp); 602 603 Op->Asl.Child = RootOp; 604 Op = RootOp; 605 UtSetParseOpName (Op); 606 607 /* Peer to the child is the raw buffer data */ 608 609 RootOp = TrAllocateNode (PARSEOP_RAW_DATA); 610 RootOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; 611 RootOp->Asl.AmlLength = ObjDesc->Buffer.Length; 612 RootOp->Asl.Value.String = (char *) ObjDesc->Buffer.Pointer; 613 RootOp->Asl.Parent = Op->Asl.Parent; 614 615 Op->Asl.Next = RootOp; 616 Op = RootOp; 617 618 DbgPrint (ASL_PARSE_OUTPUT, 619 "Constant expression reduced to (BUFFER) length %X\n\n", 620 ObjDesc->Buffer.Length); 621 break; 622 623 default: 624 break; 625 } 626 } 627 628 629 /******************************************************************************* 630 * 631 * FUNCTION: OpcUpdateIntegerNode 632 * 633 * PARAMETERS: Op - Current parse object 634 * Value - Value for the integer op 635 * 636 * RETURN: None 637 * 638 * DESCRIPTION: Update node to the correct Integer type and value 639 * 640 ******************************************************************************/ 641 642 static void 643 OpcUpdateIntegerNode ( 644 ACPI_PARSE_OBJECT *Op, 645 UINT64 Value) 646 { 647 648 Op->Common.Value.Integer = Value; 649 650 /* 651 * The AmlLength is used by the parser to indicate a constant, 652 * (if non-zero). Length is either (1/2/4/8) 653 */ 654 switch (Op->Asl.AmlLength) 655 { 656 case 1: 657 658 TrUpdateNode (PARSEOP_BYTECONST, Op); 659 Op->Asl.AmlOpcode = AML_RAW_DATA_BYTE; 660 break; 661 662 case 2: 663 664 TrUpdateNode (PARSEOP_WORDCONST, Op); 665 Op->Asl.AmlOpcode = AML_RAW_DATA_WORD; 666 break; 667 668 case 4: 669 670 TrUpdateNode (PARSEOP_DWORDCONST, Op); 671 Op->Asl.AmlOpcode = AML_RAW_DATA_DWORD; 672 break; 673 674 case 8: 675 676 TrUpdateNode (PARSEOP_QWORDCONST, Op); 677 Op->Asl.AmlOpcode = AML_RAW_DATA_QWORD; 678 break; 679 680 case 0: 681 default: 682 683 OpcSetOptimalIntegerSize (Op); 684 TrUpdateNode (PARSEOP_INTEGER, Op); 685 break; 686 } 687 688 Op->Asl.AmlLength = 0; 689 } 690 691 692 /******************************************************************************* 693 * 694 * FUNCTION: OpcAmlEvaluationWalk1 695 * 696 * PARAMETERS: ASL_WALK_CALLBACK 697 * 698 * RETURN: Status 699 * 700 * DESCRIPTION: Descending callback for AML execution of constant subtrees 701 * 702 ******************************************************************************/ 703 704 static ACPI_STATUS 705 OpcAmlEvaluationWalk1 ( 706 ACPI_PARSE_OBJECT *Op, 707 UINT32 Level, 708 void *Context) 709 { 710 ACPI_WALK_STATE *WalkState = Context; 711 ACPI_STATUS Status; 712 ACPI_PARSE_OBJECT *OutOp; 713 714 715 WalkState->Op = Op; 716 WalkState->Opcode = Op->Common.AmlOpcode; 717 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 718 719 /* Copy child pointer to Arg for compatibility with Interpreter */ 720 721 if (Op->Asl.Child) 722 { 723 Op->Common.Value.Arg = Op->Asl.Child; 724 } 725 726 /* Call AML dispatcher */ 727 728 Status = AcpiDsExecBeginOp (WalkState, &OutOp); 729 if (ACPI_FAILURE (Status)) 730 { 731 DbgPrint (ASL_PARSE_OUTPUT, 732 "%s Constant interpretation failed (1) - %s\n", 733 Op->Asl.ParseOpName, AcpiFormatException (Status)); 734 } 735 736 return (Status); 737 } 738 739 740 /******************************************************************************* 741 * 742 * FUNCTION: OpcAmlEvaluationWalk2 743 * 744 * PARAMETERS: ASL_WALK_CALLBACK 745 * 746 * RETURN: Status 747 * 748 * DESCRIPTION: Ascending callback for AML execution of constant subtrees 749 * 750 ******************************************************************************/ 751 752 static ACPI_STATUS 753 OpcAmlEvaluationWalk2 ( 754 ACPI_PARSE_OBJECT *Op, 755 UINT32 Level, 756 void *Context) 757 { 758 ACPI_WALK_STATE *WalkState = Context; 759 ACPI_STATUS Status; 760 761 762 WalkState->Op = Op; 763 WalkState->Opcode = Op->Common.AmlOpcode; 764 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 765 766 /* Copy child pointer to Arg for compatibility with Interpreter */ 767 768 if (Op->Asl.Child) 769 { 770 Op->Common.Value.Arg = Op->Asl.Child; 771 } 772 773 /* Call AML dispatcher */ 774 775 Status = AcpiDsExecEndOp (WalkState); 776 if (ACPI_FAILURE (Status)) 777 { 778 DbgPrint (ASL_PARSE_OUTPUT, 779 "%s: Constant interpretation failed (2) - %s\n", 780 Op->Asl.ParseOpName, AcpiFormatException (Status)); 781 } 782 783 return (Status); 784 } 785