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