asltransform.c revision 1.1.1.20 1 1.1 jruoho /******************************************************************************
2 1.1 jruoho *
3 1.1 jruoho * Module Name: asltransform - Parse tree transforms
4 1.1 jruoho *
5 1.1 jruoho *****************************************************************************/
6 1.1 jruoho
7 1.1.1.20 christos /******************************************************************************
8 1.1.1.20 christos *
9 1.1.1.20 christos * 1. Copyright Notice
10 1.1.1.20 christos *
11 1.1.1.20 christos * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
12 1.1 jruoho * All rights reserved.
13 1.1 jruoho *
14 1.1.1.20 christos * 2. License
15 1.1.1.20 christos *
16 1.1.1.20 christos * 2.1. This is your license from Intel Corp. under its intellectual property
17 1.1.1.20 christos * rights. You may have additional license terms from the party that provided
18 1.1.1.20 christos * you this software, covering your right to use that party's intellectual
19 1.1.1.20 christos * property rights.
20 1.1.1.20 christos *
21 1.1.1.20 christos * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 1.1.1.20 christos * copy of the source code appearing in this file ("Covered Code") an
23 1.1.1.20 christos * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 1.1.1.20 christos * base code distributed originally by Intel ("Original Intel Code") to copy,
25 1.1.1.20 christos * make derivatives, distribute, use and display any portion of the Covered
26 1.1.1.20 christos * Code in any form, with the right to sublicense such rights; and
27 1.1.1.20 christos *
28 1.1.1.20 christos * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 1.1.1.20 christos * license (with the right to sublicense), under only those claims of Intel
30 1.1.1.20 christos * patents that are infringed by the Original Intel Code, to make, use, sell,
31 1.1.1.20 christos * offer to sell, and import the Covered Code and derivative works thereof
32 1.1.1.20 christos * solely to the minimum extent necessary to exercise the above copyright
33 1.1.1.20 christos * license, and in no event shall the patent license extend to any additions
34 1.1.1.20 christos * to or modifications of the Original Intel Code. No other license or right
35 1.1.1.20 christos * is granted directly or by implication, estoppel or otherwise;
36 1.1.1.20 christos *
37 1.1.1.20 christos * The above copyright and patent license is granted only if the following
38 1.1.1.20 christos * conditions are met:
39 1.1.1.20 christos *
40 1.1.1.20 christos * 3. Conditions
41 1.1.1.20 christos *
42 1.1.1.20 christos * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 1.1.1.20 christos * Redistribution of source code of any substantial portion of the Covered
44 1.1.1.20 christos * Code or modification with rights to further distribute source must include
45 1.1.1.20 christos * the above Copyright Notice, the above License, this list of Conditions,
46 1.1.1.20 christos * and the following Disclaimer and Export Compliance provision. In addition,
47 1.1.1.20 christos * Licensee must cause all Covered Code to which Licensee contributes to
48 1.1.1.20 christos * contain a file documenting the changes Licensee made to create that Covered
49 1.1.1.20 christos * Code and the date of any change. Licensee must include in that file the
50 1.1.1.20 christos * documentation of any changes made by any predecessor Licensee. Licensee
51 1.1.1.20 christos * must include a prominent statement that the modification is derived,
52 1.1.1.20 christos * directly or indirectly, from Original Intel Code.
53 1.1.1.20 christos *
54 1.1.1.20 christos * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 1.1.1.20 christos * Redistribution of source code of any substantial portion of the Covered
56 1.1.1.20 christos * Code or modification without rights to further distribute source must
57 1.1.1.20 christos * include the following Disclaimer and Export Compliance provision in the
58 1.1.1.20 christos * documentation and/or other materials provided with distribution. In
59 1.1.1.20 christos * addition, Licensee may not authorize further sublicense of source of any
60 1.1.1.20 christos * portion of the Covered Code, and must include terms to the effect that the
61 1.1.1.20 christos * license from Licensee to its licensee is limited to the intellectual
62 1.1.1.20 christos * property embodied in the software Licensee provides to its licensee, and
63 1.1.1.20 christos * not to intellectual property embodied in modifications its licensee may
64 1.1.1.20 christos * make.
65 1.1.1.20 christos *
66 1.1.1.20 christos * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 1.1.1.20 christos * substantial portion of the Covered Code or modification must reproduce the
68 1.1.1.20 christos * above Copyright Notice, and the following Disclaimer and Export Compliance
69 1.1.1.20 christos * provision in the documentation and/or other materials provided with the
70 1.1.1.20 christos * distribution.
71 1.1.1.20 christos *
72 1.1.1.20 christos * 3.4. Intel retains all right, title, and interest in and to the Original
73 1.1.1.20 christos * Intel Code.
74 1.1.1.20 christos *
75 1.1.1.20 christos * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 1.1.1.20 christos * Intel shall be used in advertising or otherwise to promote the sale, use or
77 1.1.1.20 christos * other dealings in products derived from or relating to the Covered Code
78 1.1.1.20 christos * without prior written authorization from Intel.
79 1.1.1.20 christos *
80 1.1.1.20 christos * 4. Disclaimer and Export Compliance
81 1.1.1.20 christos *
82 1.1.1.20 christos * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 1.1.1.20 christos * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 1.1.1.20 christos * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85 1.1.1.20 christos * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86 1.1.1.20 christos * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 1.1.1.20 christos * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88 1.1.1.20 christos * PARTICULAR PURPOSE.
89 1.1.1.20 christos *
90 1.1.1.20 christos * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 1.1.1.20 christos * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 1.1.1.20 christos * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 1.1.1.20 christos * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 1.1.1.20 christos * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 1.1.1.20 christos * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 1.1.1.20 christos * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97 1.1.1.20 christos * LIMITED REMEDY.
98 1.1.1.20 christos *
99 1.1.1.20 christos * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 1.1.1.20 christos * software or system incorporating such software without first obtaining any
101 1.1.1.20 christos * required license or other approval from the U. S. Department of Commerce or
102 1.1.1.20 christos * any other agency or department of the United States Government. In the
103 1.1.1.20 christos * event Licensee exports any such software from the United States or
104 1.1.1.20 christos * re-exports any such software from a foreign destination, Licensee shall
105 1.1.1.20 christos * ensure that the distribution and export/re-export of the software is in
106 1.1.1.20 christos * compliance with all laws, regulations, orders, or other restrictions of the
107 1.1.1.20 christos * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 1.1.1.20 christos * any of its subsidiaries will export/re-export any technical data, process,
109 1.1.1.20 christos * software, or service, directly or indirectly, to any country for which the
110 1.1.1.20 christos * United States government or any agency thereof requires an export license,
111 1.1.1.20 christos * other governmental approval, or letter of assurance, without first obtaining
112 1.1.1.20 christos * such license, approval or letter.
113 1.1.1.20 christos *
114 1.1.1.20 christos *****************************************************************************
115 1.1.1.20 christos *
116 1.1.1.20 christos * Alternatively, you may choose to be licensed under the terms of the
117 1.1.1.20 christos * following license:
118 1.1.1.20 christos *
119 1.1.1.2 jruoho * Redistribution and use in source and binary forms, with or without
120 1.1.1.2 jruoho * modification, are permitted provided that the following conditions
121 1.1.1.2 jruoho * are met:
122 1.1.1.2 jruoho * 1. Redistributions of source code must retain the above copyright
123 1.1.1.2 jruoho * notice, this list of conditions, and the following disclaimer,
124 1.1.1.2 jruoho * without modification.
125 1.1.1.2 jruoho * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126 1.1.1.2 jruoho * substantially similar to the "NO WARRANTY" disclaimer below
127 1.1.1.2 jruoho * ("Disclaimer") and any redistribution must be conditioned upon
128 1.1.1.2 jruoho * including a substantially similar Disclaimer requirement for further
129 1.1.1.2 jruoho * binary redistribution.
130 1.1.1.2 jruoho * 3. Neither the names of the above-listed copyright holders nor the names
131 1.1.1.2 jruoho * of any contributors may be used to endorse or promote products derived
132 1.1.1.2 jruoho * from this software without specific prior written permission.
133 1.1.1.2 jruoho *
134 1.1.1.2 jruoho * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135 1.1.1.2 jruoho * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136 1.1.1.17 christos * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137 1.1.1.2 jruoho * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138 1.1.1.20 christos * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139 1.1.1.20 christos * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140 1.1.1.20 christos * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141 1.1.1.20 christos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142 1.1.1.20 christos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143 1.1.1.20 christos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144 1.1.1.20 christos * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145 1.1.1.20 christos *
146 1.1.1.20 christos * Alternatively, you may choose to be licensed under the terms of the
147 1.1.1.20 christos * GNU General Public License ("GPL") version 2 as published by the Free
148 1.1.1.20 christos * Software Foundation.
149 1.1.1.20 christos *
150 1.1.1.20 christos *****************************************************************************/
151 1.1 jruoho
152 1.1 jruoho #include "aslcompiler.h"
153 1.1 jruoho #include "aslcompiler.y.h"
154 1.1.1.15 christos #include "acnamesp.h"
155 1.1 jruoho
156 1.1 jruoho #define _COMPONENT ACPI_COMPILER
157 1.1 jruoho ACPI_MODULE_NAME ("asltransform")
158 1.1 jruoho
159 1.1 jruoho /* Local prototypes */
160 1.1 jruoho
161 1.1 jruoho static void
162 1.1 jruoho TrTransformSubtree (
163 1.1 jruoho ACPI_PARSE_OBJECT *Op);
164 1.1 jruoho
165 1.1 jruoho static char *
166 1.1 jruoho TrAmlGetNextTempName (
167 1.1 jruoho ACPI_PARSE_OBJECT *Op,
168 1.1 jruoho UINT8 *TempCount);
169 1.1 jruoho
170 1.1 jruoho static void
171 1.1 jruoho TrAmlInitLineNumbers (
172 1.1 jruoho ACPI_PARSE_OBJECT *Op,
173 1.1 jruoho ACPI_PARSE_OBJECT *Neighbor);
174 1.1 jruoho
175 1.1 jruoho static void
176 1.1 jruoho TrAmlInitNode (
177 1.1 jruoho ACPI_PARSE_OBJECT *Op,
178 1.1 jruoho UINT16 ParseOpcode);
179 1.1 jruoho
180 1.1 jruoho static void
181 1.1 jruoho TrAmlSetSubtreeParent (
182 1.1 jruoho ACPI_PARSE_OBJECT *Op,
183 1.1 jruoho ACPI_PARSE_OBJECT *Parent);
184 1.1 jruoho
185 1.1 jruoho static void
186 1.1 jruoho TrAmlInsertPeer (
187 1.1 jruoho ACPI_PARSE_OBJECT *Op,
188 1.1 jruoho ACPI_PARSE_OBJECT *NewPeer);
189 1.1 jruoho
190 1.1 jruoho static void
191 1.1 jruoho TrDoDefinitionBlock (
192 1.1 jruoho ACPI_PARSE_OBJECT *Op);
193 1.1 jruoho
194 1.1 jruoho static void
195 1.1 jruoho TrDoSwitch (
196 1.1 jruoho ACPI_PARSE_OBJECT *StartNode);
197 1.1 jruoho
198 1.1.1.15 christos static void
199 1.1.1.15 christos TrCheckForDuplicateCase (
200 1.1.1.15 christos ACPI_PARSE_OBJECT *CaseOp,
201 1.1.1.15 christos ACPI_PARSE_OBJECT *Predicate1);
202 1.1.1.15 christos
203 1.1.1.15 christos static BOOLEAN
204 1.1.1.15 christos TrCheckForBufferMatch (
205 1.1.1.15 christos ACPI_PARSE_OBJECT *Next1,
206 1.1.1.15 christos ACPI_PARSE_OBJECT *Next2);
207 1.1.1.15 christos
208 1.1.1.16 christos static void
209 1.1.1.16 christos TrDoMethod (
210 1.1.1.16 christos ACPI_PARSE_OBJECT *Op);
211 1.1.1.16 christos
212 1.1 jruoho
213 1.1 jruoho /*******************************************************************************
214 1.1 jruoho *
215 1.1 jruoho * FUNCTION: TrAmlGetNextTempName
216 1.1 jruoho *
217 1.1 jruoho * PARAMETERS: Op - Current parse op
218 1.1 jruoho * TempCount - Current temporary counter. Was originally
219 1.1 jruoho * per-module; Currently per method, could be
220 1.1 jruoho * expanded to per-scope.
221 1.1 jruoho *
222 1.1 jruoho * RETURN: A pointer to name (allocated here).
223 1.1 jruoho *
224 1.1.1.3 christos * DESCRIPTION: Generate an ACPI name of the form _T_x. These names are
225 1.1 jruoho * reserved for use by the ASL compiler. (_T_0 through _T_Z)
226 1.1 jruoho *
227 1.1 jruoho ******************************************************************************/
228 1.1 jruoho
229 1.1 jruoho static char *
230 1.1 jruoho TrAmlGetNextTempName (
231 1.1 jruoho ACPI_PARSE_OBJECT *Op,
232 1.1 jruoho UINT8 *TempCount)
233 1.1 jruoho {
234 1.1 jruoho char *TempName;
235 1.1 jruoho
236 1.1 jruoho
237 1.1.1.6 christos if (*TempCount >= (10 + 26)) /* 0-35 valid: 0-9 and A-Z for TempName[3] */
238 1.1 jruoho {
239 1.1 jruoho /* Too many temps */
240 1.1 jruoho
241 1.1 jruoho AslError (ASL_ERROR, ASL_MSG_TOO_MANY_TEMPS, Op, NULL);
242 1.1 jruoho return (NULL);
243 1.1 jruoho }
244 1.1 jruoho
245 1.1 jruoho TempName = UtLocalCalloc (5);
246 1.1 jruoho
247 1.1 jruoho if (*TempCount < 10) /* 0-9 */
248 1.1 jruoho {
249 1.1 jruoho TempName[3] = (char) (*TempCount + '0');
250 1.1 jruoho }
251 1.1 jruoho else /* 10-35: A-Z */
252 1.1 jruoho {
253 1.1 jruoho TempName[3] = (char) (*TempCount + ('A' - 10));
254 1.1 jruoho }
255 1.1.1.6 christos
256 1.1 jruoho (*TempCount)++;
257 1.1 jruoho
258 1.1 jruoho /* First three characters are always "_T_" */
259 1.1 jruoho
260 1.1 jruoho TempName[0] = '_';
261 1.1 jruoho TempName[1] = 'T';
262 1.1 jruoho TempName[2] = '_';
263 1.1 jruoho
264 1.1 jruoho return (TempName);
265 1.1 jruoho }
266 1.1 jruoho
267 1.1 jruoho
268 1.1 jruoho /*******************************************************************************
269 1.1 jruoho *
270 1.1 jruoho * FUNCTION: TrAmlInitLineNumbers
271 1.1 jruoho *
272 1.1 jruoho * PARAMETERS: Op - Op to be initialized
273 1.1 jruoho * Neighbor - Op used for initialization values
274 1.1 jruoho *
275 1.1 jruoho * RETURN: None
276 1.1 jruoho *
277 1.1 jruoho * DESCRIPTION: Initialized the various line numbers for a parse node.
278 1.1 jruoho *
279 1.1 jruoho ******************************************************************************/
280 1.1 jruoho
281 1.1 jruoho static void
282 1.1 jruoho TrAmlInitLineNumbers (
283 1.1 jruoho ACPI_PARSE_OBJECT *Op,
284 1.1 jruoho ACPI_PARSE_OBJECT *Neighbor)
285 1.1 jruoho {
286 1.1 jruoho
287 1.1 jruoho Op->Asl.EndLine = Neighbor->Asl.EndLine;
288 1.1 jruoho Op->Asl.EndLogicalLine = Neighbor->Asl.EndLogicalLine;
289 1.1 jruoho Op->Asl.LineNumber = Neighbor->Asl.LineNumber;
290 1.1 jruoho Op->Asl.LogicalByteOffset = Neighbor->Asl.LogicalByteOffset;
291 1.1 jruoho Op->Asl.LogicalLineNumber = Neighbor->Asl.LogicalLineNumber;
292 1.1 jruoho }
293 1.1 jruoho
294 1.1 jruoho
295 1.1 jruoho /*******************************************************************************
296 1.1 jruoho *
297 1.1 jruoho * FUNCTION: TrAmlInitNode
298 1.1 jruoho *
299 1.1 jruoho * PARAMETERS: Op - Op to be initialized
300 1.1 jruoho * ParseOpcode - Opcode for this node
301 1.1 jruoho *
302 1.1 jruoho * RETURN: None
303 1.1 jruoho *
304 1.1 jruoho * DESCRIPTION: Initialize a node with the parse opcode and opcode name.
305 1.1 jruoho *
306 1.1 jruoho ******************************************************************************/
307 1.1 jruoho
308 1.1 jruoho static void
309 1.1 jruoho TrAmlInitNode (
310 1.1 jruoho ACPI_PARSE_OBJECT *Op,
311 1.1 jruoho UINT16 ParseOpcode)
312 1.1 jruoho {
313 1.1 jruoho
314 1.1 jruoho Op->Asl.ParseOpcode = ParseOpcode;
315 1.1 jruoho UtSetParseOpName (Op);
316 1.1 jruoho }
317 1.1 jruoho
318 1.1 jruoho
319 1.1 jruoho /*******************************************************************************
320 1.1 jruoho *
321 1.1 jruoho * FUNCTION: TrAmlSetSubtreeParent
322 1.1 jruoho *
323 1.1 jruoho * PARAMETERS: Op - First node in a list of peer nodes
324 1.1 jruoho * Parent - Parent of the subtree
325 1.1 jruoho *
326 1.1 jruoho * RETURN: None
327 1.1 jruoho *
328 1.1 jruoho * DESCRIPTION: Set the parent for all peer nodes in a subtree
329 1.1 jruoho *
330 1.1 jruoho ******************************************************************************/
331 1.1 jruoho
332 1.1 jruoho static void
333 1.1 jruoho TrAmlSetSubtreeParent (
334 1.1 jruoho ACPI_PARSE_OBJECT *Op,
335 1.1 jruoho ACPI_PARSE_OBJECT *Parent)
336 1.1 jruoho {
337 1.1 jruoho ACPI_PARSE_OBJECT *Next;
338 1.1 jruoho
339 1.1 jruoho
340 1.1 jruoho Next = Op;
341 1.1 jruoho while (Next)
342 1.1 jruoho {
343 1.1 jruoho Next->Asl.Parent = Parent;
344 1.1.1.6 christos Next = Next->Asl.Next;
345 1.1 jruoho }
346 1.1 jruoho }
347 1.1 jruoho
348 1.1 jruoho
349 1.1 jruoho /*******************************************************************************
350 1.1 jruoho *
351 1.1 jruoho * FUNCTION: TrAmlInsertPeer
352 1.1 jruoho *
353 1.1 jruoho * PARAMETERS: Op - First node in a list of peer nodes
354 1.1 jruoho * NewPeer - Peer node to insert
355 1.1 jruoho *
356 1.1 jruoho * RETURN: None
357 1.1 jruoho *
358 1.1 jruoho * DESCRIPTION: Insert a new peer node into a list of peers.
359 1.1 jruoho *
360 1.1 jruoho ******************************************************************************/
361 1.1 jruoho
362 1.1 jruoho static void
363 1.1 jruoho TrAmlInsertPeer (
364 1.1 jruoho ACPI_PARSE_OBJECT *Op,
365 1.1 jruoho ACPI_PARSE_OBJECT *NewPeer)
366 1.1 jruoho {
367 1.1 jruoho
368 1.1 jruoho NewPeer->Asl.Next = Op->Asl.Next;
369 1.1.1.6 christos Op->Asl.Next = NewPeer;
370 1.1 jruoho }
371 1.1 jruoho
372 1.1 jruoho
373 1.1 jruoho /*******************************************************************************
374 1.1 jruoho *
375 1.1.1.7 christos * FUNCTION: TrAmlTransformWalkBegin
376 1.1 jruoho *
377 1.1 jruoho * PARAMETERS: ASL_WALK_CALLBACK
378 1.1 jruoho *
379 1.1 jruoho * RETURN: None
380 1.1 jruoho *
381 1.1 jruoho * DESCRIPTION: Parse tree walk to generate both the AML opcodes and the AML
382 1.1 jruoho * operands.
383 1.1 jruoho *
384 1.1 jruoho ******************************************************************************/
385 1.1 jruoho
386 1.1 jruoho ACPI_STATUS
387 1.1.1.7 christos TrAmlTransformWalkBegin (
388 1.1 jruoho ACPI_PARSE_OBJECT *Op,
389 1.1 jruoho UINT32 Level,
390 1.1 jruoho void *Context)
391 1.1 jruoho {
392 1.1 jruoho
393 1.1 jruoho TrTransformSubtree (Op);
394 1.1 jruoho return (AE_OK);
395 1.1 jruoho }
396 1.1 jruoho
397 1.1 jruoho
398 1.1 jruoho /*******************************************************************************
399 1.1 jruoho *
400 1.1.1.7 christos * FUNCTION: TrAmlTransformWalkEnd
401 1.1.1.7 christos *
402 1.1.1.7 christos * PARAMETERS: ASL_WALK_CALLBACK
403 1.1.1.7 christos *
404 1.1.1.7 christos * RETURN: None
405 1.1.1.7 christos *
406 1.1.1.7 christos * DESCRIPTION: Parse tree walk to generate both the AML opcodes and the AML
407 1.1.1.7 christos * operands.
408 1.1.1.7 christos *
409 1.1.1.7 christos ******************************************************************************/
410 1.1.1.7 christos
411 1.1.1.7 christos ACPI_STATUS
412 1.1.1.7 christos TrAmlTransformWalkEnd (
413 1.1.1.7 christos ACPI_PARSE_OBJECT *Op,
414 1.1.1.7 christos UINT32 Level,
415 1.1.1.7 christos void *Context)
416 1.1.1.7 christos {
417 1.1.1.7 christos
418 1.1.1.7 christos /* Save possible Externals list in the DefintionBlock Op */
419 1.1.1.7 christos
420 1.1.1.7 christos if (Op->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK)
421 1.1.1.7 christos {
422 1.1.1.12 christos Op->Asl.Value.Arg = AslGbl_ExternalsListHead;
423 1.1.1.12 christos AslGbl_ExternalsListHead = NULL;
424 1.1.1.7 christos }
425 1.1.1.7 christos
426 1.1.1.7 christos return (AE_OK);
427 1.1.1.7 christos }
428 1.1.1.7 christos
429 1.1.1.7 christos
430 1.1.1.7 christos /*******************************************************************************
431 1.1.1.7 christos *
432 1.1 jruoho * FUNCTION: TrTransformSubtree
433 1.1 jruoho *
434 1.1 jruoho * PARAMETERS: Op - The parent parse node
435 1.1 jruoho *
436 1.1 jruoho * RETURN: None
437 1.1 jruoho *
438 1.1.1.3 christos * DESCRIPTION: Prepare nodes to be output as AML data and operands. The more
439 1.1 jruoho * complex AML opcodes require processing of the child nodes
440 1.1 jruoho * (arguments/operands).
441 1.1 jruoho *
442 1.1 jruoho ******************************************************************************/
443 1.1 jruoho
444 1.1 jruoho static void
445 1.1 jruoho TrTransformSubtree (
446 1.1 jruoho ACPI_PARSE_OBJECT *Op)
447 1.1 jruoho {
448 1.1.1.9 christos ACPI_PARSE_OBJECT *MethodOp;
449 1.1.1.15 christos ACPI_NAMESTRING_INFO Info;
450 1.1.1.9 christos
451 1.1 jruoho
452 1.1 jruoho if (Op->Asl.AmlOpcode == AML_RAW_DATA_BYTE)
453 1.1 jruoho {
454 1.1 jruoho return;
455 1.1 jruoho }
456 1.1 jruoho
457 1.1 jruoho switch (Op->Asl.ParseOpcode)
458 1.1 jruoho {
459 1.1.1.6 christos case PARSEOP_DEFINITION_BLOCK:
460 1.1.1.3 christos
461 1.1 jruoho TrDoDefinitionBlock (Op);
462 1.1 jruoho break;
463 1.1 jruoho
464 1.1 jruoho case PARSEOP_SWITCH:
465 1.1.1.3 christos
466 1.1 jruoho TrDoSwitch (Op);
467 1.1 jruoho break;
468 1.1 jruoho
469 1.1 jruoho case PARSEOP_METHOD:
470 1.1.1.16 christos
471 1.1.1.16 christos TrDoMethod (Op);
472 1.1 jruoho break;
473 1.1 jruoho
474 1.1.1.7 christos case PARSEOP_EXTERNAL:
475 1.1.1.7 christos
476 1.1.1.12 christos ExDoExternal (Op);
477 1.1.1.7 christos break;
478 1.1.1.7 christos
479 1.1.1.9 christos case PARSEOP___METHOD__:
480 1.1.1.9 christos
481 1.1.1.9 christos /* Transform to a string op containing the parent method name */
482 1.1.1.9 christos
483 1.1.1.9 christos Op->Asl.ParseOpcode = PARSEOP_STRING_LITERAL;
484 1.1.1.9 christos UtSetParseOpName (Op);
485 1.1.1.9 christos
486 1.1.1.9 christos /* Find the parent control method op */
487 1.1.1.9 christos
488 1.1.1.9 christos MethodOp = Op;
489 1.1.1.9 christos while (MethodOp)
490 1.1.1.9 christos {
491 1.1.1.9 christos if (MethodOp->Asl.ParseOpcode == PARSEOP_METHOD)
492 1.1.1.9 christos {
493 1.1.1.9 christos /* First child contains the method name */
494 1.1.1.9 christos
495 1.1.1.9 christos MethodOp = MethodOp->Asl.Child;
496 1.1.1.9 christos Op->Asl.Value.String = MethodOp->Asl.Value.String;
497 1.1.1.9 christos return;
498 1.1.1.9 christos }
499 1.1.1.9 christos
500 1.1.1.9 christos MethodOp = MethodOp->Asl.Parent;
501 1.1.1.9 christos }
502 1.1.1.9 christos
503 1.1.1.9 christos /* At the root, invocation not within a control method */
504 1.1.1.9 christos
505 1.1.1.9 christos Op->Asl.Value.String = "\\";
506 1.1.1.9 christos break;
507 1.1.1.9 christos
508 1.1.1.15 christos case PARSEOP_NAMESTRING:
509 1.1.1.15 christos /*
510 1.1.1.15 christos * A NameString can be up to 255 (0xFF) individual NameSegs maximum
511 1.1.1.15 christos * (with 254 dot separators) - as per the ACPI specification. Note:
512 1.1.1.15 christos * Cannot check for NumSegments == 0 because things like
513 1.1.1.15 christos * Scope(\) are legal and OK.
514 1.1.1.15 christos */
515 1.1.1.15 christos Info.ExternalName = Op->Asl.Value.String;
516 1.1.1.15 christos AcpiNsGetInternalNameLength (&Info);
517 1.1.1.15 christos
518 1.1.1.15 christos if (Info.NumSegments > 255)
519 1.1.1.15 christos {
520 1.1.1.15 christos AslError (ASL_ERROR, ASL_MSG_NAMESTRING_LENGTH, Op, NULL);
521 1.1.1.15 christos }
522 1.1.1.15 christos break;
523 1.1.1.15 christos
524 1.1.1.11 christos case PARSEOP_UNLOAD:
525 1.1.1.11 christos
526 1.1.1.11 christos AslError (ASL_WARNING, ASL_MSG_UNLOAD, Op, NULL);
527 1.1.1.11 christos break;
528 1.1.1.11 christos
529 1.1.1.12 christos case PARSEOP_SLEEP:
530 1.1.1.12 christos
531 1.1.1.12 christos /* Remark for very long sleep values */
532 1.1.1.12 christos
533 1.1.1.12 christos if (Op->Asl.Child->Asl.Value.Integer > 1000)
534 1.1.1.12 christos {
535 1.1.1.12 christos AslError (ASL_REMARK, ASL_MSG_LONG_SLEEP, Op, NULL);
536 1.1.1.12 christos }
537 1.1.1.12 christos break;
538 1.1.1.12 christos
539 1.1.1.14 christos case PARSEOP_PROCESSOR:
540 1.1.1.14 christos
541 1.1.1.14 christos AslError (ASL_WARNING, ASL_MSG_LEGACY_PROCESSOR_OP, Op, Op->Asl.ExternalName);
542 1.1.1.14 christos break;
543 1.1.1.14 christos
544 1.1.1.17 christos case PARSEOP_OBJECTTYPE_DDB:
545 1.1.1.17 christos
546 1.1.1.17 christos AslError (ASL_WARNING, ASL_MSG_LEGACY_DDB_TYPE, Op, Op->Asl.ExternalName);
547 1.1.1.17 christos break;
548 1.1.1.17 christos
549 1.1 jruoho default:
550 1.1.1.3 christos
551 1.1 jruoho /* Nothing to do here for other opcodes */
552 1.1.1.3 christos
553 1.1 jruoho break;
554 1.1 jruoho }
555 1.1 jruoho }
556 1.1 jruoho
557 1.1 jruoho
558 1.1 jruoho /*******************************************************************************
559 1.1 jruoho *
560 1.1 jruoho * FUNCTION: TrDoDefinitionBlock
561 1.1 jruoho *
562 1.1 jruoho * PARAMETERS: Op - Parse node
563 1.1 jruoho *
564 1.1 jruoho * RETURN: None
565 1.1 jruoho *
566 1.1 jruoho * DESCRIPTION: Find the end of the definition block and set a global to this
567 1.1.1.3 christos * node. It is used by the compiler to insert compiler-generated
568 1.1 jruoho * names at the root level of the namespace.
569 1.1 jruoho *
570 1.1 jruoho ******************************************************************************/
571 1.1 jruoho
572 1.1 jruoho static void
573 1.1 jruoho TrDoDefinitionBlock (
574 1.1 jruoho ACPI_PARSE_OBJECT *Op)
575 1.1 jruoho {
576 1.1 jruoho ACPI_PARSE_OBJECT *Next;
577 1.1 jruoho UINT32 i;
578 1.1 jruoho
579 1.1 jruoho
580 1.1.1.7 christos /* Reset external list when starting a definition block */
581 1.1.1.7 christos
582 1.1.1.12 christos AslGbl_ExternalsListHead = NULL;
583 1.1.1.7 christos
584 1.1 jruoho Next = Op->Asl.Child;
585 1.1 jruoho for (i = 0; i < 5; i++)
586 1.1 jruoho {
587 1.1 jruoho Next = Next->Asl.Next;
588 1.1 jruoho if (i == 0)
589 1.1 jruoho {
590 1.1 jruoho /*
591 1.1 jruoho * This is the table signature. Only the DSDT can be assumed
592 1.1 jruoho * to be at the root of the namespace; Therefore, namepath
593 1.1 jruoho * optimization can only be performed on the DSDT.
594 1.1 jruoho */
595 1.1.1.13 christos if (!ACPI_COMPARE_NAMESEG (Next->Asl.Value.String, ACPI_SIG_DSDT))
596 1.1 jruoho {
597 1.1.1.12 christos AslGbl_ReferenceOptimizationFlag = FALSE;
598 1.1 jruoho }
599 1.1 jruoho }
600 1.1 jruoho }
601 1.1 jruoho
602 1.1.1.12 christos AslGbl_FirstLevelInsertionNode = Next;
603 1.1 jruoho }
604 1.1 jruoho
605 1.1 jruoho
606 1.1 jruoho /*******************************************************************************
607 1.1 jruoho *
608 1.1 jruoho * FUNCTION: TrDoSwitch
609 1.1 jruoho *
610 1.1 jruoho * PARAMETERS: StartNode - Parse node for SWITCH
611 1.1 jruoho *
612 1.1 jruoho * RETURN: None
613 1.1 jruoho *
614 1.1.1.3 christos * DESCRIPTION: Translate ASL SWITCH statement to if/else pairs. There is
615 1.1 jruoho * no actual AML opcode for SWITCH -- it must be simulated.
616 1.1 jruoho *
617 1.1 jruoho ******************************************************************************/
618 1.1 jruoho
619 1.1 jruoho static void
620 1.1 jruoho TrDoSwitch (
621 1.1 jruoho ACPI_PARSE_OBJECT *StartNode)
622 1.1 jruoho {
623 1.1 jruoho ACPI_PARSE_OBJECT *Next;
624 1.1 jruoho ACPI_PARSE_OBJECT *CaseOp = NULL;
625 1.1 jruoho ACPI_PARSE_OBJECT *CaseBlock = NULL;
626 1.1 jruoho ACPI_PARSE_OBJECT *DefaultOp = NULL;
627 1.1 jruoho ACPI_PARSE_OBJECT *CurrentParentNode;
628 1.1 jruoho ACPI_PARSE_OBJECT *Conditional = NULL;
629 1.1 jruoho ACPI_PARSE_OBJECT *Predicate;
630 1.1 jruoho ACPI_PARSE_OBJECT *Peer;
631 1.1 jruoho ACPI_PARSE_OBJECT *NewOp;
632 1.1 jruoho ACPI_PARSE_OBJECT *NewOp2;
633 1.1 jruoho ACPI_PARSE_OBJECT *MethodOp;
634 1.1 jruoho ACPI_PARSE_OBJECT *StoreOp;
635 1.1 jruoho ACPI_PARSE_OBJECT *BreakOp;
636 1.1.1.3 christos ACPI_PARSE_OBJECT *BufferOp;
637 1.1 jruoho char *PredicateValueName;
638 1.1 jruoho UINT16 Index;
639 1.1 jruoho UINT32 Btype;
640 1.1 jruoho
641 1.1 jruoho
642 1.1 jruoho /* Start node is the Switch() node */
643 1.1 jruoho
644 1.1 jruoho CurrentParentNode = StartNode;
645 1.1 jruoho
646 1.1 jruoho /* Create a new temp name of the form _T_x */
647 1.1 jruoho
648 1.1.1.12 christos PredicateValueName = TrAmlGetNextTempName (StartNode, &AslGbl_TempCount);
649 1.1 jruoho if (!PredicateValueName)
650 1.1 jruoho {
651 1.1 jruoho return;
652 1.1 jruoho }
653 1.1 jruoho
654 1.1 jruoho /* First child is the Switch() predicate */
655 1.1 jruoho
656 1.1 jruoho Next = StartNode->Asl.Child;
657 1.1 jruoho
658 1.1 jruoho /*
659 1.1 jruoho * Examine the return type of the Switch Value -
660 1.1 jruoho * must be Integer/Buffer/String
661 1.1 jruoho */
662 1.1 jruoho Index = (UINT16) (Next->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE);
663 1.1 jruoho Btype = AslKeywordMapping[Index].AcpiBtype;
664 1.1 jruoho if ((Btype != ACPI_BTYPE_INTEGER) &&
665 1.1 jruoho (Btype != ACPI_BTYPE_STRING) &&
666 1.1 jruoho (Btype != ACPI_BTYPE_BUFFER))
667 1.1 jruoho {
668 1.1 jruoho AslError (ASL_WARNING, ASL_MSG_SWITCH_TYPE, Next, NULL);
669 1.1 jruoho Btype = ACPI_BTYPE_INTEGER;
670 1.1 jruoho }
671 1.1 jruoho
672 1.1 jruoho /* CASE statements start at next child */
673 1.1 jruoho
674 1.1 jruoho Peer = Next->Asl.Next;
675 1.1 jruoho while (Peer)
676 1.1 jruoho {
677 1.1 jruoho Next = Peer;
678 1.1 jruoho Peer = Next->Asl.Next;
679 1.1 jruoho
680 1.1 jruoho if (Next->Asl.ParseOpcode == PARSEOP_CASE)
681 1.1 jruoho {
682 1.1.1.15 christos TrCheckForDuplicateCase (Next, Next->Asl.Child);
683 1.1.1.15 christos
684 1.1 jruoho if (CaseOp)
685 1.1 jruoho {
686 1.1 jruoho /* Add an ELSE to complete the previous CASE */
687 1.1 jruoho
688 1.1.1.9 christos NewOp = TrCreateLeafOp (PARSEOP_ELSE);
689 1.1 jruoho NewOp->Asl.Parent = Conditional->Asl.Parent;
690 1.1 jruoho TrAmlInitLineNumbers (NewOp, NewOp->Asl.Parent);
691 1.1 jruoho
692 1.1 jruoho /* Link ELSE node as a peer to the previous IF */
693 1.1 jruoho
694 1.1 jruoho TrAmlInsertPeer (Conditional, NewOp);
695 1.1 jruoho CurrentParentNode = NewOp;
696 1.1 jruoho }
697 1.1 jruoho
698 1.1.1.6 christos CaseOp = Next;
699 1.1 jruoho Conditional = CaseOp;
700 1.1.1.6 christos CaseBlock = CaseOp->Asl.Child->Asl.Next;
701 1.1 jruoho Conditional->Asl.Child->Asl.Next = NULL;
702 1.1 jruoho Predicate = CaseOp->Asl.Child;
703 1.1 jruoho
704 1.1 jruoho if ((Predicate->Asl.ParseOpcode == PARSEOP_PACKAGE) ||
705 1.1 jruoho (Predicate->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE))
706 1.1 jruoho {
707 1.1 jruoho /*
708 1.1 jruoho * Convert the package declaration to this form:
709 1.1 jruoho *
710 1.1 jruoho * If (LNotEqual (Match (Package(<size>){<data>},
711 1.1 jruoho * MEQ, _T_x, MTR, Zero, Zero), Ones))
712 1.1 jruoho */
713 1.1.1.9 christos NewOp2 = TrCreateLeafOp (PARSEOP_MATCHTYPE_MEQ);
714 1.1 jruoho Predicate->Asl.Next = NewOp2;
715 1.1 jruoho TrAmlInitLineNumbers (NewOp2, Conditional);
716 1.1 jruoho
717 1.1 jruoho NewOp = NewOp2;
718 1.1.1.9 christos NewOp2 = TrCreateValuedLeafOp (PARSEOP_NAMESTRING,
719 1.1 jruoho (UINT64) ACPI_TO_INTEGER (PredicateValueName));
720 1.1 jruoho NewOp->Asl.Next = NewOp2;
721 1.1 jruoho TrAmlInitLineNumbers (NewOp2, Predicate);
722 1.1 jruoho
723 1.1 jruoho NewOp = NewOp2;
724 1.1.1.9 christos NewOp2 = TrCreateLeafOp (PARSEOP_MATCHTYPE_MTR);
725 1.1 jruoho NewOp->Asl.Next = NewOp2;
726 1.1 jruoho TrAmlInitLineNumbers (NewOp2, Predicate);
727 1.1 jruoho
728 1.1 jruoho NewOp = NewOp2;
729 1.1.1.9 christos NewOp2 = TrCreateLeafOp (PARSEOP_ZERO);
730 1.1 jruoho NewOp->Asl.Next = NewOp2;
731 1.1 jruoho TrAmlInitLineNumbers (NewOp2, Predicate);
732 1.1 jruoho
733 1.1 jruoho NewOp = NewOp2;
734 1.1.1.9 christos NewOp2 = TrCreateLeafOp (PARSEOP_ZERO);
735 1.1 jruoho NewOp->Asl.Next = NewOp2;
736 1.1 jruoho TrAmlInitLineNumbers (NewOp2, Predicate);
737 1.1 jruoho
738 1.1.1.9 christos NewOp2 = TrCreateLeafOp (PARSEOP_MATCH);
739 1.1 jruoho NewOp2->Asl.Child = Predicate; /* PARSEOP_PACKAGE */
740 1.1 jruoho TrAmlInitLineNumbers (NewOp2, Conditional);
741 1.1 jruoho TrAmlSetSubtreeParent (Predicate, NewOp2);
742 1.1 jruoho
743 1.1 jruoho NewOp = NewOp2;
744 1.1.1.9 christos NewOp2 = TrCreateLeafOp (PARSEOP_ONES);
745 1.1 jruoho NewOp->Asl.Next = NewOp2;
746 1.1 jruoho TrAmlInitLineNumbers (NewOp2, Conditional);
747 1.1 jruoho
748 1.1.1.9 christos NewOp2 = TrCreateLeafOp (PARSEOP_LEQUAL);
749 1.1 jruoho NewOp2->Asl.Child = NewOp;
750 1.1 jruoho NewOp->Asl.Parent = NewOp2;
751 1.1 jruoho TrAmlInitLineNumbers (NewOp2, Conditional);
752 1.1 jruoho TrAmlSetSubtreeParent (NewOp, NewOp2);
753 1.1 jruoho
754 1.1 jruoho NewOp = NewOp2;
755 1.1.1.9 christos NewOp2 = TrCreateLeafOp (PARSEOP_LNOT);
756 1.1 jruoho NewOp2->Asl.Child = NewOp;
757 1.1 jruoho NewOp2->Asl.Parent = Conditional;
758 1.1 jruoho NewOp->Asl.Parent = NewOp2;
759 1.1 jruoho TrAmlInitLineNumbers (NewOp2, Conditional);
760 1.1 jruoho
761 1.1 jruoho Conditional->Asl.Child = NewOp2;
762 1.1 jruoho NewOp2->Asl.Next = CaseBlock;
763 1.1 jruoho }
764 1.1 jruoho else
765 1.1 jruoho {
766 1.1 jruoho /*
767 1.1 jruoho * Integer and Buffer case.
768 1.1 jruoho *
769 1.1 jruoho * Change CaseOp() to: If (LEqual (SwitchValue, CaseValue)) {...}
770 1.1 jruoho * Note: SwitchValue is first to allow the CaseValue to be implicitly
771 1.1 jruoho * converted to the type of SwitchValue if necessary.
772 1.1 jruoho *
773 1.1 jruoho * CaseOp->Child is the case value
774 1.1 jruoho * CaseOp->Child->Peer is the beginning of the case block
775 1.1 jruoho */
776 1.1.1.9 christos NewOp = TrCreateValuedLeafOp (PARSEOP_NAMESTRING,
777 1.1.1.6 christos (UINT64) ACPI_TO_INTEGER (PredicateValueName));
778 1.1 jruoho NewOp->Asl.Next = Predicate;
779 1.1 jruoho TrAmlInitLineNumbers (NewOp, Predicate);
780 1.1 jruoho
781 1.1.1.9 christos NewOp2 = TrCreateLeafOp (PARSEOP_LEQUAL);
782 1.1 jruoho NewOp2->Asl.Parent = Conditional;
783 1.1 jruoho NewOp2->Asl.Child = NewOp;
784 1.1 jruoho TrAmlInitLineNumbers (NewOp2, Conditional);
785 1.1 jruoho
786 1.1 jruoho TrAmlSetSubtreeParent (NewOp, NewOp2);
787 1.1 jruoho
788 1.1 jruoho Predicate = NewOp2;
789 1.1 jruoho Predicate->Asl.Next = CaseBlock;
790 1.1 jruoho
791 1.1 jruoho TrAmlSetSubtreeParent (Predicate, Conditional);
792 1.1 jruoho Conditional->Asl.Child = Predicate;
793 1.1 jruoho }
794 1.1 jruoho
795 1.1 jruoho /* Reinitialize the CASE node to an IF node */
796 1.1 jruoho
797 1.1 jruoho TrAmlInitNode (Conditional, PARSEOP_IF);
798 1.1 jruoho
799 1.1 jruoho /*
800 1.1 jruoho * The first CASE(IF) is not nested under an ELSE.
801 1.1 jruoho * All other CASEs are children of a parent ELSE.
802 1.1 jruoho */
803 1.1 jruoho if (CurrentParentNode == StartNode)
804 1.1 jruoho {
805 1.1 jruoho Conditional->Asl.Next = NULL;
806 1.1 jruoho }
807 1.1 jruoho else
808 1.1 jruoho {
809 1.1 jruoho /*
810 1.1.1.3 christos * The IF is a child of previous IF/ELSE. It
811 1.1 jruoho * is therefore without peer.
812 1.1 jruoho */
813 1.1 jruoho CurrentParentNode->Asl.Child = Conditional;
814 1.1 jruoho Conditional->Asl.Parent = CurrentParentNode;
815 1.1 jruoho Conditional->Asl.Next = NULL;
816 1.1 jruoho }
817 1.1 jruoho }
818 1.1 jruoho else if (Next->Asl.ParseOpcode == PARSEOP_DEFAULT)
819 1.1 jruoho {
820 1.1 jruoho if (DefaultOp)
821 1.1 jruoho {
822 1.1 jruoho /*
823 1.1 jruoho * More than one Default
824 1.1 jruoho * (Parser does not catch this, must check here)
825 1.1 jruoho */
826 1.1 jruoho AslError (ASL_ERROR, ASL_MSG_MULTIPLE_DEFAULT, Next, NULL);
827 1.1 jruoho }
828 1.1 jruoho else
829 1.1 jruoho {
830 1.1 jruoho /* Save the DEFAULT node for later, after CASEs */
831 1.1 jruoho
832 1.1 jruoho DefaultOp = Next;
833 1.1 jruoho }
834 1.1 jruoho }
835 1.1 jruoho else
836 1.1 jruoho {
837 1.1 jruoho /* Unknown peer opcode */
838 1.1 jruoho
839 1.1 jruoho AcpiOsPrintf ("Unknown parse opcode for switch statement: %s (%u)\n",
840 1.1.1.6 christos Next->Asl.ParseOpName, Next->Asl.ParseOpcode);
841 1.1 jruoho }
842 1.1 jruoho }
843 1.1 jruoho
844 1.1 jruoho /* Add the default case at the end of the if/else construct */
845 1.1 jruoho
846 1.1 jruoho if (DefaultOp)
847 1.1 jruoho {
848 1.1 jruoho /* If no CASE statements, this is an error - see below */
849 1.1 jruoho
850 1.1 jruoho if (CaseOp)
851 1.1 jruoho {
852 1.1 jruoho /* Convert the DEFAULT node to an ELSE */
853 1.1 jruoho
854 1.1 jruoho TrAmlInitNode (DefaultOp, PARSEOP_ELSE);
855 1.1 jruoho DefaultOp->Asl.Parent = Conditional->Asl.Parent;
856 1.1 jruoho
857 1.1 jruoho /* Link ELSE node as a peer to the previous IF */
858 1.1 jruoho
859 1.1 jruoho TrAmlInsertPeer (Conditional, DefaultOp);
860 1.1 jruoho }
861 1.1 jruoho }
862 1.1 jruoho
863 1.1 jruoho if (!CaseOp)
864 1.1 jruoho {
865 1.1 jruoho AslError (ASL_ERROR, ASL_MSG_NO_CASES, StartNode, NULL);
866 1.1 jruoho }
867 1.1 jruoho
868 1.1 jruoho
869 1.1 jruoho /*
870 1.1 jruoho * Create a Name(_T_x, ...) statement. This statement must appear at the
871 1.1 jruoho * method level, in case a loop surrounds the switch statement and could
872 1.1 jruoho * cause the name to be created twice (error).
873 1.1 jruoho */
874 1.1 jruoho
875 1.1 jruoho /* Create the Name node */
876 1.1 jruoho
877 1.1 jruoho Predicate = StartNode->Asl.Child;
878 1.1.1.9 christos NewOp = TrCreateLeafOp (PARSEOP_NAME);
879 1.1.1.3 christos TrAmlInitLineNumbers (NewOp, StartNode);
880 1.1 jruoho
881 1.1 jruoho /* Find the parent method */
882 1.1 jruoho
883 1.1 jruoho Next = StartNode;
884 1.1 jruoho while ((Next->Asl.ParseOpcode != PARSEOP_METHOD) &&
885 1.1.1.6 christos (Next->Asl.ParseOpcode != PARSEOP_DEFINITION_BLOCK))
886 1.1 jruoho {
887 1.1 jruoho Next = Next->Asl.Parent;
888 1.1 jruoho }
889 1.1 jruoho MethodOp = Next;
890 1.1 jruoho
891 1.1.1.9 christos NewOp->Asl.CompileFlags |= OP_COMPILER_EMITTED;
892 1.1 jruoho NewOp->Asl.Parent = Next;
893 1.1 jruoho
894 1.1 jruoho /* Insert name after the method name and arguments */
895 1.1 jruoho
896 1.1 jruoho Next = Next->Asl.Child; /* Name */
897 1.1 jruoho Next = Next->Asl.Next; /* NumArgs */
898 1.1 jruoho Next = Next->Asl.Next; /* SerializeRule */
899 1.1 jruoho
900 1.1 jruoho /*
901 1.1 jruoho * If method is not Serialized, we must make is so, because of the way
902 1.1 jruoho * that Switch() must be implemented -- we cannot allow multiple threads
903 1.1 jruoho * to execute this method concurrently since we need to create local
904 1.1 jruoho * temporary name(s).
905 1.1 jruoho */
906 1.1 jruoho if (Next->Asl.ParseOpcode != PARSEOP_SERIALIZERULE_SERIAL)
907 1.1 jruoho {
908 1.1.1.6 christos AslError (ASL_REMARK, ASL_MSG_SERIALIZED, MethodOp,
909 1.1.1.6 christos "Due to use of Switch operator");
910 1.1 jruoho Next->Asl.ParseOpcode = PARSEOP_SERIALIZERULE_SERIAL;
911 1.1 jruoho }
912 1.1 jruoho
913 1.1 jruoho Next = Next->Asl.Next; /* SyncLevel */
914 1.1 jruoho Next = Next->Asl.Next; /* ReturnType */
915 1.1 jruoho Next = Next->Asl.Next; /* ParameterTypes */
916 1.1 jruoho
917 1.1 jruoho TrAmlInsertPeer (Next, NewOp);
918 1.1 jruoho TrAmlInitLineNumbers (NewOp, Next);
919 1.1 jruoho
920 1.1 jruoho /* Create the NameSeg child for the Name node */
921 1.1 jruoho
922 1.1.1.9 christos NewOp2 = TrCreateValuedLeafOp (PARSEOP_NAMESEG,
923 1.1.1.6 christos (UINT64) ACPI_TO_INTEGER (PredicateValueName));
924 1.1.1.3 christos TrAmlInitLineNumbers (NewOp2, NewOp);
925 1.1.1.9 christos NewOp2->Asl.CompileFlags |= OP_IS_NAME_DECLARATION;
926 1.1 jruoho NewOp->Asl.Child = NewOp2;
927 1.1 jruoho
928 1.1 jruoho /* Create the initial value for the Name. Btype was already validated above */
929 1.1 jruoho
930 1.1 jruoho switch (Btype)
931 1.1 jruoho {
932 1.1 jruoho case ACPI_BTYPE_INTEGER:
933 1.1.1.3 christos
934 1.1.1.9 christos NewOp2->Asl.Next = TrCreateValuedLeafOp (PARSEOP_ZERO,
935 1.1.1.6 christos (UINT64) 0);
936 1.1.1.3 christos TrAmlInitLineNumbers (NewOp2->Asl.Next, NewOp);
937 1.1 jruoho break;
938 1.1 jruoho
939 1.1 jruoho case ACPI_BTYPE_STRING:
940 1.1.1.3 christos
941 1.1.1.9 christos NewOp2->Asl.Next = TrCreateValuedLeafOp (PARSEOP_STRING_LITERAL,
942 1.1.1.6 christos (UINT64) ACPI_TO_INTEGER (""));
943 1.1.1.3 christos TrAmlInitLineNumbers (NewOp2->Asl.Next, NewOp);
944 1.1 jruoho break;
945 1.1 jruoho
946 1.1 jruoho case ACPI_BTYPE_BUFFER:
947 1.1.1.3 christos
948 1.1.1.9 christos (void) TrLinkPeerOp (NewOp2, TrCreateValuedLeafOp (PARSEOP_BUFFER,
949 1.1.1.6 christos (UINT64) 0));
950 1.1 jruoho Next = NewOp2->Asl.Next;
951 1.1.1.3 christos TrAmlInitLineNumbers (Next, NewOp2);
952 1.1.1.9 christos
953 1.1.1.9 christos (void) TrLinkOpChildren (Next, 1, TrCreateValuedLeafOp (PARSEOP_ZERO,
954 1.1.1.6 christos (UINT64) 1));
955 1.1.1.3 christos TrAmlInitLineNumbers (Next->Asl.Child, Next);
956 1.1.1.3 christos
957 1.1.1.9 christos BufferOp = TrCreateValuedLeafOp (PARSEOP_DEFAULT_ARG, (UINT64) 0);
958 1.1.1.3 christos TrAmlInitLineNumbers (BufferOp, Next->Asl.Child);
959 1.1.1.9 christos (void) TrLinkPeerOp (Next->Asl.Child, BufferOp);
960 1.1 jruoho
961 1.1 jruoho TrAmlSetSubtreeParent (Next->Asl.Child, Next);
962 1.1 jruoho break;
963 1.1 jruoho
964 1.1 jruoho default:
965 1.1.1.3 christos
966 1.1 jruoho break;
967 1.1 jruoho }
968 1.1 jruoho
969 1.1 jruoho TrAmlSetSubtreeParent (NewOp2, NewOp);
970 1.1 jruoho
971 1.1 jruoho /*
972 1.1 jruoho * Transform the Switch() into a While(One)-Break node.
973 1.1 jruoho * And create a Store() node which will be used to save the
974 1.1.1.3 christos * Switch() value. The store is of the form: Store (Value, _T_x)
975 1.1 jruoho * where _T_x is the temp variable.
976 1.1 jruoho */
977 1.1 jruoho TrAmlInitNode (StartNode, PARSEOP_WHILE);
978 1.1.1.9 christos NewOp = TrCreateLeafOp (PARSEOP_ONE);
979 1.1.1.3 christos TrAmlInitLineNumbers (NewOp, StartNode);
980 1.1 jruoho NewOp->Asl.Next = Predicate->Asl.Next;
981 1.1 jruoho NewOp->Asl.Parent = StartNode;
982 1.1 jruoho StartNode->Asl.Child = NewOp;
983 1.1 jruoho
984 1.1 jruoho /* Create a Store() node */
985 1.1 jruoho
986 1.1.1.9 christos StoreOp = TrCreateLeafOp (PARSEOP_STORE);
987 1.1.1.3 christos TrAmlInitLineNumbers (StoreOp, NewOp);
988 1.1 jruoho StoreOp->Asl.Parent = StartNode;
989 1.1 jruoho TrAmlInsertPeer (NewOp, StoreOp);
990 1.1 jruoho
991 1.1 jruoho /* Complete the Store subtree */
992 1.1 jruoho
993 1.1 jruoho StoreOp->Asl.Child = Predicate;
994 1.1 jruoho Predicate->Asl.Parent = StoreOp;
995 1.1 jruoho
996 1.1.1.9 christos NewOp = TrCreateValuedLeafOp (PARSEOP_NAMESEG,
997 1.1.1.6 christos (UINT64) ACPI_TO_INTEGER (PredicateValueName));
998 1.1.1.3 christos TrAmlInitLineNumbers (NewOp, StoreOp);
999 1.1 jruoho NewOp->Asl.Parent = StoreOp;
1000 1.1 jruoho Predicate->Asl.Next = NewOp;
1001 1.1 jruoho
1002 1.1 jruoho /* Create a Break() node and insert it into the end of While() */
1003 1.1 jruoho
1004 1.1 jruoho Conditional = StartNode->Asl.Child;
1005 1.1 jruoho while (Conditional->Asl.Next)
1006 1.1 jruoho {
1007 1.1 jruoho Conditional = Conditional->Asl.Next;
1008 1.1 jruoho }
1009 1.1 jruoho
1010 1.1.1.9 christos BreakOp = TrCreateLeafOp (PARSEOP_BREAK);
1011 1.1.1.3 christos TrAmlInitLineNumbers (BreakOp, NewOp);
1012 1.1 jruoho BreakOp->Asl.Parent = StartNode;
1013 1.1 jruoho TrAmlInsertPeer (Conditional, BreakOp);
1014 1.1 jruoho }
1015 1.1.1.15 christos
1016 1.1.1.15 christos
1017 1.1.1.15 christos /*******************************************************************************
1018 1.1.1.15 christos *
1019 1.1.1.15 christos * FUNCTION: TrCheckForDuplicateCase
1020 1.1.1.15 christos *
1021 1.1.1.15 christos * PARAMETERS: CaseOp - Parse node for first Case statement in list
1022 1.1.1.15 christos * Predicate1 - Case value for the input CaseOp
1023 1.1.1.15 christos *
1024 1.1.1.15 christos * RETURN: None
1025 1.1.1.15 christos *
1026 1.1.1.15 christos * DESCRIPTION: Check for duplicate case values. Currently, only handles
1027 1.1.1.15 christos * Integers, Strings and Buffers. No support for Package objects.
1028 1.1.1.15 christos *
1029 1.1.1.15 christos ******************************************************************************/
1030 1.1.1.15 christos
1031 1.1.1.15 christos static void
1032 1.1.1.15 christos TrCheckForDuplicateCase (
1033 1.1.1.15 christos ACPI_PARSE_OBJECT *CaseOp,
1034 1.1.1.15 christos ACPI_PARSE_OBJECT *Predicate1)
1035 1.1.1.15 christos {
1036 1.1.1.15 christos ACPI_PARSE_OBJECT *Next;
1037 1.1.1.15 christos ACPI_PARSE_OBJECT *Predicate2;
1038 1.1.1.15 christos
1039 1.1.1.15 christos
1040 1.1.1.15 christos /* Walk the list of CASE opcodes */
1041 1.1.1.15 christos
1042 1.1.1.15 christos Next = CaseOp->Asl.Next;
1043 1.1.1.15 christos while (Next)
1044 1.1.1.15 christos {
1045 1.1.1.15 christos if (Next->Asl.ParseOpcode == PARSEOP_CASE)
1046 1.1.1.15 christos {
1047 1.1.1.15 christos /* Emit error only once */
1048 1.1.1.15 christos
1049 1.1.1.15 christos if (Next->Asl.CompileFlags & OP_IS_DUPLICATE)
1050 1.1.1.15 christos {
1051 1.1.1.15 christos goto NextCase;
1052 1.1.1.15 christos }
1053 1.1.1.15 christos
1054 1.1.1.15 christos /* Check for a duplicate plain integer */
1055 1.1.1.15 christos
1056 1.1.1.15 christos Predicate2 = Next->Asl.Child;
1057 1.1.1.15 christos if ((Predicate1->Asl.ParseOpcode == PARSEOP_INTEGER) &&
1058 1.1.1.15 christos (Predicate2->Asl.ParseOpcode == PARSEOP_INTEGER))
1059 1.1.1.15 christos {
1060 1.1.1.15 christos if (Predicate1->Asl.Value.Integer == Predicate2->Asl.Value.Integer)
1061 1.1.1.15 christos {
1062 1.1.1.15 christos goto FoundDuplicate;
1063 1.1.1.15 christos }
1064 1.1.1.15 christos }
1065 1.1.1.15 christos
1066 1.1.1.15 christos /* Check for pairs of the constants ZERO, ONE, ONES */
1067 1.1.1.15 christos
1068 1.1.1.15 christos else if (((Predicate1->Asl.ParseOpcode == PARSEOP_ZERO) &&
1069 1.1.1.15 christos (Predicate2->Asl.ParseOpcode == PARSEOP_ZERO)) ||
1070 1.1.1.15 christos ((Predicate1->Asl.ParseOpcode == PARSEOP_ONE) &&
1071 1.1.1.15 christos (Predicate2->Asl.ParseOpcode == PARSEOP_ONE)) ||
1072 1.1.1.15 christos ((Predicate1->Asl.ParseOpcode == PARSEOP_ONES) &&
1073 1.1.1.15 christos (Predicate2->Asl.ParseOpcode == PARSEOP_ONES)))
1074 1.1.1.15 christos {
1075 1.1.1.15 christos goto FoundDuplicate;
1076 1.1.1.15 christos }
1077 1.1.1.15 christos
1078 1.1.1.15 christos /* Check for a duplicate string constant (literal) */
1079 1.1.1.15 christos
1080 1.1.1.15 christos else if ((Predicate1->Asl.ParseOpcode == PARSEOP_STRING_LITERAL) &&
1081 1.1.1.15 christos (Predicate2->Asl.ParseOpcode == PARSEOP_STRING_LITERAL))
1082 1.1.1.15 christos {
1083 1.1.1.15 christos if (!strcmp (Predicate1->Asl.Value.String,
1084 1.1.1.15 christos Predicate2->Asl.Value.String))
1085 1.1.1.15 christos {
1086 1.1.1.15 christos goto FoundDuplicate;
1087 1.1.1.15 christos }
1088 1.1.1.15 christos }
1089 1.1.1.15 christos
1090 1.1.1.15 christos /* Check for a duplicate buffer constant */
1091 1.1.1.15 christos
1092 1.1.1.15 christos else if ((Predicate1->Asl.ParseOpcode == PARSEOP_BUFFER) &&
1093 1.1.1.15 christos (Predicate2->Asl.ParseOpcode == PARSEOP_BUFFER))
1094 1.1.1.15 christos {
1095 1.1.1.15 christos if (TrCheckForBufferMatch (Predicate1->Asl.Child,
1096 1.1.1.15 christos Predicate2->Asl.Child))
1097 1.1.1.15 christos {
1098 1.1.1.15 christos goto FoundDuplicate;
1099 1.1.1.15 christos }
1100 1.1.1.15 christos }
1101 1.1.1.15 christos }
1102 1.1.1.15 christos goto NextCase;
1103 1.1.1.15 christos
1104 1.1.1.15 christos FoundDuplicate:
1105 1.1.1.15 christos /* Emit error message only once */
1106 1.1.1.15 christos
1107 1.1.1.15 christos Next->Asl.CompileFlags |= OP_IS_DUPLICATE;
1108 1.1.1.15 christos
1109 1.1.1.15 christos AslDualParseOpError (ASL_ERROR, ASL_MSG_DUPLICATE_CASE, Next,
1110 1.1.1.15 christos Next->Asl.Value.String, ASL_MSG_CASE_FOUND_HERE, CaseOp,
1111 1.1.1.15 christos CaseOp->Asl.ExternalName);
1112 1.1.1.15 christos
1113 1.1.1.15 christos NextCase:
1114 1.1.1.15 christos Next = Next->Asl.Next;
1115 1.1.1.15 christos }
1116 1.1.1.15 christos }
1117 1.1.1.15 christos
1118 1.1.1.16 christos /*******************************************************************************
1119 1.1.1.16 christos *
1120 1.1.1.16 christos * FUNCTION: TrBufferIsAllZero
1121 1.1.1.16 christos *
1122 1.1.1.16 christos * PARAMETERS: Op - Parse node for first opcode in buffer initializer
1123 1.1.1.16 christos * list
1124 1.1.1.16 christos *
1125 1.1.1.16 christos * RETURN: TRUE if buffer contains all zeros or a DEFAULT_ARG
1126 1.1.1.16 christos *
1127 1.1.1.16 christos * DESCRIPTION: Check for duplicate Buffer case values.
1128 1.1.1.16 christos *
1129 1.1.1.16 christos ******************************************************************************/
1130 1.1.1.16 christos
1131 1.1.1.16 christos static BOOLEAN
1132 1.1.1.16 christos TrBufferIsAllZero (
1133 1.1.1.16 christos ACPI_PARSE_OBJECT *Op)
1134 1.1.1.16 christos {
1135 1.1.1.16 christos while (Op)
1136 1.1.1.16 christos {
1137 1.1.1.16 christos if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
1138 1.1.1.16 christos {
1139 1.1.1.16 christos return (TRUE);
1140 1.1.1.16 christos }
1141 1.1.1.16 christos else if (Op->Asl.Value.Integer != 0)
1142 1.1.1.16 christos {
1143 1.1.1.16 christos return (FALSE);
1144 1.1.1.16 christos }
1145 1.1.1.16 christos
1146 1.1.1.16 christos Op = Op->Asl.Next;
1147 1.1.1.16 christos }
1148 1.1.1.16 christos
1149 1.1.1.16 christos return (TRUE);
1150 1.1.1.16 christos }
1151 1.1.1.16 christos
1152 1.1.1.15 christos
1153 1.1.1.15 christos /*******************************************************************************
1154 1.1.1.15 christos *
1155 1.1.1.15 christos * FUNCTION: TrCheckForBufferMatch
1156 1.1.1.15 christos *
1157 1.1.1.15 christos * PARAMETERS: Next1 - Parse node for first opcode in first buffer list
1158 1.1.1.15 christos * (The DEFAULT_ARG or INTEGER node)
1159 1.1.1.15 christos * Next2 - Parse node for first opcode in second buffer list
1160 1.1.1.15 christos * (The DEFAULT_ARG or INTEGER node)
1161 1.1.1.15 christos *
1162 1.1.1.15 christos * RETURN: TRUE if buffers match, FALSE otherwise
1163 1.1.1.15 christos *
1164 1.1.1.15 christos * DESCRIPTION: Check for duplicate Buffer case values.
1165 1.1.1.15 christos *
1166 1.1.1.15 christos ******************************************************************************/
1167 1.1.1.15 christos
1168 1.1.1.15 christos static BOOLEAN
1169 1.1.1.15 christos TrCheckForBufferMatch (
1170 1.1.1.15 christos ACPI_PARSE_OBJECT *NextOp1,
1171 1.1.1.15 christos ACPI_PARSE_OBJECT *NextOp2)
1172 1.1.1.15 christos {
1173 1.1.1.16 christos /*
1174 1.1.1.16 christos * The buffer length can be a DEFAULT_ARG or INTEGER. If any of the nodes
1175 1.1.1.16 christos * are DEFAULT_ARG, it means that the length has yet to be computed.
1176 1.1.1.16 christos * However, the initializer list can be compared to determine if these two
1177 1.1.1.16 christos * buffers match.
1178 1.1.1.16 christos */
1179 1.1.1.16 christos if ((NextOp1->Asl.ParseOpcode == PARSEOP_INTEGER &&
1180 1.1.1.16 christos NextOp2->Asl.ParseOpcode == PARSEOP_INTEGER) &&
1181 1.1.1.16 christos NextOp1->Asl.Value.Integer != NextOp2->Asl.Value.Integer)
1182 1.1.1.15 christos {
1183 1.1.1.15 christos return (FALSE);
1184 1.1.1.15 christos }
1185 1.1.1.15 christos
1186 1.1.1.16 christos /*
1187 1.1.1.16 christos * Buffers that have explicit lengths but no initializer lists are
1188 1.1.1.16 christos * filled with zeros at runtime. This is equivalent to buffers that have the
1189 1.1.1.16 christos * same length that are filled with zeros.
1190 1.1.1.16 christos *
1191 1.1.1.16 christos * In other words, the following buffers are equivalent:
1192 1.1.1.16 christos *
1193 1.1.1.16 christos * Buffer(0x4) {}
1194 1.1.1.16 christos * Buffer() {0x0, 0x0, 0x0, 0x0}
1195 1.1.1.16 christos *
1196 1.1.1.16 christos * This statement checks for matches where one buffer does not have an
1197 1.1.1.16 christos * initializer list and another buffer contains all zeros.
1198 1.1.1.16 christos */
1199 1.1.1.16 christos if (NextOp1->Asl.ParseOpcode != NextOp2->Asl.ParseOpcode &&
1200 1.1.1.16 christos TrBufferIsAllZero (NextOp1->Asl.Next) &&
1201 1.1.1.16 christos TrBufferIsAllZero (NextOp2->Asl.Next))
1202 1.1.1.16 christos {
1203 1.1.1.16 christos return (TRUE);
1204 1.1.1.16 christos }
1205 1.1.1.16 christos
1206 1.1.1.15 christos /* Start at the BYTECONST initializer node list */
1207 1.1.1.15 christos
1208 1.1.1.15 christos NextOp1 = NextOp1->Asl.Next;
1209 1.1.1.15 christos NextOp2 = NextOp2->Asl.Next;
1210 1.1.1.15 christos
1211 1.1.1.15 christos /*
1212 1.1.1.15 christos * Walk both lists until either a mismatch is found, or one or more
1213 1.1.1.15 christos * end-of-lists are found
1214 1.1.1.15 christos */
1215 1.1.1.15 christos while (NextOp1 && NextOp2)
1216 1.1.1.15 christos {
1217 1.1.1.15 christos if ((NextOp1->Asl.ParseOpcode == PARSEOP_STRING_LITERAL) &&
1218 1.1.1.15 christos (NextOp2->Asl.ParseOpcode == PARSEOP_STRING_LITERAL))
1219 1.1.1.15 christos {
1220 1.1.1.15 christos if (!strcmp (NextOp1->Asl.Value.String, NextOp2->Asl.Value.String))
1221 1.1.1.15 christos {
1222 1.1.1.15 christos return (TRUE);
1223 1.1.1.15 christos }
1224 1.1.1.15 christos else
1225 1.1.1.15 christos {
1226 1.1.1.15 christos return (FALSE);
1227 1.1.1.15 christos }
1228 1.1.1.15 christos }
1229 1.1.1.15 christos if ((UINT8) NextOp1->Asl.Value.Integer != (UINT8) NextOp2->Asl.Value.Integer)
1230 1.1.1.15 christos {
1231 1.1.1.15 christos return (FALSE);
1232 1.1.1.15 christos }
1233 1.1.1.15 christos
1234 1.1.1.15 christos NextOp1 = NextOp1->Asl.Next;
1235 1.1.1.15 christos NextOp2 = NextOp2->Asl.Next;
1236 1.1.1.15 christos }
1237 1.1.1.15 christos
1238 1.1.1.15 christos /* Not a match if one of the lists is not at end-of-list */
1239 1.1.1.15 christos
1240 1.1.1.15 christos if (NextOp1 || NextOp2)
1241 1.1.1.15 christos {
1242 1.1.1.15 christos return (FALSE);
1243 1.1.1.15 christos }
1244 1.1.1.15 christos
1245 1.1.1.15 christos /* Otherwise, the buffers match */
1246 1.1.1.15 christos
1247 1.1.1.15 christos return (TRUE);
1248 1.1.1.15 christos }
1249 1.1.1.16 christos
1250 1.1.1.16 christos
1251 1.1.1.16 christos /*******************************************************************************
1252 1.1.1.16 christos *
1253 1.1.1.16 christos * FUNCTION: TrDoMethod
1254 1.1.1.16 christos *
1255 1.1.1.16 christos * PARAMETERS: Op - Parse node for SWITCH
1256 1.1.1.16 christos *
1257 1.1.1.16 christos * RETURN: None
1258 1.1.1.16 christos *
1259 1.1.1.16 christos * DESCRIPTION: Determine that parameter count of an ASL method node by
1260 1.1.1.16 christos * translating the parameter count parse node from
1261 1.1.1.16 christos * PARSEOP_DEFAULT_ARG to PARSEOP_BYTECONST.
1262 1.1.1.16 christos *
1263 1.1.1.16 christos ******************************************************************************/
1264 1.1.1.16 christos
1265 1.1.1.16 christos static void
1266 1.1.1.16 christos TrDoMethod (
1267 1.1.1.16 christos ACPI_PARSE_OBJECT *Op)
1268 1.1.1.16 christos {
1269 1.1.1.16 christos ACPI_PARSE_OBJECT *ArgCountOp;
1270 1.1.1.16 christos UINT8 ArgCount;
1271 1.1.1.16 christos ACPI_PARSE_OBJECT *ParameterOp;
1272 1.1.1.16 christos
1273 1.1.1.16 christos
1274 1.1.1.16 christos /*
1275 1.1.1.16 christos * TBD: Zero the tempname (_T_x) count. Probably shouldn't be a global,
1276 1.1.1.16 christos * however
1277 1.1.1.16 christos */
1278 1.1.1.16 christos AslGbl_TempCount = 0;
1279 1.1.1.16 christos
1280 1.1.1.16 christos ArgCountOp = Op->Asl.Child->Asl.Next;
1281 1.1.1.16 christos if (ArgCountOp->Asl.ParseOpcode == PARSEOP_BYTECONST)
1282 1.1.1.16 christos {
1283 1.1.1.16 christos /*
1284 1.1.1.16 christos * Parameter count for this method has already been recorded in the
1285 1.1.1.16 christos * method declaration.
1286 1.1.1.16 christos */
1287 1.1.1.16 christos return;
1288 1.1.1.16 christos }
1289 1.1.1.16 christos
1290 1.1.1.16 christos /*
1291 1.1.1.16 christos * Parameter count has been omitted in the method declaration.
1292 1.1.1.16 christos * Count the amount of arguments here.
1293 1.1.1.16 christos */
1294 1.1.1.16 christos ParameterOp = ArgCountOp->Asl.Next->Asl.Next->Asl.Next->Asl.Next;
1295 1.1.1.16 christos if (ParameterOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
1296 1.1.1.16 christos {
1297 1.1.1.16 christos ArgCount = 0;
1298 1.1.1.16 christos ParameterOp = ParameterOp->Asl.Child;
1299 1.1.1.16 christos
1300 1.1.1.16 christos while (ParameterOp)
1301 1.1.1.16 christos {
1302 1.1.1.16 christos ParameterOp = ParameterOp->Asl.Next;
1303 1.1.1.16 christos ArgCount++;
1304 1.1.1.16 christos }
1305 1.1.1.16 christos
1306 1.1.1.16 christos ArgCountOp->Asl.Value.Integer = ArgCount;
1307 1.1.1.16 christos ArgCountOp->Asl.ParseOpcode = PARSEOP_BYTECONST;
1308 1.1.1.16 christos }
1309 1.1.1.16 christos else
1310 1.1.1.16 christos {
1311 1.1.1.16 christos /*
1312 1.1.1.16 christos * Method parameters can be counted by analyzing the Parameter type
1313 1.1.1.16 christos * list. If the Parameter list contains more than 1 parameter, it
1314 1.1.1.16 christos * is nested under PARSEOP_DEFAULT_ARG. When there is only 1
1315 1.1.1.16 christos * parameter, the parse tree contains a single node representing
1316 1.1.1.16 christos * that type.
1317 1.1.1.16 christos */
1318 1.1.1.16 christos ArgCountOp->Asl.Value.Integer = 1;
1319 1.1.1.16 christos ArgCountOp->Asl.ParseOpcode = PARSEOP_BYTECONST;
1320 1.1.1.16 christos }
1321 1.1.1.16 christos }
1322