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