Subversion Repositories Kolibri OS

Rev

Rev 1498 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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 - 2011, 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.     UINT32                  ParamCount = 0;
  796.  
  797.  
  798.     WalkState = Info->WalkState;
  799.     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
  800.     ObjectType = OpInfo->ObjectType;
  801.     ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
  802.  
  803.     if ((!(OpInfo->Flags & AML_NAMED)) &&
  804.         (!(OpInfo->Flags & AML_CREATE)) &&
  805.         (Op->Common.AmlOpcode != AML_INT_NAMEPATH_OP))
  806.     {
  807.         goto Exit;
  808.     }
  809.  
  810.     /* Get the NamePath from the appropriate place */
  811.  
  812.     if (OpInfo->Flags & AML_NAMED)
  813.     {
  814.         if ((Op->Common.AmlOpcode == AML_ALIAS_OP) ||
  815.             (Op->Common.AmlOpcode == AML_SCOPE_OP))
  816.         {
  817.             /*
  818.              * Only these two operators refer to an existing name,
  819.              * first argument
  820.              */
  821.             Path = (char *) Op->Named.Path;
  822.         }
  823.     }
  824.     else if (OpInfo->Flags & AML_CREATE)
  825.     {
  826.         /* Referenced Buffer Name is the first child */
  827.  
  828.         NextOp = Op->Common.Value.Arg;
  829.         if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
  830.         {
  831.             Path = NextOp->Common.Value.String;
  832.         }
  833.     }
  834.     else
  835.     {
  836.         Path = Op->Common.Value.String;
  837.     }
  838.  
  839.     if (!Path)
  840.     {
  841.         goto Exit;
  842.     }
  843.  
  844.     /*
  845.      * Lookup the name in the namespace.  Name must exist at this point, or it
  846.      * is an invalid reference.
  847.      *
  848.      * The namespace is also used as a lookup table for references to resource
  849.      * descriptors and the fields within them.
  850.      */
  851.     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
  852.                 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
  853.                 WalkState, &Node);
  854.     if (ACPI_FAILURE (Status))
  855.     {
  856.         if (Status == AE_NOT_FOUND)
  857.         {
  858.             AcpiDmAddToExternalList (Op, Path, (UINT8) ObjectType, 0);
  859.  
  860.             /*
  861.              * We could install this into the namespace, but we catch duplicate
  862.              * externals when they are added to the list.
  863.              */
  864. #if 0
  865.             Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
  866.                        ACPI_IMODE_LOAD_PASS1, ACPI_NS_DONT_OPEN_SCOPE,
  867.                        WalkState, &Node);
  868. #endif
  869.         }
  870.     }
  871.  
  872.     /*
  873.      * Found the node in external table, add it to external list
  874.      * Node->OwnerId == 0 indicates built-in ACPI Names, _OS_ etc
  875.      */
  876.     else if (Node->OwnerId && WalkState->OwnerId != Node->OwnerId)
  877.     {
  878.         ObjectType2 = ObjectType;
  879.  
  880.         Object = AcpiNsGetAttachedObject (Node);
  881.         if (Object)
  882.         {
  883.             ObjectType2 = Object->Common.Type;
  884.         if (ObjectType2 == ACPI_TYPE_METHOD)
  885.         {
  886.                 ParamCount = Object->Method.ParamCount;
  887.         }
  888.         }
  889.  
  890.         AcpiDmAddToExternalList (Op, Path, (UINT8) ObjectType2, ParamCount);
  891.         Op->Common.Node = Node;
  892.     }
  893.     else
  894.     {
  895.         Op->Common.Node = Node;
  896.     }
  897.  
  898.  
  899. Exit:
  900.     /* Open new scope if necessary */
  901.  
  902.     if (AcpiNsOpensScope (ObjectType))
  903.     {
  904.         if (Op->Common.Node)
  905.         {
  906.             Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState);
  907.             if (ACPI_FAILURE (Status))
  908.             {
  909.                 return (Status);
  910.             }
  911.         }
  912.     }
  913.  
  914.     return (AE_OK);
  915. }
  916.  
  917.  
  918. /*******************************************************************************
  919.  *
  920.  * FUNCTION:    AcpiDmResourceDescendingOp
  921.  *
  922.  * PARAMETERS:  ASL_WALK_CALLBACK
  923.  *
  924.  * RETURN:      None
  925.  *
  926.  * DESCRIPTION: Process one parse op during symbolic resource index conversion.
  927.  *
  928.  ******************************************************************************/
  929.  
  930. static ACPI_STATUS
  931. AcpiDmResourceDescendingOp (
  932.     ACPI_PARSE_OBJECT       *Op,
  933.     UINT32                  Level,
  934.     void                    *Context)
  935. {
  936.     ACPI_OP_WALK_INFO       *Info = Context;
  937.     const ACPI_OPCODE_INFO  *OpInfo;
  938.     ACPI_WALK_STATE         *WalkState;
  939.     ACPI_OBJECT_TYPE        ObjectType;
  940.     ACPI_STATUS             Status;
  941.  
  942.  
  943.     WalkState = Info->WalkState;
  944.     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
  945.  
  946.     /* Open new scope if necessary */
  947.  
  948.     ObjectType = OpInfo->ObjectType;
  949.     if (AcpiNsOpensScope (ObjectType))
  950.     {
  951.         if (Op->Common.Node)
  952.         {
  953.  
  954.             Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState);
  955.             if (ACPI_FAILURE (Status))
  956.             {
  957.                 return (Status);
  958.             }
  959.         }
  960.     }
  961.  
  962.     /*
  963.      * Check if this operator contains a reference to a resource descriptor.
  964.      * If so, convert the reference into a symbolic reference.
  965.      */
  966.     AcpiDmCheckResourceReference (Op, WalkState);
  967.     return (AE_OK);
  968. }
  969.  
  970.  
  971. /*******************************************************************************
  972.  *
  973.  * FUNCTION:    AcpiDmCommonAscendingOp
  974.  *
  975.  * PARAMETERS:  ASL_WALK_CALLBACK
  976.  *
  977.  * RETURN:      None
  978.  *
  979.  * DESCRIPTION: Ascending handler for combined parse/namespace walks. Closes
  980.  *              scope if necessary.
  981.  *
  982.  ******************************************************************************/
  983.  
  984. static ACPI_STATUS
  985. AcpiDmCommonAscendingOp (
  986.     ACPI_PARSE_OBJECT       *Op,
  987.     UINT32                  Level,
  988.     void                    *Context)
  989. {
  990.     ACPI_OP_WALK_INFO       *Info = Context;
  991.     const ACPI_OPCODE_INFO  *OpInfo;
  992.     ACPI_OBJECT_TYPE        ObjectType;
  993.  
  994.  
  995.     /* Close scope if necessary */
  996.  
  997.     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
  998.     ObjectType = OpInfo->ObjectType;
  999.     ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
  1000.  
  1001.     if (AcpiNsOpensScope (ObjectType))
  1002.     {
  1003.         (void) AcpiDsScopeStackPop (Info->WalkState);
  1004.     }
  1005.  
  1006.     return (AE_OK);
  1007. }
  1008.  
  1009.  
  1010. /*******************************************************************************
  1011.  *
  1012.  * FUNCTION:    AcpiDmInspectPossibleArgs
  1013.  *
  1014.  * PARAMETERS:  CurrentOpArgCount   - Which arg of the current op was the
  1015.  *                                    possible method invocation found
  1016.  *              TargetCount         - Number of targets (0,1,2) for this op
  1017.  *              Op                  - Parse op
  1018.  *
  1019.  * RETURN:      Status
  1020.  *
  1021.  * DESCRIPTION: Examine following args and next ops for possible arguments
  1022.  *              for an unrecognized method invocation.
  1023.  *
  1024.  ******************************************************************************/
  1025.  
  1026. static UINT32
  1027. AcpiDmInspectPossibleArgs (
  1028.     UINT32                  CurrentOpArgCount,
  1029.     UINT32                  TargetCount,
  1030.     ACPI_PARSE_OBJECT       *Op)
  1031. {
  1032.     const ACPI_OPCODE_INFO  *OpInfo;
  1033.     UINT32                  i;
  1034.     UINT32                  Last = 0;
  1035.     UINT32                  Lookahead;
  1036.  
  1037.  
  1038.     Lookahead = (ACPI_METHOD_NUM_ARGS + TargetCount) - CurrentOpArgCount;
  1039.  
  1040.     /* Lookahead for the maximum number of possible arguments */
  1041.  
  1042.     for (i = 0; i < Lookahead; i++)
  1043.     {
  1044.         if (!Op)
  1045.         {
  1046.             break;
  1047.         }
  1048.  
  1049.         OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
  1050.  
  1051.         /*
  1052.          * Any one of these operators is "very probably" not a method arg
  1053.          */
  1054.         if ((Op->Common.AmlOpcode == AML_STORE_OP) ||
  1055.             (Op->Common.AmlOpcode == AML_NOTIFY_OP))
  1056.         {
  1057.             break;
  1058.         }
  1059.  
  1060.         if ((OpInfo->Class != AML_CLASS_EXECUTE) &&
  1061.             (OpInfo->Class != AML_CLASS_CONTROL))
  1062.         {
  1063.             Last = i+1;
  1064.         }
  1065.  
  1066.         Op = Op->Common.Next;
  1067.     }
  1068.  
  1069.     return (Last);
  1070. }
  1071.  
  1072.  
  1073.