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