Home | History | Annotate | Line # | Download | only in common
      1 /******************************************************************************
      2  *
      3  * Module Name: adwalk - Application-level disassembler parse tree walk routines
      4  *
      5  *****************************************************************************/
      6 
      7 /******************************************************************************
      8  *
      9  * 1. Copyright Notice
     10  *
     11  * Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
     12  * All rights reserved.
     13  *
     14  * 2. License
     15  *
     16  * 2.1. This is your license from Intel Corp. under its intellectual property
     17  * rights. You may have additional license terms from the party that provided
     18  * you this software, covering your right to use that party's intellectual
     19  * property rights.
     20  *
     21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
     22  * copy of the source code appearing in this file ("Covered Code") an
     23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
     24  * base code distributed originally by Intel ("Original Intel Code") to copy,
     25  * make derivatives, distribute, use and display any portion of the Covered
     26  * Code in any form, with the right to sublicense such rights; and
     27  *
     28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
     29  * license (with the right to sublicense), under only those claims of Intel
     30  * patents that are infringed by the Original Intel Code, to make, use, sell,
     31  * offer to sell, and import the Covered Code and derivative works thereof
     32  * solely to the minimum extent necessary to exercise the above copyright
     33  * license, and in no event shall the patent license extend to any additions
     34  * to or modifications of the Original Intel Code. No other license or right
     35  * is granted directly or by implication, estoppel or otherwise;
     36  *
     37  * The above copyright and patent license is granted only if the following
     38  * conditions are met:
     39  *
     40  * 3. Conditions
     41  *
     42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
     43  * Redistribution of source code of any substantial portion of the Covered
     44  * Code or modification with rights to further distribute source must include
     45  * the above Copyright Notice, the above License, this list of Conditions,
     46  * and the following Disclaimer and Export Compliance provision. In addition,
     47  * Licensee must cause all Covered Code to which Licensee contributes to
     48  * contain a file documenting the changes Licensee made to create that Covered
     49  * Code and the date of any change. Licensee must include in that file the
     50  * documentation of any changes made by any predecessor Licensee. Licensee
     51  * must include a prominent statement that the modification is derived,
     52  * directly or indirectly, from Original Intel Code.
     53  *
     54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
     55  * Redistribution of source code of any substantial portion of the Covered
     56  * Code or modification without rights to further distribute source must
     57  * include the following Disclaimer and Export Compliance provision in the
     58  * documentation and/or other materials provided with distribution. In
     59  * addition, Licensee may not authorize further sublicense of source of any
     60  * portion of the Covered Code, and must include terms to the effect that the
     61  * license from Licensee to its licensee is limited to the intellectual
     62  * property embodied in the software Licensee provides to its licensee, and
     63  * not to intellectual property embodied in modifications its licensee may
     64  * make.
     65  *
     66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
     67  * substantial portion of the Covered Code or modification must reproduce the
     68  * above Copyright Notice, and the following Disclaimer and Export Compliance
     69  * provision in the documentation and/or other materials provided with the
     70  * distribution.
     71  *
     72  * 3.4. Intel retains all right, title, and interest in and to the Original
     73  * Intel Code.
     74  *
     75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
     76  * Intel shall be used in advertising or otherwise to promote the sale, use or
     77  * other dealings in products derived from or relating to the Covered Code
     78  * without prior written authorization from Intel.
     79  *
     80  * 4. Disclaimer and Export Compliance
     81  *
     82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
     83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
     84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
     85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
     86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
     87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
     88  * PARTICULAR PURPOSE.
     89  *
     90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
     91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
     92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
     93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
     94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
     95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
     96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
     97  * LIMITED REMEDY.
     98  *
     99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
    100  * software or system incorporating such software without first obtaining any
    101  * required license or other approval from the U. S. Department of Commerce or
    102  * any other agency or department of the United States Government. In the
    103  * event Licensee exports any such software from the United States or
    104  * re-exports any such software from a foreign destination, Licensee shall
    105  * ensure that the distribution and export/re-export of the software is in
    106  * compliance with all laws, regulations, orders, or other restrictions of the
    107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
    108  * any of its subsidiaries will export/re-export any technical data, process,
    109  * software, or service, directly or indirectly, to any country for which the
    110  * United States government or any agency thereof requires an export license,
    111  * other governmental approval, or letter of assurance, without first obtaining
    112  * such license, approval or letter.
    113  *
    114  *****************************************************************************
    115  *
    116  * Alternatively, you may choose to be licensed under the terms of the
    117  * following license:
    118  *
    119  * Redistribution and use in source and binary forms, with or without
    120  * modification, are permitted provided that the following conditions
    121  * are met:
    122  * 1. Redistributions of source code must retain the above copyright
    123  *    notice, this list of conditions, and the following disclaimer,
    124  *    without modification.
    125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
    126  *    substantially similar to the "NO WARRANTY" disclaimer below
    127  *    ("Disclaimer") and any redistribution must be conditioned upon
    128  *    including a substantially similar Disclaimer requirement for further
    129  *    binary redistribution.
    130  * 3. Neither the names of the above-listed copyright holders nor the names
    131  *    of any contributors may be used to endorse or promote products derived
    132  *    from this software without specific prior written permission.
    133  *
    134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    145  *
    146  * Alternatively, you may choose to be licensed under the terms of the
    147  * GNU General Public License ("GPL") version 2 as published by the Free
    148  * Software Foundation.
    149  *
    150  *****************************************************************************/
    151 
    152 #include "acpi.h"
    153 #include "accommon.h"
    154 #include "acparser.h"
    155 #include "amlcode.h"
    156 #include "acdisasm.h"
    157 #include "acdispat.h"
    158 #include "acnamesp.h"
    159 #include "acapps.h"
    160 
    161 
    162 #define _COMPONENT          ACPI_TOOLS
    163         ACPI_MODULE_NAME    ("adwalk")
    164 
    165 /*
    166  * aslmap - opcode mappings and reserved method names
    167  */
    168 ACPI_OBJECT_TYPE
    169 AslMapNamedOpcodeToDataType (
    170     UINT16                  Opcode);
    171 
    172 /* Local prototypes */
    173 
    174 static ACPI_STATUS
    175 AcpiDmFindOrphanDescending (
    176     ACPI_PARSE_OBJECT       *Op,
    177     UINT32                  Level,
    178     void                    *Context);
    179 
    180 static ACPI_STATUS
    181 AcpiDmDumpDescending (
    182     ACPI_PARSE_OBJECT       *Op,
    183     UINT32                  Level,
    184     void                    *Context);
    185 
    186 static ACPI_STATUS
    187 AcpiDmXrefDescendingOp (
    188     ACPI_PARSE_OBJECT       *Op,
    189     UINT32                  Level,
    190     void                    *Context);
    191 
    192 static ACPI_STATUS
    193 AcpiDmCommonAscendingOp (
    194     ACPI_PARSE_OBJECT       *Op,
    195     UINT32                  Level,
    196     void                    *Context);
    197 
    198 static ACPI_STATUS
    199 AcpiDmLoadDescendingOp (
    200     ACPI_PARSE_OBJECT       *Op,
    201     UINT32                  Level,
    202     void                    *Context);
    203 
    204 static UINT32
    205 AcpiDmInspectPossibleArgs (
    206     UINT32                  CurrentOpArgCount,
    207     UINT32                  TargetCount,
    208     ACPI_PARSE_OBJECT       *Op);
    209 
    210 static ACPI_STATUS
    211 AcpiDmCommonDescendingOp (
    212     ACPI_PARSE_OBJECT       *Op,
    213     UINT32                  Level,
    214     void                    *Context);
    215 
    216 static ACPI_STATUS
    217 AcpiDmProcessResourceDescriptors (
    218     ACPI_PARSE_OBJECT       *Op,
    219     UINT32                  Level,
    220     void                    *Context);
    221 
    222 /*******************************************************************************
    223  *
    224  * FUNCTION:    AcpiDmDumpTree
    225  *
    226  * PARAMETERS:  Origin              - Starting object
    227  *
    228  * RETURN:      None
    229  *
    230  * DESCRIPTION: Parse tree walk to format and output the nodes
    231  *
    232  ******************************************************************************/
    233 
    234 void
    235 AcpiDmDumpTree (
    236     ACPI_PARSE_OBJECT       *Origin)
    237 {
    238     ACPI_OP_WALK_INFO       Info;
    239 
    240 
    241     if (!Origin)
    242     {
    243         return;
    244     }
    245 
    246     AcpiOsPrintf ("/*\nAML Parse Tree\n\n");
    247     Info.Flags = 0;
    248     Info.Count = 0;
    249     Info.Level = 0;
    250     Info.WalkState = NULL;
    251 
    252     AcpiDmWalkParseTree (Origin, AcpiDmDumpDescending, NULL, &Info);
    253     AcpiOsPrintf ("*/\n\n");
    254 }
    255 
    256 
    257 /*******************************************************************************
    258  *
    259  * FUNCTION:    AcpiDmFindOrphanMethods
    260  *
    261  * PARAMETERS:  Origin              - Starting object
    262  *
    263  * RETURN:      None
    264  *
    265  * DESCRIPTION: Parse tree walk to find "orphaned" method invocations -- methods
    266  *              that are not resolved in the namespace
    267  *
    268  ******************************************************************************/
    269 
    270 void
    271 AcpiDmFindOrphanMethods (
    272     ACPI_PARSE_OBJECT       *Origin)
    273 {
    274     ACPI_OP_WALK_INFO       Info;
    275 
    276 
    277     if (!Origin)
    278     {
    279         return;
    280     }
    281 
    282     Info.Flags = 0;
    283     Info.Level = 0;
    284     Info.WalkState = NULL;
    285 
    286     AcpiDmWalkParseTree (Origin, AcpiDmFindOrphanDescending, NULL, &Info);
    287 }
    288 
    289 
    290 /*******************************************************************************
    291  *
    292  * FUNCTION:    AcpiDmFinishNamespaceLoad
    293  *
    294  * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
    295  *              NamespaceRoot       - Root of the internal namespace
    296  *              OwnerId             - OwnerId of the table to be disassembled
    297  *
    298  * RETURN:      None
    299  *
    300  * DESCRIPTION: Load all namespace items that are created within control
    301  *              methods. Used before namespace cross reference
    302  *
    303  ******************************************************************************/
    304 
    305 void
    306 AcpiDmFinishNamespaceLoad (
    307     ACPI_PARSE_OBJECT       *ParseTreeRoot,
    308     ACPI_NAMESPACE_NODE     *NamespaceRoot,
    309     ACPI_OWNER_ID           OwnerId)
    310 {
    311     ACPI_STATUS             Status;
    312     ACPI_OP_WALK_INFO       Info;
    313     ACPI_WALK_STATE         *WalkState;
    314 
    315 
    316     if (!ParseTreeRoot)
    317     {
    318         return;
    319     }
    320 
    321     /* Create and initialize a new walk state */
    322 
    323     WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL);
    324     if (!WalkState)
    325     {
    326         return;
    327     }
    328 
    329     Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type,
    330         WalkState);
    331     if (ACPI_FAILURE (Status))
    332     {
    333         return;
    334     }
    335 
    336     Info.Flags = 0;
    337     Info.Level = 0;
    338     Info.WalkState = WalkState;
    339 
    340     AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmLoadDescendingOp,
    341         AcpiDmCommonAscendingOp, &Info);
    342     ACPI_FREE (WalkState);
    343 }
    344 
    345 
    346 /*******************************************************************************
    347  *
    348  * FUNCTION:    AcpiDmCrossReferenceNamespace
    349  *
    350  * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
    351  *              NamespaceRoot       - Root of the internal namespace
    352  *              OwnerId             - OwnerId of the table to be disassembled
    353  *
    354  * RETURN:      None
    355  *
    356  * DESCRIPTION: Cross reference the namespace to create externals
    357  *
    358  ******************************************************************************/
    359 
    360 void
    361 AcpiDmCrossReferenceNamespace (
    362     ACPI_PARSE_OBJECT       *ParseTreeRoot,
    363     ACPI_NAMESPACE_NODE     *NamespaceRoot,
    364     ACPI_OWNER_ID           OwnerId)
    365 {
    366     ACPI_STATUS             Status;
    367     ACPI_OP_WALK_INFO       Info;
    368     ACPI_WALK_STATE         *WalkState;
    369 
    370 
    371     if (!ParseTreeRoot)
    372     {
    373         return;
    374     }
    375 
    376     /* Create and initialize a new walk state */
    377 
    378     WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL);
    379     if (!WalkState)
    380     {
    381         return;
    382     }
    383 
    384     Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type,
    385         WalkState);
    386     if (ACPI_FAILURE (Status))
    387     {
    388         return;
    389     }
    390 
    391     Info.Flags = 0;
    392     Info.Level = 0;
    393     Info.WalkState = WalkState;
    394 
    395     AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmXrefDescendingOp,
    396         AcpiDmCommonAscendingOp, &Info);
    397     ACPI_FREE (WalkState);
    398 }
    399 
    400 
    401 /*******************************************************************************
    402  *
    403  * FUNCTION:    AcpiDmConvertParseObjects
    404  *
    405  * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
    406  *              NamespaceRoot       - Root of the internal namespace
    407  *
    408  * RETURN:      None
    409  *
    410  * DESCRIPTION: Begin parse tree walk to perform conversions needed for
    411  *              disassembly. These include resource descriptors and switch/case
    412  *              operations.
    413  *
    414  ******************************************************************************/
    415 
    416 void
    417 AcpiDmConvertParseObjects (
    418     ACPI_PARSE_OBJECT       *ParseTreeRoot,
    419     ACPI_NAMESPACE_NODE     *NamespaceRoot)
    420 {
    421     ACPI_STATUS             Status;
    422     ACPI_OP_WALK_INFO       Info;
    423     ACPI_WALK_STATE         *WalkState;
    424 
    425 
    426     if (!ParseTreeRoot)
    427     {
    428         return;
    429     }
    430 
    431     /* Create and initialize a new walk state */
    432 
    433     WalkState = AcpiDsCreateWalkState (0, ParseTreeRoot, NULL, NULL);
    434     if (!WalkState)
    435     {
    436         return;
    437     }
    438 
    439     Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type,
    440         WalkState);
    441     if (ACPI_FAILURE (Status))
    442     {
    443         ACPI_FREE (WalkState);
    444         return;
    445     }
    446 
    447     Info.Flags = 0;
    448     Info.Level = 0;
    449     Info.WalkState = WalkState;
    450 
    451     AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmCommonDescendingOp,
    452         AcpiDmCommonAscendingOp, &Info);
    453     ACPI_FREE (WalkState);
    454 
    455     if (AcpiGbl_TempListHead) {
    456         AcpiDmClearTempList();
    457     }
    458 
    459     return;
    460 }
    461 
    462 
    463 /*******************************************************************************
    464  *
    465  * FUNCTION:    AcpiDmDumpDescending
    466  *
    467  * PARAMETERS:  ASL_WALK_CALLBACK
    468  *
    469  * RETURN:      Status
    470  *
    471  * DESCRIPTION: Format and print contents of one parse Op.
    472  *
    473  ******************************************************************************/
    474 
    475 static ACPI_STATUS
    476 AcpiDmDumpDescending (
    477     ACPI_PARSE_OBJECT       *Op,
    478     UINT32                  Level,
    479     void                    *Context)
    480 {
    481     ACPI_OP_WALK_INFO       *Info = Context;
    482     char                    *Path;
    483     ACPI_STATUS             Status;
    484 
    485 
    486     if (!Op)
    487     {
    488         return (AE_OK);
    489     }
    490 
    491     /* Most of the information (count, level, name) here */
    492 
    493     Info->Count++;
    494     AcpiOsPrintf ("% 5d [%2.2d] ", Info->Count, Level);
    495     AcpiDmIndent (Level);
    496     AcpiOsPrintf ("%-28s", AcpiPsGetOpcodeName (Op->Common.AmlOpcode));
    497 
    498     /* Extra info is helpful */
    499 
    500     switch (Op->Common.AmlOpcode)
    501     {
    502     case AML_BYTE_OP:
    503 
    504         AcpiOsPrintf ("%2.2X", (UINT32) Op->Common.Value.Integer);
    505         break;
    506 
    507     case AML_WORD_OP:
    508 
    509         AcpiOsPrintf ("%4.4X", (UINT32) Op->Common.Value.Integer);
    510         break;
    511 
    512     case AML_DWORD_OP:
    513 
    514         AcpiOsPrintf ("%8.8X", (UINT32) Op->Common.Value.Integer);
    515         break;
    516 
    517     case AML_QWORD_OP:
    518 
    519         AcpiOsPrintf ("%8.8X%8.8X", ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
    520         break;
    521 
    522     case AML_INT_NAMEPATH_OP:
    523 
    524         if (Op->Common.Value.String)
    525         {
    526             Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Op->Common.Value.String,
    527                 NULL, &Path);
    528             if (ACPI_SUCCESS (Status))
    529             {
    530                 AcpiOsPrintf ("%s %p", Path, Op->Common.Node);
    531                 ACPI_FREE (Path);
    532             }
    533             else
    534             {
    535                 AcpiOsPrintf ("Could not externalize pathname for node [%4.4s]",
    536                     Op->Common.Node->Name.Ascii);
    537             }
    538         }
    539         else
    540         {
    541             AcpiOsPrintf ("[NULL]");
    542         }
    543         break;
    544 
    545     case AML_NAME_OP:
    546     case AML_METHOD_OP:
    547     case AML_DEVICE_OP:
    548 
    549         AcpiOsPrintf ("%4.4s",
    550             ACPI_CAST_PTR (char, &Op->Named.Name));
    551         break;
    552 
    553     case AML_INT_NAMEDFIELD_OP:
    554 
    555         AcpiOsPrintf ("%4.4s Length: (bits) %8.8X%8.8X (bytes) %8.8X%8.8X",
    556             ACPI_CAST_PTR (char, &Op->Named.Name),
    557             ACPI_FORMAT_UINT64 (Op->Common.Value.Integer),
    558             ACPI_FORMAT_UINT64 (Op->Common.Value.Integer / 8));
    559         break;
    560 
    561 
    562     default:
    563 
    564         break;
    565     }
    566 
    567     AcpiOsPrintf ("\n");
    568     return (AE_OK);
    569 }
    570 
    571 
    572 /*******************************************************************************
    573  *
    574  * FUNCTION:    AcpiDmFindOrphanDescending
    575  *
    576  * PARAMETERS:  ASL_WALK_CALLBACK
    577  *
    578  * RETURN:      Status
    579  *
    580  * DESCRIPTION: Check namepath Ops for orphaned method invocations
    581  *
    582  * Note: Parts of this are experimental, under possible further development.
    583  *
    584  ******************************************************************************/
    585 
    586 static ACPI_STATUS
    587 AcpiDmFindOrphanDescending (
    588     ACPI_PARSE_OBJECT       *Op,
    589     UINT32                  Level,
    590     void                    *Context)
    591 {
    592     const ACPI_OPCODE_INFO  *OpInfo;
    593     ACPI_PARSE_OBJECT       *ChildOp;
    594     ACPI_PARSE_OBJECT       *NextOp;
    595     ACPI_PARSE_OBJECT       *ParentOp;
    596     UINT32                  ArgCount;
    597 
    598 
    599     if (!Op)
    600     {
    601         return (AE_OK);
    602     }
    603 
    604 #ifdef ACPI_UNDER_DEVELOPMENT
    605     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    606 #endif
    607 
    608     switch (Op->Common.AmlOpcode)
    609     {
    610 #ifdef ACPI_UNDER_DEVELOPMENT
    611     case AML_ADD_OP:
    612 
    613         ChildOp = Op->Common.Value.Arg;
    614         if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
    615             !ChildOp->Common.Node)
    616         {
    617             AcpiNsExternalizeName (ACPI_UINT32_MAX, ChildOp->Common.Value.String,
    618                 NULL, &Path);
    619             AcpiOsPrintf ("/* %-16s A-NAMEPATH: %s  */\n",
    620                 Op->Common.AmlOpName, Path);
    621             ACPI_FREE (Path);
    622 
    623             NextOp = Op->Common.Next;
    624             if (!NextOp)
    625             {
    626                 /* This NamePath has no args, assume it is an integer */
    627 
    628                 AcpiDmAddOpToExternalList (ChildOp,
    629                     ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
    630                 return (AE_OK);
    631             }
    632 
    633             ArgCount = AcpiDmInspectPossibleArgs (3, 1, NextOp);
    634             AcpiOsPrintf ("/* A-CHILDREN: %u Actual %u */\n",
    635                 ArgCount, AcpiDmCountChildren (Op));
    636 
    637             if (ArgCount < 1)
    638             {
    639                 /* One Arg means this is just a Store(Name,Target) */
    640 
    641                 AcpiDmAddOpToExternalList (ChildOp,
    642                     ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
    643                 return (AE_OK);
    644             }
    645 
    646             AcpiDmAddOpToExternalList (ChildOp,
    647                 ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
    648         }
    649         break;
    650 
    651 #endif
    652 
    653     case AML_STORE_OP:
    654 
    655         ChildOp = Op->Common.Value.Arg;
    656         if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
    657             !ChildOp->Common.Node)
    658         {
    659             NextOp = Op->Common.Next;
    660             if (!NextOp)
    661             {
    662                 /* This NamePath has no args, assume it is an integer */
    663 
    664                 AcpiDmAddOpToExternalList (ChildOp,
    665                     ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
    666                 return (AE_OK);
    667             }
    668 
    669             ArgCount = AcpiDmInspectPossibleArgs (2, 1, NextOp);
    670             if (ArgCount <= 1)
    671             {
    672                 /* One Arg means this is just a Store(Name,Target) */
    673 
    674                 AcpiDmAddOpToExternalList (ChildOp,
    675                     ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, ArgCount, 0);
    676                 return (AE_OK);
    677             }
    678 
    679             AcpiDmAddOpToExternalList (ChildOp,
    680                 ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
    681         }
    682         break;
    683 
    684     case AML_INT_NAMEPATH_OP:
    685 
    686         /* Must examine parent to see if this namepath is an argument */
    687 
    688         ParentOp = Op->Common.Parent;
    689         OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode);
    690 
    691         if ((OpInfo->Class != AML_CLASS_EXECUTE) &&
    692             (OpInfo->Class != AML_CLASS_CREATE) &&
    693             (OpInfo->ObjectType != ACPI_TYPE_LOCAL_ALIAS) &&
    694             (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) &&
    695             !Op->Common.Node)
    696         {
    697             ArgCount = AcpiDmInspectPossibleArgs (0, 0, Op);
    698 
    699             /*
    700              * Check if namepath is a predicate for if/while or lone parameter to
    701              * a return.
    702              */
    703             if (ArgCount == 0)
    704             {
    705                 if (((ParentOp->Common.AmlOpcode == AML_IF_OP) ||
    706                      (ParentOp->Common.AmlOpcode == AML_WHILE_OP) ||
    707                      (ParentOp->Common.AmlOpcode == AML_RETURN_OP)) &&
    708 
    709                      /* And namepath is the first argument */
    710                      (ParentOp->Common.Value.Arg == Op))
    711                 {
    712                     AcpiDmAddOpToExternalList (Op,
    713                         Op->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
    714                     break;
    715                 }
    716             }
    717 
    718             /*
    719              * This is a standalone namestring (not a parameter to another
    720              * operator) - it *must* be a method invocation, nothing else is
    721              * grammatically possible.
    722              */
    723             AcpiDmAddOpToExternalList (Op,
    724                 Op->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
    725         }
    726         break;
    727 
    728     default:
    729 
    730         break;
    731     }
    732 
    733     return (AE_OK);
    734 }
    735 
    736 
    737 /*******************************************************************************
    738  *
    739  * FUNCTION:    AcpiDmLoadDescendingOp
    740  *
    741  * PARAMETERS:  ASL_WALK_CALLBACK
    742  *
    743  * RETURN:      Status
    744  *
    745  * DESCRIPTION: Descending handler for namespace control method object load
    746  *
    747  ******************************************************************************/
    748 
    749 static ACPI_STATUS
    750 AcpiDmLoadDescendingOp (
    751     ACPI_PARSE_OBJECT       *Op,
    752     UINT32                  Level,
    753     void                    *Context)
    754 {
    755     ACPI_OP_WALK_INFO       *Info = Context;
    756     const ACPI_OPCODE_INFO  *OpInfo;
    757     ACPI_WALK_STATE         *WalkState;
    758     ACPI_OBJECT_TYPE        ObjectType;
    759     ACPI_STATUS             Status;
    760     char                    *Path = NULL;
    761     ACPI_PARSE_OBJECT       *NextOp;
    762     ACPI_NAMESPACE_NODE     *Node;
    763     char                    FieldPath[5];
    764     BOOLEAN                 PreDefined = FALSE;
    765     UINT8                   PreDefineIndex = 0;
    766 
    767 
    768     WalkState = Info->WalkState;
    769     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    770     ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
    771 
    772     /* Only interested in operators that create new names */
    773 
    774     if (!(OpInfo->Flags & AML_NAMED) &&
    775         !(OpInfo->Flags & AML_CREATE))
    776     {
    777         goto Exit;
    778     }
    779 
    780     /* Get the NamePath from the appropriate place */
    781 
    782     if (OpInfo->Flags & AML_NAMED)
    783     {
    784         /* For all named operators, get the new name */
    785 
    786         Path = Op->Named.Path;
    787 
    788         if (!Path && Op->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
    789         {
    790             *ACPI_CAST_PTR (UINT32, &FieldPath[0]) = Op->Named.Name;
    791             FieldPath[4] = 0;
    792             Path = FieldPath;
    793         }
    794     }
    795     else if (OpInfo->Flags & AML_CREATE)
    796     {
    797         /* New name is the last child */
    798 
    799         NextOp = Op->Common.Value.Arg;
    800 
    801         while (NextOp->Common.Next)
    802         {
    803             NextOp = NextOp->Common.Next;
    804         }
    805 
    806         Path = NextOp->Common.Value.String;
    807     }
    808 
    809     if (!Path)
    810     {
    811         goto Exit;
    812     }
    813 
    814     /* Insert the name into the namespace */
    815 
    816     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
    817         ACPI_IMODE_LOAD_PASS2, ACPI_NS_DONT_OPEN_SCOPE,
    818         WalkState, &Node);
    819 
    820     Op->Common.Node = Node;
    821 
    822     if (ACPI_SUCCESS (Status))
    823     {
    824         /* Check if it's a predefined node */
    825 
    826         while (AcpiGbl_PreDefinedNames[PreDefineIndex].Name)
    827         {
    828             if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii,
    829                 AcpiGbl_PreDefinedNames[PreDefineIndex].Name))
    830             {
    831                 PreDefined = TRUE;
    832                 break;
    833             }
    834 
    835             PreDefineIndex++;
    836         }
    837 
    838         /*
    839          * Set node owner id if it satisfies all the following conditions:
    840          * 1) Not a predefined node, _SB_ etc
    841          * 2) Not the root node
    842          * 3) Not a node created by Scope
    843          */
    844         if (!PreDefined &&
    845             (Node != AcpiGbl_RootNode) &&
    846             (Op->Common.AmlOpcode != AML_SCOPE_OP))
    847         {
    848             Node->OwnerId = WalkState->OwnerId;
    849         }
    850     }
    851 
    852 
    853 Exit:
    854 
    855     if (AcpiNsOpensScope (ObjectType))
    856     {
    857         if (Op->Common.Node)
    858         {
    859             Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType,
    860                 WalkState);
    861             if (ACPI_FAILURE (Status))
    862             {
    863                 return (Status);
    864             }
    865         }
    866     }
    867 
    868     return (AE_OK);
    869 }
    870 
    871 
    872 /*******************************************************************************
    873  *
    874  * FUNCTION:    AcpiDmXrefDescendingOp
    875  *
    876  * PARAMETERS:  ASL_WALK_CALLBACK
    877  *
    878  * RETURN:      Status
    879  *
    880  * DESCRIPTION: Descending handler for namespace cross reference
    881  *
    882  ******************************************************************************/
    883 
    884 static ACPI_STATUS
    885 AcpiDmXrefDescendingOp (
    886     ACPI_PARSE_OBJECT       *Op,
    887     UINT32                  Level,
    888     void                    *Context)
    889 {
    890     ACPI_OP_WALK_INFO       *Info = Context;
    891     const ACPI_OPCODE_INFO  *OpInfo;
    892     ACPI_WALK_STATE         *WalkState;
    893     ACPI_OBJECT_TYPE        ObjectType;
    894     ACPI_OBJECT_TYPE        ObjectType2;
    895     ACPI_STATUS             Status;
    896     char                    *Path = NULL;
    897     ACPI_PARSE_OBJECT       *NextOp;
    898     ACPI_NAMESPACE_NODE     *Node;
    899     ACPI_OPERAND_OBJECT     *Object;
    900     UINT32                  ParamCount = 0;
    901     char                    *Pathname;
    902     UINT16                  Flags = 0;
    903 
    904 
    905     WalkState = Info->WalkState;
    906     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    907     ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
    908 
    909     if ((!(OpInfo->Flags & AML_NAMED)) &&
    910         (!(OpInfo->Flags & AML_CREATE)) &&
    911         (Op->Common.AmlOpcode != AML_INT_NAMEPATH_OP) &&
    912         (Op->Common.AmlOpcode != AML_NOTIFY_OP))
    913     {
    914         goto Exit;
    915     }
    916 
    917     /* Get the NamePath from the appropriate place */
    918 
    919     if (OpInfo->Flags & AML_NAMED)
    920     {
    921         /*
    922          * Only these two operators (Alias, Scope) refer to an existing
    923          * name, it is the first argument
    924          */
    925         if (Op->Common.AmlOpcode == AML_ALIAS_OP)
    926         {
    927             ObjectType = ACPI_TYPE_ANY;
    928 
    929             NextOp = Op->Common.Value.Arg;
    930             NextOp = NextOp->Common.Value.Arg;
    931             if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
    932             {
    933                 Path = NextOp->Common.Value.String;
    934             }
    935         }
    936         else if (Op->Common.AmlOpcode == AML_SCOPE_OP ||
    937                  Op->Common.AmlOpcode == AML_EXTERNAL_OP)
    938         {
    939             Path = Op->Named.Path;
    940         }
    941     }
    942     else if (OpInfo->Flags & AML_CREATE)
    943     {
    944         /* Referenced Buffer Name is the first child */
    945 
    946         ObjectType = ACPI_TYPE_BUFFER; /* Change from TYPE_BUFFER_FIELD */
    947 
    948         NextOp = Op->Common.Value.Arg;
    949         if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
    950         {
    951             Path = NextOp->Common.Value.String;
    952         }
    953     }
    954     else if (Op->Common.AmlOpcode == AML_NOTIFY_OP)
    955     {
    956         Path = Op->Common.Value.Arg->Asl.Value.String;
    957     }
    958     else
    959     {
    960         Path = Op->Common.Value.String;
    961     }
    962 
    963     if (!Path)
    964     {
    965         goto Exit;
    966     }
    967 
    968     /*
    969      * Lookup the name in the namespace. Name must exist at this point, or it
    970      * is an invalid reference.
    971      *
    972      * The namespace is also used as a lookup table for references to resource
    973      * descriptors and the fields within them.
    974      */
    975     Node = NULL;
    976     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
    977         ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
    978         WalkState, &Node);
    979 
    980     if (ACPI_SUCCESS (Status) && (Node->Flags & ANOBJ_IS_EXTERNAL))
    981     {
    982         /* Node was created by an External() statement */
    983 
    984         Status = AE_NOT_FOUND;
    985     }
    986 
    987     if (ACPI_FAILURE (Status))
    988     {
    989         if (Status == AE_NOT_FOUND)
    990         {
    991             /*
    992              * Add this symbol as an external declaration, except if the
    993              * parent is a CondRefOf operator. For this operator, we do not
    994              * need an external, nor do we want one, since this can cause
    995              * disassembly problems if the symbol is actually a control
    996              * method.
    997              */
    998             if (!(Op->Asl.Parent &&
    999                 (Op->Asl.Parent->Asl.AmlOpcode == AML_CONDITIONAL_REF_OF_OP)))
   1000             {
   1001                 if (Node)
   1002                 {
   1003                     AcpiDmAddNodeToExternalList (Node,
   1004                         (UINT8) ObjectType, 7, Flags);
   1005                 }
   1006                 else
   1007                 {
   1008                     AcpiDmAddOpToExternalList (Op, Path,
   1009                         (UINT8) ObjectType, 7, Flags);
   1010                 }
   1011             }
   1012         }
   1013     }
   1014 
   1015     /*
   1016      * Found the node, but check if it came from an external table.
   1017      * Add it to external list. Note: Node->OwnerId == 0 indicates
   1018      * one of the built-in ACPI Names (_OS_ etc.) which can safely
   1019      * be ignored.
   1020      */
   1021     else if (Node->OwnerId &&
   1022             (WalkState->OwnerId != Node->OwnerId))
   1023     {
   1024         ObjectType2 = ObjectType;
   1025 
   1026         Object = AcpiNsGetAttachedObject (Node);
   1027         if (Object)
   1028         {
   1029             ObjectType2 = Object->Common.Type;
   1030             if (ObjectType2 == ACPI_TYPE_METHOD)
   1031             {
   1032                 ParamCount = Object->Method.ParamCount;
   1033             }
   1034         }
   1035 
   1036         Pathname = AcpiNsGetExternalPathname (Node);
   1037         if (!Pathname)
   1038         {
   1039             return (AE_NO_MEMORY);
   1040         }
   1041 
   1042         AcpiDmAddNodeToExternalList (Node, (UINT8) ObjectType2,
   1043             ParamCount, ACPI_EXT_RESOLVED_REFERENCE);
   1044 
   1045         ACPI_FREE (Pathname);
   1046         Op->Common.Node = Node;
   1047     }
   1048     else
   1049     {
   1050         Op->Common.Node = Node;
   1051     }
   1052 
   1053 
   1054 Exit:
   1055     /* Open new scope if necessary */
   1056 
   1057     if (AcpiNsOpensScope (ObjectType))
   1058     {
   1059         if (Op->Common.Node)
   1060         {
   1061             Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType,
   1062                 WalkState);
   1063             if (ACPI_FAILURE (Status))
   1064             {
   1065                 return (Status);
   1066             }
   1067         }
   1068     }
   1069 
   1070     return (AE_OK);
   1071 }
   1072 
   1073 /*******************************************************************************
   1074  *
   1075  * FUNCTION:    AcpiDmCommonDescendingOp
   1076  *
   1077  * PARAMETERS:  ASL_WALK_CALLBACK
   1078  *
   1079  * RETURN:      ACPI_STATUS
   1080  *
   1081  * DESCRIPTION: Perform parse tree preprocessing before main disassembly walk.
   1082  *
   1083  ******************************************************************************/
   1084 
   1085 static ACPI_STATUS
   1086 AcpiDmCommonDescendingOp (
   1087     ACPI_PARSE_OBJECT       *Op,
   1088     UINT32                  Level,
   1089     void                    *Context)
   1090 {
   1091     ACPI_STATUS             Status;
   1092 
   1093 
   1094     /* Resource descriptor conversion */
   1095 
   1096     Status = AcpiDmProcessResourceDescriptors (Op, Level, Context);
   1097     if (ACPI_FAILURE (Status))
   1098     {
   1099         return (Status);
   1100     }
   1101 
   1102     /* Switch/Case conversion */
   1103 
   1104     Status = AcpiDmProcessSwitch (Op);
   1105     return (Status);
   1106 }
   1107 
   1108 
   1109 /*******************************************************************************
   1110  *
   1111  * FUNCTION:    AcpiDmProcessResourceDescriptors
   1112  *
   1113  * PARAMETERS:  ASL_WALK_CALLBACK
   1114  *
   1115  * RETURN:      ACPI_STATUS
   1116  *
   1117  * DESCRIPTION: Convert fixed-offset references to resource descriptors to
   1118  *              symbolic references. Should only be called after namespace has
   1119  *              been cross referenced.
   1120  *
   1121  ******************************************************************************/
   1122 
   1123 static ACPI_STATUS
   1124 AcpiDmProcessResourceDescriptors (
   1125     ACPI_PARSE_OBJECT       *Op,
   1126     UINT32                  Level,
   1127     void                    *Context)
   1128 {
   1129     ACPI_OP_WALK_INFO       *Info = Context;
   1130     const ACPI_OPCODE_INFO  *OpInfo;
   1131     ACPI_WALK_STATE         *WalkState;
   1132     ACPI_OBJECT_TYPE        ObjectType;
   1133     ACPI_STATUS             Status;
   1134 
   1135 
   1136     WalkState = Info->WalkState;
   1137     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
   1138 
   1139     /* Open new scope if necessary */
   1140 
   1141     ObjectType = OpInfo->ObjectType;
   1142     if (AcpiNsOpensScope (ObjectType))
   1143     {
   1144         if (Op->Common.Node)
   1145         {
   1146 
   1147             Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType,
   1148                 WalkState);
   1149             if (ACPI_FAILURE (Status))
   1150             {
   1151                 return (Status);
   1152             }
   1153         }
   1154     }
   1155 
   1156     /*
   1157      * Check if this operator contains a reference to a resource descriptor.
   1158      * If so, convert the reference into a symbolic reference.
   1159      */
   1160     AcpiDmCheckResourceReference (Op, WalkState);
   1161     return (AE_OK);
   1162 }
   1163 
   1164 /*******************************************************************************
   1165  *
   1166  * FUNCTION:    AcpiDmCommonAscendingOp
   1167  *
   1168  * PARAMETERS:  ASL_WALK_CALLBACK
   1169  *
   1170  * RETURN:      None
   1171  *
   1172  * DESCRIPTION: Ascending handler for combined parse/namespace walks. Closes
   1173  *              scope if necessary.
   1174  *
   1175  ******************************************************************************/
   1176 
   1177 static ACPI_STATUS
   1178 AcpiDmCommonAscendingOp (
   1179     ACPI_PARSE_OBJECT       *Op,
   1180     UINT32                  Level,
   1181     void                    *Context)
   1182 {
   1183     ACPI_OP_WALK_INFO       *Info = Context;
   1184     ACPI_OBJECT_TYPE        ObjectType;
   1185 
   1186 
   1187     /* Close scope if necessary */
   1188 
   1189     ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
   1190 
   1191     if (AcpiNsOpensScope (ObjectType))
   1192     {
   1193         (void) AcpiDsScopeStackPop (Info->WalkState);
   1194     }
   1195 
   1196     return (AE_OK);
   1197 }
   1198 
   1199 /*******************************************************************************
   1200  *
   1201  * FUNCTION:    AcpiDmInspectPossibleArgs
   1202  *
   1203  * PARAMETERS:  CurrentOpArgCount   - Which arg of the current op was the
   1204  *                                    possible method invocation found
   1205  *              TargetCount         - Number of targets (0,1,2) for this op
   1206  *              Op                  - Parse op
   1207  *
   1208  * RETURN:      Status
   1209  *
   1210  * DESCRIPTION: Examine following args and next ops for possible arguments
   1211  *              for an unrecognized method invocation.
   1212  *
   1213  ******************************************************************************/
   1214 
   1215 static UINT32
   1216 AcpiDmInspectPossibleArgs (
   1217     UINT32                  CurrentOpArgCount,
   1218     UINT32                  TargetCount,
   1219     ACPI_PARSE_OBJECT       *Op)
   1220 {
   1221     const ACPI_OPCODE_INFO  *OpInfo;
   1222     UINT32                  i;
   1223     UINT32                  ArgumentCount = 0;
   1224     ACPI_PARSE_OBJECT       *NextOp;
   1225     ACPI_PARSE_OBJECT       *ExecuteOp;
   1226 
   1227 
   1228     if (!Op)
   1229     {
   1230         return (0);
   1231     }
   1232 
   1233     /* Lookahead for the maximum number of possible arguments */
   1234 
   1235     NextOp = Op->Common.Next;
   1236 
   1237     for (i = 0; (i < ACPI_METHOD_NUM_ARGS) && NextOp; i++)
   1238     {
   1239         OpInfo = AcpiPsGetOpcodeInfo (NextOp->Common.AmlOpcode);
   1240 
   1241         /* Any one of these operators is "very probably" not a method arg */
   1242 
   1243         if ((NextOp->Common.AmlOpcode == AML_STORE_OP) ||
   1244             (NextOp->Common.AmlOpcode == AML_NOTIFY_OP) ||
   1245             (OpInfo->Class == AML_CLASS_CONTROL) ||
   1246             (OpInfo->Class == AML_CLASS_CREATE) ||
   1247             (OpInfo->Class == AML_CLASS_NAMED_OBJECT))
   1248         {
   1249             break;
   1250         }
   1251 
   1252         if (OpInfo->Class == AML_CLASS_EXECUTE)
   1253         {
   1254             /* Probable that this is method arg if there is no target */
   1255 
   1256             ExecuteOp = NextOp->Common.Value.Arg;
   1257             while (ExecuteOp)
   1258             {
   1259                 if ((ExecuteOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
   1260                     (ExecuteOp->Common.Value.Arg == NULL))
   1261                 {
   1262                     /* No target, could be a method arg */
   1263 
   1264                     break;
   1265                 }
   1266 
   1267                 if (NextOp->Common.AmlOpcode == AML_REF_OF_OP)
   1268                 {
   1269                     break;
   1270                 }
   1271 
   1272                 ExecuteOp = ExecuteOp->Common.Next;
   1273             }
   1274 
   1275             if (!ExecuteOp)
   1276             {
   1277                 /* Has a target, not method arg */
   1278 
   1279                 return (ArgumentCount);
   1280             }
   1281         }
   1282 
   1283         ArgumentCount++;
   1284         NextOp = NextOp->Common.Next;
   1285     }
   1286 
   1287     return (ArgumentCount);
   1288 }
   1289