aslprune.c revision 281075
1/******************************************************************************
2 *
3 * Module Name: aslprune - Parse tree prune utility
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
45#include "aslcompiler.y.h"
46#include <contrib/dev/acpica/include/acapps.h>
47
48#define _COMPONENT          ACPI_COMPILER
49        ACPI_MODULE_NAME    ("aslprune")
50
51
52/* Local prototypes */
53
54static ACPI_STATUS
55PrTreePruneWalk (
56    ACPI_PARSE_OBJECT       *Op,
57    UINT32                  Level,
58    void                    *Context);
59
60static void
61PrPrintObjectAtLevel (
62    UINT32                  Level,
63    const char              *ObjectName);
64
65
66typedef struct acpi_prune_info
67{
68    UINT32                  PruneLevel;
69    UINT16                  ParseOpcode;
70    UINT16                  Count;
71
72} ACPI_PRUNE_INFO;
73
74
75/*******************************************************************************
76 *
77 * FUNCTION:    AslPruneParseTree
78 *
79 * PARAMETERS:  PruneDepth              - Number of levels to prune
80 *              Type                    - Prune type (Device, Method, etc.)
81 *
82 * RETURN:      None
83 *
84 * DESCRIPTION: Prune off one or more levels of the ASL parse tree
85 *
86 ******************************************************************************/
87
88void
89AslPruneParseTree (
90    UINT32                  PruneDepth,
91    UINT32                  Type)
92{
93    ACPI_PRUNE_INFO         PruneObj;
94
95
96    PruneObj.PruneLevel = PruneDepth;
97    PruneObj.Count = 0;
98
99    switch (Type)
100    {
101    case 0:
102        PruneObj.ParseOpcode = (UINT16) PARSEOP_DEVICE;
103        break;
104
105    case 1:
106        PruneObj.ParseOpcode = (UINT16) PARSEOP_METHOD;
107        break;
108
109    case 2:
110        PruneObj.ParseOpcode = (UINT16) PARSEOP_IF;
111        break;
112
113    default:
114        AcpiOsPrintf ("Unsupported type: %u\n", Type);
115        return;
116    }
117
118    AcpiOsPrintf ("Pruning parse tree, from depth %u\n",
119        PruneDepth);
120
121    AcpiOsPrintf ("\nRemoving Objects:\n");
122
123    TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
124        PrTreePruneWalk, NULL, ACPI_CAST_PTR (void, &PruneObj));
125
126    AcpiOsPrintf ("\n%u Total Objects Removed\n", PruneObj.Count);
127}
128
129
130/*******************************************************************************
131 *
132 * FUNCTION:    PrPrintObjectAtLevel
133 *
134 * PARAMETERS:  Level                   - Current nesting level
135 *              ObjectName              - ACPI name for the object
136 *
137 * RETURN:      None
138 *
139 * DESCRIPTION: Print object name with indent
140 *
141 ******************************************************************************/
142
143static void
144PrPrintObjectAtLevel (
145    UINT32                  Level,
146    const char              *ObjectName)
147{
148    UINT32                  i;
149
150
151    for (i = 0; i < Level; i++)
152    {
153        AcpiOsPrintf ("  ");
154    }
155
156    AcpiOsPrintf ("[%s] at Level [%u]\n", ObjectName, Level);
157}
158
159
160/*******************************************************************************
161 *
162 * FUNCTION:    PrTreePruneWalk
163 *
164 * PARAMETERS:  Parse tree walk callback
165 *
166 * RETURN:      Status
167 *
168 * DESCRIPTION: Prune off one or more levels of the ASL parse tree
169 *
170 * Current objects that can be pruned are: Devices, Methods, and If/Else
171 * blocks.
172 *
173 ******************************************************************************/
174
175static ACPI_STATUS
176PrTreePruneWalk (
177    ACPI_PARSE_OBJECT       *Op,
178    UINT32                  Level,
179    void                    *Context)
180{
181    ACPI_PRUNE_INFO         *PruneObj = (ACPI_PRUNE_INFO *) Context;
182
183
184    /* We only care about objects below the Prune Level threshold */
185
186    if (Level <= PruneObj->PruneLevel)
187    {
188        return (AE_OK);
189    }
190
191    if ((Op->Asl.ParseOpcode != PruneObj->ParseOpcode) &&
192       !(Op->Asl.ParseOpcode == PARSEOP_ELSE &&
193             PruneObj->ParseOpcode == PARSEOP_IF))
194    {
195        return (AE_OK);
196    }
197
198    switch (Op->Asl.ParseOpcode)
199    {
200    case PARSEOP_METHOD:
201
202        AcpiOsPrintf ("Method");
203        PrPrintObjectAtLevel (Level, Op->Asl.Child->Asl.Value.Name);
204        Op->Asl.Child->Asl.Next->Asl.Next->Asl.Next->Asl.Next->Asl.Next->Asl.Next = NULL;
205        PruneObj->Count++;
206        break;
207
208    case PARSEOP_DEVICE:
209
210        AcpiOsPrintf ("Device");
211        PrPrintObjectAtLevel (Level, Op->Asl.Child->Asl.Value.Name);
212        Op->Asl.Child->Asl.Next = NULL;
213        PruneObj->Count++;
214        break;
215
216    case PARSEOP_IF:
217    case PARSEOP_ELSE:
218
219        if (Op->Asl.ParseOpcode == PARSEOP_ELSE)
220        {
221            PrPrintObjectAtLevel(Level, "Else");
222            Op->Asl.Child = NULL;
223        }
224        else
225        {
226            PrPrintObjectAtLevel(Level, "If");
227            Op->Asl.Child->Asl.Next = NULL;
228        }
229
230        PruneObj->Count++;
231        break;
232
233    default:
234
235        break;
236    }
237
238    return (AE_OK);
239}
240