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