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