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