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