Sync ACPICA with Intel's version 20160108.
[dragonfly.git] / sys / contrib / dev / acpica / source / compiler / aslprune.c
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 "aslcompiler.h"
45 #include "aslcompiler.y.h"
46 #include "acapps.h"
47
48 #define _COMPONENT          ACPI_COMPILER
49         ACPI_MODULE_NAME    ("aslprune")
50
51
52 /* Local prototypes */
53
54 static ACPI_STATUS
55 PrTreePruneWalk (
56     ACPI_PARSE_OBJECT       *Op,
57     UINT32                  Level,
58     void                    *Context);
59
60 static void
61 PrPrintObjectAtLevel (
62     UINT32                  Level,
63     const char              *ObjectName);
64
65
66 /* Structure used for the pruning parse tree walk */
67
68 typedef 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
90 void
91 AslPruneParseTree (
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 (RootNode, 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
145 static void
146 PrPrintObjectAtLevel (
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
177 static ACPI_STATUS
178 PrTreePruneWalk (
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 }