1 /******************************************************************************
   2  *
   3  * Module Name: adwalk - Application-level disassembler parse tree walk routines
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2014, 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 "acpi.h"
  46 #include "accommon.h"
  47 #include "acparser.h"
  48 #include "amlcode.h"
  49 #include "acdisasm.h"
  50 #include "acdispat.h"
  51 #include "acnamesp.h"
  52 #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 
 377         AcpiOsPrintf ("%2.2X", (UINT32) Op->Common.Value.Integer);
 378         break;
 379 
 380     case AML_WORD_OP:
 381 
 382         AcpiOsPrintf ("%4.4X", (UINT32) Op->Common.Value.Integer);
 383         break;
 384 
 385     case AML_DWORD_OP:
 386 
 387         AcpiOsPrintf ("%8.8X", (UINT32) Op->Common.Value.Integer);
 388         break;
 389 
 390     case AML_QWORD_OP:
 391 
 392         AcpiOsPrintf ("%8.8X%8.8X", ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
 393         break;
 394 
 395     case AML_INT_NAMEPATH_OP:
 396 
 397         if (Op->Common.Value.String)
 398         {
 399             AcpiNsExternalizeName (ACPI_UINT32_MAX, Op->Common.Value.String,
 400                             NULL, &Path);
 401             AcpiOsPrintf ("%s %p", Path, Op->Common.Node);
 402             ACPI_FREE (Path);
 403         }
 404         else
 405         {
 406             AcpiOsPrintf ("[NULL]");
 407         }
 408         break;
 409 
 410     case AML_NAME_OP:
 411     case AML_METHOD_OP:
 412     case AML_DEVICE_OP:
 413     case AML_INT_NAMEDFIELD_OP:
 414 
 415         AcpiOsPrintf ("%4.4s", ACPI_CAST_PTR (char, &Op->Named.Name));
 416         break;
 417 
 418     default:
 419 
 420         break;
 421     }
 422 
 423     AcpiOsPrintf ("\n");
 424     return (AE_OK);
 425 }
 426 
 427 
 428 /*******************************************************************************
 429  *
 430  * FUNCTION:    AcpiDmFindOrphanDescending
 431  *
 432  * PARAMETERS:  ASL_WALK_CALLBACK
 433  *
 434  * RETURN:      Status
 435  *
 436  * DESCRIPTION: Check namepath Ops for orphaned method invocations
 437  *
 438  * Note: Experimental.
 439  *
 440  ******************************************************************************/
 441 
 442 static ACPI_STATUS
 443 AcpiDmFindOrphanDescending (
 444     ACPI_PARSE_OBJECT       *Op,
 445     UINT32                  Level,
 446     void                    *Context)
 447 {
 448     const ACPI_OPCODE_INFO  *OpInfo;
 449     ACPI_PARSE_OBJECT       *ChildOp;
 450     ACPI_PARSE_OBJECT       *NextOp;
 451     ACPI_PARSE_OBJECT       *ParentOp;
 452     UINT32                  ArgCount;
 453 
 454 
 455     if (!Op)
 456     {
 457         return (AE_OK);
 458     }
 459 
 460     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
 461 
 462     switch (Op->Common.AmlOpcode)
 463     {
 464 #ifdef ACPI_UNDER_DEVELOPMENT
 465     case AML_ADD_OP:
 466 
 467         ChildOp = Op->Common.Value.Arg;
 468         if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
 469             !ChildOp->Common.Node)
 470         {
 471             AcpiNsExternalizeName (ACPI_UINT32_MAX, ChildOp->Common.Value.String,
 472                 NULL, &Path);
 473             AcpiOsPrintf ("/* %-16s A-NAMEPATH: %s  */\n",
 474                 Op->Common.AmlOpName, Path);
 475             ACPI_FREE (Path);
 476 
 477             NextOp = Op->Common.Next;
 478             if (!NextOp)
 479             {
 480                 /* This NamePath has no args, assume it is an integer */
 481 
 482                 AcpiDmAddOpToExternalList (ChildOp,
 483                     ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
 484                 return (AE_OK);
 485             }
 486 
 487             ArgCount = AcpiDmInspectPossibleArgs (3, 1, NextOp);
 488             AcpiOsPrintf ("/* A-CHILDREN: %u Actual %u */\n",
 489                 ArgCount, AcpiDmCountChildren (Op));
 490 
 491             if (ArgCount < 1)
 492             {
 493                 /* One Arg means this is just a Store(Name,Target) */
 494 
 495                 AcpiDmAddOpToExternalList (ChildOp,
 496                     ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
 497                 return (AE_OK);
 498             }
 499 
 500             AcpiDmAddOpToExternalList (ChildOp,
 501                 ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
 502         }
 503         break;
 504 #endif
 505 
 506     case AML_STORE_OP:
 507 
 508         ChildOp = Op->Common.Value.Arg;
 509         if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
 510             !ChildOp->Common.Node)
 511         {
 512             NextOp = Op->Common.Next;
 513             if (!NextOp)
 514             {
 515                 /* This NamePath has no args, assume it is an integer */
 516 
 517                 AcpiDmAddOpToExternalList (ChildOp,
 518                     ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
 519                 return (AE_OK);
 520             }
 521 
 522             ArgCount = AcpiDmInspectPossibleArgs (2, 1, NextOp);
 523             if (ArgCount <= 1)
 524             {
 525                 /* One Arg means this is just a Store(Name,Target) */
 526 
 527                 AcpiDmAddOpToExternalList (ChildOp,
 528                     ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
 529                 return (AE_OK);
 530             }
 531 
 532             AcpiDmAddOpToExternalList (ChildOp,
 533                 ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
 534         }
 535         break;
 536 
 537     case AML_INT_NAMEPATH_OP:
 538 
 539         /* Must examine parent to see if this namepath is an argument */
 540 
 541         ParentOp = Op->Common.Parent;
 542         OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode);
 543 
 544         if ((OpInfo->Class != AML_CLASS_EXECUTE) &&
 545             (OpInfo->Class != AML_CLASS_CREATE) &&
 546             (OpInfo->ObjectType != ACPI_TYPE_LOCAL_ALIAS) &&
 547             (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) &&
 548             !Op->Common.Node)
 549         {
 550             ArgCount = AcpiDmInspectPossibleArgs (0, 0, Op->Common.Next);
 551 
 552             /*
 553              * Check if namepath is a predicate for if/while or lone parameter to
 554              * a return.
 555              */
 556             if (ArgCount == 0)
 557             {
 558                 if (((ParentOp->Common.AmlOpcode == AML_IF_OP) ||
 559                      (ParentOp->Common.AmlOpcode == AML_WHILE_OP) ||
 560                      (ParentOp->Common.AmlOpcode == AML_RETURN_OP)) &&
 561 
 562                      /* And namepath is the first argument */
 563                      (ParentOp->Common.Value.Arg == Op))
 564                 {
 565                     AcpiDmAddOpToExternalList (Op,
 566                         Op->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
 567                     break;
 568                 }
 569             }
 570 
 571             /*
 572              * This is a standalone namestring (not a parameter to another
 573              * operator) - it *must* be a method invocation, nothing else is
 574              * grammatically possible.
 575              */
 576             AcpiDmAddOpToExternalList (Op,
 577                 Op->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
 578         }
 579         break;
 580 
 581     default:
 582 
 583         break;
 584     }
 585 
 586     return (AE_OK);
 587 }
 588 
 589 
 590 /*******************************************************************************
 591  *
 592  * FUNCTION:    AcpiDmLoadDescendingOp
 593  *
 594  * PARAMETERS:  ASL_WALK_CALLBACK
 595  *
 596  * RETURN:      Status
 597  *
 598  * DESCRIPTION: Descending handler for namespace control method object load
 599  *
 600  ******************************************************************************/
 601 
 602 static ACPI_STATUS
 603 AcpiDmLoadDescendingOp (
 604     ACPI_PARSE_OBJECT       *Op,
 605     UINT32                  Level,
 606     void                    *Context)
 607 {
 608     ACPI_OP_WALK_INFO       *Info = Context;
 609     const ACPI_OPCODE_INFO  *OpInfo;
 610     ACPI_WALK_STATE         *WalkState;
 611     ACPI_OBJECT_TYPE        ObjectType;
 612     ACPI_STATUS             Status;
 613     char                    *Path = NULL;
 614     ACPI_PARSE_OBJECT       *NextOp;
 615     ACPI_NAMESPACE_NODE     *Node;
 616     char                    FieldPath[5];
 617     BOOLEAN                 PreDefined = FALSE;
 618     UINT8                   PreDefineIndex = 0;
 619 
 620 
 621     WalkState = Info->WalkState;
 622     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
 623     ObjectType = OpInfo->ObjectType;
 624     ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
 625 
 626     /* Only interested in operators that create new names */
 627 
 628     if (!(OpInfo->Flags & AML_NAMED) &&
 629         !(OpInfo->Flags & AML_CREATE))
 630     {
 631         goto Exit;
 632     }
 633 
 634     /* Get the NamePath from the appropriate place */
 635 
 636     if (OpInfo->Flags & AML_NAMED)
 637     {
 638         /* For all named operators, get the new name */
 639 
 640         Path = (char *) Op->Named.Path;
 641 
 642         if (!Path && Op->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
 643         {
 644             *ACPI_CAST_PTR (UINT32, &FieldPath[0]) = Op->Named.Name;
 645             FieldPath[4] = 0;
 646             Path = FieldPath;
 647         }
 648     }
 649     else if (OpInfo->Flags & AML_CREATE)
 650     {
 651         /* New name is the last child */
 652 
 653         NextOp = Op->Common.Value.Arg;
 654 
 655         while (NextOp->Common.Next)
 656         {
 657             NextOp = NextOp->Common.Next;
 658         }
 659         Path = NextOp->Common.Value.String;
 660     }
 661 
 662     if (!Path)
 663     {
 664         goto Exit;
 665     }
 666 
 667     /* Insert the name into the namespace */
 668 
 669     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
 670                 ACPI_IMODE_LOAD_PASS2, ACPI_NS_DONT_OPEN_SCOPE,
 671                 WalkState, &Node);
 672 
 673     Op->Common.Node = Node;
 674 
 675     if (ACPI_SUCCESS (Status))
 676     {
 677         /* Check if it's a predefined node */
 678 
 679         while (AcpiGbl_PreDefinedNames[PreDefineIndex].Name)
 680         {
 681             if (ACPI_COMPARE_NAME (Node->Name.Ascii,
 682                 AcpiGbl_PreDefinedNames[PreDefineIndex].Name))
 683             {
 684                 PreDefined = TRUE;
 685                 break;
 686             }
 687 
 688             PreDefineIndex++;
 689         }
 690 
 691         /*
 692          * Set node owner id if it satisfies all the following conditions:
 693          * 1) Not a predefined node, _SB_ etc
 694          * 2) Not the root node
 695          * 3) Not a node created by Scope
 696          */
 697 
 698         if (!PreDefined && Node != AcpiGbl_RootNode &&
 699             Op->Common.AmlOpcode != AML_SCOPE_OP)
 700         {
 701             Node->OwnerId = WalkState->OwnerId;
 702         }
 703     }
 704 
 705 
 706 Exit:
 707 
 708     if (AcpiNsOpensScope (ObjectType))
 709     {
 710         if (Op->Common.Node)
 711         {
 712             Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState);
 713             if (ACPI_FAILURE (Status))
 714             {
 715                 return (Status);
 716             }
 717         }
 718     }
 719 
 720     return (AE_OK);
 721 }
 722 
 723 
 724 /*******************************************************************************
 725  *
 726  * FUNCTION:    AcpiDmXrefDescendingOp
 727  *
 728  * PARAMETERS:  ASL_WALK_CALLBACK
 729  *
 730  * RETURN:      Status
 731  *
 732  * DESCRIPTION: Descending handler for namespace cross reference
 733  *
 734  ******************************************************************************/
 735 
 736 static ACPI_STATUS
 737 AcpiDmXrefDescendingOp (
 738     ACPI_PARSE_OBJECT       *Op,
 739     UINT32                  Level,
 740     void                    *Context)
 741 {
 742     ACPI_OP_WALK_INFO       *Info = Context;
 743     const ACPI_OPCODE_INFO  *OpInfo;
 744     ACPI_WALK_STATE         *WalkState;
 745     ACPI_OBJECT_TYPE        ObjectType;
 746     ACPI_OBJECT_TYPE        ObjectType2;
 747     ACPI_STATUS             Status;
 748     char                    *Path = NULL;
 749     ACPI_PARSE_OBJECT       *NextOp;
 750     ACPI_NAMESPACE_NODE     *Node;
 751     ACPI_OPERAND_OBJECT     *Object;
 752     UINT32                  ParamCount = 0;
 753     char                    *Pathname;
 754 
 755 
 756     WalkState = Info->WalkState;
 757     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
 758     ObjectType = OpInfo->ObjectType;
 759     ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
 760 
 761     if ((!(OpInfo->Flags & AML_NAMED)) &&
 762         (!(OpInfo->Flags & AML_CREATE)) &&
 763         (Op->Common.AmlOpcode != AML_INT_NAMEPATH_OP))
 764     {
 765         goto Exit;
 766     }
 767 
 768     /* Get the NamePath from the appropriate place */
 769 
 770     if (OpInfo->Flags & AML_NAMED)
 771     {
 772         /*
 773          * Only these two operators (Alias, Scope) refer to an existing
 774          * name, it is the first argument
 775          */
 776         if (Op->Common.AmlOpcode == AML_ALIAS_OP)
 777         {
 778             ObjectType = ACPI_TYPE_ANY;
 779 
 780             NextOp = Op->Common.Value.Arg;
 781             NextOp = NextOp->Common.Value.Arg;
 782             if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
 783             {
 784                 Path = NextOp->Common.Value.String;
 785             }
 786         }
 787         else if (Op->Common.AmlOpcode == AML_SCOPE_OP)
 788         {
 789             Path = (char *) Op->Named.Path;
 790         }
 791     }
 792     else if (OpInfo->Flags & AML_CREATE)
 793     {
 794         /* Referenced Buffer Name is the first child */
 795 
 796         ObjectType = ACPI_TYPE_BUFFER; /* Change from TYPE_BUFFER_FIELD */
 797 
 798         NextOp = Op->Common.Value.Arg;
 799         if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
 800         {
 801             Path = NextOp->Common.Value.String;
 802         }
 803     }
 804     else
 805     {
 806         Path = Op->Common.Value.String;
 807     }
 808 
 809     if (!Path)
 810     {
 811         goto Exit;
 812     }
 813 
 814     /*
 815      * Lookup the name in the namespace. Name must exist at this point, or it
 816      * is an invalid reference.
 817      *
 818      * The namespace is also used as a lookup table for references to resource
 819      * descriptors and the fields within them.
 820      */
 821     Node = NULL;
 822     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
 823                 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
 824                 WalkState, &Node);
 825     if (ACPI_SUCCESS (Status) && (Node->Flags & ANOBJ_IS_EXTERNAL))
 826     {
 827         /* Node was created by an External() statement */
 828 
 829         Status = AE_NOT_FOUND;
 830     }
 831 
 832     if (ACPI_FAILURE (Status))
 833     {
 834         if (Status == AE_NOT_FOUND)
 835         {
 836             /*
 837              * Add this symbol as an external declaration, except if the
 838              * parent is a CondRefOf operator. For this operator, we do not
 839              * need an external, nor do we want one, since this can cause
 840              * disassembly problems if the symbol is actually a control
 841              * method.
 842              */
 843             if (!(Op->Asl.Parent &&
 844                 (Op->Asl.Parent->Asl.AmlOpcode == AML_COND_REF_OF_OP)))
 845             {
 846                 if (Node)
 847                 {
 848                     AcpiDmAddNodeToExternalList (Node,
 849                         (UINT8) ObjectType, 0, 0);
 850                 }
 851                 else
 852                 {
 853                     AcpiDmAddOpToExternalList (Op, Path,
 854                         (UINT8) ObjectType, 0, 0);
 855                 }
 856             }
 857         }
 858     }
 859 
 860     /*
 861      * Found the node, but check if it came from an external table.
 862      * Add it to external list. Note: Node->OwnerId == 0 indicates
 863      * one of the built-in ACPI Names (_OS_ etc.) which can safely
 864      * be ignored.
 865      */
 866     else if (Node->OwnerId &&
 867             (WalkState->OwnerId != Node->OwnerId))
 868     {
 869         ObjectType2 = ObjectType;
 870 
 871         Object = AcpiNsGetAttachedObject (Node);
 872         if (Object)
 873         {
 874             ObjectType2 = Object->Common.Type;
 875             if (ObjectType2 == ACPI_TYPE_METHOD)
 876             {
 877                 ParamCount = Object->Method.ParamCount;
 878             }
 879         }
 880 
 881         Pathname = AcpiNsGetExternalPathname (Node);
 882         if (!Pathname)
 883         {
 884             return (AE_NO_MEMORY);
 885         }
 886 
 887         AcpiDmAddNodeToExternalList (Node, (UINT8) ObjectType2,
 888             ParamCount, ACPI_EXT_RESOLVED_REFERENCE);
 889 
 890         ACPI_FREE (Pathname);
 891         Op->Common.Node = Node;
 892     }
 893     else
 894     {
 895         Op->Common.Node = Node;
 896     }
 897 
 898 
 899 Exit:
 900     /* Open new scope if necessary */
 901 
 902     if (AcpiNsOpensScope (ObjectType))
 903     {
 904         if (Op->Common.Node)
 905         {
 906             Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState);
 907             if (ACPI_FAILURE (Status))
 908             {
 909                 return (Status);
 910             }
 911         }
 912     }
 913 
 914     return (AE_OK);
 915 }
 916 
 917 
 918 /*******************************************************************************
 919  *
 920  * FUNCTION:    AcpiDmResourceDescendingOp
 921  *
 922  * PARAMETERS:  ASL_WALK_CALLBACK
 923  *
 924  * RETURN:      None
 925  *
 926  * DESCRIPTION: Process one parse op during symbolic resource index conversion.
 927  *
 928  ******************************************************************************/
 929 
 930 static ACPI_STATUS
 931 AcpiDmResourceDescendingOp (
 932     ACPI_PARSE_OBJECT       *Op,
 933     UINT32                  Level,
 934     void                    *Context)
 935 {
 936     ACPI_OP_WALK_INFO       *Info = Context;
 937     const ACPI_OPCODE_INFO  *OpInfo;
 938     ACPI_WALK_STATE         *WalkState;
 939     ACPI_OBJECT_TYPE        ObjectType;
 940     ACPI_STATUS             Status;
 941 
 942 
 943     WalkState = Info->WalkState;
 944     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
 945 
 946     /* Open new scope if necessary */
 947 
 948     ObjectType = OpInfo->ObjectType;
 949     if (AcpiNsOpensScope (ObjectType))
 950     {
 951         if (Op->Common.Node)
 952         {
 953 
 954             Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState);
 955             if (ACPI_FAILURE (Status))
 956             {
 957                 return (Status);
 958             }
 959         }
 960     }
 961 
 962     /*
 963      * Check if this operator contains a reference to a resource descriptor.
 964      * If so, convert the reference into a symbolic reference.
 965      */
 966     AcpiDmCheckResourceReference (Op, WalkState);
 967     return (AE_OK);
 968 }
 969 
 970 
 971 /*******************************************************************************
 972  *
 973  * FUNCTION:    AcpiDmCommonAscendingOp
 974  *
 975  * PARAMETERS:  ASL_WALK_CALLBACK
 976  *
 977  * RETURN:      None
 978  *
 979  * DESCRIPTION: Ascending handler for combined parse/namespace walks. Closes
 980  *              scope if necessary.
 981  *
 982  ******************************************************************************/
 983 
 984 static ACPI_STATUS
 985 AcpiDmCommonAscendingOp (
 986     ACPI_PARSE_OBJECT       *Op,
 987     UINT32                  Level,
 988     void                    *Context)
 989 {
 990     ACPI_OP_WALK_INFO       *Info = Context;
 991     const ACPI_OPCODE_INFO  *OpInfo;
 992     ACPI_OBJECT_TYPE        ObjectType;
 993 
 994 
 995     /* Close scope if necessary */
 996 
 997     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
 998     ObjectType = OpInfo->ObjectType;
 999     ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
1000 
1001     if (AcpiNsOpensScope (ObjectType))
1002     {
1003         (void) AcpiDsScopeStackPop (Info->WalkState);
1004     }
1005 
1006     return (AE_OK);
1007 }
1008 
1009 
1010 /*******************************************************************************
1011  *
1012  * FUNCTION:    AcpiDmInspectPossibleArgs
1013  *
1014  * PARAMETERS:  CurrentOpArgCount   - Which arg of the current op was the
1015  *                                    possible method invocation found
1016  *              TargetCount         - Number of targets (0,1,2) for this op
1017  *              Op                  - Parse op
1018  *
1019  * RETURN:      Status
1020  *
1021  * DESCRIPTION: Examine following args and next ops for possible arguments
1022  *              for an unrecognized method invocation.
1023  *
1024  ******************************************************************************/
1025 
1026 static UINT32
1027 AcpiDmInspectPossibleArgs (
1028     UINT32                  CurrentOpArgCount,
1029     UINT32                  TargetCount,
1030     ACPI_PARSE_OBJECT       *Op)
1031 {
1032     const ACPI_OPCODE_INFO  *OpInfo;
1033     UINT32                  i;
1034     UINT32                  Last = 0;
1035     UINT32                  Lookahead;
1036 
1037 
1038     Lookahead = (ACPI_METHOD_NUM_ARGS + TargetCount) - CurrentOpArgCount;
1039 
1040     /* Lookahead for the maximum number of possible arguments */
1041 
1042     for (i = 0; i < Lookahead; i++)
1043     {
1044         if (!Op)
1045         {
1046             break;
1047         }
1048 
1049         OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
1050 
1051         /*
1052          * Any one of these operators is "very probably" not a method arg
1053          */
1054         if ((Op->Common.AmlOpcode == AML_STORE_OP) ||
1055             (Op->Common.AmlOpcode == AML_NOTIFY_OP))
1056         {
1057             break;
1058         }
1059 
1060         if ((OpInfo->Class != AML_CLASS_EXECUTE) &&
1061             (OpInfo->Class != AML_CLASS_CONTROL))
1062         {
1063             Last = i+1;
1064         }
1065 
1066         Op = Op->Common.Next;
1067     }
1068 
1069     return (Last);
1070 }