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 DbgPrint (ASL_PARSE_OUTPUT, 240 "\nBuffer+Buffer->Buffer constant reduction is not supported yet"); 241 Status = AE_TYPE; 242 goto CleanupAndExit; 243 } 244 245 /* 246 * These opcodes do not appear in the OpcodeInfo table, but 247 * they represent constants, so abort the constant walk now. 248 */ 249 if ((WalkState->Opcode == AML_RAW_DATA_BYTE) || 250 (WalkState->Opcode == AML_RAW_DATA_WORD) || 251 (WalkState->Opcode == AML_RAW_DATA_DWORD) || 252 (WalkState->Opcode == AML_RAW_DATA_QWORD)) 253 { 254 DbgPrint (ASL_PARSE_OUTPUT, "RAW DATA"); 255 Status = AE_TYPE; 256 goto CleanupAndExit; 257 } 258 259 /* Type 3/4/5 opcodes have the AML_CONSTANT flag set */ 260 261 if (!(WalkState->OpInfo->Flags & AML_CONSTANT)) 262 { 263 /* Not 3/4/5 opcode, but maybe can convert to STORE */ 264 265 if (Op->Asl.CompileFlags & NODE_IS_TARGET) 266 { 267 DbgPrint (ASL_PARSE_OUTPUT, 268 "**** Valid Target, transform to Store ****\n"); 269 return (AE_CTRL_RETURN_VALUE); 270 } 271 272 /* Expression cannot be reduced */ 273 274 DbgPrint (ASL_PARSE_OUTPUT, 275 "**** Not a Type 3/4/5 opcode (%s) ****", 276 Op->Asl.ParseOpName); 277 278 Status = AE_TYPE; 279 goto CleanupAndExit; 280 } 281 282 /* Debug output */ 283 284 DbgPrint (ASL_PARSE_OUTPUT, "TYPE_345"); 285 286 if (Op->Asl.CompileFlags & NODE_IS_TARGET) 287 { 288 if (Op->Asl.ParseOpcode == PARSEOP_ZERO) 289 { 290 DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " NULL TARGET"); 291 } 292 else 293 { 294 DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " VALID TARGET"); 295 } 296 } 297 if (Op->Asl.CompileFlags & NODE_IS_TERM_ARG) 298 { 299 DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " TERMARG"); 300 } 301 302 CleanupAndExit: 303 304 /* Dump the node compile flags also */ 305 306 TrPrintNodeCompileFlags (Op->Asl.CompileFlags); 307 DbgPrint (ASL_PARSE_OUTPUT, "\n"); 308 return (Status); 309 } 310 311 312 /******************************************************************************* 313 * 314 * FUNCTION: TrSimpleConstantReduction 315 * 316 * PARAMETERS: Op - Parent operator to be transformed 317 * WalkState - Current walk state 318 * 319 * RETURN: Status 320 * 321 * DESCRIPTION: Reduce an entire AML operation to a single constant. The 322 * operation must not have a target operand. 323 * 324 * Add (32,64) --> 96 325 * 326 ******************************************************************************/ 327 328 static ACPI_STATUS 329 TrSimpleConstantReduction ( 330 ACPI_PARSE_OBJECT *Op, 331 ACPI_WALK_STATE *WalkState) 332 { 333 ACPI_PARSE_OBJECT *RootOp; 334 ACPI_PARSE_OBJECT *OriginalParentOp; 335 ACPI_OPERAND_OBJECT *ObjDesc; 336 ACPI_STATUS Status; 337 338 339 DbgPrint (ASL_PARSE_OUTPUT, 340 "Simple subtree constant reduction, operator to constant\n"); 341 342 /* Allocate a new temporary root for this subtree */ 343 344 RootOp = TrAllocateNode (PARSEOP_INTEGER); 345 if (!RootOp) 346 { 347 return (AE_NO_MEMORY); 348 } 349 350 RootOp->Common.AmlOpcode = AML_INT_EVAL_SUBTREE_OP; 351 352 OriginalParentOp = Op->Common.Parent; 353 Op->Common.Parent = RootOp; 354 355 /* Hand off the subtree to the AML interpreter */ 356 357 WalkState->CallerReturnDesc = &ObjDesc; 358 359 Status = TrWalkParseTree (Op, ASL_WALK_VISIT_TWICE, 360 OpcAmlEvaluationWalk1, OpcAmlEvaluationWalk2, WalkState); 361 362 /* Restore original parse tree */ 363 364 Op->Common.Parent = OriginalParentOp; 365 366 if (ACPI_FAILURE (Status)) 367 { 368 DbgPrint (ASL_PARSE_OUTPUT, 369 "Constant Subtree evaluation(1), %s\n", 370 AcpiFormatException (Status)); 371 return (Status); 372 } 373 374 /* Get the final result */ 375 376 Status = AcpiDsResultPop (&ObjDesc, WalkState); 377 if (ACPI_FAILURE (Status)) 378 { 379 DbgPrint (ASL_PARSE_OUTPUT, 380 "Constant Subtree evaluation(2), %s\n", 381 AcpiFormatException (Status)); 382 return (Status); 383 } 384 385 /* Disconnect any existing children, install new constant */ 386 387 Op->Asl.Child = NULL; 388 TrInstallReducedConstant (Op, ObjDesc); 389 390 UtSetParseOpName (Op); 391 return (AE_OK); 392 } 393 394 395 /******************************************************************************* 396 * 397 * FUNCTION: TrTransformToStoreOp 398 * 399 * PARAMETERS: Op - Parent operator to be transformed 400 * WalkState - Current walk state 401 * 402 * RETURN: Status 403 * 404 * DESCRIPTION: Transforms a single AML operation with a constant and target 405 * to a simple store operation: 406 * 407 * Add (32,64,DATA) --> Store (96,DATA) 408 * 409 ******************************************************************************/ 410 411 static ACPI_STATUS 412 TrTransformToStoreOp ( 413 ACPI_PARSE_OBJECT *Op, 414 ACPI_WALK_STATE *WalkState) 415 { 416 ACPI_PARSE_OBJECT *OriginalTarget; 417 ACPI_PARSE_OBJECT *NewTarget; 418 ACPI_PARSE_OBJECT *Child1; 419 ACPI_PARSE_OBJECT *Child2; 420 ACPI_OPERAND_OBJECT *ObjDesc; 421 ACPI_PARSE_OBJECT *NewParent; 422 ACPI_PARSE_OBJECT *OriginalParent; 423 ACPI_STATUS Status; 424 425 426 DbgPrint (ASL_PARSE_OUTPUT, 427 "Reduction/Transform to StoreOp: Store(Constant, Target)\n"); 428 429 /* Extract the operands */ 430 431 Child1 = Op->Asl.Child; 432 Child2 = Child1->Asl.Next; 433 434 /* 435 * Special case for DIVIDE -- it has two targets. The first 436 * is for the remainder and if present, we will not attempt 437 * to reduce the expression. 438 */ 439 if (Op->Asl.ParseOpcode == PARSEOP_DIVIDE) 440 { 441 Child2 = Child2->Asl.Next; 442 if (Child2->Asl.ParseOpcode != PARSEOP_ZERO) 443 { 444 DbgPrint (ASL_PARSE_OUTPUT, 445 "Cannot reduce DIVIDE - has two targets\n\n"); 446 return (AE_OK); 447 } 448 } 449 450 /* 451 * Create a NULL (zero) target so that we can use the 452 * interpreter to evaluate the expression. 453 */ 454 NewTarget = TrCreateNullTarget (); 455 NewTarget->Common.AmlOpcode = AML_INT_NAMEPATH_OP; 456 457 /* Handle one-operand cases (NOT, TOBCD, etc.) */ 458 459 if (!Child2->Asl.Next) 460 { 461 Child2 = Child1; 462 } 463 464 /* Link in new NULL target as the last operand */ 465 466 OriginalTarget = Child2->Asl.Next; 467 Child2->Asl.Next = NewTarget; 468 NewTarget->Asl.Parent = OriginalTarget->Asl.Parent; 469 470 NewParent = TrAllocateNode (PARSEOP_INTEGER); 471 NewParent->Common.AmlOpcode = AML_INT_EVAL_SUBTREE_OP; 472 473 OriginalParent = Op->Common.Parent; 474 Op->Common.Parent = NewParent; 475 476 /* Hand off the subtree to the AML interpreter */ 477 478 WalkState->CallerReturnDesc = &ObjDesc; 479 480 Status = TrWalkParseTree (Op, ASL_WALK_VISIT_TWICE, 481 OpcAmlEvaluationWalk1, OpcAmlEvaluationWalk2, WalkState); 482 if (ACPI_FAILURE (Status)) 483 { 484 DbgPrint (ASL_PARSE_OUTPUT, 485 "Constant Subtree evaluation(3), %s\n", 486 AcpiFormatException (Status)); 487 goto EvalError; 488 } 489 490 /* Get the final result */ 491 492 Status = AcpiDsResultPop (&ObjDesc, WalkState); 493 if (ACPI_FAILURE (Status)) 494 { 495 DbgPrint (ASL_PARSE_OUTPUT, 496 "Constant Subtree evaluation(4), %s\n", 497 AcpiFormatException (Status)); 498 goto EvalError; 499 } 500 501 /* Truncate any subtree expressions, they have been evaluated */ 502 503 Child1->Asl.Child = NULL; 504 505 /* Folded constant is in ObjDesc, store into Child1 */ 506 507 TrInstallReducedConstant (Child1, ObjDesc); 508 509 /* Convert operator to STORE */ 510 511 Op->Asl.ParseOpcode = PARSEOP_STORE; 512 Op->Asl.AmlOpcode = AML_STORE_OP; 513 UtSetParseOpName (Op); 514 Op->Common.Parent = OriginalParent; 515 516 /* First child is the folded constant */ 517 518 /* Second child will be the target */ 519 520 Child1->Asl.Next = OriginalTarget; 521 return (AE_OK); 522 523 524 EvalError: 525 526 /* Restore original links */ 527 528 Op->Common.Parent = OriginalParent; 529 Child2->Asl.Next = OriginalTarget; 530 return (Status); 531 } 532 533 534 /******************************************************************************* 535 * 536 * FUNCTION: TrInstallReducedConstant 537 * 538 * PARAMETERS: Op - Parent operator to be transformed 539 * ObjDesc - Reduced constant to be installed 540 * 541 * RETURN: None 542 * 543 * DESCRIPTION: Transform the original operator to a simple constant. 544 * Handles Integers, Strings, and Buffers. 545 * 546 ******************************************************************************/ 547 548 static void 549 TrInstallReducedConstant ( 550 ACPI_PARSE_OBJECT *Op, 551 ACPI_OPERAND_OBJECT *ObjDesc) 552 { 553 ACPI_PARSE_OBJECT *LengthOp; 554 ACPI_PARSE_OBJECT *DataOp; 555 556 557 TotalFolds++; 558 AslError (ASL_OPTIMIZATION, ASL_MSG_CONSTANT_FOLDED, Op, 559 Op->Asl.ParseOpName); 560 561 /* 562 * Because we know we executed type 3/4/5 opcodes above, we know that 563 * the result must be either an Integer, String, or Buffer. 564 */ 565 switch (ObjDesc->Common.Type) 566 { 567 case ACPI_TYPE_INTEGER: 568 569 OpcUpdateIntegerNode (Op, ObjDesc->Integer.Value); 570 571 DbgPrint (ASL_PARSE_OUTPUT, 572 "Constant expression reduced to (%s) %8.8X%8.8X\n\n", 573 Op->Asl.ParseOpName, 574 ACPI_FORMAT_UINT64 (Op->Common.Value.Integer)); 575 break; 576 577 case ACPI_TYPE_STRING: 578 579 Op->Asl.ParseOpcode = PARSEOP_STRING_LITERAL; 580 Op->Common.AmlOpcode = AML_STRING_OP; 581 Op->Asl.AmlLength = strlen (ObjDesc->String.Pointer) + 1; 582 Op->Common.Value.String = ObjDesc->String.Pointer; 583 584 DbgPrint (ASL_PARSE_OUTPUT, 585 "Constant expression reduced to (STRING) %s\n\n", 586 Op->Common.Value.String); 587 break; 588 589 case ACPI_TYPE_BUFFER: 590 /* 591 * Create a new parse subtree of the form: 592 * 593 * BUFFER (Buffer AML opcode) 594 * INTEGER (Buffer length in bytes) 595 * RAW_DATA (Buffer byte data) 596 */ 597 Op->Asl.ParseOpcode = PARSEOP_BUFFER; 598 Op->Common.AmlOpcode = AML_BUFFER_OP; 599 Op->Asl.CompileFlags = NODE_AML_PACKAGE; 600 UtSetParseOpName (Op); 601 602 /* Child node is the buffer length */ 603 604 LengthOp = TrAllocateNode (PARSEOP_INTEGER); 605 606 LengthOp->Asl.AmlOpcode = AML_DWORD_OP; 607 LengthOp->Asl.Value.Integer = ObjDesc->Buffer.Length; 608 LengthOp->Asl.Parent = Op; 609 (void) OpcSetOptimalIntegerSize (LengthOp); 610 611 Op->Asl.Child = LengthOp; 612 613 /* Next child is the raw buffer data */ 614 615 DataOp = TrAllocateNode (PARSEOP_RAW_DATA); 616 DataOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; 617 DataOp->Asl.AmlLength = ObjDesc->Buffer.Length; 618 DataOp->Asl.Value.String = (char *) ObjDesc->Buffer.Pointer; 619 DataOp->Asl.Parent = Op; 620 621 LengthOp->Asl.Next = DataOp; 622 623 DbgPrint (ASL_PARSE_OUTPUT, 624 "Constant expression reduced to (BUFFER) length %X\n\n", 625 ObjDesc->Buffer.Length); 626 break; 627 628 default: 629 break; 630 } 631 } 632 633 634 /******************************************************************************* 635 * 636 * FUNCTION: OpcUpdateIntegerNode 637 * 638 * PARAMETERS: Op - Current parse object 639 * Value - Value for the integer op 640 * 641 * RETURN: None 642 * 643 * DESCRIPTION: Update node to the correct Integer type and value 644 * 645 ******************************************************************************/ 646 647 static void 648 OpcUpdateIntegerNode ( 649 ACPI_PARSE_OBJECT *Op, 650 UINT64 Value) 651 { 652 653 Op->Common.Value.Integer = Value; 654 655 /* 656 * The AmlLength is used by the parser to indicate a constant, 657 * (if non-zero). Length is either (1/2/4/8) 658 */ 659 switch (Op->Asl.AmlLength) 660 { 661 case 1: 662 663 TrUpdateNode (PARSEOP_BYTECONST, Op); 664 Op->Asl.AmlOpcode = AML_RAW_DATA_BYTE; 665 break; 666 667 case 2: 668 669 TrUpdateNode (PARSEOP_WORDCONST, Op); 670 Op->Asl.AmlOpcode = AML_RAW_DATA_WORD; 671 break; 672 673 case 4: 674 675 TrUpdateNode (PARSEOP_DWORDCONST, Op); 676 Op->Asl.AmlOpcode = AML_RAW_DATA_DWORD; 677 break; 678 679 case 8: 680 681 TrUpdateNode (PARSEOP_QWORDCONST, Op); 682 Op->Asl.AmlOpcode = AML_RAW_DATA_QWORD; 683 break; 684 685 case 0: 686 default: 687 688 OpcSetOptimalIntegerSize (Op); 689 TrUpdateNode (PARSEOP_INTEGER, Op); 690 break; 691 } 692 693 Op->Asl.AmlLength = 0; 694 } 695 696 697 /******************************************************************************* 698 * 699 * FUNCTION: OpcAmlEvaluationWalk1 700 * 701 * PARAMETERS: ASL_WALK_CALLBACK 702 * 703 * RETURN: Status 704 * 705 * DESCRIPTION: Descending callback for AML execution of constant subtrees 706 * 707 ******************************************************************************/ 708 709 static ACPI_STATUS 710 OpcAmlEvaluationWalk1 ( 711 ACPI_PARSE_OBJECT *Op, 712 UINT32 Level, 713 void *Context) 714 { 715 ACPI_WALK_STATE *WalkState = Context; 716 ACPI_STATUS Status; 717 ACPI_PARSE_OBJECT *OutOp; 718 719 720 WalkState->Op = Op; 721 WalkState->Opcode = Op->Common.AmlOpcode; 722 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 723 724 /* Copy child pointer to Arg for compatibility with Interpreter */ 725 726 if (Op->Asl.Child) 727 { 728 Op->Common.Value.Arg = Op->Asl.Child; 729 } 730 731 /* Call AML dispatcher */ 732 733 Status = AcpiDsExecBeginOp (WalkState, &OutOp); 734 if (ACPI_FAILURE (Status)) 735 { 736 DbgPrint (ASL_PARSE_OUTPUT, 737 "%s Constant interpretation failed (1) - %s\n", 738 Op->Asl.ParseOpName, AcpiFormatException (Status)); 739 } 740 741 return (Status); 742 } 743 744 745 /******************************************************************************* 746 * 747 * FUNCTION: OpcAmlEvaluationWalk2 748 * 749 * PARAMETERS: ASL_WALK_CALLBACK 750 * 751 * RETURN: Status 752 * 753 * DESCRIPTION: Ascending callback for AML execution of constant subtrees 754 * 755 ******************************************************************************/ 756 757 static ACPI_STATUS 758 OpcAmlEvaluationWalk2 ( 759 ACPI_PARSE_OBJECT *Op, 760 UINT32 Level, 761 void *Context) 762 { 763 ACPI_WALK_STATE *WalkState = Context; 764 ACPI_STATUS Status; 765 766 767 WalkState->Op = Op; 768 WalkState->Opcode = Op->Common.AmlOpcode; 769 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 770 771 /* Copy child pointer to Arg for compatibility with Interpreter */ 772 773 if (Op->Asl.Child) 774 { 775 Op->Common.Value.Arg = Op->Asl.Child; 776 } 777 778 /* Call AML dispatcher */ 779 780 Status = AcpiDsExecEndOp (WalkState); 781 if (ACPI_FAILURE (Status)) 782 { 783 DbgPrint (ASL_PARSE_OUTPUT, 784 "%s: Constant interpretation failed (2) - %s\n", 785 Op->Asl.ParseOpName, AcpiFormatException (Status)); 786 } 787 788 return (Status); 789 } 790