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