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