1/****************************************************************************** 2 * 3 * Module Name: adwalk - Application-level disassembler parse tree walk routines 4 * 5 *****************************************************************************/ 6 7/****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2012, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 *****************************************************************************/ 115 116 117#include "acpi.h" 118#include "accommon.h" 119#include "acparser.h" 120#include "amlcode.h" 121#include "acdisasm.h" 122#include "acdispat.h" 123#include "acnamesp.h" 124#include "acapps.h" 125 126 127#define _COMPONENT ACPI_TOOLS 128 ACPI_MODULE_NAME ("adwalk") 129 130/* 131 * aslmap - opcode mappings and reserved method names 132 */ 133ACPI_OBJECT_TYPE 134AslMapNamedOpcodeToDataType ( 135 UINT16 Opcode); 136 137/* Local prototypes */ 138 139static ACPI_STATUS 140AcpiDmFindOrphanDescending ( 141 ACPI_PARSE_OBJECT *Op, 142 UINT32 Level, 143 void *Context); 144 145static ACPI_STATUS 146AcpiDmDumpDescending ( 147 ACPI_PARSE_OBJECT *Op, 148 UINT32 Level, 149 void *Context); 150 151static ACPI_STATUS 152AcpiDmXrefDescendingOp ( 153 ACPI_PARSE_OBJECT *Op, 154 UINT32 Level, 155 void *Context); 156 157static ACPI_STATUS 158AcpiDmCommonAscendingOp ( 159 ACPI_PARSE_OBJECT *Op, 160 UINT32 Level, 161 void *Context); 162 163static ACPI_STATUS 164AcpiDmLoadDescendingOp ( 165 ACPI_PARSE_OBJECT *Op, 166 UINT32 Level, 167 void *Context); 168 169static UINT32 170AcpiDmInspectPossibleArgs ( 171 UINT32 CurrentOpArgCount, 172 UINT32 TargetCount, 173 ACPI_PARSE_OBJECT *Op); 174 175static ACPI_STATUS 176AcpiDmResourceDescendingOp ( 177 ACPI_PARSE_OBJECT *Op, 178 UINT32 Level, 179 void *Context); 180 181 182/******************************************************************************* 183 * 184 * FUNCTION: AcpiDmDumpTree 185 * 186 * PARAMETERS: Origin - Starting object 187 * 188 * RETURN: None 189 * 190 * DESCRIPTION: Parse tree walk to format and output the nodes 191 * 192 ******************************************************************************/ 193 194void 195AcpiDmDumpTree ( 196 ACPI_PARSE_OBJECT *Origin) 197{ 198 ACPI_OP_WALK_INFO Info; 199 200 201 if (!Origin) 202 { 203 return; 204 } 205 206 AcpiOsPrintf ("/*\nAML Parse Tree\n\n"); 207 Info.Flags = 0; 208 Info.Count = 0; 209 Info.Level = 0; 210 Info.WalkState = NULL; 211 AcpiDmWalkParseTree (Origin, AcpiDmDumpDescending, NULL, &Info); 212 AcpiOsPrintf ("*/\n\n"); 213} 214 215 216/******************************************************************************* 217 * 218 * FUNCTION: AcpiDmFindOrphanMethods 219 * 220 * PARAMETERS: Origin - Starting object 221 * 222 * RETURN: None 223 * 224 * DESCRIPTION: Parse tree walk to find "orphaned" method invocations -- methods 225 * that are not resolved in the namespace 226 * 227 ******************************************************************************/ 228 229void 230AcpiDmFindOrphanMethods ( 231 ACPI_PARSE_OBJECT *Origin) 232{ 233 ACPI_OP_WALK_INFO Info; 234 235 236 if (!Origin) 237 { 238 return; 239 } 240 241 Info.Flags = 0; 242 Info.Level = 0; 243 Info.WalkState = NULL; 244 AcpiDmWalkParseTree (Origin, AcpiDmFindOrphanDescending, NULL, &Info); 245} 246 247 248/******************************************************************************* 249 * 250 * FUNCTION: AcpiDmFinishNamespaceLoad 251 * 252 * PARAMETERS: ParseTreeRoot - Root of the parse tree 253 * NamespaceRoot - Root of the internal namespace 254 * OwnerId - OwnerId of the table to be disassembled 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 263void 264AcpiDmFinishNamespaceLoad ( 265 ACPI_PARSE_OBJECT *ParseTreeRoot, 266 ACPI_NAMESPACE_NODE *NamespaceRoot, 267 ACPI_OWNER_ID OwnerId) 268{ 269 ACPI_STATUS Status; 270 ACPI_OP_WALK_INFO Info; 271 ACPI_WALK_STATE *WalkState; 272 273 274 if (!ParseTreeRoot) 275 { 276 return; 277 } 278 279 /* Create and initialize a new walk state */ 280 281 WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL); 282 if (!WalkState) 283 { 284 return; 285 } 286 287 Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState); 288 if (ACPI_FAILURE (Status)) 289 { 290 return; 291 } 292 293 Info.Flags = 0; 294 Info.Level = 0; 295 Info.WalkState = WalkState; 296 AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmLoadDescendingOp, 297 AcpiDmCommonAscendingOp, &Info); 298 ACPI_FREE (WalkState); 299} 300 301 302/******************************************************************************* 303 * 304 * FUNCTION: AcpiDmCrossReferenceNamespace 305 * 306 * PARAMETERS: ParseTreeRoot - Root of the parse tree 307 * NamespaceRoot - Root of the internal namespace 308 * OwnerId - OwnerId of the table to be disassembled 309 * 310 * RETURN: None 311 * 312 * DESCRIPTION: Cross reference the namespace to create externals 313 * 314 ******************************************************************************/ 315 316void 317AcpiDmCrossReferenceNamespace ( 318 ACPI_PARSE_OBJECT *ParseTreeRoot, 319 ACPI_NAMESPACE_NODE *NamespaceRoot, 320 ACPI_OWNER_ID OwnerId) 321{ 322 ACPI_STATUS Status; 323 ACPI_OP_WALK_INFO Info; 324 ACPI_WALK_STATE *WalkState; 325 326 327 if (!ParseTreeRoot) 328 { 329 return; 330 } 331 332 /* Create and initialize a new walk state */ 333 334 WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL); 335 if (!WalkState) 336 { 337 return; 338 } 339 340 Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState); 341 if (ACPI_FAILURE (Status)) 342 { 343 return; 344 } 345 346 Info.Flags = 0; 347 Info.Level = 0; 348 Info.WalkState = WalkState; 349 AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmXrefDescendingOp, 350 AcpiDmCommonAscendingOp, &Info); 351 ACPI_FREE (WalkState); 352} 353 354 355/******************************************************************************* 356 * 357 * FUNCTION: AcpiDmConvertResourceIndexes 358 * 359 * PARAMETERS: ParseTreeRoot - Root of the parse tree 360 * NamespaceRoot - Root of the internal namespace 361 * 362 * RETURN: None 363 * 364 * DESCRIPTION: Convert fixed-offset references to resource descriptors to 365 * symbolic references. Should only be called after namespace has 366 * been cross referenced. 367 * 368 ******************************************************************************/ 369 370void 371AcpiDmConvertResourceIndexes ( 372 ACPI_PARSE_OBJECT *ParseTreeRoot, 373 ACPI_NAMESPACE_NODE *NamespaceRoot) 374{ 375 ACPI_STATUS Status; 376 ACPI_OP_WALK_INFO Info; 377 ACPI_WALK_STATE *WalkState; 378 379 380 if (!ParseTreeRoot) 381 { 382 return; 383 } 384 385 /* Create and initialize a new walk state */ 386 387 WalkState = AcpiDsCreateWalkState (0, ParseTreeRoot, NULL, NULL); 388 if (!WalkState) 389 { 390 return; 391 } 392 393 Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState); 394 if (ACPI_FAILURE (Status)) 395 { 396 return; 397 } 398 399 Info.Flags = 0; 400 Info.Level = 0; 401 Info.WalkState = WalkState; 402 AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmResourceDescendingOp, 403 AcpiDmCommonAscendingOp, &Info); 404 ACPI_FREE (WalkState); 405 return; 406} 407 408 409/******************************************************************************* 410 * 411 * FUNCTION: AcpiDmDumpDescending 412 * 413 * PARAMETERS: ASL_WALK_CALLBACK 414 * 415 * RETURN: Status 416 * 417 * DESCRIPTION: Format and print contents of one parse Op. 418 * 419 ******************************************************************************/ 420 421static ACPI_STATUS 422AcpiDmDumpDescending ( 423 ACPI_PARSE_OBJECT *Op, 424 UINT32 Level, 425 void *Context) 426{ 427 ACPI_OP_WALK_INFO *Info = Context; 428 char *Path; 429 430 431 if (!Op) 432 { 433 return (AE_OK); 434 } 435 436 /* Most of the information (count, level, name) here */ 437 438 Info->Count++; 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_QWORD_OP: 454 AcpiOsPrintf ("%8.8X%8.8X", ACPI_FORMAT_UINT64 (Op->Common.Value.Integer)); 455 break; 456 457 case AML_INT_NAMEPATH_OP: 458 if (Op->Common.Value.String) 459 { 460 AcpiNsExternalizeName (ACPI_UINT32_MAX, Op->Common.Value.String, 461 NULL, &Path); 462 AcpiOsPrintf ("%s %p", Path, Op->Common.Node); 463 ACPI_FREE (Path); 464 } 465 else 466 { 467 AcpiOsPrintf ("[NULL]"); 468 } 469 break; 470 471 case AML_NAME_OP: 472 case AML_METHOD_OP: 473 case AML_DEVICE_OP: 474 case AML_INT_NAMEDFIELD_OP: 475 AcpiOsPrintf ("%4.4s", ACPI_CAST_PTR (char, &Op->Named.Name)); 476 break; 477 478 default: 479 break; 480 } 481 482 AcpiOsPrintf ("\n"); 483 return (AE_OK); 484} 485 486 487/******************************************************************************* 488 * 489 * FUNCTION: AcpiDmFindOrphanDescending 490 * 491 * PARAMETERS: ASL_WALK_CALLBACK 492 * 493 * RETURN: Status 494 * 495 * DESCRIPTION: Check namepath Ops for orphaned method invocations 496 * 497 * Note: Experimental. 498 * 499 ******************************************************************************/ 500 501static ACPI_STATUS 502AcpiDmFindOrphanDescending ( 503 ACPI_PARSE_OBJECT *Op, 504 UINT32 Level, 505 void *Context) 506{ 507 const ACPI_OPCODE_INFO *OpInfo; 508 ACPI_PARSE_OBJECT *ChildOp; 509 ACPI_PARSE_OBJECT *NextOp; 510 ACPI_PARSE_OBJECT *ParentOp; 511 UINT32 ArgCount; 512 513 514 if (!Op) 515 { 516 return (AE_OK); 517 } 518 519 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 520 521 switch (Op->Common.AmlOpcode) 522 { 523#ifdef ACPI_UNDER_DEVELOPMENT 524 case AML_ADD_OP: 525 ChildOp = Op->Common.Value.Arg; 526 if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) && 527 !ChildOp->Common.Node) 528 { 529 AcpiNsExternalizeName (ACPI_UINT32_MAX, ChildOp->Common.Value.String, 530 NULL, &Path); 531 AcpiOsPrintf ("/* %-16s A-NAMEPATH: %s */\n", Op->Common.AmlOpName, Path); 532 ACPI_FREE (Path); 533 534 NextOp = Op->Common.Next; 535 if (!NextOp) 536 { 537 /* This NamePath has no args, assume it is an integer */ 538 539 AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0); 540 return (AE_OK); 541 } 542 543 ArgCount = AcpiDmInspectPossibleArgs (3, 1, NextOp); 544 AcpiOsPrintf ("/* A-CHILDREN: %u Actual %u */\n", ArgCount, AcpiDmCountChildren (Op)); 545 546 if (ArgCount < 1) 547 { 548 /* One Arg means this is just a Store(Name,Target) */ 549 550 AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0); 551 return (AE_OK); 552 } 553 554 AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount); 555 } 556 break; 557#endif 558 559 case AML_STORE_OP: 560 561 ChildOp = Op->Common.Value.Arg; 562 if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) && 563 !ChildOp->Common.Node) 564 { 565 NextOp = Op->Common.Next; 566 if (!NextOp) 567 { 568 /* This NamePath has no args, assume it is an integer */ 569 570 AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0); 571 return (AE_OK); 572 } 573 574 ArgCount = AcpiDmInspectPossibleArgs (2, 1, NextOp); 575 if (ArgCount <= 1) 576 { 577 /* One Arg means this is just a Store(Name,Target) */ 578 579 AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0); 580 return (AE_OK); 581 } 582 583 AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount); 584 } 585 break; 586 587 case AML_INT_NAMEPATH_OP: 588 589 /* Must examine parent to see if this namepath is an argument */ 590 591 ParentOp = Op->Common.Parent; 592 OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode); 593 594 if ((OpInfo->Class != AML_CLASS_EXECUTE) && 595 (OpInfo->Class != AML_CLASS_CREATE) && 596 (OpInfo->ObjectType != ACPI_TYPE_LOCAL_ALIAS) && 597 (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) && 598 !Op->Common.Node) 599 { 600 ArgCount = AcpiDmInspectPossibleArgs (0, 0, Op->Common.Next); 601 602 /* 603 * Check if namepath is a predicate for if/while or lone parameter to 604 * a return. 605 */ 606 if (ArgCount == 0) 607 { 608 if (((ParentOp->Common.AmlOpcode == AML_IF_OP) || 609 (ParentOp->Common.AmlOpcode == AML_WHILE_OP) || 610 (ParentOp->Common.AmlOpcode == AML_RETURN_OP)) && 611 612 /* And namepath is the first argument */ 613 (ParentOp->Common.Value.Arg == Op)) 614 { 615 AcpiDmAddToExternalList (Op, Op->Common.Value.String, ACPI_TYPE_INTEGER, 0); 616 break; 617 } 618 } 619 620 /* 621 * This is a standalone namestring (not a parameter to another 622 * operator) - it *must* be a method invocation, nothing else is 623 * grammatically possible. 624 */ 625 AcpiDmAddToExternalList (Op, Op->Common.Value.String, ACPI_TYPE_METHOD, ArgCount); 626 627 } 628 break; 629 630 default: 631 break; 632 } 633 634 return (AE_OK); 635} 636 637 638/******************************************************************************* 639 * 640 * FUNCTION: AcpiDmLoadDescendingOp 641 * 642 * PARAMETERS: ASL_WALK_CALLBACK 643 * 644 * RETURN: Status 645 * 646 * DESCRIPTION: Descending handler for namespace control method object load 647 * 648 ******************************************************************************/ 649 650static ACPI_STATUS 651AcpiDmLoadDescendingOp ( 652 ACPI_PARSE_OBJECT *Op, 653 UINT32 Level, 654 void *Context) 655{ 656 ACPI_OP_WALK_INFO *Info = Context; 657 const ACPI_OPCODE_INFO *OpInfo; 658 ACPI_WALK_STATE *WalkState; 659 ACPI_OBJECT_TYPE ObjectType; 660 ACPI_STATUS Status; 661 char *Path = NULL; 662 ACPI_PARSE_OBJECT *NextOp; 663 ACPI_NAMESPACE_NODE *Node; 664 char FieldPath[5]; 665 BOOLEAN PreDefined = FALSE; 666 UINT8 PreDefineIndex = 0; 667 668 669 WalkState = Info->WalkState; 670 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 671 ObjectType = OpInfo->ObjectType; 672 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 673 674 /* Only interested in operators that create new names */ 675 676 if (!(OpInfo->Flags & AML_NAMED) && 677 !(OpInfo->Flags & AML_CREATE)) 678 { 679 goto Exit; 680 } 681 682 /* Get the NamePath from the appropriate place */ 683 684 if (OpInfo->Flags & AML_NAMED) 685 { 686 /* For all named operators, get the new name */ 687 688 Path = (char *) Op->Named.Path; 689 690 if (!Path && Op->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP) 691 { 692 *ACPI_CAST_PTR (UINT32, &FieldPath[0]) = Op->Named.Name; 693 FieldPath[4] = 0; 694 Path = FieldPath; 695 } 696 } 697 else if (OpInfo->Flags & AML_CREATE) 698 { 699 /* New name is the last child */ 700 701 NextOp = Op->Common.Value.Arg; 702 703 while (NextOp->Common.Next) 704 { 705 NextOp = NextOp->Common.Next; 706 } 707 Path = NextOp->Common.Value.String; 708 } 709 710 if (!Path) 711 { 712 goto Exit; 713 } 714 715 /* Insert the name into the namespace */ 716 717 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, 718 ACPI_IMODE_LOAD_PASS2, ACPI_NS_DONT_OPEN_SCOPE, 719 WalkState, &Node); 720 721 Op->Common.Node = Node; 722 723 if (ACPI_SUCCESS (Status)) 724 { 725 /* Check if it's a predefined node */ 726 727 while (AcpiGbl_PreDefinedNames[PreDefineIndex].Name) 728 { 729 if (ACPI_COMPARE_NAME (Node->Name.Ascii, 730 AcpiGbl_PreDefinedNames[PreDefineIndex].Name)) 731 { 732 PreDefined = TRUE; 733 break; 734 } 735 736 PreDefineIndex++; 737 } 738 739 /* 740 * Set node owner id if it satisfies all the following conditions: 741 * 1) Not a predefined node, _SB_ etc 742 * 2) Not the root node 743 * 3) Not a node created by Scope 744 */ 745 746 if (!PreDefined && Node != AcpiGbl_RootNode && 747 Op->Common.AmlOpcode != AML_SCOPE_OP) 748 { 749 Node->OwnerId = WalkState->OwnerId; 750 } 751 } 752 753 754Exit: 755 756 if (AcpiNsOpensScope (ObjectType)) 757 { 758 if (Op->Common.Node) 759 { 760 Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState); 761 if (ACPI_FAILURE (Status)) 762 { 763 return (Status); 764 } 765 } 766 } 767 768 return (AE_OK); 769} 770 771 772/******************************************************************************* 773 * 774 * FUNCTION: AcpiDmXrefDescendingOp 775 * 776 * PARAMETERS: ASL_WALK_CALLBACK 777 * 778 * RETURN: Status 779 * 780 * DESCRIPTION: Descending handler for namespace cross reference 781 * 782 ******************************************************************************/ 783 784static ACPI_STATUS 785AcpiDmXrefDescendingOp ( 786 ACPI_PARSE_OBJECT *Op, 787 UINT32 Level, 788 void *Context) 789{ 790 ACPI_OP_WALK_INFO *Info = Context; 791 const ACPI_OPCODE_INFO *OpInfo; 792 ACPI_WALK_STATE *WalkState; 793 ACPI_OBJECT_TYPE ObjectType; 794 ACPI_OBJECT_TYPE ObjectType2; 795 ACPI_STATUS Status; 796 char *Path = NULL; 797 ACPI_PARSE_OBJECT *NextOp; 798 ACPI_NAMESPACE_NODE *Node; 799 ACPI_OPERAND_OBJECT *Object; 800 UINT32 ParamCount = 0; 801 802 803 WalkState = Info->WalkState; 804 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 805 ObjectType = OpInfo->ObjectType; 806 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 807 808 if ((!(OpInfo->Flags & AML_NAMED)) && 809 (!(OpInfo->Flags & AML_CREATE)) && 810 (Op->Common.AmlOpcode != AML_INT_NAMEPATH_OP)) 811 { 812 goto Exit; 813 } 814 815 /* Get the NamePath from the appropriate place */ 816 817 if (OpInfo->Flags & AML_NAMED) 818 { 819 /* 820 * Only these two operators (Alias, Scope) refer to an existing 821 * name, it is the first argument 822 */ 823 if (Op->Common.AmlOpcode == AML_ALIAS_OP) 824 { 825 ObjectType = ACPI_TYPE_ANY; 826 827 NextOp = Op->Common.Value.Arg; 828 NextOp = NextOp->Common.Value.Arg; 829 if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) 830 { 831 Path = NextOp->Common.Value.String; 832 } 833 } 834 else if (Op->Common.AmlOpcode == AML_SCOPE_OP) 835 { 836 Path = (char *) Op->Named.Path; 837 } 838 } 839 else if (OpInfo->Flags & AML_CREATE) 840 { 841 /* Referenced Buffer Name is the first child */ 842 843 ObjectType = ACPI_TYPE_BUFFER; /* Change from TYPE_BUFFER_FIELD */ 844 845 NextOp = Op->Common.Value.Arg; 846 if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) 847 { 848 Path = NextOp->Common.Value.String; 849 } 850 } 851 else 852 { 853 Path = Op->Common.Value.String; 854 } 855 856 if (!Path) 857 { 858 goto Exit; 859 } 860 861 /* 862 * Lookup the name in the namespace. Name must exist at this point, or it 863 * is an invalid reference. 864 * 865 * The namespace is also used as a lookup table for references to resource 866 * descriptors and the fields within them. 867 */ 868 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 869 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 870 WalkState, &Node); 871 if (ACPI_SUCCESS (Status) && (Node->Flags & ANOBJ_IS_EXTERNAL)) 872 { 873 Status = AE_NOT_FOUND; 874 } 875 876 if (ACPI_FAILURE (Status)) 877 { 878 if (Status == AE_NOT_FOUND) 879 { 880 AcpiDmAddToExternalList (Op, Path, (UINT8) ObjectType, 0); 881 882 /* 883 * We could install this into the namespace, but we catch duplicate 884 * externals when they are added to the list. 885 */ 886#if 0 887 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 888 ACPI_IMODE_LOAD_PASS1, ACPI_NS_DONT_OPEN_SCOPE, 889 WalkState, &Node); 890#endif 891 } 892 } 893 894 /* 895 * Found the node in external table, add it to external list 896 * Node->OwnerId == 0 indicates built-in ACPI Names, _OS_ etc 897 */ 898 else if (Node->OwnerId && WalkState->OwnerId != Node->OwnerId) 899 { 900 ObjectType2 = ObjectType; 901 902 Object = AcpiNsGetAttachedObject (Node); 903 if (Object) 904 { 905 ObjectType2 = Object->Common.Type; 906 if (ObjectType2 == ACPI_TYPE_METHOD) 907 { 908 ParamCount = Object->Method.ParamCount; 909 } 910 } 911 912 AcpiDmAddToExternalList (Op, Path, (UINT8) ObjectType2, ParamCount); 913 Op->Common.Node = Node; 914 } 915 else 916 { 917 Op->Common.Node = Node; 918 } 919 920 921Exit: 922 /* Open new scope if necessary */ 923 924 if (AcpiNsOpensScope (ObjectType)) 925 { 926 if (Op->Common.Node) 927 { 928 Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState); 929 if (ACPI_FAILURE (Status)) 930 { 931 return (Status); 932 } 933 } 934 } 935 936 return (AE_OK); 937} 938 939 940/******************************************************************************* 941 * 942 * FUNCTION: AcpiDmResourceDescendingOp 943 * 944 * PARAMETERS: ASL_WALK_CALLBACK 945 * 946 * RETURN: None 947 * 948 * DESCRIPTION: Process one parse op during symbolic resource index conversion. 949 * 950 ******************************************************************************/ 951 952static ACPI_STATUS 953AcpiDmResourceDescendingOp ( 954 ACPI_PARSE_OBJECT *Op, 955 UINT32 Level, 956 void *Context) 957{ 958 ACPI_OP_WALK_INFO *Info = Context; 959 const ACPI_OPCODE_INFO *OpInfo; 960 ACPI_WALK_STATE *WalkState; 961 ACPI_OBJECT_TYPE ObjectType; 962 ACPI_STATUS Status; 963 964 965 WalkState = Info->WalkState; 966 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 967 968 /* Open new scope if necessary */ 969 970 ObjectType = OpInfo->ObjectType; 971 if (AcpiNsOpensScope (ObjectType)) 972 { 973 if (Op->Common.Node) 974 { 975 976 Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState); 977 if (ACPI_FAILURE (Status)) 978 { 979 return (Status); 980 } 981 } 982 } 983 984 /* 985 * Check if this operator contains a reference to a resource descriptor. 986 * If so, convert the reference into a symbolic reference. 987 */ 988 AcpiDmCheckResourceReference (Op, WalkState); 989 return (AE_OK); 990} 991 992 993/******************************************************************************* 994 * 995 * FUNCTION: AcpiDmCommonAscendingOp 996 * 997 * PARAMETERS: ASL_WALK_CALLBACK 998 * 999 * RETURN: None 1000 * 1001 * DESCRIPTION: Ascending handler for combined parse/namespace walks. Closes 1002 * scope if necessary. 1003 * 1004 ******************************************************************************/ 1005 1006static ACPI_STATUS 1007AcpiDmCommonAscendingOp ( 1008 ACPI_PARSE_OBJECT *Op, 1009 UINT32 Level, 1010 void *Context) 1011{ 1012 ACPI_OP_WALK_INFO *Info = Context; 1013 const ACPI_OPCODE_INFO *OpInfo; 1014 ACPI_OBJECT_TYPE ObjectType; 1015 1016 1017 /* Close scope if necessary */ 1018 1019 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 1020 ObjectType = OpInfo->ObjectType; 1021 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 1022 1023 if (AcpiNsOpensScope (ObjectType)) 1024 { 1025 (void) AcpiDsScopeStackPop (Info->WalkState); 1026 } 1027 1028 return (AE_OK); 1029} 1030 1031 1032/******************************************************************************* 1033 * 1034 * FUNCTION: AcpiDmInspectPossibleArgs 1035 * 1036 * PARAMETERS: CurrentOpArgCount - Which arg of the current op was the 1037 * possible method invocation found 1038 * TargetCount - Number of targets (0,1,2) for this op 1039 * Op - Parse op 1040 * 1041 * RETURN: Status 1042 * 1043 * DESCRIPTION: Examine following args and next ops for possible arguments 1044 * for an unrecognized method invocation. 1045 * 1046 ******************************************************************************/ 1047 1048static UINT32 1049AcpiDmInspectPossibleArgs ( 1050 UINT32 CurrentOpArgCount, 1051 UINT32 TargetCount, 1052 ACPI_PARSE_OBJECT *Op) 1053{ 1054 const ACPI_OPCODE_INFO *OpInfo; 1055 UINT32 i; 1056 UINT32 Last = 0; 1057 UINT32 Lookahead; 1058 1059 1060 Lookahead = (ACPI_METHOD_NUM_ARGS + TargetCount) - CurrentOpArgCount; 1061 1062 /* Lookahead for the maximum number of possible arguments */ 1063 1064 for (i = 0; i < Lookahead; i++) 1065 { 1066 if (!Op) 1067 { 1068 break; 1069 } 1070 1071 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 1072 1073 /* 1074 * Any one of these operators is "very probably" not a method arg 1075 */ 1076 if ((Op->Common.AmlOpcode == AML_STORE_OP) || 1077 (Op->Common.AmlOpcode == AML_NOTIFY_OP)) 1078 { 1079 break; 1080 } 1081 1082 if ((OpInfo->Class != AML_CLASS_EXECUTE) && 1083 (OpInfo->Class != AML_CLASS_CONTROL)) 1084 { 1085 Last = i+1; 1086 } 1087 1088 Op = Op->Common.Next; 1089 } 1090 1091 return (Last); 1092} 1093