1 /******************************************************************************* 2 * 3 * Module Name: dmwalk - AML disassembly tree walk 4 * $Revision: 1.35 $ 5 * 6 ******************************************************************************/ 7 8 /****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999 - 2008, Intel Corp. 13 * All rights reserved. 14 * 15 * 2. License 16 * 17 * 2.1. This is your license from Intel Corp. under its intellectual property 18 * rights. You may have additional license terms from the party that provided 19 * you this software, covering your right to use that party's intellectual 20 * property rights. 21 * 22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23 * copy of the source code appearing in this file ("Covered Code") an 24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25 * base code distributed originally by Intel ("Original Intel Code") to copy, 26 * make derivatives, distribute, use and display any portion of the Covered 27 * Code in any form, with the right to sublicense such rights; and 28 * 29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30 * license (with the right to sublicense), under only those claims of Intel 31 * patents that are infringed by the Original Intel Code, to make, use, sell, 32 * offer to sell, and import the Covered Code and derivative works thereof 33 * solely to the minimum extent necessary to exercise the above copyright 34 * license, and in no event shall the patent license extend to any additions 35 * to or modifications of the Original Intel Code. No other license or right 36 * is granted directly or by implication, estoppel or otherwise; 37 * 38 * The above copyright and patent license is granted only if the following 39 * conditions are met: 40 * 41 * 3. Conditions 42 * 43 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44 * Redistribution of source code of any substantial portion of the Covered 45 * Code or modification with rights to further distribute source must include 46 * the above Copyright Notice, the above License, this list of Conditions, 47 * and the following Disclaimer and Export Compliance provision. In addition, 48 * Licensee must cause all Covered Code to which Licensee contributes to 49 * contain a file documenting the changes Licensee made to create that Covered 50 * Code and the date of any change. Licensee must include in that file the 51 * documentation of any changes made by any predecessor Licensee. Licensee 52 * must include a prominent statement that the modification is derived, 53 * directly or indirectly, from Original Intel Code. 54 * 55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56 * Redistribution of source code of any substantial portion of the Covered 57 * Code or modification without rights to further distribute source must 58 * include the following Disclaimer and Export Compliance provision in the 59 * documentation and/or other materials provided with distribution. In 60 * addition, Licensee may not authorize further sublicense of source of any 61 * portion of the Covered Code, and must include terms to the effect that the 62 * license from Licensee to its licensee is limited to the intellectual 63 * property embodied in the software Licensee provides to its licensee, and 64 * not to intellectual property embodied in modifications its licensee may 65 * make. 66 * 67 * 3.3. Redistribution of Executable. Redistribution in executable form of any 68 * substantial portion of the Covered Code or modification must reproduce the 69 * above Copyright Notice, and the following Disclaimer and Export Compliance 70 * provision in the documentation and/or other materials provided with the 71 * distribution. 72 * 73 * 3.4. Intel retains all right, title, and interest in and to the Original 74 * Intel Code. 75 * 76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77 * Intel shall be used in advertising or otherwise to promote the sale, use or 78 * other dealings in products derived from or relating to the Covered Code 79 * without prior written authorization from Intel. 80 * 81 * 4. Disclaimer and Export Compliance 82 * 83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89 * PARTICULAR PURPOSE. 90 * 91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98 * LIMITED REMEDY. 99 * 100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 101 * software or system incorporating such software without first obtaining any 102 * required license or other approval from the U. S. Department of Commerce or 103 * any other agency or department of the United States Government. In the 104 * event Licensee exports any such software from the United States or 105 * re-exports any such software from a foreign destination, Licensee shall 106 * ensure that the distribution and export/re-export of the software is in 107 * compliance with all laws, regulations, orders, or other restrictions of the 108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109 * any of its subsidiaries will export/re-export any technical data, process, 110 * software, or service, directly or indirectly, to any country for which the 111 * United States government or any agency thereof requires an export license, 112 * other governmental approval, or letter of assurance, without first obtaining 113 * such license, approval or letter. 114 * 115 *****************************************************************************/ 116 117 118 #include "acpi.h" 119 #include "acparser.h" 120 #include "amlcode.h" 121 #include "acdisasm.h" 122 #include "acdebug.h" 123 124 125 #ifdef ACPI_DISASSEMBLER 126 127 #define _COMPONENT ACPI_CA_DEBUGGER 128 ACPI_MODULE_NAME ("dmwalk") 129 130 131 #define DB_FULL_OP_INFO "[%4.4s] @%5.5X #%4.4X: " 132 133 /* Local prototypes */ 134 135 static ACPI_STATUS 136 AcpiDmDescendingOp ( 137 ACPI_PARSE_OBJECT *Op, 138 UINT32 Level, 139 void *Context); 140 141 static ACPI_STATUS 142 AcpiDmAscendingOp ( 143 ACPI_PARSE_OBJECT *Op, 144 UINT32 Level, 145 void *Context); 146 147 static UINT32 148 AcpiDmBlockType ( 149 ACPI_PARSE_OBJECT *Op); 150 151 152 /******************************************************************************* 153 * 154 * FUNCTION: AcpiDmDisassemble 155 * 156 * PARAMETERS: WalkState - Current state 157 * Origin - Starting object 158 * NumOpcodes - Max number of opcodes to be displayed 159 * 160 * RETURN: None 161 * 162 * DESCRIPTION: Disassemble parser object and its children. This is the 163 * main entry point of the disassembler. 164 * 165 ******************************************************************************/ 166 167 void 168 AcpiDmDisassemble ( 169 ACPI_WALK_STATE *WalkState, 170 ACPI_PARSE_OBJECT *Origin, 171 UINT32 NumOpcodes) 172 { 173 ACPI_PARSE_OBJECT *Op = Origin; 174 ACPI_OP_WALK_INFO Info; 175 176 177 if (!Op) 178 { 179 return; 180 } 181 182 Info.Flags = 0; 183 Info.Level = 0; 184 Info.Count = 0; 185 Info.WalkState = WalkState; 186 AcpiDmWalkParseTree (Op, AcpiDmDescendingOp, AcpiDmAscendingOp, &Info); 187 return; 188 } 189 190 191 /******************************************************************************* 192 * 193 * FUNCTION: AcpiDmWalkParseTree 194 * 195 * PARAMETERS: Op - Root Op object 196 * DescendingCallback - Called during tree descent 197 * AscendingCallback - Called during tree ascent 198 * Context - To be passed to the callbacks 199 * 200 * RETURN: Status from callback(s) 201 * 202 * DESCRIPTION: Walk the entire parse tree. 203 * 204 ******************************************************************************/ 205 206 void 207 AcpiDmWalkParseTree ( 208 ACPI_PARSE_OBJECT *Op, 209 ASL_WALK_CALLBACK DescendingCallback, 210 ASL_WALK_CALLBACK AscendingCallback, 211 void *Context) 212 { 213 BOOLEAN NodePreviouslyVisited; 214 ACPI_PARSE_OBJECT *StartOp = Op; 215 ACPI_STATUS Status; 216 ACPI_PARSE_OBJECT *Next; 217 ACPI_OP_WALK_INFO *Info = Context; 218 219 220 Info->Level = 0; 221 NodePreviouslyVisited = FALSE; 222 223 while (Op) 224 { 225 if (NodePreviouslyVisited) 226 { 227 if (AscendingCallback) 228 { 229 Status = AscendingCallback (Op, Info->Level, Context); 230 if (ACPI_FAILURE (Status)) 231 { 232 return; 233 } 234 } 235 } 236 else 237 { 238 /* Let the callback process the node */ 239 240 Status = DescendingCallback (Op, Info->Level, Context); 241 if (ACPI_SUCCESS (Status)) 242 { 243 /* Visit children first, once */ 244 245 Next = AcpiPsGetArg (Op, 0); 246 if (Next) 247 { 248 Info->Level++; 249 Op = Next; 250 continue; 251 } 252 } 253 else if (Status != AE_CTRL_DEPTH) 254 { 255 /* Exit immediately on any error */ 256 257 return; 258 } 259 } 260 261 /* Terminate walk at start op */ 262 263 if (Op == StartOp) 264 { 265 break; 266 } 267 268 /* No more children, re-visit this node */ 269 270 if (!NodePreviouslyVisited) 271 { 272 NodePreviouslyVisited = TRUE; 273 continue; 274 } 275 276 /* No more children, visit peers */ 277 278 if (Op->Common.Next) 279 { 280 Op = Op->Common.Next; 281 NodePreviouslyVisited = FALSE; 282 } 283 else 284 { 285 /* No peers, re-visit parent */ 286 287 if (Info->Level != 0 ) 288 { 289 Info->Level--; 290 } 291 292 Op = Op->Common.Parent; 293 NodePreviouslyVisited = TRUE; 294 } 295 } 296 297 /* If we get here, the walk completed with no errors */ 298 299 return; 300 } 301 302 303 /******************************************************************************* 304 * 305 * FUNCTION: AcpiDmBlockType 306 * 307 * PARAMETERS: Op - Object to be examined 308 * 309 * RETURN: BlockType - not a block, parens, braces, or even both. 310 * 311 * DESCRIPTION: Type of block for this op (parens or braces) 312 * 313 ******************************************************************************/ 314 315 static UINT32 316 AcpiDmBlockType ( 317 ACPI_PARSE_OBJECT *Op) 318 { 319 const ACPI_OPCODE_INFO *OpInfo; 320 321 322 if (!Op) 323 { 324 return (BLOCK_NONE); 325 } 326 327 switch (Op->Common.AmlOpcode) 328 { 329 case AML_ELSE_OP: 330 331 return (BLOCK_BRACE); 332 333 case AML_METHOD_OP: 334 case AML_DEVICE_OP: 335 case AML_SCOPE_OP: 336 case AML_PROCESSOR_OP: 337 case AML_POWER_RES_OP: 338 case AML_THERMAL_ZONE_OP: 339 case AML_IF_OP: 340 case AML_WHILE_OP: 341 case AML_FIELD_OP: 342 case AML_INDEX_FIELD_OP: 343 case AML_BANK_FIELD_OP: 344 345 return (BLOCK_PAREN | BLOCK_BRACE); 346 347 case AML_BUFFER_OP: 348 349 if (Op->Common.DisasmOpcode == ACPI_DASM_UNICODE) 350 { 351 return (BLOCK_NONE); 352 } 353 354 /*lint -fallthrough */ 355 356 case AML_PACKAGE_OP: 357 case AML_VAR_PACKAGE_OP: 358 359 return (BLOCK_PAREN | BLOCK_BRACE); 360 361 case AML_EVENT_OP: 362 363 return (BLOCK_PAREN); 364 365 default: 366 367 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 368 if (OpInfo->Flags & AML_HAS_ARGS) 369 { 370 return (BLOCK_PAREN); 371 } 372 373 return (BLOCK_NONE); 374 } 375 } 376 377 378 /******************************************************************************* 379 * 380 * FUNCTION: AcpiDmListType 381 * 382 * PARAMETERS: Op - Object to be examined 383 * 384 * RETURN: ListType - has commas or not. 385 * 386 * DESCRIPTION: Type of block for this op (parens or braces) 387 * 388 ******************************************************************************/ 389 390 UINT32 391 AcpiDmListType ( 392 ACPI_PARSE_OBJECT *Op) 393 { 394 const ACPI_OPCODE_INFO *OpInfo; 395 396 397 if (!Op) 398 { 399 return (BLOCK_NONE); 400 } 401 402 switch (Op->Common.AmlOpcode) 403 { 404 405 case AML_ELSE_OP: 406 case AML_METHOD_OP: 407 case AML_DEVICE_OP: 408 case AML_SCOPE_OP: 409 case AML_POWER_RES_OP: 410 case AML_PROCESSOR_OP: 411 case AML_THERMAL_ZONE_OP: 412 case AML_IF_OP: 413 case AML_WHILE_OP: 414 case AML_FIELD_OP: 415 case AML_INDEX_FIELD_OP: 416 case AML_BANK_FIELD_OP: 417 418 return (BLOCK_NONE); 419 420 case AML_BUFFER_OP: 421 case AML_PACKAGE_OP: 422 case AML_VAR_PACKAGE_OP: 423 424 return (BLOCK_COMMA_LIST); 425 426 default: 427 428 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 429 if (OpInfo->Flags & AML_HAS_ARGS) 430 { 431 return (BLOCK_COMMA_LIST); 432 } 433 434 return (BLOCK_NONE); 435 } 436 } 437 438 439 /******************************************************************************* 440 * 441 * FUNCTION: AcpiDmDescendingOp 442 * 443 * PARAMETERS: ASL_WALK_CALLBACK 444 * 445 * RETURN: Status 446 * 447 * DESCRIPTION: First visitation of a parse object during tree descent. 448 * Decode opcode name and begin parameter list(s), if any. 449 * 450 ******************************************************************************/ 451 452 static ACPI_STATUS 453 AcpiDmDescendingOp ( 454 ACPI_PARSE_OBJECT *Op, 455 UINT32 Level, 456 void *Context) 457 { 458 ACPI_OP_WALK_INFO *Info = Context; 459 const ACPI_OPCODE_INFO *OpInfo; 460 UINT32 Name; 461 ACPI_PARSE_OBJECT *NextOp; 462 ACPI_EXTERNAL_LIST *NextExternal; 463 464 465 if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE) 466 { 467 /* Ignore this op -- it was handled elsewhere */ 468 469 return (AE_CTRL_DEPTH); 470 } 471 472 /* Level 0 is at the Definition Block level */ 473 474 if (Level == 0) 475 { 476 /* In verbose mode, print the AML offset, opcode and depth count */ 477 478 if (Info->WalkState) 479 { 480 VERBOSE_PRINT ((DB_FULL_OP_INFO, 481 (Info->WalkState->MethodNode ? 482 Info->WalkState->MethodNode->Name.Ascii : " "), 483 Op->Common.AmlOffset, (UINT32) Op->Common.AmlOpcode)); 484 } 485 486 if (Op->Common.AmlOpcode == AML_SCOPE_OP) 487 { 488 /* This is the beginning of the Definition Block */ 489 490 AcpiOsPrintf ("{\n"); 491 492 /* Emit all External() declarations here */ 493 494 if (AcpiGbl_ExternalList) 495 { 496 /* 497 * Walk the list of externals (unresolved references) 498 * found during parsing 499 */ 500 while (AcpiGbl_ExternalList) 501 { 502 AcpiOsPrintf (" External (%s", 503 AcpiGbl_ExternalList->Path); 504 505 /* TBD: should be a lookup table */ 506 507 switch (AcpiGbl_ExternalList->Type) 508 { 509 case ACPI_TYPE_DEVICE: 510 AcpiOsPrintf (", DeviceObj"); 511 break; 512 513 case ACPI_TYPE_METHOD: 514 AcpiOsPrintf (", MethodObj"); 515 break; 516 517 case ACPI_TYPE_INTEGER: 518 AcpiOsPrintf (", IntObj"); 519 break; 520 521 default: 522 break; 523 } 524 525 if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) 526 { 527 AcpiOsPrintf (") // %d Arguments\n", AcpiGbl_ExternalList->Value); 528 } 529 else 530 { 531 AcpiOsPrintf (")\n"); 532 } 533 534 NextExternal = AcpiGbl_ExternalList->Next; 535 ACPI_FREE (AcpiGbl_ExternalList->Path); 536 ACPI_FREE (AcpiGbl_ExternalList); 537 AcpiGbl_ExternalList = NextExternal; 538 } 539 AcpiOsPrintf ("\n"); 540 } 541 542 return (AE_OK); 543 } 544 } 545 else if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) && 546 (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) && 547 (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP)) 548 { 549 /* 550 * This is a first-level element of a term list, 551 * indent a new line 552 */ 553 AcpiDmIndent (Level); 554 Info->LastLevel = Level; 555 Info->Count = 0; 556 } 557 558 /* 559 * This is an inexpensive mechanism to try and keep lines from getting 560 * too long. When the limit is hit, start a new line at the previous 561 * indent plus one. A better but more expensive mechanism would be to 562 * keep track of the current column. 563 */ 564 Info->Count++; 565 if (Info->Count /*+Info->LastLevel*/ > 10) 566 { 567 Info->Count = 0; 568 AcpiOsPrintf ("\n"); 569 AcpiDmIndent (Info->LastLevel + 1); 570 } 571 572 /* Print the opcode name */ 573 574 AcpiDmDisassembleOneOp (NULL, Info, Op); 575 576 if (Op->Common.DisasmOpcode == ACPI_DASM_LNOT_PREFIX) 577 { 578 return (AE_OK); 579 } 580 581 if ((Op->Common.AmlOpcode == AML_NAME_OP) || 582 (Op->Common.AmlOpcode == AML_RETURN_OP)) 583 { 584 Info->Level--; 585 } 586 587 /* Start the opcode argument list if necessary */ 588 589 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 590 591 if ((OpInfo->Flags & AML_HAS_ARGS) || 592 (Op->Common.AmlOpcode == AML_EVENT_OP)) 593 { 594 /* This opcode has an argument list */ 595 596 if (AcpiDmBlockType (Op) & BLOCK_PAREN) 597 { 598 AcpiOsPrintf (" ("); 599 } 600 601 /* If this is a named opcode, print the associated name value */ 602 603 if (OpInfo->Flags & AML_NAMED) 604 { 605 switch (Op->Common.AmlOpcode) 606 { 607 case AML_ALIAS_OP: 608 609 NextOp = AcpiPsGetDepthNext (NULL, Op); 610 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 611 AcpiDmNamestring (NextOp->Common.Value.Name); 612 AcpiOsPrintf (", "); 613 614 /*lint -fallthrough */ 615 616 default: 617 618 Name = AcpiPsGetName (Op); 619 if (Op->Named.Path) 620 { 621 AcpiDmNamestring ((char *) Op->Named.Path); 622 } 623 else 624 { 625 AcpiDmDumpName (Name); 626 } 627 628 if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP) 629 { 630 if (AcpiGbl_DbOpt_verbose) 631 { 632 (void) AcpiPsDisplayObjectPathname (NULL, Op); 633 } 634 } 635 break; 636 } 637 638 switch (Op->Common.AmlOpcode) 639 { 640 case AML_METHOD_OP: 641 642 AcpiDmMethodFlags (Op); 643 AcpiOsPrintf (")"); 644 break; 645 646 647 case AML_NAME_OP: 648 649 /* Check for _HID and related EISAID() */ 650 651 AcpiDmIsEisaId (Op); 652 AcpiOsPrintf (", "); 653 break; 654 655 656 case AML_REGION_OP: 657 658 AcpiDmRegionFlags (Op); 659 break; 660 661 662 case AML_POWER_RES_OP: 663 664 /* Mark the next two Ops as part of the parameter list */ 665 666 AcpiOsPrintf (", "); 667 NextOp = AcpiPsGetDepthNext (NULL, Op); 668 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 669 670 NextOp = NextOp->Common.Next; 671 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 672 return (AE_OK); 673 674 675 case AML_PROCESSOR_OP: 676 677 /* Mark the next three Ops as part of the parameter list */ 678 679 AcpiOsPrintf (", "); 680 NextOp = AcpiPsGetDepthNext (NULL, Op); 681 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 682 683 NextOp = NextOp->Common.Next; 684 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 685 686 NextOp = NextOp->Common.Next; 687 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 688 return (AE_OK); 689 690 691 case AML_MUTEX_OP: 692 case AML_DATA_REGION_OP: 693 694 AcpiOsPrintf (", "); 695 return (AE_OK); 696 697 698 case AML_EVENT_OP: 699 case AML_ALIAS_OP: 700 701 return (AE_OK); 702 703 704 case AML_SCOPE_OP: 705 case AML_DEVICE_OP: 706 case AML_THERMAL_ZONE_OP: 707 708 AcpiOsPrintf (")"); 709 break; 710 711 712 default: 713 714 AcpiOsPrintf ("*** Unhandled named opcode %X\n", Op->Common.AmlOpcode); 715 break; 716 } 717 } 718 719 else switch (Op->Common.AmlOpcode) 720 { 721 case AML_FIELD_OP: 722 case AML_BANK_FIELD_OP: 723 case AML_INDEX_FIELD_OP: 724 725 Info->BitOffset = 0; 726 727 /* Name of the parent OperationRegion */ 728 729 NextOp = AcpiPsGetDepthNext (NULL, Op); 730 AcpiDmNamestring (NextOp->Common.Value.Name); 731 AcpiOsPrintf (", "); 732 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 733 734 switch (Op->Common.AmlOpcode) 735 { 736 case AML_BANK_FIELD_OP: 737 738 /* Namestring - Bank Name */ 739 740 NextOp = AcpiPsGetDepthNext (NULL, NextOp); 741 AcpiDmNamestring (NextOp->Common.Value.Name); 742 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 743 AcpiOsPrintf (", "); 744 745 /* 746 * Bank Value. This is a TermArg in the middle of the parameter 747 * list, must handle it here. 748 * 749 * Disassemble the TermArg parse tree. ACPI_PARSEOP_PARAMLIST 750 * eliminates newline in the output. 751 */ 752 NextOp = NextOp->Common.Next; 753 754 Info->Flags = ACPI_PARSEOP_PARAMLIST; 755 AcpiDmWalkParseTree (NextOp, AcpiDmDescendingOp, AcpiDmAscendingOp, Info); 756 Info->Flags = 0; 757 Info->Level = Level; 758 759 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 760 AcpiOsPrintf (", "); 761 break; 762 763 case AML_INDEX_FIELD_OP: 764 765 /* Namestring - Data Name */ 766 767 NextOp = AcpiPsGetDepthNext (NULL, NextOp); 768 AcpiDmNamestring (NextOp->Common.Value.Name); 769 AcpiOsPrintf (", "); 770 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 771 break; 772 773 default: 774 775 break; 776 } 777 778 AcpiDmFieldFlags (NextOp); 779 break; 780 781 782 case AML_BUFFER_OP: 783 784 /* The next op is the size parameter */ 785 786 NextOp = AcpiPsGetDepthNext (NULL, Op); 787 if (!NextOp) 788 { 789 /* Single-step support */ 790 791 return (AE_OK); 792 } 793 794 if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE) 795 { 796 /* 797 * We have a resource list. Don't need to output 798 * the buffer size Op. Open up a new block 799 */ 800 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 801 NextOp = NextOp->Common.Next; 802 AcpiOsPrintf (")\n"); 803 AcpiDmIndent (Info->Level); 804 AcpiOsPrintf ("{\n"); 805 return (AE_OK); 806 } 807 808 /* Normal Buffer, mark size as in the parameter list */ 809 810 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 811 return (AE_OK); 812 813 814 case AML_VAR_PACKAGE_OP: 815 case AML_IF_OP: 816 case AML_WHILE_OP: 817 818 /* The next op is the size or predicate parameter */ 819 820 NextOp = AcpiPsGetDepthNext (NULL, Op); 821 if (NextOp) 822 { 823 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 824 } 825 return (AE_OK); 826 827 828 case AML_PACKAGE_OP: 829 830 /* The next op is the size or predicate parameter */ 831 832 NextOp = AcpiPsGetDepthNext (NULL, Op); 833 if (NextOp) 834 { 835 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 836 } 837 return (AE_OK); 838 839 840 case AML_MATCH_OP: 841 842 AcpiDmMatchOp (Op); 843 break; 844 845 846 default: 847 848 break; 849 } 850 851 if (AcpiDmBlockType (Op) & BLOCK_BRACE) 852 { 853 AcpiOsPrintf ("\n"); 854 AcpiDmIndent (Level); 855 AcpiOsPrintf ("{\n"); 856 } 857 } 858 859 return (AE_OK); 860 } 861 862 863 /******************************************************************************* 864 * 865 * FUNCTION: AcpiDmAscendingOp 866 * 867 * PARAMETERS: ASL_WALK_CALLBACK 868 * 869 * RETURN: Status 870 * 871 * DESCRIPTION: Second visitation of a parse object, during ascent of parse 872 * tree. Close out any parameter lists and complete the opcode. 873 * 874 ******************************************************************************/ 875 876 static ACPI_STATUS 877 AcpiDmAscendingOp ( 878 ACPI_PARSE_OBJECT *Op, 879 UINT32 Level, 880 void *Context) 881 { 882 ACPI_OP_WALK_INFO *Info = Context; 883 884 885 if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE) 886 { 887 /* Ignore this op -- it was handled elsewhere */ 888 889 return (AE_OK); 890 } 891 892 if ((Level == 0) && (Op->Common.AmlOpcode == AML_SCOPE_OP)) 893 { 894 /* Indicates the end of the current descriptor block (table) */ 895 896 AcpiOsPrintf ("}\n\n"); 897 return (AE_OK); 898 } 899 900 switch (AcpiDmBlockType (Op)) 901 { 902 case BLOCK_PAREN: 903 904 /* Completed an op that has arguments, add closing paren */ 905 906 AcpiOsPrintf (")"); 907 908 /* Could be a nested operator, check if comma required */ 909 910 if (!AcpiDmCommaIfListMember (Op)) 911 { 912 if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) && 913 (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) && 914 (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP)) 915 { 916 /* 917 * This is a first-level element of a term list 918 * start a new line 919 */ 920 if (!(Info->Flags & ACPI_PARSEOP_PARAMLIST)) 921 { 922 AcpiOsPrintf ("\n"); 923 } 924 } 925 } 926 break; 927 928 929 case BLOCK_BRACE: 930 case (BLOCK_BRACE | BLOCK_PAREN): 931 932 /* Completed an op that has a term list, add closing brace */ 933 934 if (Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST) 935 { 936 AcpiOsPrintf ("}"); 937 } 938 else 939 { 940 AcpiDmIndent (Level); 941 AcpiOsPrintf ("}"); 942 } 943 944 AcpiDmCommaIfListMember (Op); 945 946 if (AcpiDmBlockType (Op->Common.Parent) != BLOCK_PAREN) 947 { 948 AcpiOsPrintf ("\n"); 949 if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST)) 950 { 951 if ((Op->Common.AmlOpcode == AML_IF_OP) && 952 (Op->Common.Next) && 953 (Op->Common.Next->Common.AmlOpcode == AML_ELSE_OP)) 954 { 955 break; 956 } 957 958 if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) && 959 (!Op->Common.Next)) 960 { 961 break; 962 } 963 AcpiOsPrintf ("\n"); 964 } 965 } 966 break; 967 968 969 case BLOCK_NONE: 970 default: 971 972 /* Could be a nested operator, check if comma required */ 973 974 if (!AcpiDmCommaIfListMember (Op)) 975 { 976 if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) && 977 (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) && 978 (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP)) 979 { 980 /* 981 * This is a first-level element of a term list 982 * start a new line 983 */ 984 AcpiOsPrintf ("\n"); 985 } 986 } 987 else if (Op->Common.Parent) 988 { 989 switch (Op->Common.Parent->Common.AmlOpcode) 990 { 991 case AML_PACKAGE_OP: 992 case AML_VAR_PACKAGE_OP: 993 994 if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) 995 { 996 AcpiOsPrintf ("\n"); 997 } 998 break; 999 1000 default: 1001 1002 break; 1003 } 1004 } 1005 break; 1006 } 1007 1008 if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST) 1009 { 1010 if ((Op->Common.Next) && 1011 (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) 1012 { 1013 return (AE_OK); 1014 } 1015 1016 /* 1017 * Just completed a parameter node for something like "Buffer (param)". 1018 * Close the paren and open up the term list block with a brace 1019 */ 1020 if (Op->Common.Next) 1021 { 1022 AcpiOsPrintf (")\n"); 1023 AcpiDmIndent (Level - 1); 1024 AcpiOsPrintf ("{\n"); 1025 } 1026 else 1027 { 1028 Op->Common.Parent->Common.DisasmFlags |= 1029 ACPI_PARSEOP_EMPTY_TERMLIST; 1030 AcpiOsPrintf (") {"); 1031 } 1032 } 1033 1034 if ((Op->Common.AmlOpcode == AML_NAME_OP) || 1035 (Op->Common.AmlOpcode == AML_RETURN_OP)) 1036 { 1037 Info->Level++; 1038 } 1039 return (AE_OK); 1040 } 1041 1042 1043 #endif /* ACPI_DISASSEMBLER */ 1044