Home | History | Annotate | Line # | Download | only in parser
pstree.c revision 1.1.1.8.8.1
      1 /******************************************************************************
      2  *
      3  * Module Name: pstree - Parser op tree manipulation/traversal/search
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2018, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "acpi.h"
     45 #include "accommon.h"
     46 #include "acparser.h"
     47 #include "amlcode.h"
     48 #include "acconvert.h"
     49 
     50 #define _COMPONENT          ACPI_PARSER
     51         ACPI_MODULE_NAME    ("pstree")
     52 
     53 /* Local prototypes */
     54 
     55 #ifdef ACPI_OBSOLETE_FUNCTIONS
     56 ACPI_PARSE_OBJECT *
     57 AcpiPsGetChild (
     58     ACPI_PARSE_OBJECT       *op);
     59 #endif
     60 
     61 
     62 /*******************************************************************************
     63  *
     64  * FUNCTION:    AcpiPsGetArg
     65  *
     66  * PARAMETERS:  Op              - Get an argument for this op
     67  *              Argn            - Nth argument to get
     68  *
     69  * RETURN:      The argument (as an Op object). NULL if argument does not exist
     70  *
     71  * DESCRIPTION: Get the specified op's argument.
     72  *
     73  ******************************************************************************/
     74 
     75 ACPI_PARSE_OBJECT *
     76 AcpiPsGetArg (
     77     ACPI_PARSE_OBJECT       *Op,
     78     UINT32                  Argn)
     79 {
     80     ACPI_PARSE_OBJECT       *Arg = NULL;
     81     const ACPI_OPCODE_INFO  *OpInfo;
     82 
     83 
     84     ACPI_FUNCTION_ENTRY ();
     85 
     86 /*
     87     if (Op->Common.AmlOpcode == AML_INT_CONNECTION_OP)
     88     {
     89         return (Op->Common.Value.Arg);
     90     }
     91 */
     92     /* Get the info structure for this opcode */
     93 
     94     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
     95     if (OpInfo->Class == AML_CLASS_UNKNOWN)
     96     {
     97         /* Invalid opcode or ASCII character */
     98 
     99         return (NULL);
    100     }
    101 
    102     /* Check if this opcode requires argument sub-objects */
    103 
    104     if (!(OpInfo->Flags & AML_HAS_ARGS))
    105     {
    106         /* Has no linked argument objects */
    107 
    108         return (NULL);
    109     }
    110 
    111     /* Get the requested argument object */
    112 
    113     Arg = Op->Common.Value.Arg;
    114     while (Arg && Argn)
    115     {
    116         Argn--;
    117         Arg = Arg->Common.Next;
    118     }
    119 
    120     return (Arg);
    121 }
    122 
    123 
    124 /*******************************************************************************
    125  *
    126  * FUNCTION:    AcpiPsAppendArg
    127  *
    128  * PARAMETERS:  Op              - Append an argument to this Op.
    129  *              Arg             - Argument Op to append
    130  *
    131  * RETURN:      None.
    132  *
    133  * DESCRIPTION: Append an argument to an op's argument list (a NULL arg is OK)
    134  *
    135  ******************************************************************************/
    136 
    137 void
    138 AcpiPsAppendArg (
    139     ACPI_PARSE_OBJECT       *Op,
    140     ACPI_PARSE_OBJECT       *Arg)
    141 {
    142     ACPI_PARSE_OBJECT       *PrevArg;
    143     const ACPI_OPCODE_INFO  *OpInfo;
    144 
    145 
    146     ACPI_FUNCTION_TRACE (PsAppendArg);
    147 
    148 
    149     if (!Op)
    150     {
    151         return_VOID;
    152     }
    153 
    154     /* Get the info structure for this opcode */
    155 
    156     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    157     if (OpInfo->Class == AML_CLASS_UNKNOWN)
    158     {
    159         /* Invalid opcode */
    160 
    161         ACPI_ERROR ((AE_INFO, "Invalid AML Opcode: 0x%2.2X",
    162             Op->Common.AmlOpcode));
    163         return_VOID;
    164     }
    165 
    166     /* Check if this opcode requires argument sub-objects */
    167 
    168     if (!(OpInfo->Flags & AML_HAS_ARGS))
    169     {
    170         /* Has no linked argument objects */
    171 
    172         return_VOID;
    173     }
    174 
    175     /* Append the argument to the linked argument list */
    176 
    177     if (Op->Common.Value.Arg)
    178     {
    179         /* Append to existing argument list */
    180 
    181         PrevArg = Op->Common.Value.Arg;
    182         while (PrevArg->Common.Next)
    183         {
    184             PrevArg = PrevArg->Common.Next;
    185         }
    186         PrevArg->Common.Next = Arg;
    187     }
    188     else
    189     {
    190         /* No argument list, this will be the first argument */
    191 
    192         Op->Common.Value.Arg = Arg;
    193     }
    194 
    195     /* Set the parent in this arg and any args linked after it */
    196 
    197     while (Arg)
    198     {
    199         Arg->Common.Parent = Op;
    200         Arg = Arg->Common.Next;
    201 
    202         Op->Common.ArgListLength++;
    203     }
    204 
    205     return_VOID;
    206 }
    207 
    208 
    209 /*******************************************************************************
    210  *
    211  * FUNCTION:    AcpiPsGetDepthNext
    212  *
    213  * PARAMETERS:  Origin          - Root of subtree to search
    214  *              Op              - Last (previous) Op that was found
    215  *
    216  * RETURN:      Next Op found in the search.
    217  *
    218  * DESCRIPTION: Get next op in tree (walking the tree in depth-first order)
    219  *              Return NULL when reaching "origin" or when walking up from root
    220  *
    221  ******************************************************************************/
    222 
    223 ACPI_PARSE_OBJECT *
    224 AcpiPsGetDepthNext (
    225     ACPI_PARSE_OBJECT       *Origin,
    226     ACPI_PARSE_OBJECT       *Op)
    227 {
    228     ACPI_PARSE_OBJECT       *Next = NULL;
    229     ACPI_PARSE_OBJECT       *Parent;
    230     ACPI_PARSE_OBJECT       *Arg;
    231 
    232 
    233     ACPI_FUNCTION_ENTRY ();
    234 
    235 
    236     if (!Op)
    237     {
    238         return (NULL);
    239     }
    240 
    241     /* Look for an argument or child */
    242 
    243     Next = AcpiPsGetArg (Op, 0);
    244     if (Next)
    245     {
    246         ASL_CV_LABEL_FILENODE (Next);
    247         return (Next);
    248     }
    249 
    250     /* Look for a sibling */
    251 
    252     Next = Op->Common.Next;
    253     if (Next)
    254     {
    255         ASL_CV_LABEL_FILENODE (Next);
    256         return (Next);
    257     }
    258 
    259     /* Look for a sibling of parent */
    260 
    261     Parent = Op->Common.Parent;
    262 
    263     while (Parent)
    264     {
    265         Arg = AcpiPsGetArg (Parent, 0);
    266         while (Arg && (Arg != Origin) && (Arg != Op))
    267         {
    268 
    269             ASL_CV_LABEL_FILENODE (Arg);
    270             Arg = Arg->Common.Next;
    271         }
    272 
    273         if (Arg == Origin)
    274         {
    275             /* Reached parent of origin, end search */
    276 
    277             return (NULL);
    278         }
    279 
    280         if (Parent->Common.Next)
    281         {
    282             /* Found sibling of parent */
    283 
    284             ASL_CV_LABEL_FILENODE (Parent->Common.Next);
    285             return (Parent->Common.Next);
    286         }
    287 
    288         Op = Parent;
    289         Parent = Parent->Common.Parent;
    290     }
    291 
    292     ASL_CV_LABEL_FILENODE (Next);
    293     return (Next);
    294 }
    295 
    296 
    297 #ifdef ACPI_OBSOLETE_FUNCTIONS
    298 /*******************************************************************************
    299  *
    300  * FUNCTION:    AcpiPsGetChild
    301  *
    302  * PARAMETERS:  Op              - Get the child of this Op
    303  *
    304  * RETURN:      Child Op, Null if none is found.
    305  *
    306  * DESCRIPTION: Get op's children or NULL if none
    307  *
    308  ******************************************************************************/
    309 
    310 ACPI_PARSE_OBJECT *
    311 AcpiPsGetChild (
    312     ACPI_PARSE_OBJECT       *Op)
    313 {
    314     ACPI_PARSE_OBJECT       *Child = NULL;
    315 
    316 
    317     ACPI_FUNCTION_ENTRY ();
    318 
    319 
    320     switch (Op->Common.AmlOpcode)
    321     {
    322     case AML_SCOPE_OP:
    323     case AML_ELSE_OP:
    324     case AML_DEVICE_OP:
    325     case AML_THERMAL_ZONE_OP:
    326     case AML_INT_METHODCALL_OP:
    327 
    328         Child = AcpiPsGetArg (Op, 0);
    329         break;
    330 
    331     case AML_BUFFER_OP:
    332     case AML_PACKAGE_OP:
    333     case AML_VARIABLE_PACKAGE_OP:
    334     case AML_METHOD_OP:
    335     case AML_IF_OP:
    336     case AML_WHILE_OP:
    337     case AML_FIELD_OP:
    338 
    339         Child = AcpiPsGetArg (Op, 1);
    340         break;
    341 
    342     case AML_POWER_RESOURCE_OP:
    343     case AML_INDEX_FIELD_OP:
    344 
    345         Child = AcpiPsGetArg (Op, 2);
    346         break;
    347 
    348     case AML_PROCESSOR_OP:
    349     case AML_BANK_FIELD_OP:
    350 
    351         Child = AcpiPsGetArg (Op, 3);
    352         break;
    353 
    354     default:
    355 
    356         /* All others have no children */
    357 
    358         break;
    359     }
    360 
    361     return (Child);
    362 }
    363 #endif
    364