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