1 /****************************************************************************** 2 * 3 * Module Name: adwalk - Application-level disassembler parse tree walk routines 4 * $Revision: 1.6 $ 5 * 6 *****************************************************************************/ 7 8 /****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999 - 2007, 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 <contrib/dev/acpica/acpi.h> 119 #include <contrib/dev/acpica/acparser.h> 120 #include <contrib/dev/acpica/amlcode.h> 121 #include <contrib/dev/acpica/acdebug.h> 122 #include <contrib/dev/acpica/acdisasm.h> 123 #include <contrib/dev/acpica/acdispat.h> 124 #include <contrib/dev/acpica/acnamesp.h> 125 #include <contrib/dev/acpica/acapps.h> 126 127 128 #define _COMPONENT ACPI_TOOLS 129 ACPI_MODULE_NAME ("adwalk") 130 131 /* 132 * aslmap - opcode mappings and reserved method names 133 */ 134 ACPI_OBJECT_TYPE 135 AslMapNamedOpcodeToDataType ( 136 UINT16 Opcode); 137 138 /* Local prototypes */ 139 140 static ACPI_STATUS 141 AcpiDmFindOrphanDescending ( 142 ACPI_PARSE_OBJECT *Op, 143 UINT32 Level, 144 void *Context); 145 146 static ACPI_STATUS 147 AcpiDmDumpDescending ( 148 ACPI_PARSE_OBJECT *Op, 149 UINT32 Level, 150 void *Context); 151 152 static ACPI_STATUS 153 AcpiDmXrefDescendingOp ( 154 ACPI_PARSE_OBJECT *Op, 155 UINT32 Level, 156 void *Context); 157 158 static ACPI_STATUS 159 AcpiDmCommonAscendingOp ( 160 ACPI_PARSE_OBJECT *Op, 161 UINT32 Level, 162 void *Context); 163 164 static ACPI_STATUS 165 AcpiDmLoadDescendingOp ( 166 ACPI_PARSE_OBJECT *Op, 167 UINT32 Level, 168 void *Context); 169 170 static UINT32 171 AcpiDmInspectPossibleArgs ( 172 UINT32 CurrentOpArgCount, 173 UINT32 TargetCount, 174 ACPI_PARSE_OBJECT *Op); 175 176 static ACPI_STATUS 177 AcpiDmResourceDescendingOp ( 178 ACPI_PARSE_OBJECT *Op, 179 UINT32 Level, 180 void *Context); 181 182 183 /******************************************************************************* 184 * 185 * FUNCTION: AcpiDmDumpTree 186 * 187 * PARAMETERS: Origin - Starting object 188 * 189 * RETURN: None 190 * 191 * DESCRIPTION: Parse tree walk to format and output the nodes 192 * 193 ******************************************************************************/ 194 195 void 196 AcpiDmDumpTree ( 197 ACPI_PARSE_OBJECT *Origin) 198 { 199 ACPI_OP_WALK_INFO Info; 200 201 202 if (!Origin) 203 { 204 return; 205 } 206 207 AcpiOsPrintf ("/*\nAML Parse Tree\n\n"); 208 Info.Flags = 0; 209 Info.Count = 0; 210 Info.Level = 0; 211 Info.WalkState = NULL; 212 AcpiDmWalkParseTree (Origin, AcpiDmDumpDescending, NULL, &Info); 213 AcpiOsPrintf ("*/\n\n"); 214 } 215 216 217 /******************************************************************************* 218 * 219 * FUNCTION: AcpiDmFindOrphanMethods 220 * 221 * PARAMETERS: Origin - Starting object 222 * 223 * RETURN: None 224 * 225 * DESCRIPTION: Parse tree walk to find "orphaned" method invocations -- methods 226 * that are not resolved in the namespace 227 * 228 ******************************************************************************/ 229 230 void 231 AcpiDmFindOrphanMethods ( 232 ACPI_PARSE_OBJECT *Origin) 233 { 234 ACPI_OP_WALK_INFO Info; 235 236 237 if (!Origin) 238 { 239 return; 240 } 241 242 Info.Flags = 0; 243 Info.Level = 0; 244 Info.WalkState = NULL; 245 AcpiDmWalkParseTree (Origin, AcpiDmFindOrphanDescending, NULL, &Info); 246 } 247 248 249 /******************************************************************************* 250 * 251 * FUNCTION: AcpiDmFinishNamespaceLoad 252 * 253 * PARAMETERS: ParseTreeRoot - Root of the parse tree 254 * NamespaceRoot - Root of the internal namespace 255 * 256 * RETURN: None 257 * 258 * DESCRIPTION: Load all namespace items that are created within control 259 * methods. Used before namespace cross reference 260 * 261 ******************************************************************************/ 262 263 void 264 AcpiDmFinishNamespaceLoad ( 265 ACPI_PARSE_OBJECT *ParseTreeRoot, 266 ACPI_NAMESPACE_NODE *NamespaceRoot) 267 { 268 ACPI_STATUS Status; 269 ACPI_OP_WALK_INFO Info; 270 ACPI_WALK_STATE *WalkState; 271 272 273 if (!ParseTreeRoot) 274 { 275 return; 276 } 277 278 /* Create and initialize a new walk state */ 279 280 WalkState = AcpiDsCreateWalkState (0, ParseTreeRoot, NULL, NULL); 281 if (!WalkState) 282 { 283 return; 284 } 285 286 Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState); 287 if (ACPI_FAILURE (Status)) 288 { 289 return; 290 } 291 292 Info.Flags = 0; 293 Info.Level = 0; 294 Info.WalkState = WalkState; 295 AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmLoadDescendingOp, 296 AcpiDmCommonAscendingOp, &Info); 297 ACPI_FREE (WalkState); 298 } 299 300 301 /******************************************************************************* 302 * 303 * FUNCTION: AcpiDmCrossReferenceNamespace 304 * 305 * PARAMETERS: ParseTreeRoot - Root of the parse tree 306 * NamespaceRoot - Root of the internal namespace 307 * 308 * RETURN: None 309 * 310 * DESCRIPTION: Cross reference the namespace to create externals 311 * 312 ******************************************************************************/ 313 314 void 315 AcpiDmCrossReferenceNamespace ( 316 ACPI_PARSE_OBJECT *ParseTreeRoot, 317 ACPI_NAMESPACE_NODE *NamespaceRoot) 318 { 319 ACPI_STATUS Status; 320 ACPI_OP_WALK_INFO Info; 321 ACPI_WALK_STATE *WalkState; 322 323 324 if (!ParseTreeRoot) 325 { 326 return; 327 } 328 329 /* Create and initialize a new walk state */ 330 331 WalkState = AcpiDsCreateWalkState (0, ParseTreeRoot, NULL, NULL); 332 if (!WalkState) 333 { 334 return; 335 } 336 337 Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState); 338 if (ACPI_FAILURE (Status)) 339 { 340 return; 341 } 342 343 Info.Flags = 0; 344 Info.Level = 0; 345 Info.WalkState = WalkState; 346 AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmXrefDescendingOp, 347 AcpiDmCommonAscendingOp, &Info); 348 ACPI_FREE (WalkState); 349 } 350 351 352 /******************************************************************************* 353 * 354 * FUNCTION: AcpiDmConvertResourceIndexes 355 * 356 * PARAMETERS: ParseTreeRoot - Root of the parse tree 357 * NamespaceRoot - Root of the internal namespace 358 * 359 * RETURN: None 360 * 361 * DESCRIPTION: Convert fixed-offset references to resource descriptors to 362 * symbolic references. Should only be called after namespace has 363 * been cross referenced. 364 * 365 ******************************************************************************/ 366 367 void 368 AcpiDmConvertResourceIndexes ( 369 ACPI_PARSE_OBJECT *ParseTreeRoot, 370 ACPI_NAMESPACE_NODE *NamespaceRoot) 371 { 372 ACPI_STATUS Status; 373 ACPI_OP_WALK_INFO Info; 374 ACPI_WALK_STATE *WalkState; 375 376 377 if (!ParseTreeRoot) 378 { 379 return; 380 } 381 382 /* Create and initialize a new walk state */ 383 384 WalkState = AcpiDsCreateWalkState (0, ParseTreeRoot, NULL, NULL); 385 if (!WalkState) 386 { 387 return; 388 } 389 390 Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState); 391 if (ACPI_FAILURE (Status)) 392 { 393 return; 394 } 395 396 Info.Flags = 0; 397 Info.Level = 0; 398 Info.WalkState = WalkState; 399 AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmResourceDescendingOp, 400 AcpiDmCommonAscendingOp, &Info); 401 ACPI_FREE (WalkState); 402 return; 403 } 404 405 406 /******************************************************************************* 407 * 408 * FUNCTION: AcpiDmDumpDescending 409 * 410 * PARAMETERS: ASL_WALK_CALLBACK 411 * 412 * RETURN: Status 413 * 414 * DESCRIPTION: Format and print contents of one parse Op. 415 * 416 ******************************************************************************/ 417 418 static ACPI_STATUS 419 AcpiDmDumpDescending ( 420 ACPI_PARSE_OBJECT *Op, 421 UINT32 Level, 422 void *Context) 423 { 424 ACPI_OP_WALK_INFO *Info = Context; 425 const ACPI_OPCODE_INFO *OpInfo; 426 char *Path; 427 428 429 if (!Op) 430 { 431 return (AE_OK); 432 } 433 434 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 435 Info->Count++; 436 437 /* Most of the information (count, level, name) here */ 438 439 AcpiOsPrintf ("% 5d [%2.2d] ", Info->Count, Level); 440 AcpiDmIndent (Level); 441 AcpiOsPrintf ("%-28s", AcpiPsGetOpcodeName (Op->Common.AmlOpcode)); 442 443 /* Extra info is helpful */ 444 445 switch (Op->Common.AmlOpcode) 446 { 447 case AML_BYTE_OP: 448 case AML_WORD_OP: 449 case AML_DWORD_OP: 450 AcpiOsPrintf ("%X", (UINT32) Op->Common.Value.Integer); 451 break; 452 453 case AML_INT_NAMEPATH_OP: 454 if (Op->Common.Value.String) 455 { 456 AcpiNsExternalizeName (ACPI_UINT32_MAX, Op->Common.Value.String, 457 NULL, &Path); 458 AcpiOsPrintf ("%s %p", Path, Op->Common.Node); 459 ACPI_FREE (Path); 460 } 461 else 462 { 463 AcpiOsPrintf ("[NULL]"); 464 } 465 break; 466 467 case AML_NAME_OP: 468 case AML_METHOD_OP: 469 case AML_DEVICE_OP: 470 case AML_INT_NAMEDFIELD_OP: 471 AcpiOsPrintf ("%4.4s", &Op->Named.Name); 472 break; 473 } 474 475 AcpiOsPrintf ("\n"); 476 return (AE_OK); 477 } 478 479 480 /******************************************************************************* 481 * 482 * FUNCTION: AcpiDmFindOrphanDescending 483 * 484 * PARAMETERS: ASL_WALK_CALLBACK 485 * 486 * RETURN: Status 487 * 488 * DESCRIPTION: Check namepath Ops for orphaned method invocations 489 * 490 * Note: Experimental. 491 * 492 ******************************************************************************/ 493 494 static ACPI_STATUS 495 AcpiDmFindOrphanDescending ( 496 ACPI_PARSE_OBJECT *Op, 497 UINT32 Level, 498 void *Context) 499 { 500 const ACPI_OPCODE_INFO *OpInfo; 501 ACPI_PARSE_OBJECT *ChildOp; 502 ACPI_PARSE_OBJECT *NextOp; 503 ACPI_PARSE_OBJECT *ParentOp; 504 UINT32 ArgCount; 505 506 507 if (!Op) 508 { 509 return (AE_OK); 510 } 511 512 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 513 514 switch (Op->Common.AmlOpcode) 515 { 516 #ifdef ACPI_UNDER_DEVELOPMENT 517 case AML_ADD_OP: 518 ChildOp = Op->Common.Value.Arg; 519 if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) && 520 !ChildOp->Common.Node) 521 { 522 AcpiNsExternalizeName (ACPI_UINT32_MAX, ChildOp->Common.Value.String, 523 NULL, &Path); 524 AcpiOsPrintf ("/* %-16s A-NAMEPATH: %s */\n", Op->Common.AmlOpName, Path); 525 ACPI_FREE (Path); 526 527 NextOp = Op->Common.Next; 528 if (!NextOp) 529 { 530 /* This NamePath has no args, assume it is an integer */ 531 532 AcpiDmAddToExternalList (ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0); 533 return (AE_OK); 534 } 535 536 ArgCount = AcpiDmInspectPossibleArgs (3, 1, NextOp); 537 AcpiOsPrintf ("/* A-CHILDREN: %d Actual %d */\n", ArgCount, AcpiDmCountChildren (Op)); 538 539 if (ArgCount < 1) 540 { 541 /* One Arg means this is just a Store(Name,Target) */ 542 543 AcpiDmAddToExternalList (ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0); 544 return (AE_OK); 545 } 546 547 AcpiDmAddToExternalList (ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount); 548 } 549 break; 550 #endif 551 552 case AML_STORE_OP: 553 554 ChildOp = Op->Common.Value.Arg; 555 if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) && 556 !ChildOp->Common.Node) 557 { 558 NextOp = Op->Common.Next; 559 if (!NextOp) 560 { 561 /* This NamePath has no args, assume it is an integer */ 562 563 AcpiDmAddToExternalList (ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0); 564 return (AE_OK); 565 } 566 567 ArgCount = AcpiDmInspectPossibleArgs (2, 1, NextOp); 568 if (ArgCount <= 1) 569 { 570 /* One Arg means this is just a Store(Name,Target) */ 571 572 AcpiDmAddToExternalList (ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0); 573 return (AE_OK); 574 } 575 576 AcpiDmAddToExternalList (ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount); 577 } 578 break; 579 580 case AML_INT_NAMEPATH_OP: 581 582 /* Must examine parent to see if this namepath is an argument */ 583 584 ParentOp = Op->Common.Parent; 585 OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode); 586 587 if ((OpInfo->Class != AML_CLASS_EXECUTE) && 588 (OpInfo->Class != AML_CLASS_CREATE) && 589 (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) && 590 !Op->Common.Node) 591 { 592 ArgCount = AcpiDmInspectPossibleArgs (0, 0, Op->Common.Next); 593 594 /* 595 * Check if namepath is a predicate for if/while or lone parameter to 596 * a return. 597 */ 598 if (ArgCount == 0) 599 { 600 if (((ParentOp->Common.AmlOpcode == AML_IF_OP) || 601 (ParentOp->Common.AmlOpcode == AML_WHILE_OP) || 602 (ParentOp->Common.AmlOpcode == AML_RETURN_OP)) && 603 604 /* And namepath is the first argument */ 605 (ParentOp->Common.Value.Arg == Op)) 606 { 607 AcpiDmAddToExternalList (Op->Common.Value.String, ACPI_TYPE_INTEGER, 0); 608 break; 609 } 610 } 611 612 /* 613 * This is a standalone namestring (not a parameter to another 614 * operator) - it *must* be a method invocation, nothing else is 615 * grammatically possible. 616 */ 617 AcpiDmAddToExternalList (Op->Common.Value.String, ACPI_TYPE_METHOD, ArgCount); 618 619 } 620 break; 621 } 622 623 return (AE_OK); 624 } 625 626 627 /******************************************************************************* 628 * 629 * FUNCTION: AcpiDmLoadDescendingOp 630 * 631 * PARAMETERS: ASL_WALK_CALLBACK 632 * 633 * RETURN: Status 634 * 635 * DESCRIPTION: Descending handler for namespace control method object load 636 * 637 ******************************************************************************/ 638 639 static ACPI_STATUS 640 AcpiDmLoadDescendingOp ( 641 ACPI_PARSE_OBJECT *Op, 642 UINT32 Level, 643 void *Context) 644 { 645 ACPI_OP_WALK_INFO *Info = Context; 646 const ACPI_OPCODE_INFO *OpInfo; 647 ACPI_WALK_STATE *WalkState; 648 ACPI_OBJECT_TYPE ObjectType; 649 ACPI_STATUS Status; 650 char *Path = NULL; 651 ACPI_PARSE_OBJECT *NextOp; 652 ACPI_NAMESPACE_NODE *Node; 653 654 655 WalkState = Info->WalkState; 656 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 657 ObjectType = OpInfo->ObjectType; 658 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 659 660 /* Only interested in operators that create new names */ 661 662 if (!(OpInfo->Flags & AML_NAMED) && 663 !(OpInfo->Flags & AML_CREATE)) 664 { 665 goto Exit; 666 } 667 668 /* Get the NamePath from the appropriate place */ 669 670 if (OpInfo->Flags & AML_NAMED) 671 { 672 /* For all named operators, get the new name */ 673 674 Path = (char *) Op->Named.Path; 675 } 676 else if (OpInfo->Flags & AML_CREATE) 677 { 678 /* New name is the last child */ 679 680 NextOp = Op->Common.Value.Arg; 681 682 while (NextOp->Common.Next) 683 { 684 NextOp = NextOp->Common.Next; 685 } 686 Path = NextOp->Common.Value.String; 687 } 688 689 if (!Path) 690 { 691 goto Exit; 692 } 693 694 /* Insert the name into the namespace */ 695 696 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, 697 ACPI_IMODE_LOAD_PASS2, ACPI_NS_DONT_OPEN_SCOPE, 698 WalkState, &Node); 699 700 Op->Common.Node = Node; 701 702 703 Exit: 704 705 if (AcpiNsOpensScope (ObjectType)) 706 { 707 if (Op->Common.Node) 708 { 709 Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState); 710 if (ACPI_FAILURE (Status)) 711 { 712 return (Status); 713 } 714 } 715 } 716 717 return (AE_OK); 718 } 719 720 721 /******************************************************************************* 722 * 723 * FUNCTION: AcpiDmXrefDescendingOp 724 * 725 * PARAMETERS: ASL_WALK_CALLBACK 726 * 727 * RETURN: Status 728 * 729 * DESCRIPTION: Descending handler for namespace cross reference 730 * 731 ******************************************************************************/ 732 733 static ACPI_STATUS 734 AcpiDmXrefDescendingOp ( 735 ACPI_PARSE_OBJECT *Op, 736 UINT32 Level, 737 void *Context) 738 { 739 ACPI_OP_WALK_INFO *Info = Context; 740 const ACPI_OPCODE_INFO *OpInfo; 741 ACPI_WALK_STATE *WalkState; 742 ACPI_OBJECT_TYPE ObjectType; 743 ACPI_STATUS Status; 744 char *Path = NULL; 745 ACPI_PARSE_OBJECT *NextOp; 746 ACPI_NAMESPACE_NODE *Node; 747 748 749 WalkState = Info->WalkState; 750 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 751 ObjectType = OpInfo->ObjectType; 752 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 753 754 if ((!(OpInfo->Flags & AML_NAMED)) && 755 (!(OpInfo->Flags & AML_CREATE)) && 756 (Op->Common.AmlOpcode != AML_INT_NAMEPATH_OP)) 757 { 758 goto Exit; 759 } 760 761 /* Get the NamePath from the appropriate place */ 762 763 if (OpInfo->Flags & AML_NAMED) 764 { 765 if ((Op->Common.AmlOpcode == AML_ALIAS_OP) || 766 (Op->Common.AmlOpcode == AML_SCOPE_OP)) 767 { 768 /* 769 * Only these two operators refer to an existing name, 770 * first argument 771 */ 772 Path = (char *) Op->Named.Path; 773 } 774 } 775 else if (OpInfo->Flags & AML_CREATE) 776 { 777 /* Referenced Buffer Name is the first child */ 778 779 NextOp = Op->Common.Value.Arg; 780 if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) 781 { 782 Path = NextOp->Common.Value.String; 783 } 784 } 785 else 786 { 787 Path = Op->Common.Value.String; 788 } 789 790 if (!Path) 791 { 792 goto Exit; 793 } 794 795 /* 796 * Lookup the name in the namespace. Name must exist at this point, or it 797 * is an invalid reference. 798 * 799 * The namespace is also used as a lookup table for references to resource 800 * descriptors and the fields within them. 801 */ 802 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 803 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 804 WalkState, &Node); 805 if (ACPI_FAILURE (Status)) 806 { 807 if (Status == AE_NOT_FOUND) 808 { 809 AcpiDmAddToExternalList (Path, (UINT8) ObjectType, 0); 810 811 /* 812 * We could install this into the namespace, but we catch duplicate 813 * externals when they are added to the list. 814 */ 815 #if 0 816 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 817 ACPI_IMODE_LOAD_PASS1, ACPI_NS_DONT_OPEN_SCOPE, 818 WalkState, &Node); 819 #endif 820 } 821 } 822 else 823 { 824 Op->Common.Node = Node; 825 } 826 827 828 Exit: 829 /* Open new scope if necessary */ 830 831 if (AcpiNsOpensScope (ObjectType)) 832 { 833 if (Op->Common.Node) 834 { 835 Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState); 836 if (ACPI_FAILURE (Status)) 837 { 838 return (Status); 839 } 840 } 841 } 842 843 return (AE_OK); 844 } 845 846 847 /******************************************************************************* 848 * 849 * FUNCTION: AcpiDmResourceDescendingOp 850 * 851 * PARAMETERS: ASL_WALK_CALLBACK 852 * 853 * RETURN: None 854 * 855 * DESCRIPTION: Process one parse op during symbolic resource index conversion. 856 * 857 ******************************************************************************/ 858 859 static ACPI_STATUS 860 AcpiDmResourceDescendingOp ( 861 ACPI_PARSE_OBJECT *Op, 862 UINT32 Level, 863 void *Context) 864 { 865 ACPI_OP_WALK_INFO *Info = Context; 866 const ACPI_OPCODE_INFO *OpInfo; 867 ACPI_WALK_STATE *WalkState; 868 ACPI_OBJECT_TYPE ObjectType; 869 ACPI_STATUS Status; 870 871 872 WalkState = Info->WalkState; 873 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 874 875 /* Open new scope if necessary */ 876 877 ObjectType = OpInfo->ObjectType; 878 if (AcpiNsOpensScope (ObjectType)) 879 { 880 if (Op->Common.Node) 881 { 882 883 Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState); 884 if (ACPI_FAILURE (Status)) 885 { 886 return (Status); 887 } 888 } 889 } 890 891 /* 892 * Check if this operator contains a reference to a resource descriptor. 893 * If so, convert the reference into a symbolic reference. 894 */ 895 AcpiDmCheckResourceReference (Op, WalkState); 896 return (AE_OK); 897 } 898 899 900 /******************************************************************************* 901 * 902 * FUNCTION: AcpiDmCommonAscendingOp 903 * 904 * PARAMETERS: ASL_WALK_CALLBACK 905 * 906 * RETURN: None 907 * 908 * DESCRIPTION: Ascending handler for combined parse/namespace walks. Closes 909 * scope if necessary. 910 * 911 ******************************************************************************/ 912 913 static ACPI_STATUS 914 AcpiDmCommonAscendingOp ( 915 ACPI_PARSE_OBJECT *Op, 916 UINT32 Level, 917 void *Context) 918 { 919 ACPI_OP_WALK_INFO *Info = Context; 920 const ACPI_OPCODE_INFO *OpInfo; 921 ACPI_OBJECT_TYPE ObjectType; 922 923 924 /* Close scope if necessary */ 925 926 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 927 ObjectType = OpInfo->ObjectType; 928 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 929 930 if (AcpiNsOpensScope (ObjectType)) 931 { 932 (void) AcpiDsScopeStackPop (Info->WalkState); 933 } 934 935 return (AE_OK); 936 } 937 938 939 /******************************************************************************* 940 * 941 * FUNCTION: AcpiDmInspectPossibleArgs 942 * 943 * PARAMETERS: CurrentOpArgCount - Which arg of the current op was the 944 * possible method invocation found 945 * TargetCount - Number of targets (0,1,2) for this op 946 * Op - Parse op 947 * 948 * RETURN: Status 949 * 950 * DESCRIPTION: Examine following args and next ops for possible arguments 951 * for an unrecognized method invocation. 952 * 953 ******************************************************************************/ 954 955 static UINT32 956 AcpiDmInspectPossibleArgs ( 957 UINT32 CurrentOpArgCount, 958 UINT32 TargetCount, 959 ACPI_PARSE_OBJECT *Op) 960 { 961 const ACPI_OPCODE_INFO *OpInfo; 962 UINT32 i; 963 UINT32 Last = 0; 964 UINT32 Lookahead; 965 966 967 Lookahead = (ACPI_METHOD_NUM_ARGS + TargetCount) - CurrentOpArgCount; 968 969 /* Lookahead for the maximum number of possible arguments */ 970 971 for (i = 0; i < Lookahead; i++) 972 { 973 if (!Op) 974 { 975 break; 976 } 977 978 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 979 980 /* 981 * Any one of these operators is "very probably" not a method arg 982 */ 983 if ((Op->Common.AmlOpcode == AML_STORE_OP) || 984 (Op->Common.AmlOpcode == AML_NOTIFY_OP)) 985 { 986 break; 987 } 988 989 if ((OpInfo->Class != AML_CLASS_EXECUTE) && 990 (OpInfo->Class != AML_CLASS_CONTROL)) 991 { 992 Last = i+1; 993 } 994 995 Op = Op->Common.Next; 996 } 997 998 return (Last); 999 } 1000 1001 1002