Home | History | Annotate | Line # | Download | only in common
adwalk.c revision 1.1.1.14
      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 #ifdef ACPI_UNDER_DEVELOPMENT
    497     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    498 #endif
    499 
    500     switch (Op->Common.AmlOpcode)
    501     {
    502 #ifdef ACPI_UNDER_DEVELOPMENT
    503     case AML_ADD_OP:
    504 
    505         ChildOp = Op->Common.Value.Arg;
    506         if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
    507             !ChildOp->Common.Node)
    508         {
    509             AcpiNsExternalizeName (ACPI_UINT32_MAX, ChildOp->Common.Value.String,
    510                 NULL, &Path);
    511             AcpiOsPrintf ("/* %-16s A-NAMEPATH: %s  */\n",
    512                 Op->Common.AmlOpName, Path);
    513             ACPI_FREE (Path);
    514 
    515             NextOp = Op->Common.Next;
    516             if (!NextOp)
    517             {
    518                 /* This NamePath has no args, assume it is an integer */
    519 
    520                 AcpiDmAddOpToExternalList (ChildOp,
    521                     ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
    522                 return (AE_OK);
    523             }
    524 
    525             ArgCount = AcpiDmInspectPossibleArgs (3, 1, NextOp);
    526             AcpiOsPrintf ("/* A-CHILDREN: %u Actual %u */\n",
    527                 ArgCount, AcpiDmCountChildren (Op));
    528 
    529             if (ArgCount < 1)
    530             {
    531                 /* One Arg means this is just a Store(Name,Target) */
    532 
    533                 AcpiDmAddOpToExternalList (ChildOp,
    534                     ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
    535                 return (AE_OK);
    536             }
    537 
    538             AcpiDmAddOpToExternalList (ChildOp,
    539                 ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
    540         }
    541         break;
    542 
    543 #endif
    544 
    545     case AML_STORE_OP:
    546 
    547         ChildOp = Op->Common.Value.Arg;
    548         if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
    549             !ChildOp->Common.Node)
    550         {
    551             NextOp = Op->Common.Next;
    552             if (!NextOp)
    553             {
    554                 /* This NamePath has no args, assume it is an integer */
    555 
    556                 AcpiDmAddOpToExternalList (ChildOp,
    557                     ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
    558                 return (AE_OK);
    559             }
    560 
    561             ArgCount = AcpiDmInspectPossibleArgs (2, 1, NextOp);
    562             if (ArgCount <= 1)
    563             {
    564                 /* One Arg means this is just a Store(Name,Target) */
    565 
    566                 AcpiDmAddOpToExternalList (ChildOp,
    567                     ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, ArgCount, 0);
    568                 return (AE_OK);
    569             }
    570 
    571             AcpiDmAddOpToExternalList (ChildOp,
    572                 ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
    573         }
    574         break;
    575 
    576     case AML_INT_NAMEPATH_OP:
    577 
    578         /* Must examine parent to see if this namepath is an argument */
    579 
    580         ParentOp = Op->Common.Parent;
    581         OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode);
    582 
    583         if ((OpInfo->Class != AML_CLASS_EXECUTE) &&
    584             (OpInfo->Class != AML_CLASS_CREATE) &&
    585             (OpInfo->ObjectType != ACPI_TYPE_LOCAL_ALIAS) &&
    586             (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) &&
    587             !Op->Common.Node)
    588         {
    589             ArgCount = AcpiDmInspectPossibleArgs (0, 0, Op);
    590 
    591             /*
    592              * Check if namepath is a predicate for if/while or lone parameter to
    593              * a return.
    594              */
    595             if (ArgCount == 0)
    596             {
    597                 if (((ParentOp->Common.AmlOpcode == AML_IF_OP) ||
    598                      (ParentOp->Common.AmlOpcode == AML_WHILE_OP) ||
    599                      (ParentOp->Common.AmlOpcode == AML_RETURN_OP)) &&
    600 
    601                      /* And namepath is the first argument */
    602                      (ParentOp->Common.Value.Arg == Op))
    603                 {
    604                     AcpiDmAddOpToExternalList (Op,
    605                         Op->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
    606                     break;
    607                 }
    608             }
    609 
    610             /*
    611              * This is a standalone namestring (not a parameter to another
    612              * operator) - it *must* be a method invocation, nothing else is
    613              * grammatically possible.
    614              */
    615             AcpiDmAddOpToExternalList (Op,
    616                 Op->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
    617         }
    618         break;
    619 
    620     default:
    621 
    622         break;
    623     }
    624 
    625     return (AE_OK);
    626 }
    627 
    628 
    629 /*******************************************************************************
    630  *
    631  * FUNCTION:    AcpiDmLoadDescendingOp
    632  *
    633  * PARAMETERS:  ASL_WALK_CALLBACK
    634  *
    635  * RETURN:      Status
    636  *
    637  * DESCRIPTION: Descending handler for namespace control method object load
    638  *
    639  ******************************************************************************/
    640 
    641 static ACPI_STATUS
    642 AcpiDmLoadDescendingOp (
    643     ACPI_PARSE_OBJECT       *Op,
    644     UINT32                  Level,
    645     void                    *Context)
    646 {
    647     ACPI_OP_WALK_INFO       *Info = Context;
    648     const ACPI_OPCODE_INFO  *OpInfo;
    649     ACPI_WALK_STATE         *WalkState;
    650     ACPI_OBJECT_TYPE        ObjectType;
    651     ACPI_STATUS             Status;
    652     char                    *Path = NULL;
    653     ACPI_PARSE_OBJECT       *NextOp;
    654     ACPI_NAMESPACE_NODE     *Node;
    655     char                    FieldPath[5];
    656     BOOLEAN                 PreDefined = FALSE;
    657     UINT8                   PreDefineIndex = 0;
    658 
    659 
    660     WalkState = Info->WalkState;
    661     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    662     ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
    663 
    664     /* Only interested in operators that create new names */
    665 
    666     if (!(OpInfo->Flags & AML_NAMED) &&
    667         !(OpInfo->Flags & AML_CREATE))
    668     {
    669         goto Exit;
    670     }
    671 
    672     /* Get the NamePath from the appropriate place */
    673 
    674     if (OpInfo->Flags & AML_NAMED)
    675     {
    676         /* For all named operators, get the new name */
    677 
    678         Path = Op->Named.Path;
    679 
    680         if (!Path && Op->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
    681         {
    682             *ACPI_CAST_PTR (UINT32, &FieldPath[0]) = Op->Named.Name;
    683             FieldPath[4] = 0;
    684             Path = FieldPath;
    685         }
    686     }
    687     else if (OpInfo->Flags & AML_CREATE)
    688     {
    689         /* New name is the last child */
    690 
    691         NextOp = Op->Common.Value.Arg;
    692 
    693         while (NextOp->Common.Next)
    694         {
    695             NextOp = NextOp->Common.Next;
    696         }
    697 
    698         Path = NextOp->Common.Value.String;
    699     }
    700 
    701     if (!Path)
    702     {
    703         goto Exit;
    704     }
    705 
    706     /* Insert the name into the namespace */
    707 
    708     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
    709         ACPI_IMODE_LOAD_PASS2, ACPI_NS_DONT_OPEN_SCOPE,
    710         WalkState, &Node);
    711 
    712     Op->Common.Node = Node;
    713 
    714     if (ACPI_SUCCESS (Status))
    715     {
    716         /* Check if it's a predefined node */
    717 
    718         while (AcpiGbl_PreDefinedNames[PreDefineIndex].Name)
    719         {
    720             if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii,
    721                 AcpiGbl_PreDefinedNames[PreDefineIndex].Name))
    722             {
    723                 PreDefined = TRUE;
    724                 break;
    725             }
    726 
    727             PreDefineIndex++;
    728         }
    729 
    730         /*
    731          * Set node owner id if it satisfies all the following conditions:
    732          * 1) Not a predefined node, _SB_ etc
    733          * 2) Not the root node
    734          * 3) Not a node created by Scope
    735          */
    736         if (!PreDefined &&
    737             (Node != AcpiGbl_RootNode) &&
    738             (Op->Common.AmlOpcode != AML_SCOPE_OP))
    739         {
    740             Node->OwnerId = WalkState->OwnerId;
    741         }
    742     }
    743 
    744 
    745 Exit:
    746 
    747     if (AcpiNsOpensScope (ObjectType))
    748     {
    749         if (Op->Common.Node)
    750         {
    751             Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType,
    752                 WalkState);
    753             if (ACPI_FAILURE (Status))
    754             {
    755                 return (Status);
    756             }
    757         }
    758     }
    759 
    760     return (AE_OK);
    761 }
    762 
    763 
    764 /*******************************************************************************
    765  *
    766  * FUNCTION:    AcpiDmXrefDescendingOp
    767  *
    768  * PARAMETERS:  ASL_WALK_CALLBACK
    769  *
    770  * RETURN:      Status
    771  *
    772  * DESCRIPTION: Descending handler for namespace cross reference
    773  *
    774  ******************************************************************************/
    775 
    776 static ACPI_STATUS
    777 AcpiDmXrefDescendingOp (
    778     ACPI_PARSE_OBJECT       *Op,
    779     UINT32                  Level,
    780     void                    *Context)
    781 {
    782     ACPI_OP_WALK_INFO       *Info = Context;
    783     const ACPI_OPCODE_INFO  *OpInfo;
    784     ACPI_WALK_STATE         *WalkState;
    785     ACPI_OBJECT_TYPE        ObjectType;
    786     ACPI_OBJECT_TYPE        ObjectType2;
    787     ACPI_STATUS             Status;
    788     char                    *Path = NULL;
    789     ACPI_PARSE_OBJECT       *NextOp;
    790     ACPI_NAMESPACE_NODE     *Node;
    791     ACPI_OPERAND_OBJECT     *Object;
    792     UINT32                  ParamCount = 0;
    793     char                    *Pathname;
    794     UINT16                  Flags = 0;
    795 
    796 
    797     WalkState = Info->WalkState;
    798     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    799     ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
    800 
    801     if ((!(OpInfo->Flags & AML_NAMED)) &&
    802         (!(OpInfo->Flags & AML_CREATE)) &&
    803         (Op->Common.AmlOpcode != AML_INT_NAMEPATH_OP) &&
    804         (Op->Common.AmlOpcode != AML_NOTIFY_OP))
    805     {
    806         goto Exit;
    807     }
    808 
    809     /* Get the NamePath from the appropriate place */
    810 
    811     if (OpInfo->Flags & AML_NAMED)
    812     {
    813         /*
    814          * Only these two operators (Alias, Scope) refer to an existing
    815          * name, it is the first argument
    816          */
    817         if (Op->Common.AmlOpcode == AML_ALIAS_OP)
    818         {
    819             ObjectType = ACPI_TYPE_ANY;
    820 
    821             NextOp = Op->Common.Value.Arg;
    822             NextOp = NextOp->Common.Value.Arg;
    823             if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
    824             {
    825                 Path = NextOp->Common.Value.String;
    826             }
    827         }
    828         else if (Op->Common.AmlOpcode == AML_SCOPE_OP ||
    829                  Op->Common.AmlOpcode == AML_EXTERNAL_OP)
    830         {
    831             Path = Op->Named.Path;
    832         }
    833     }
    834     else if (OpInfo->Flags & AML_CREATE)
    835     {
    836         /* Referenced Buffer Name is the first child */
    837 
    838         ObjectType = ACPI_TYPE_BUFFER; /* Change from TYPE_BUFFER_FIELD */
    839 
    840         NextOp = Op->Common.Value.Arg;
    841         if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
    842         {
    843             Path = NextOp->Common.Value.String;
    844         }
    845     }
    846     else if (Op->Common.AmlOpcode == AML_NOTIFY_OP)
    847     {
    848         Path = Op->Common.Value.Arg->Asl.Value.String;
    849     }
    850     else
    851     {
    852         Path = Op->Common.Value.String;
    853     }
    854 
    855     if (!Path)
    856     {
    857         goto Exit;
    858     }
    859 
    860     /*
    861      * Lookup the name in the namespace. Name must exist at this point, or it
    862      * is an invalid reference.
    863      *
    864      * The namespace is also used as a lookup table for references to resource
    865      * descriptors and the fields within them.
    866      */
    867     Node = NULL;
    868     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
    869         ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
    870         WalkState, &Node);
    871 
    872     if (ACPI_SUCCESS (Status) && (Node->Flags & ANOBJ_IS_EXTERNAL))
    873     {
    874         /* Node was created by an External() statement */
    875 
    876         Status = AE_NOT_FOUND;
    877     }
    878 
    879     if (ACPI_FAILURE (Status))
    880     {
    881         if (Status == AE_NOT_FOUND)
    882         {
    883             /*
    884              * Add this symbol as an external declaration, except if the
    885              * parent is a CondRefOf operator. For this operator, we do not
    886              * need an external, nor do we want one, since this can cause
    887              * disassembly problems if the symbol is actually a control
    888              * method.
    889              */
    890             if (!(Op->Asl.Parent &&
    891                 (Op->Asl.Parent->Asl.AmlOpcode == AML_CONDITIONAL_REF_OF_OP)))
    892             {
    893                 if (Node)
    894                 {
    895                     AcpiDmAddNodeToExternalList (Node,
    896                         (UINT8) ObjectType, 7, Flags);
    897                 }
    898                 else
    899                 {
    900                     AcpiDmAddOpToExternalList (Op, Path,
    901                         (UINT8) ObjectType, 7, Flags);
    902                 }
    903             }
    904         }
    905     }
    906 
    907     /*
    908      * Found the node, but check if it came from an external table.
    909      * Add it to external list. Note: Node->OwnerId == 0 indicates
    910      * one of the built-in ACPI Names (_OS_ etc.) which can safely
    911      * be ignored.
    912      */
    913     else if (Node->OwnerId &&
    914             (WalkState->OwnerId != Node->OwnerId))
    915     {
    916         ObjectType2 = ObjectType;
    917 
    918         Object = AcpiNsGetAttachedObject (Node);
    919         if (Object)
    920         {
    921             ObjectType2 = Object->Common.Type;
    922             if (ObjectType2 == ACPI_TYPE_METHOD)
    923             {
    924                 ParamCount = Object->Method.ParamCount;
    925             }
    926         }
    927 
    928         Pathname = AcpiNsGetExternalPathname (Node);
    929         if (!Pathname)
    930         {
    931             return (AE_NO_MEMORY);
    932         }
    933 
    934         AcpiDmAddNodeToExternalList (Node, (UINT8) ObjectType2,
    935             ParamCount, ACPI_EXT_RESOLVED_REFERENCE);
    936 
    937         ACPI_FREE (Pathname);
    938         Op->Common.Node = Node;
    939     }
    940     else
    941     {
    942         Op->Common.Node = Node;
    943     }
    944 
    945 
    946 Exit:
    947     /* Open new scope if necessary */
    948 
    949     if (AcpiNsOpensScope (ObjectType))
    950     {
    951         if (Op->Common.Node)
    952         {
    953             Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType,
    954                 WalkState);
    955             if (ACPI_FAILURE (Status))
    956             {
    957                 return (Status);
    958             }
    959         }
    960     }
    961 
    962     return (AE_OK);
    963 }
    964 
    965 /*******************************************************************************
    966  *
    967  * FUNCTION:    AcpiDmCommonDescendingOp
    968  *
    969  * PARAMETERS:  ASL_WALK_CALLBACK
    970  *
    971  * RETURN:      ACPI_STATUS
    972  *
    973  * DESCRIPTION: Perform parse tree preprocessing before main disassembly walk.
    974  *
    975  ******************************************************************************/
    976 
    977 static ACPI_STATUS
    978 AcpiDmCommonDescendingOp (
    979     ACPI_PARSE_OBJECT       *Op,
    980     UINT32                  Level,
    981     void                    *Context)
    982 {
    983     ACPI_STATUS             Status;
    984 
    985 
    986     /* Resource descriptor conversion */
    987 
    988     Status = AcpiDmProcessResourceDescriptors (Op, Level, Context);
    989     if (ACPI_FAILURE (Status))
    990     {
    991         return (Status);
    992     }
    993 
    994     /* Switch/Case conversion */
    995 
    996     Status = AcpiDmProcessSwitch (Op);
    997     return (Status);
    998 }
    999 
   1000 
   1001 /*******************************************************************************
   1002  *
   1003  * FUNCTION:    AcpiDmProcessResourceDescriptors
   1004  *
   1005  * PARAMETERS:  ASL_WALK_CALLBACK
   1006  *
   1007  * RETURN:      ACPI_STATUS
   1008  *
   1009  * DESCRIPTION: Convert fixed-offset references to resource descriptors to
   1010  *              symbolic references. Should only be called after namespace has
   1011  *              been cross referenced.
   1012  *
   1013  ******************************************************************************/
   1014 
   1015 static ACPI_STATUS
   1016 AcpiDmProcessResourceDescriptors (
   1017     ACPI_PARSE_OBJECT       *Op,
   1018     UINT32                  Level,
   1019     void                    *Context)
   1020 {
   1021     ACPI_OP_WALK_INFO       *Info = Context;
   1022     const ACPI_OPCODE_INFO  *OpInfo;
   1023     ACPI_WALK_STATE         *WalkState;
   1024     ACPI_OBJECT_TYPE        ObjectType;
   1025     ACPI_STATUS             Status;
   1026 
   1027 
   1028     WalkState = Info->WalkState;
   1029     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
   1030 
   1031     /* Open new scope if necessary */
   1032 
   1033     ObjectType = OpInfo->ObjectType;
   1034     if (AcpiNsOpensScope (ObjectType))
   1035     {
   1036         if (Op->Common.Node)
   1037         {
   1038 
   1039             Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType,
   1040                 WalkState);
   1041             if (ACPI_FAILURE (Status))
   1042             {
   1043                 return (Status);
   1044             }
   1045         }
   1046     }
   1047 
   1048     /*
   1049      * Check if this operator contains a reference to a resource descriptor.
   1050      * If so, convert the reference into a symbolic reference.
   1051      */
   1052     AcpiDmCheckResourceReference (Op, WalkState);
   1053     return (AE_OK);
   1054 }
   1055 
   1056 /*******************************************************************************
   1057  *
   1058  * FUNCTION:    AcpiDmCommonAscendingOp
   1059  *
   1060  * PARAMETERS:  ASL_WALK_CALLBACK
   1061  *
   1062  * RETURN:      None
   1063  *
   1064  * DESCRIPTION: Ascending handler for combined parse/namespace walks. Closes
   1065  *              scope if necessary.
   1066  *
   1067  ******************************************************************************/
   1068 
   1069 static ACPI_STATUS
   1070 AcpiDmCommonAscendingOp (
   1071     ACPI_PARSE_OBJECT       *Op,
   1072     UINT32                  Level,
   1073     void                    *Context)
   1074 {
   1075     ACPI_OP_WALK_INFO       *Info = Context;
   1076     ACPI_OBJECT_TYPE        ObjectType;
   1077 
   1078 
   1079     /* Close scope if necessary */
   1080 
   1081     ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
   1082 
   1083     if (AcpiNsOpensScope (ObjectType))
   1084     {
   1085         (void) AcpiDsScopeStackPop (Info->WalkState);
   1086     }
   1087 
   1088     return (AE_OK);
   1089 }
   1090 
   1091 /*******************************************************************************
   1092  *
   1093  * FUNCTION:    AcpiDmInspectPossibleArgs
   1094  *
   1095  * PARAMETERS:  CurrentOpArgCount   - Which arg of the current op was the
   1096  *                                    possible method invocation found
   1097  *              TargetCount         - Number of targets (0,1,2) for this op
   1098  *              Op                  - Parse op
   1099  *
   1100  * RETURN:      Status
   1101  *
   1102  * DESCRIPTION: Examine following args and next ops for possible arguments
   1103  *              for an unrecognized method invocation.
   1104  *
   1105  ******************************************************************************/
   1106 
   1107 static UINT32
   1108 AcpiDmInspectPossibleArgs (
   1109     UINT32                  CurrentOpArgCount,
   1110     UINT32                  TargetCount,
   1111     ACPI_PARSE_OBJECT       *Op)
   1112 {
   1113     const ACPI_OPCODE_INFO  *OpInfo;
   1114     UINT32                  i;
   1115     UINT32                  ArgumentCount = 0;
   1116     ACPI_PARSE_OBJECT       *NextOp;
   1117     ACPI_PARSE_OBJECT       *ExecuteOp;
   1118 
   1119 
   1120     if (!Op)
   1121     {
   1122         return (0);
   1123     }
   1124 
   1125     /* Lookahead for the maximum number of possible arguments */
   1126 
   1127     NextOp = Op->Common.Next;
   1128 
   1129     for (i = 0; (i < ACPI_METHOD_NUM_ARGS) && NextOp; i++)
   1130     {
   1131         OpInfo = AcpiPsGetOpcodeInfo (NextOp->Common.AmlOpcode);
   1132 
   1133         /* Any one of these operators is "very probably" not a method arg */
   1134 
   1135         if ((NextOp->Common.AmlOpcode == AML_STORE_OP) ||
   1136             (NextOp->Common.AmlOpcode == AML_NOTIFY_OP) ||
   1137             (OpInfo->Class == AML_CLASS_CONTROL) ||
   1138             (OpInfo->Class == AML_CLASS_CREATE) ||
   1139             (OpInfo->Class == AML_CLASS_NAMED_OBJECT))
   1140         {
   1141             break;
   1142         }
   1143 
   1144         if (OpInfo->Class == AML_CLASS_EXECUTE)
   1145         {
   1146             /* Probable that this is method arg if there is no target */
   1147 
   1148             ExecuteOp = NextOp->Common.Value.Arg;
   1149             while (ExecuteOp)
   1150             {
   1151                 if ((ExecuteOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
   1152                     (ExecuteOp->Common.Value.Arg == NULL))
   1153                 {
   1154                     /* No target, could be a method arg */
   1155 
   1156                     break;
   1157                 }
   1158 
   1159                 if (NextOp->Common.AmlOpcode == AML_REF_OF_OP)
   1160                 {
   1161                     break;
   1162                 }
   1163 
   1164                 ExecuteOp = ExecuteOp->Common.Next;
   1165             }
   1166 
   1167             if (!ExecuteOp)
   1168             {
   1169                 /* Has a target, not method arg */
   1170 
   1171                 return (ArgumentCount);
   1172             }
   1173         }
   1174 
   1175         ArgumentCount++;
   1176         NextOp = NextOp->Common.Next;
   1177     }
   1178 
   1179     return (ArgumentCount);
   1180 }
   1181