Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.  
  2. /******************************************************************************
  3.  *
  4.  * Module Name: asltree - parse tree management
  5.  *
  6.  *****************************************************************************/
  7.  
  8. /******************************************************************************
  9.  *
  10.  * 1. Copyright Notice
  11.  *
  12.  * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
  13.  * All rights reserved.
  14.  *
  15.  * 2. License
  16.  *
  17.  * 2.1. This is your license from Intel Corp. under its intellectual property
  18.  * rights.  You may have additional license terms from the party that provided
  19.  * you this software, covering your right to use that party's intellectual
  20.  * property rights.
  21.  *
  22.  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
  23.  * copy of the source code appearing in this file ("Covered Code") an
  24.  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
  25.  * base code distributed originally by Intel ("Original Intel Code") to copy,
  26.  * make derivatives, distribute, use and display any portion of the Covered
  27.  * Code in any form, with the right to sublicense such rights; and
  28.  *
  29.  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
  30.  * license (with the right to sublicense), under only those claims of Intel
  31.  * patents that are infringed by the Original Intel Code, to make, use, sell,
  32.  * offer to sell, and import the Covered Code and derivative works thereof
  33.  * solely to the minimum extent necessary to exercise the above copyright
  34.  * license, and in no event shall the patent license extend to any additions
  35.  * to or modifications of the Original Intel Code.  No other license or right
  36.  * is granted directly or by implication, estoppel or otherwise;
  37.  *
  38.  * The above copyright and patent license is granted only if the following
  39.  * conditions are met:
  40.  *
  41.  * 3. Conditions
  42.  *
  43.  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
  44.  * Redistribution of source code of any substantial portion of the Covered
  45.  * Code or modification with rights to further distribute source must include
  46.  * the above Copyright Notice, the above License, this list of Conditions,
  47.  * and the following Disclaimer and Export Compliance provision.  In addition,
  48.  * Licensee must cause all Covered Code to which Licensee contributes to
  49.  * contain a file documenting the changes Licensee made to create that Covered
  50.  * Code and the date of any change.  Licensee must include in that file the
  51.  * documentation of any changes made by any predecessor Licensee.  Licensee
  52.  * must include a prominent statement that the modification is derived,
  53.  * directly or indirectly, from Original Intel Code.
  54.  *
  55.  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
  56.  * Redistribution of source code of any substantial portion of the Covered
  57.  * Code or modification without rights to further distribute source must
  58.  * include the following Disclaimer and Export Compliance provision in the
  59.  * documentation and/or other materials provided with distribution.  In
  60.  * addition, Licensee may not authorize further sublicense of source of any
  61.  * portion of the Covered Code, and must include terms to the effect that the
  62.  * license from Licensee to its licensee is limited to the intellectual
  63.  * property embodied in the software Licensee provides to its licensee, and
  64.  * not to intellectual property embodied in modifications its licensee may
  65.  * make.
  66.  *
  67.  * 3.3. Redistribution of Executable. Redistribution in executable form of any
  68.  * substantial portion of the Covered Code or modification must reproduce the
  69.  * above Copyright Notice, and the following Disclaimer and Export Compliance
  70.  * provision in the documentation and/or other materials provided with the
  71.  * distribution.
  72.  *
  73.  * 3.4. Intel retains all right, title, and interest in and to the Original
  74.  * Intel Code.
  75.  *
  76.  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
  77.  * Intel shall be used in advertising or otherwise to promote the sale, use or
  78.  * other dealings in products derived from or relating to the Covered Code
  79.  * without prior written authorization from Intel.
  80.  *
  81.  * 4. Disclaimer and Export Compliance
  82.  *
  83.  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
  84.  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
  85.  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
  86.  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
  87.  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
  88.  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
  89.  * PARTICULAR PURPOSE.
  90.  *
  91.  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
  92.  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
  93.  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
  94.  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
  95.  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
  96.  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
  97.  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
  98.  * LIMITED REMEDY.
  99.  *
  100.  * 4.3. Licensee shall not export, either directly or indirectly, any of this
  101.  * software or system incorporating such software without first obtaining any
  102.  * required license or other approval from the U. S. Department of Commerce or
  103.  * any other agency or department of the United States Government.  In the
  104.  * event Licensee exports any such software from the United States or
  105.  * re-exports any such software from a foreign destination, Licensee shall
  106.  * ensure that the distribution and export/re-export of the software is in
  107.  * compliance with all laws, regulations, orders, or other restrictions of the
  108.  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  109.  * any of its subsidiaries will export/re-export any technical data, process,
  110.  * software, or service, directly or indirectly, to any country for which the
  111.  * United States government or any agency thereof requires an export license,
  112.  * other governmental approval, or letter of assurance, without first obtaining
  113.  * such license, approval or letter.
  114.  *
  115.  *****************************************************************************/
  116.  
  117.  
  118. #include "aslcompiler.h"
  119. #include "aslcompiler.y.h"
  120.  
  121. #define _COMPONENT          ACPI_COMPILER
  122.         ACPI_MODULE_NAME    ("asltree")
  123.  
  124. /* Local prototypes */
  125.  
  126. static ACPI_PARSE_OBJECT *
  127. TrGetNextNode (
  128.     void);
  129.  
  130. static char *
  131. TrGetNodeFlagName (
  132.     UINT32                  Flags);
  133.  
  134.  
  135. /*******************************************************************************
  136.  *
  137.  * FUNCTION:    TrGetNextNode
  138.  *
  139.  * PARAMETERS:  None
  140.  *
  141.  * RETURN:      New parse node.  Aborts on allocation failure
  142.  *
  143.  * DESCRIPTION: Allocate a new parse node for the parse tree.  Bypass the local
  144.  *              dynamic memory manager for performance reasons (This has a
  145.  *              major impact on the speed of the compiler.)
  146.  *
  147.  ******************************************************************************/
  148.  
  149. static ACPI_PARSE_OBJECT *
  150. TrGetNextNode (
  151.     void)
  152. {
  153.  
  154.     if (Gbl_NodeCacheNext >= Gbl_NodeCacheLast)
  155.     {
  156.         Gbl_NodeCacheNext = UtLocalCalloc (sizeof (ACPI_PARSE_OBJECT) *
  157.                                 ASL_NODE_CACHE_SIZE);
  158.         Gbl_NodeCacheLast = Gbl_NodeCacheNext + ASL_NODE_CACHE_SIZE;
  159.     }
  160.  
  161.     return (Gbl_NodeCacheNext++);
  162. }
  163.  
  164.  
  165. /*******************************************************************************
  166.  *
  167.  * FUNCTION:    TrAllocateNode
  168.  *
  169.  * PARAMETERS:  ParseOpcode         - Opcode to be assigned to the node
  170.  *
  171.  * RETURN:      New parse node.  Aborts on allocation failure
  172.  *
  173.  * DESCRIPTION: Allocate and initialize a new parse node for the parse tree
  174.  *
  175.  ******************************************************************************/
  176.  
  177. ACPI_PARSE_OBJECT *
  178. TrAllocateNode (
  179.     UINT32                  ParseOpcode)
  180. {
  181.     ACPI_PARSE_OBJECT       *Op;
  182.  
  183.  
  184.     Op = TrGetNextNode ();
  185.  
  186.     Op->Asl.ParseOpcode       = (UINT16) ParseOpcode;
  187.     Op->Asl.Filename          = Gbl_Files[ASL_FILE_INPUT].Filename;
  188.     Op->Asl.LineNumber        = Gbl_CurrentLineNumber;
  189.     Op->Asl.LogicalLineNumber = Gbl_LogicalLineNumber;
  190.     Op->Asl.LogicalByteOffset = Gbl_CurrentLineOffset;
  191.     Op->Asl.Column            = Gbl_CurrentColumn;
  192.  
  193.     UtSetParseOpName (Op);
  194.     return Op;
  195. }
  196.  
  197.  
  198. /*******************************************************************************
  199.  *
  200.  * FUNCTION:    TrReleaseNode
  201.  *
  202.  * PARAMETERS:  Op            - Op to be released
  203.  *
  204.  * RETURN:      None
  205.  *
  206.  * DESCRIPTION: "release" a node.  In truth, nothing is done since the node
  207.  *              is part of a larger buffer
  208.  *
  209.  ******************************************************************************/
  210.  
  211. void
  212. TrReleaseNode (
  213.     ACPI_PARSE_OBJECT       *Op)
  214. {
  215.  
  216.     return;
  217. }
  218.  
  219.  
  220. /*******************************************************************************
  221.  *
  222.  * FUNCTION:    TrUpdateNode
  223.  *
  224.  * PARAMETERS:  ParseOpcode         - New opcode to be assigned to the node
  225.  *              Op                - An existing parse node
  226.  *
  227.  * RETURN:      The updated node
  228.  *
  229.  * DESCRIPTION: Change the parse opcode assigned to a node.  Usually used to
  230.  *              change an opcode to DEFAULT_ARG so that the node is ignored
  231.  *              during the code generation.  Also used to set generic integers
  232.  *              to a specific size (8, 16, 32, or 64 bits)
  233.  *
  234.  ******************************************************************************/
  235.  
  236. ACPI_PARSE_OBJECT *
  237. TrUpdateNode (
  238.     UINT32                  ParseOpcode,
  239.     ACPI_PARSE_OBJECT       *Op)
  240. {
  241.  
  242.     if (!Op)
  243.     {
  244.         return NULL;
  245.     }
  246.  
  247.     DbgPrint (ASL_PARSE_OUTPUT,
  248.         "\nUpdateNode: Old - %s, New - %s\n\n",
  249.         UtGetOpName (Op->Asl.ParseOpcode),
  250.         UtGetOpName (ParseOpcode));
  251.  
  252.     /* Assign new opcode and name */
  253.  
  254.     if (Op->Asl.ParseOpcode == PARSEOP_ONES)
  255.     {
  256.         switch (ParseOpcode)
  257.         {
  258.         case PARSEOP_BYTECONST:
  259.             Op->Asl.Value.Integer = 0xFF;
  260.             break;
  261.  
  262.         case PARSEOP_WORDCONST:
  263.             Op->Asl.Value.Integer = 0xFFFF;
  264.             break;
  265.  
  266.         case PARSEOP_DWORDCONST:
  267.             Op->Asl.Value.Integer = 0xFFFFFFFF;
  268.             break;
  269.  
  270.         default:
  271.             /* Don't care about others, don't need to check QWORD */
  272.             break;
  273.         }
  274.     }
  275.  
  276.     Op->Asl.ParseOpcode = (UINT16) ParseOpcode;
  277.     UtSetParseOpName (Op);
  278.  
  279.     /*
  280.      * For the BYTE, WORD, and DWORD constants, make sure that the integer
  281.      * that was passed in will actually fit into the data type
  282.      */
  283.     switch (ParseOpcode)
  284.     {
  285.     case PARSEOP_BYTECONST:
  286.         Op = UtCheckIntegerRange (Op, 0x00, ACPI_UINT8_MAX);
  287.         break;
  288.  
  289.     case PARSEOP_WORDCONST:
  290.         Op = UtCheckIntegerRange (Op, 0x00, ACPI_UINT16_MAX);
  291.         break;
  292.  
  293.     case PARSEOP_DWORDCONST:
  294.         Op = UtCheckIntegerRange (Op, 0x00, ACPI_UINT32_MAX);
  295.         break;
  296.  
  297.     default:
  298.         /* Don't care about others, don't need to check QWORD */
  299.         break;
  300.     }
  301.  
  302.     return Op;
  303. }
  304.  
  305.  
  306. /*******************************************************************************
  307.  *
  308.  * FUNCTION:    TrGetNodeFlagName
  309.  *
  310.  * PARAMETERS:  Flags               - Flags word to be decoded
  311.  *
  312.  * RETURN:      Name string. Always returns a valid string pointer.
  313.  *
  314.  * DESCRIPTION: Decode a flags word
  315.  *
  316.  ******************************************************************************/
  317.  
  318. static char *
  319. TrGetNodeFlagName (
  320.     UINT32                  Flags)
  321. {
  322.  
  323.     switch (Flags)
  324.     {
  325.     case NODE_VISITED:
  326.         return ("NODE_VISITED");
  327.  
  328.     case NODE_AML_PACKAGE:
  329.         return ("NODE_AML_PACKAGE");
  330.  
  331.     case NODE_IS_TARGET:
  332.         return ("NODE_IS_TARGET");
  333.  
  334.     case NODE_IS_RESOURCE_DESC:
  335.         return ("NODE_IS_RESOURCE_DESC");
  336.  
  337.     case NODE_IS_RESOURCE_FIELD:
  338.         return ("NODE_IS_RESOURCE_FIELD");
  339.  
  340.     case NODE_HAS_NO_EXIT:
  341.         return ("NODE_HAS_NO_EXIT");
  342.  
  343.     case NODE_IF_HAS_NO_EXIT:
  344.         return ("NODE_IF_HAS_NO_EXIT");
  345.  
  346.     case NODE_NAME_INTERNALIZED:
  347.         return ("NODE_NAME_INTERNALIZED");
  348.  
  349.     case NODE_METHOD_NO_RETVAL:
  350.         return ("NODE_METHOD_NO_RETVAL");
  351.  
  352.     case NODE_METHOD_SOME_NO_RETVAL:
  353.         return ("NODE_METHOD_SOME_NO_RETVAL");
  354.  
  355.     case NODE_RESULT_NOT_USED:
  356.         return ("NODE_RESULT_NOT_USED");
  357.  
  358.     case NODE_METHOD_TYPED:
  359.         return ("NODE_METHOD_TYPED");
  360.  
  361.     case NODE_IS_BIT_OFFSET:
  362.         return ("NODE_IS_BIT_OFFSET");
  363.  
  364.     case NODE_COMPILE_TIME_CONST:
  365.         return ("NODE_COMPILE_TIME_CONST");
  366.  
  367.     case NODE_IS_TERM_ARG:
  368.         return ("NODE_IS_TERM_ARG");
  369.  
  370.     case NODE_WAS_ONES_OP:
  371.         return ("NODE_WAS_ONES_OP");
  372.  
  373.     case NODE_IS_NAME_DECLARATION:
  374.         return ("NODE_IS_NAME_DECLARATION");
  375.  
  376.     default:
  377.         return ("Multiple Flags (or unknown flag) set");
  378.     }
  379. }
  380.  
  381.  
  382. /*******************************************************************************
  383.  *
  384.  * FUNCTION:    TrSetNodeFlags
  385.  *
  386.  * PARAMETERS:  Op                  - An existing parse node
  387.  *              Flags               - New flags word
  388.  *
  389.  * RETURN:      The updated parser op
  390.  *
  391.  * DESCRIPTION: Set bits in the node flags word.  Will not clear bits, only set
  392.  *
  393.  ******************************************************************************/
  394.  
  395. ACPI_PARSE_OBJECT *
  396. TrSetNodeFlags (
  397.     ACPI_PARSE_OBJECT       *Op,
  398.     UINT32                  Flags)
  399. {
  400.  
  401.     DbgPrint (ASL_PARSE_OUTPUT,
  402.         "\nSetNodeFlags: Op %p, %8.8X %s\n\n", Op, Flags,
  403.         TrGetNodeFlagName (Flags));
  404.  
  405.     if (!Op)
  406.     {
  407.         return NULL;
  408.     }
  409.  
  410.     Op->Asl.CompileFlags |= Flags;
  411.  
  412.     return Op;
  413. }
  414.  
  415.  
  416. /*******************************************************************************
  417.  *
  418.  * FUNCTION:    TrSetEndLineNumber
  419.  *
  420.  * PARAMETERS:  Op                - An existing parse node
  421.  *
  422.  * RETURN:      None.
  423.  *
  424.  * DESCRIPTION: Set the ending line numbers (file line and logical line) of a
  425.  *              parse node to the current line numbers.
  426.  *
  427.  ******************************************************************************/
  428.  
  429. void
  430. TrSetEndLineNumber (
  431.     ACPI_PARSE_OBJECT       *Op)
  432. {
  433.  
  434.     /* If the end line # is already set, just return */
  435.  
  436.     if (Op->Asl.EndLine)
  437.     {
  438.         return;
  439.     }
  440.  
  441.     Op->Asl.EndLine        = Gbl_CurrentLineNumber;
  442.     Op->Asl.EndLogicalLine = Gbl_LogicalLineNumber;
  443. }
  444.  
  445.  
  446. /*******************************************************************************
  447.  *
  448.  * FUNCTION:    TrCreateLeafNode
  449.  *
  450.  * PARAMETERS:  ParseOpcode         - New opcode to be assigned to the node
  451.  *
  452.  * RETURN:      Pointer to the new node.  Aborts on allocation failure
  453.  *
  454.  * DESCRIPTION: Create a simple leaf node (no children or peers, and no value
  455.  *              assigned to the node)
  456.  *
  457.  ******************************************************************************/
  458.  
  459. ACPI_PARSE_OBJECT *
  460. TrCreateLeafNode (
  461.     UINT32                  ParseOpcode)
  462. {
  463.     ACPI_PARSE_OBJECT       *Op;
  464.  
  465.  
  466.     Op = TrAllocateNode (ParseOpcode);
  467.  
  468.     DbgPrint (ASL_PARSE_OUTPUT,
  469.         "\nCreateLeafNode  Ln/Col %u/%u NewNode %p  Op %s\n\n",
  470.         Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName(ParseOpcode));
  471.  
  472.     return Op;
  473. }
  474.  
  475.  
  476. /*******************************************************************************
  477.  *
  478.  * FUNCTION:    TrCreateValuedLeafNode
  479.  *
  480.  * PARAMETERS:  ParseOpcode         - New opcode to be assigned to the node
  481.  *              Value               - Value to be assigned to the node
  482.  *
  483.  * RETURN:      Pointer to the new node.  Aborts on allocation failure
  484.  *
  485.  * DESCRIPTION: Create a leaf node (no children or peers) with a value
  486.  *              assigned to it
  487.  *
  488.  ******************************************************************************/
  489.  
  490. ACPI_PARSE_OBJECT *
  491. TrCreateValuedLeafNode (
  492.     UINT32                  ParseOpcode,
  493.     UINT64                  Value)
  494. {
  495.     ACPI_PARSE_OBJECT       *Op;
  496.  
  497.  
  498.     Op = TrAllocateNode (ParseOpcode);
  499.  
  500.     DbgPrint (ASL_PARSE_OUTPUT,
  501.         "\nCreateValuedLeafNode  Ln/Col %u/%u NewNode %p  Op %s  Value %8.8X%8.8X  ",
  502.         Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName(ParseOpcode),
  503.         ACPI_FORMAT_UINT64 (Value));
  504.     Op->Asl.Value.Integer = Value;
  505.  
  506.     switch (ParseOpcode)
  507.     {
  508.     case PARSEOP_STRING_LITERAL:
  509.         DbgPrint (ASL_PARSE_OUTPUT, "STRING->%s", Value);
  510.         break;
  511.  
  512.     case PARSEOP_NAMESEG:
  513.         DbgPrint (ASL_PARSE_OUTPUT, "NAMESEG->%s", Value);
  514.         break;
  515.  
  516.     case PARSEOP_NAMESTRING:
  517.         DbgPrint (ASL_PARSE_OUTPUT, "NAMESTRING->%s", Value);
  518.         break;
  519.  
  520.     case PARSEOP_EISAID:
  521.         DbgPrint (ASL_PARSE_OUTPUT, "EISAID->%s", Value);
  522.         break;
  523.  
  524.     case PARSEOP_METHOD:
  525.         DbgPrint (ASL_PARSE_OUTPUT, "METHOD");
  526.         break;
  527.  
  528.     case PARSEOP_INTEGER:
  529.         DbgPrint (ASL_PARSE_OUTPUT, "INTEGER");
  530.         break;
  531.  
  532.     default:
  533.         break;
  534.     }
  535.  
  536.     DbgPrint (ASL_PARSE_OUTPUT, "\n\n");
  537.     return Op;
  538. }
  539.  
  540.  
  541. /*******************************************************************************
  542.  *
  543.  * FUNCTION:    TrCreateNode
  544.  *
  545.  * PARAMETERS:  ParseOpcode         - Opcode to be assigned to the node
  546.  *              NumChildren         - Number of children to follow
  547.  *              ...                 - A list of child nodes to link to the new
  548.  *                                    node.  NumChildren long.
  549.  *
  550.  * RETURN:      Pointer to the new node.  Aborts on allocation failure
  551.  *
  552.  * DESCRIPTION: Create a new parse node and link together a list of child
  553.  *              nodes underneath the new node.
  554.  *
  555.  ******************************************************************************/
  556.  
  557. ACPI_PARSE_OBJECT *
  558. TrCreateNode (
  559.     UINT32                  ParseOpcode,
  560.     UINT32                  NumChildren,
  561.     ...)
  562. {
  563.     ACPI_PARSE_OBJECT       *Op;
  564.     ACPI_PARSE_OBJECT       *Child;
  565.     ACPI_PARSE_OBJECT       *PrevChild;
  566.     va_list                 ap;
  567.     UINT32                  i;
  568.     BOOLEAN                 FirstChild;
  569.  
  570.  
  571.     va_start (ap, NumChildren);
  572.  
  573.     /* Allocate one new node */
  574.  
  575.     Op = TrAllocateNode (ParseOpcode);
  576.  
  577.     DbgPrint (ASL_PARSE_OUTPUT,
  578.         "\nCreateNode  Ln/Col %u/%u NewParent %p Child %u Op %s  ",
  579.         Op->Asl.LineNumber, Op->Asl.Column, Op, NumChildren, UtGetOpName(ParseOpcode));
  580.  
  581.     /* Some extra debug output based on the parse opcode */
  582.  
  583.     switch (ParseOpcode)
  584.     {
  585.     case PARSEOP_DEFINITIONBLOCK:
  586.         RootNode = Op;
  587.         DbgPrint (ASL_PARSE_OUTPUT, "DEFINITION_BLOCK (Tree Completed)->");
  588.         break;
  589.  
  590.     case PARSEOP_OPERATIONREGION:
  591.         DbgPrint (ASL_PARSE_OUTPUT, "OPREGION->");
  592.         break;
  593.  
  594.     case PARSEOP_OR:
  595.         DbgPrint (ASL_PARSE_OUTPUT, "OR->");
  596.         break;
  597.  
  598.     default:
  599.         /* Nothing to do for other opcodes */
  600.         break;
  601.     }
  602.  
  603.     /* Link the new node to its children */
  604.  
  605.     PrevChild = NULL;
  606.     FirstChild = TRUE;
  607.     for (i = 0; i < NumChildren; i++)
  608.     {
  609.         /* Get the next child */
  610.  
  611.         Child = va_arg (ap, ACPI_PARSE_OBJECT *);
  612.         DbgPrint (ASL_PARSE_OUTPUT, "%p, ", Child);
  613.  
  614.         /*
  615.          * If child is NULL, this means that an optional argument
  616.          * was omitted.  We must create a placeholder with a special
  617.          * opcode (DEFAULT_ARG) so that the code generator will know
  618.          * that it must emit the correct default for this argument
  619.          */
  620.         if (!Child)
  621.         {
  622.             Child = TrAllocateNode (PARSEOP_DEFAULT_ARG);
  623.         }
  624.  
  625.         /* Link first child to parent */
  626.  
  627.         if (FirstChild)
  628.         {
  629.             FirstChild = FALSE;
  630.             Op->Asl.Child = Child;
  631.         }
  632.  
  633.         /* Point all children to parent */
  634.  
  635.         Child->Asl.Parent = Op;
  636.  
  637.         /* Link children in a peer list */
  638.  
  639.         if (PrevChild)
  640.         {
  641.             PrevChild->Asl.Next = Child;
  642.         };
  643.  
  644.         /*
  645.          * This child might be a list, point all nodes in the list
  646.          * to the same parent
  647.          */
  648.         while (Child->Asl.Next)
  649.         {
  650.             Child = Child->Asl.Next;
  651.             Child->Asl.Parent = Op;
  652.         }
  653.  
  654.         PrevChild = Child;
  655.     }
  656.     va_end(ap);
  657.  
  658.     DbgPrint (ASL_PARSE_OUTPUT, "\n\n");
  659.     return Op;
  660. }
  661.  
  662.  
  663. /*******************************************************************************
  664.  *
  665.  * FUNCTION:    TrLinkChildren
  666.  *
  667.  * PARAMETERS:  Op                - An existing parse node
  668.  *              NumChildren         - Number of children to follow
  669.  *              ...                 - A list of child nodes to link to the new
  670.  *                                    node.  NumChildren long.
  671.  *
  672.  * RETURN:      The updated (linked) node
  673.  *
  674.  * DESCRIPTION: Link a group of nodes to an existing parse node
  675.  *
  676.  ******************************************************************************/
  677.  
  678. ACPI_PARSE_OBJECT *
  679. TrLinkChildren (
  680.     ACPI_PARSE_OBJECT       *Op,
  681.     UINT32                  NumChildren,
  682.     ...)
  683. {
  684.     ACPI_PARSE_OBJECT       *Child;
  685.     ACPI_PARSE_OBJECT       *PrevChild;
  686.     va_list                 ap;
  687.     UINT32                  i;
  688.     BOOLEAN                 FirstChild;
  689.  
  690.  
  691.     va_start (ap, NumChildren);
  692.  
  693.  
  694.     TrSetEndLineNumber (Op);
  695.  
  696.     DbgPrint (ASL_PARSE_OUTPUT,
  697.         "\nLinkChildren  Line [%u to %u] NewParent %p Child %u Op %s  ",
  698.         Op->Asl.LineNumber, Op->Asl.EndLine,
  699.         Op, NumChildren, UtGetOpName(Op->Asl.ParseOpcode));
  700.  
  701.     switch (Op->Asl.ParseOpcode)
  702.     {
  703.     case PARSEOP_DEFINITIONBLOCK:
  704.         RootNode = Op;
  705.         DbgPrint (ASL_PARSE_OUTPUT, "DEFINITION_BLOCK (Tree Completed)->");
  706.         break;
  707.  
  708.     case PARSEOP_OPERATIONREGION:
  709.         DbgPrint (ASL_PARSE_OUTPUT, "OPREGION->");
  710.         break;
  711.  
  712.     case PARSEOP_OR:
  713.         DbgPrint (ASL_PARSE_OUTPUT, "OR->");
  714.         break;
  715.  
  716.     default:
  717.         /* Nothing to do for other opcodes */
  718.         break;
  719.     }
  720.  
  721.     /* Link the new node to it's children */
  722.  
  723.     PrevChild = NULL;
  724.     FirstChild = TRUE;
  725.     for (i = 0; i < NumChildren; i++)
  726.     {
  727.         Child = va_arg (ap, ACPI_PARSE_OBJECT *);
  728.  
  729.         if ((Child == PrevChild) && (Child != NULL))
  730.         {
  731.             AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Child,
  732.                 "Child node list invalid");
  733.             return Op;
  734.         }
  735.  
  736.         DbgPrint (ASL_PARSE_OUTPUT, "%p, ", Child);
  737.  
  738.         /*
  739.          * If child is NULL, this means that an optional argument
  740.          * was omitted.  We must create a placeholder with a special
  741.          * opcode (DEFAULT_ARG) so that the code generator will know
  742.          * that it must emit the correct default for this argument
  743.          */
  744.         if (!Child)
  745.         {
  746.             Child = TrAllocateNode (PARSEOP_DEFAULT_ARG);
  747.         }
  748.  
  749.         /* Link first child to parent */
  750.  
  751.         if (FirstChild)
  752.         {
  753.             FirstChild = FALSE;
  754.             Op->Asl.Child = Child;
  755.         }
  756.  
  757.         /* Point all children to parent */
  758.  
  759.         Child->Asl.Parent = Op;
  760.  
  761.         /* Link children in a peer list */
  762.  
  763.         if (PrevChild)
  764.         {
  765.             PrevChild->Asl.Next = Child;
  766.         };
  767.  
  768.         /*
  769.          * This child might be a list, point all nodes in the list
  770.          * to the same parent
  771.          */
  772.         while (Child->Asl.Next)
  773.         {
  774.             Child = Child->Asl.Next;
  775.             Child->Asl.Parent = Op;
  776.         }
  777.         PrevChild = Child;
  778.     }
  779.     va_end(ap);
  780.  
  781.     DbgPrint (ASL_PARSE_OUTPUT, "\n\n");
  782.     return Op;
  783. }
  784.  
  785.  
  786. /*******************************************************************************
  787.  *
  788.  * FUNCTION:    TrLinkPeerNode
  789.  *
  790.  * PARAMETERS:  Op1           - First peer
  791.  *              Op2           - Second peer
  792.  *
  793.  * RETURN:      Op1 or the non-null node.
  794.  *
  795.  * DESCRIPTION: Link two nodes as peers.  Handles cases where one peer is null.
  796.  *
  797.  ******************************************************************************/
  798.  
  799. ACPI_PARSE_OBJECT *
  800. TrLinkPeerNode (
  801.     ACPI_PARSE_OBJECT       *Op1,
  802.     ACPI_PARSE_OBJECT       *Op2)
  803. {
  804.     ACPI_PARSE_OBJECT       *Next;
  805.  
  806.  
  807.     DbgPrint (ASL_PARSE_OUTPUT,
  808.         "\nLinkPeerNode: 1=%p (%s), 2=%p (%s)\n\n",
  809.         Op1, Op1 ? UtGetOpName(Op1->Asl.ParseOpcode) : NULL,
  810.         Op2, Op2 ? UtGetOpName(Op2->Asl.ParseOpcode) : NULL);
  811.  
  812.  
  813.     if ((!Op1) && (!Op2))
  814.     {
  815.         DbgPrint (ASL_PARSE_OUTPUT, "\nTwo Null nodes!\n");
  816.         return Op1;
  817.     }
  818.  
  819.     /* If one of the nodes is null, just return the non-null node */
  820.  
  821.     if (!Op2)
  822.     {
  823.         return Op1;
  824.     }
  825.  
  826.     if (!Op1)
  827.     {
  828.         return Op2;
  829.     }
  830.  
  831.     if (Op1 == Op2)
  832.     {
  833.         DbgPrint (ASL_DEBUG_OUTPUT,
  834.             "\n\n************* Internal error, linking node to itself %p\n\n\n",
  835.             Op1);
  836.         AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op1,
  837.             "Linking node to itself");
  838.         return Op1;
  839.     }
  840.  
  841.     Op1->Asl.Parent = Op2->Asl.Parent;
  842.  
  843.     /*
  844.      * Op 1 may already have a peer list (such as an IF/ELSE pair),
  845.      * so we must walk to the end of the list and attach the new
  846.      * peer at the end
  847.      */
  848.     Next = Op1;
  849.     while (Next->Asl.Next)
  850.     {
  851.         Next = Next->Asl.Next;
  852.     }
  853.  
  854.     Next->Asl.Next = Op2;
  855.     return Op1;
  856. }
  857.  
  858.  
  859. /*******************************************************************************
  860.  *
  861.  * FUNCTION:    TrLinkPeerNodes
  862.  *
  863.  * PARAMETERS:  NumPeers            - The number of nodes in the list to follow
  864.  *              ...                 - A list of nodes to link together as peers
  865.  *
  866.  * RETURN:      The first node in the list (head of the peer list)
  867.  *
  868.  * DESCRIPTION: Link together an arbitrary number of peer nodes.
  869.  *
  870.  ******************************************************************************/
  871.  
  872. ACPI_PARSE_OBJECT *
  873. TrLinkPeerNodes (
  874.     UINT32                  NumPeers,
  875.     ...)
  876. {
  877.     ACPI_PARSE_OBJECT       *This;
  878.     ACPI_PARSE_OBJECT       *Next;
  879.     va_list                 ap;
  880.     UINT32                  i;
  881.     ACPI_PARSE_OBJECT       *Start;
  882.  
  883.  
  884.     DbgPrint (ASL_PARSE_OUTPUT,
  885.         "\nLinkPeerNodes: (%u) ", NumPeers);
  886.  
  887.     va_start (ap, NumPeers);
  888.     This = va_arg (ap, ACPI_PARSE_OBJECT *);
  889.     Start = This;
  890.  
  891.     /*
  892.      * Link all peers
  893.      */
  894.     for (i = 0; i < (NumPeers -1); i++)
  895.     {
  896.         DbgPrint (ASL_PARSE_OUTPUT, "%u=%p ", (i+1), This);
  897.  
  898.         while (This->Asl.Next)
  899.         {
  900.             This = This->Asl.Next;
  901.         }
  902.  
  903.         /* Get another peer node */
  904.  
  905.         Next = va_arg (ap, ACPI_PARSE_OBJECT *);
  906.         if (!Next)
  907.         {
  908.             Next = TrAllocateNode (PARSEOP_DEFAULT_ARG);
  909.         }
  910.  
  911.         /* link new node to the current node */
  912.  
  913.         This->Asl.Next = Next;
  914.         This = Next;
  915.     }
  916.     va_end (ap);
  917.  
  918.     DbgPrint (ASL_PARSE_OUTPUT,"\n\n");
  919.     return (Start);
  920. }
  921.  
  922.  
  923. /*******************************************************************************
  924.  *
  925.  * FUNCTION:    TrLinkChildNode
  926.  *
  927.  * PARAMETERS:  Op1           - Parent node
  928.  *              Op2           - Op to become a child
  929.  *
  930.  * RETURN:      The parent node
  931.  *
  932.  * DESCRIPTION: Link two nodes together as a parent and child
  933.  *
  934.  ******************************************************************************/
  935.  
  936. ACPI_PARSE_OBJECT *
  937. TrLinkChildNode (
  938.     ACPI_PARSE_OBJECT       *Op1,
  939.     ACPI_PARSE_OBJECT       *Op2)
  940. {
  941.     ACPI_PARSE_OBJECT       *Next;
  942.  
  943.  
  944.     DbgPrint (ASL_PARSE_OUTPUT,
  945.         "\nLinkChildNode: Parent=%p (%s), Child=%p (%s)\n\n",
  946.         Op1, Op1 ? UtGetOpName(Op1->Asl.ParseOpcode): NULL,
  947.         Op2, Op2 ? UtGetOpName(Op2->Asl.ParseOpcode): NULL);
  948.  
  949.     if (!Op1 || !Op2)
  950.     {
  951.         return Op1;
  952.     }
  953.  
  954.     Op1->Asl.Child = Op2;
  955.  
  956.     /* Set the child and all peers of the child to point to the parent */
  957.  
  958.     Next = Op2;
  959.     while (Next)
  960.     {
  961.         Next->Asl.Parent = Op1;
  962.         Next = Next->Asl.Next;
  963.     }
  964.  
  965.     return Op1;
  966. }
  967.  
  968.  
  969. /*******************************************************************************
  970.  *
  971.  * FUNCTION:    TrWalkParseTree
  972.  *
  973.  * PARAMETERS:  Visitation              - Type of walk
  974.  *              DescendingCallback      - Called during tree descent
  975.  *              AscendingCallback       - Called during tree ascent
  976.  *              Context                 - To be passed to the callbacks
  977.  *
  978.  * RETURN:      Status from callback(s)
  979.  *
  980.  * DESCRIPTION: Walk the entire parse tree.
  981.  *
  982.  ******************************************************************************/
  983.  
  984. ACPI_STATUS
  985. TrWalkParseTree (
  986.     ACPI_PARSE_OBJECT       *Op,
  987.     UINT32                  Visitation,
  988.     ASL_WALK_CALLBACK       DescendingCallback,
  989.     ASL_WALK_CALLBACK       AscendingCallback,
  990.     void                    *Context)
  991. {
  992.     UINT32                  Level;
  993.     BOOLEAN                 NodePreviouslyVisited;
  994.     ACPI_PARSE_OBJECT       *StartOp = Op;
  995.     ACPI_STATUS             Status;
  996.  
  997.  
  998.     if (!RootNode)
  999.     {
  1000.         return (AE_OK);
  1001.     }
  1002.  
  1003.     Level = 0;
  1004.     NodePreviouslyVisited = FALSE;
  1005.  
  1006.     switch (Visitation)
  1007.     {
  1008.     case ASL_WALK_VISIT_DOWNWARD:
  1009.  
  1010.         while (Op)
  1011.         {
  1012.             if (!NodePreviouslyVisited)
  1013.             {
  1014.                 /* Let the callback process the node. */
  1015.  
  1016.                 Status = DescendingCallback (Op, Level, Context);
  1017.                 if (ACPI_SUCCESS (Status))
  1018.                 {
  1019.                     /* Visit children first, once */
  1020.  
  1021.                     if (Op->Asl.Child)
  1022.                     {
  1023.                         Level++;
  1024.                         Op = Op->Asl.Child;
  1025.                         continue;
  1026.                     }
  1027.                 }
  1028.                 else if (Status != AE_CTRL_DEPTH)
  1029.                 {
  1030.                     /* Exit immediately on any error */
  1031.  
  1032.                     return (Status);
  1033.                 }
  1034.             }
  1035.  
  1036.             /* Terminate walk at start op */
  1037.  
  1038.             if (Op == StartOp)
  1039.             {
  1040.                 break;
  1041.             }
  1042.  
  1043.             /* No more children, visit peers */
  1044.  
  1045.             if (Op->Asl.Next)
  1046.             {
  1047.                 Op = Op->Asl.Next;
  1048.                 NodePreviouslyVisited = FALSE;
  1049.             }
  1050.             else
  1051.             {
  1052.                 /* No children or peers, re-visit parent */
  1053.  
  1054.                 if (Level != 0 )
  1055.                 {
  1056.                     Level--;
  1057.                 }
  1058.                 Op = Op->Asl.Parent;
  1059.                 NodePreviouslyVisited = TRUE;
  1060.             }
  1061.         }
  1062.         break;
  1063.  
  1064.  
  1065.     case ASL_WALK_VISIT_UPWARD:
  1066.  
  1067.         while (Op)
  1068.         {
  1069.             /* Visit leaf node (no children) or parent node on return trip */
  1070.  
  1071.             if ((!Op->Asl.Child) ||
  1072.                 (NodePreviouslyVisited))
  1073.             {
  1074.                 /* Let the callback process the node. */
  1075.  
  1076.                 Status = AscendingCallback (Op, Level, Context);
  1077.                 if (ACPI_FAILURE (Status))
  1078.                 {
  1079.                     return (Status);
  1080.                 }
  1081.             }
  1082.             else
  1083.             {
  1084.                 /* Visit children first, once */
  1085.  
  1086.                 Level++;
  1087.                 Op = Op->Asl.Child;
  1088.                 continue;
  1089.             }
  1090.  
  1091.             /* Terminate walk at start op */
  1092.  
  1093.             if (Op == StartOp)
  1094.             {
  1095.                 break;
  1096.             }
  1097.  
  1098.             /* No more children, visit peers */
  1099.  
  1100.             if (Op->Asl.Next)
  1101.             {
  1102.                 Op = Op->Asl.Next;
  1103.                 NodePreviouslyVisited = FALSE;
  1104.             }
  1105.             else
  1106.             {
  1107.                 /* No children or peers, re-visit parent */
  1108.  
  1109.                 if (Level != 0 )
  1110.                 {
  1111.                     Level--;
  1112.                 }
  1113.                 Op = Op->Asl.Parent;
  1114.                 NodePreviouslyVisited = TRUE;
  1115.             }
  1116.         }
  1117.         break;
  1118.  
  1119.  
  1120.      case ASL_WALK_VISIT_TWICE:
  1121.  
  1122.         while (Op)
  1123.         {
  1124.             if (NodePreviouslyVisited)
  1125.             {
  1126.                 Status = AscendingCallback (Op, Level, Context);
  1127.                 if (ACPI_FAILURE (Status))
  1128.                 {
  1129.                     return (Status);
  1130.                 }
  1131.             }
  1132.             else
  1133.             {
  1134.                 /* Let the callback process the node. */
  1135.  
  1136.                 Status = DescendingCallback (Op, Level, Context);
  1137.                 if (ACPI_SUCCESS (Status))
  1138.                 {
  1139.                     /* Visit children first, once */
  1140.  
  1141.                     if (Op->Asl.Child)
  1142.                     {
  1143.                         Level++;
  1144.                         Op = Op->Asl.Child;
  1145.                         continue;
  1146.                     }
  1147.                 }
  1148.                 else if (Status != AE_CTRL_DEPTH)
  1149.                 {
  1150.                     /* Exit immediately on any error */
  1151.  
  1152.                     return (Status);
  1153.                 }
  1154.             }
  1155.  
  1156.             /* Terminate walk at start op */
  1157.  
  1158.             if (Op == StartOp)
  1159.             {
  1160.                 break;
  1161.             }
  1162.  
  1163.             /* No more children, visit peers */
  1164.  
  1165.             if (Op->Asl.Next)
  1166.             {
  1167.                 Op = Op->Asl.Next;
  1168.                 NodePreviouslyVisited = FALSE;
  1169.             }
  1170.             else
  1171.             {
  1172.                 /* No children or peers, re-visit parent */
  1173.  
  1174.                 if (Level != 0 )
  1175.                 {
  1176.                     Level--;
  1177.                 }
  1178.                 Op = Op->Asl.Parent;
  1179.                 NodePreviouslyVisited = TRUE;
  1180.             }
  1181.         }
  1182.         break;
  1183.  
  1184.     default:
  1185.         /* No other types supported */
  1186.         break;
  1187.     }
  1188.  
  1189.     /* If we get here, the walk completed with no errors */
  1190.  
  1191.     return (AE_OK);
  1192. }
  1193.  
  1194.  
  1195.