cvparser.c revision 1.1 1 1.1 christos /******************************************************************************
2 1.1 christos *
3 1.1 christos * Module Name: cvparser - Converter functions that are called from the AML
4 1.1 christos * parser.
5 1.1 christos *
6 1.1 christos *****************************************************************************/
7 1.1 christos
8 1.1 christos /*
9 1.1 christos * Copyright (C) 2000 - 2017, Intel Corp.
10 1.1 christos * All rights reserved.
11 1.1 christos *
12 1.1 christos * Redistribution and use in source and binary forms, with or without
13 1.1 christos * modification, are permitted provided that the following conditions
14 1.1 christos * are met:
15 1.1 christos * 1. Redistributions of source code must retain the above copyright
16 1.1 christos * notice, this list of conditions, and the following disclaimer,
17 1.1 christos * without modification.
18 1.1 christos * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 1.1 christos * substantially similar to the "NO WARRANTY" disclaimer below
20 1.1 christos * ("Disclaimer") and any redistribution must be conditioned upon
21 1.1 christos * including a substantially similar Disclaimer requirement for further
22 1.1 christos * binary redistribution.
23 1.1 christos * 3. Neither the names of the above-listed copyright holders nor the names
24 1.1 christos * of any contributors may be used to endorse or promote products derived
25 1.1 christos * from this software without specific prior written permission.
26 1.1 christos *
27 1.1 christos * Alternatively, this software may be distributed under the terms of the
28 1.1 christos * GNU General Public License ("GPL") version 2 as published by the Free
29 1.1 christos * Software Foundation.
30 1.1 christos *
31 1.1 christos * NO WARRANTY
32 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 1.1 christos * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 1.1 christos * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 1.1 christos * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 1.1 christos * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 1.1 christos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 1.1 christos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 1.1 christos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 1.1 christos * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 1.1 christos * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 1.1 christos * POSSIBILITY OF SUCH DAMAGES.
43 1.1 christos */
44 1.1 christos
45 1.1 christos #include "aslcompiler.h"
46 1.1 christos #include "acparser.h"
47 1.1 christos #include "acdispat.h"
48 1.1 christos #include "amlcode.h"
49 1.1 christos #include "acinterp.h"
50 1.1 christos #include "acdisasm.h"
51 1.1 christos #include "acconvert.h"
52 1.1 christos
53 1.1 christos
54 1.1 christos /* local prototypes */
55 1.1 christos
56 1.1 christos static BOOLEAN
57 1.1 christos CvCommentExists (
58 1.1 christos UINT8 *Address);
59 1.1 christos
60 1.1 christos static BOOLEAN
61 1.1 christos CvIsFilename (
62 1.1 christos char *Filename);
63 1.1 christos
64 1.1 christos static ACPI_FILE_NODE*
65 1.1 christos CvFileAddressLookup(
66 1.1 christos char *Address,
67 1.1 christos ACPI_FILE_NODE *Head);
68 1.1 christos
69 1.1 christos static void
70 1.1 christos CvAddToFileTree (
71 1.1 christos char *Filename,
72 1.1 christos char *PreviousFilename);
73 1.1 christos
74 1.1 christos static void
75 1.1 christos CvSetFileParent (
76 1.1 christos char *ChildFile,
77 1.1 christos char *ParentFile);
78 1.1 christos
79 1.1 christos
80 1.1 christos /*******************************************************************************
81 1.1 christos *
82 1.1 christos * FUNCTION: CvIsFilename
83 1.1 christos *
84 1.1 christos * PARAMETERS: filename - input filename
85 1.1 christos *
86 1.1 christos * RETURN: BOOLEAN - TRUE if all characters are between 0x20 and 0x7f
87 1.1 christos *
88 1.1 christos * DESCRIPTION: Take a given char * and see if it contains all printable
89 1.1 christos * characters. If all characters have hexvalues 20-7f and ends with
90 1.1 christos * .dsl, we will assume that it is a proper filename.
91 1.1 christos *
92 1.1 christos ******************************************************************************/
93 1.1 christos
94 1.1 christos static BOOLEAN
95 1.1 christos CvIsFilename (
96 1.1 christos char *Filename)
97 1.1 christos {
98 1.1 christos UINT64 Length = strlen(Filename);
99 1.1 christos UINT64 i;
100 1.1 christos char *FileExt = Filename + Length - 4;
101 1.1 christos
102 1.1 christos
103 1.1 christos if ((Length > 4) && AcpiUtStricmp (FileExt, ".dsl"))
104 1.1 christos {
105 1.1 christos return FALSE;
106 1.1 christos }
107 1.1 christos
108 1.1 christos for(i = 0; i<Length; ++i)
109 1.1 christos {
110 1.1 christos if (!isprint (Filename[i]))
111 1.1 christos {
112 1.1 christos return FALSE;
113 1.1 christos }
114 1.1 christos }
115 1.1 christos return TRUE;
116 1.1 christos }
117 1.1 christos
118 1.1 christos
119 1.1 christos /*******************************************************************************
120 1.1 christos *
121 1.1 christos * FUNCTION: CvInitFileTree
122 1.1 christos *
123 1.1 christos * PARAMETERS: Table - input table
124 1.1 christos * AmlStart - Address of the starting point of the AML.
125 1.1 christos * AmlLength - Length of the AML file.
126 1.1 christos *
127 1.1 christos * RETURN: none
128 1.1 christos *
129 1.1 christos * DESCRIPTION: Initialize the file dependency tree by scanning the AML.
130 1.1 christos * This is referred as ASL_CV_INIT_FILETREE.
131 1.1 christos *
132 1.1 christos ******************************************************************************/
133 1.1 christos
134 1.1 christos void
135 1.1 christos CvInitFileTree (
136 1.1 christos ACPI_TABLE_HEADER *Table,
137 1.1 christos UINT8 *AmlStart,
138 1.1 christos UINT32 AmlLength)
139 1.1 christos {
140 1.1 christos UINT8 *TreeAml;
141 1.1 christos UINT8 *FileEnd;
142 1.1 christos char *Filename = NULL;
143 1.1 christos char *PreviousFilename = NULL;
144 1.1 christos char *ParentFilename = NULL;
145 1.1 christos char *ChildFilename = NULL;
146 1.1 christos
147 1.1 christos
148 1.1 christos if (!Gbl_CaptureComments)
149 1.1 christos {
150 1.1 christos return;
151 1.1 christos }
152 1.1 christos
153 1.1 christos CvDbgPrint ("AmlLength: %x\n", AmlLength);
154 1.1 christos CvDbgPrint ("AmlStart: %p\n", AmlStart);
155 1.1 christos CvDbgPrint ("AmlEnd?: %p\n", AmlStart+AmlLength);
156 1.1 christos
157 1.1 christos AcpiGbl_FileTreeRoot = AcpiOsAcquireObject (AcpiGbl_FileCache);
158 1.1 christos AcpiGbl_FileTreeRoot->FileStart = (char *)(AmlStart);
159 1.1 christos AcpiGbl_FileTreeRoot->FileEnd = (char *)(AmlStart + Table->Length);
160 1.1 christos AcpiGbl_FileTreeRoot->Next = NULL;
161 1.1 christos AcpiGbl_FileTreeRoot->Parent = NULL;
162 1.1 christos AcpiGbl_FileTreeRoot->Filename = (char *)(AmlStart+2);
163 1.1 christos
164 1.1 christos /* Set the root file to the current open file */
165 1.1 christos
166 1.1 christos AcpiGbl_FileTreeRoot->File = AcpiGbl_OutputFile;
167 1.1 christos
168 1.1 christos /*
169 1.1 christos * Set this to true because we dont need to output
170 1.1 christos * an include statement for the topmost file
171 1.1 christos */
172 1.1 christos AcpiGbl_FileTreeRoot->IncludeWritten = TRUE;
173 1.1 christos Filename = NULL;
174 1.1 christos AcpiGbl_CurrentFilename = (char *)(AmlStart+2);
175 1.1 christos AcpiGbl_RootFilename = (char *)(AmlStart+2);
176 1.1 christos
177 1.1 christos TreeAml = AmlStart;
178 1.1 christos FileEnd = AmlStart + AmlLength;
179 1.1 christos
180 1.1 christos while (TreeAml <= FileEnd)
181 1.1 christos {
182 1.1 christos /*
183 1.1 christos * Make sure that this filename contains all printable characters
184 1.1 christos * and a .dsl extension at the end. If not, then it must be some
185 1.1 christos * raw data that doesn't outline a filename.
186 1.1 christos */
187 1.1 christos if ((*TreeAml == AML_COMMENT_OP) &&
188 1.1 christos (*(TreeAml+1) == FILENAME_COMMENT) &&
189 1.1 christos (CvIsFilename ((char *)(TreeAml+2))))
190 1.1 christos {
191 1.1 christos CvDbgPrint ("A9 and a 08 file\n");
192 1.1 christos PreviousFilename = Filename;
193 1.1 christos Filename = (char *) (TreeAml+2);
194 1.1 christos CvAddToFileTree (Filename, PreviousFilename);
195 1.1 christos ChildFilename = Filename;
196 1.1 christos CvDbgPrint ("%s\n", Filename);
197 1.1 christos }
198 1.1 christos else if ((*TreeAml == AML_COMMENT_OP) &&
199 1.1 christos (*(TreeAml+1) == PARENTFILENAME_COMMENT) &&
200 1.1 christos (CvIsFilename ((char *)(TreeAml+2))))
201 1.1 christos {
202 1.1 christos CvDbgPrint ("A9 and a 09 file\n");
203 1.1 christos ParentFilename = (char *)(TreeAml+2);
204 1.1 christos CvSetFileParent (ChildFilename, ParentFilename);
205 1.1 christos CvDbgPrint ("%s\n", ParentFilename);
206 1.1 christos }
207 1.1 christos ++TreeAml;
208 1.1 christos }
209 1.1 christos }
210 1.1 christos
211 1.1 christos
212 1.1 christos /*******************************************************************************
213 1.1 christos *
214 1.1 christos * FUNCTION: CvClearOpComments
215 1.1 christos *
216 1.1 christos * PARAMETERS: Op -- clear all comments within this Op
217 1.1 christos *
218 1.1 christos * RETURN: none
219 1.1 christos *
220 1.1 christos * DESCRIPTION: Clear all converter-related fields of the given Op.
221 1.1 christos * This is referred as ASL_CV_CLEAR_OP_COMMENTS.
222 1.1 christos *
223 1.1 christos ******************************************************************************/
224 1.1 christos
225 1.1 christos void
226 1.1 christos CvClearOpComments (
227 1.1 christos ACPI_PARSE_OBJECT *Op)
228 1.1 christos {
229 1.1 christos Op->Common.InlineComment = NULL;
230 1.1 christos Op->Common.EndNodeComment = NULL;
231 1.1 christos Op->Common.NameComment = NULL;
232 1.1 christos Op->Common.CommentList = NULL;
233 1.1 christos Op->Common.EndBlkComment = NULL;
234 1.1 christos Op->Common.CloseBraceComment = NULL;
235 1.1 christos Op->Common.CvFilename = NULL;
236 1.1 christos Op->Common.CvParentFilename = NULL;
237 1.1 christos }
238 1.1 christos
239 1.1 christos
240 1.1 christos /*******************************************************************************
241 1.1 christos *
242 1.1 christos * FUNCTION: CvCommentExists
243 1.1 christos *
244 1.1 christos * PARAMETERS: address - check if this address appears in the list
245 1.1 christos *
246 1.1 christos * RETURN: BOOLEAN - TRUE if the address exists.
247 1.1 christos *
248 1.1 christos * DESCRIPTION: look at the pointer address and check if this appears in the
249 1.1 christos * list of all addresses. If it exitsts in the list, return TRUE
250 1.1 christos * if it exists. Otherwise add to the list and return FALSE.
251 1.1 christos *
252 1.1 christos ******************************************************************************/
253 1.1 christos
254 1.1 christos static BOOLEAN
255 1.1 christos CvCommentExists (
256 1.1 christos UINT8 *Address)
257 1.1 christos {
258 1.1 christos ACPI_COMMENT_ADDR_NODE *Current = AcpiGbl_CommentAddrListHead;
259 1.1 christos UINT8 Option;
260 1.1 christos
261 1.1 christos
262 1.1 christos if (!Address)
263 1.1 christos {
264 1.1 christos return (FALSE);
265 1.1 christos }
266 1.1 christos Option = *(Address + 1);
267 1.1 christos
268 1.1 christos /*
269 1.1 christos * FILENAME_COMMENT and PARENTFILENAME_COMMENT are not treated as comments.
270 1.1 christos * They serve as markers for where the file starts and ends.
271 1.1 christos */
272 1.1 christos if ((Option == FILENAME_COMMENT) || (Option == PARENTFILENAME_COMMENT))
273 1.1 christos {
274 1.1 christos return (FALSE);
275 1.1 christos }
276 1.1 christos
277 1.1 christos if (!Current)
278 1.1 christos {
279 1.1 christos AcpiGbl_CommentAddrListHead =
280 1.1 christos AcpiOsAcquireObject (AcpiGbl_RegCommentCache);
281 1.1 christos AcpiGbl_CommentAddrListHead->Addr = Address;
282 1.1 christos AcpiGbl_CommentAddrListHead->Next = NULL;
283 1.1 christos return (FALSE);
284 1.1 christos }
285 1.1 christos else
286 1.1 christos {
287 1.1 christos while (Current)
288 1.1 christos {
289 1.1 christos if (Current->Addr != Address)
290 1.1 christos {
291 1.1 christos Current = Current->Next;
292 1.1 christos }
293 1.1 christos else
294 1.1 christos {
295 1.1 christos return (TRUE);
296 1.1 christos }
297 1.1 christos }
298 1.1 christos
299 1.1 christos /*
300 1.1 christos * If the execution gets to this point, it means that this address
301 1.1 christos * does not exists in the list. Add this address to the
302 1.1 christos * beginning of the list.
303 1.1 christos */
304 1.1 christos Current = AcpiGbl_CommentAddrListHead;
305 1.1 christos AcpiGbl_CommentAddrListHead =
306 1.1 christos AcpiOsAcquireObject (AcpiGbl_RegCommentCache);
307 1.1 christos AcpiGbl_CommentAddrListHead->Addr = Address;
308 1.1 christos AcpiGbl_CommentAddrListHead->Next = Current;
309 1.1 christos return (FALSE);
310 1.1 christos }
311 1.1 christos }
312 1.1 christos
313 1.1 christos
314 1.1 christos /*******************************************************************************
315 1.1 christos *
316 1.1 christos * FUNCTION: CvFilenameExists
317 1.1 christos *
318 1.1 christos * PARAMETERS: Filename - filename to search
319 1.1 christos *
320 1.1 christos * RETURN: ACPI_FILE_NODE - a pointer to a file node
321 1.1 christos *
322 1.1 christos * DESCRIPTION: Look for the given filename in the file dependency tree.
323 1.1 christos * Returns the file node if it exists, returns NULL if it does not.
324 1.1 christos *
325 1.1 christos ******************************************************************************/
326 1.1 christos
327 1.1 christos ACPI_FILE_NODE*
328 1.1 christos CvFilenameExists(
329 1.1 christos char *Filename,
330 1.1 christos ACPI_FILE_NODE *Head)
331 1.1 christos {
332 1.1 christos ACPI_FILE_NODE *Current = Head;
333 1.1 christos
334 1.1 christos
335 1.1 christos while (Current)
336 1.1 christos {
337 1.1 christos if (!AcpiUtStricmp (Current->Filename, Filename))
338 1.1 christos {
339 1.1 christos return (Current);
340 1.1 christos }
341 1.1 christos Current = Current->Next;
342 1.1 christos }
343 1.1 christos return (NULL);
344 1.1 christos }
345 1.1 christos
346 1.1 christos
347 1.1 christos /*******************************************************************************
348 1.1 christos *
349 1.1 christos * FUNCTION: CvFileAddressLookup
350 1.1 christos *
351 1.1 christos * PARAMETERS: Address - address to look up
352 1.1 christos * Head - file dependency tree
353 1.1 christos *
354 1.1 christos * RETURN: ACPI_FLE_NODE - pointer to a file node containing the address
355 1.1 christos *
356 1.1 christos * DESCRIPTION: Look for the given address in the file dependency tree.
357 1.1 christos * Returns the first file node where the given address is within
358 1.1 christos * the file node's starting and ending address.
359 1.1 christos *
360 1.1 christos ******************************************************************************/
361 1.1 christos
362 1.1 christos static ACPI_FILE_NODE*
363 1.1 christos CvFileAddressLookup(
364 1.1 christos char *Address,
365 1.1 christos ACPI_FILE_NODE *Head)
366 1.1 christos {
367 1.1 christos ACPI_FILE_NODE *Current = Head;
368 1.1 christos
369 1.1 christos
370 1.1 christos while (Current)
371 1.1 christos {
372 1.1 christos if ((Address >= Current->FileStart) &&
373 1.1 christos (Address < Current->FileEnd ||
374 1.1 christos !Current->FileEnd))
375 1.1 christos {
376 1.1 christos return (Current);
377 1.1 christos }
378 1.1 christos Current = Current->Next;
379 1.1 christos }
380 1.1 christos
381 1.1 christos return (NULL);
382 1.1 christos }
383 1.1 christos
384 1.1 christos
385 1.1 christos /*******************************************************************************
386 1.1 christos *
387 1.1 christos * FUNCTION: CvLabelFileNode
388 1.1 christos *
389 1.1 christos * PARAMETERS: Op
390 1.1 christos *
391 1.1 christos * RETURN: None
392 1.1 christos *
393 1.1 christos * DESCRIPTION: Takes a given parse op, looks up its Op->Common.Aml field
394 1.1 christos * within the file tree and fills in approperiate file information
395 1.1 christos * from a matching node within the tree.
396 1.1 christos * This is referred as ASL_CV_LABEL_FILENODE.
397 1.1 christos *
398 1.1 christos ******************************************************************************/
399 1.1 christos
400 1.1 christos void
401 1.1 christos CvLabelFileNode(
402 1.1 christos ACPI_PARSE_OBJECT *Op)
403 1.1 christos {
404 1.1 christos ACPI_FILE_NODE *Node;
405 1.1 christos
406 1.1 christos
407 1.1 christos if (!Op)
408 1.1 christos {
409 1.1 christos return;
410 1.1 christos }
411 1.1 christos
412 1.1 christos Node = CvFileAddressLookup ((char *)Op->Common.Aml, AcpiGbl_FileTreeRoot);
413 1.1 christos if (!Node)
414 1.1 christos {
415 1.1 christos return;
416 1.1 christos }
417 1.1 christos
418 1.1 christos Op->Common.CvFilename = Node->Filename;
419 1.1 christos if (Node->Parent)
420 1.1 christos {
421 1.1 christos Op->Common.CvParentFilename = Node->Parent->Filename;
422 1.1 christos }
423 1.1 christos else
424 1.1 christos {
425 1.1 christos Op->Common.CvParentFilename = Node->Filename;
426 1.1 christos }
427 1.1 christos }
428 1.1 christos
429 1.1 christos
430 1.1 christos /*******************************************************************************
431 1.1 christos *
432 1.1 christos * FUNCTION: CvAddToFileTree
433 1.1 christos *
434 1.1 christos * PARAMETERS: Filename - Address containing the name of the current
435 1.1 christos * filename
436 1.1 christos * PreviousFilename - Address containing the name of the previous
437 1.1 christos * filename
438 1.1 christos *
439 1.1 christos * RETURN: void
440 1.1 christos *
441 1.1 christos * DESCRIPTION: Add this filename to the AcpiGbl_FileTree if it does not exist.
442 1.1 christos *
443 1.1 christos ******************************************************************************/
444 1.1 christos
445 1.1 christos static void
446 1.1 christos CvAddToFileTree (
447 1.1 christos char *Filename,
448 1.1 christos char *PreviousFilename)
449 1.1 christos {
450 1.1 christos ACPI_FILE_NODE *Node;
451 1.1 christos
452 1.1 christos
453 1.1 christos if (!AcpiUtStricmp(Filename, AcpiGbl_RootFilename) &&
454 1.1 christos PreviousFilename)
455 1.1 christos {
456 1.1 christos Node = CvFilenameExists (PreviousFilename, AcpiGbl_FileTreeRoot);
457 1.1 christos if (Node)
458 1.1 christos {
459 1.1 christos /*
460 1.1 christos * Set the end point of the PreviousFilename to the address
461 1.1 christos * of Filename.
462 1.1 christos */
463 1.1 christos Node->FileEnd = Filename;
464 1.1 christos }
465 1.1 christos }
466 1.1 christos else if (!AcpiUtStricmp(Filename, AcpiGbl_RootFilename) &&
467 1.1 christos !PreviousFilename)
468 1.1 christos {
469 1.1 christos return;
470 1.1 christos }
471 1.1 christos
472 1.1 christos Node = CvFilenameExists (Filename, AcpiGbl_FileTreeRoot);
473 1.1 christos if (Node && PreviousFilename)
474 1.1 christos {
475 1.1 christos /*
476 1.1 christos * Update the end of the previous file and all of their parents' ending
477 1.1 christos * Addresses. This is done to ensure that parent file ranges extend to
478 1.1 christos * the end of their childrens' files.
479 1.1 christos */
480 1.1 christos Node = CvFilenameExists (PreviousFilename, AcpiGbl_FileTreeRoot);
481 1.1 christos if (Node && (Node->FileEnd < Filename))
482 1.1 christos {
483 1.1 christos Node->FileEnd = Filename;
484 1.1 christos Node = Node->Parent;
485 1.1 christos while (Node)
486 1.1 christos {
487 1.1 christos if (Node->FileEnd < Filename)
488 1.1 christos {
489 1.1 christos Node->FileEnd = Filename;
490 1.1 christos }
491 1.1 christos Node = Node->Parent;
492 1.1 christos }
493 1.1 christos }
494 1.1 christos }
495 1.1 christos else
496 1.1 christos {
497 1.1 christos Node = AcpiGbl_FileTreeRoot;
498 1.1 christos AcpiGbl_FileTreeRoot = AcpiOsAcquireObject (AcpiGbl_FileCache);
499 1.1 christos AcpiGbl_FileTreeRoot->Next = Node;
500 1.1 christos AcpiGbl_FileTreeRoot->Parent = NULL;
501 1.1 christos AcpiGbl_FileTreeRoot->Filename = Filename;
502 1.1 christos AcpiGbl_FileTreeRoot->FileStart = Filename;
503 1.1 christos AcpiGbl_FileTreeRoot->IncludeWritten = FALSE;
504 1.1 christos AcpiGbl_FileTreeRoot->File = fopen(Filename, "w+");
505 1.1 christos
506 1.1 christos /*
507 1.1 christos * If we can't open the file, we need to abort here before we
508 1.1 christos * accidentally write to a NULL file.
509 1.1 christos */
510 1.1 christos if (!AcpiGbl_FileTreeRoot->File)
511 1.1 christos {
512 1.1 christos /* delete the .xxx file */
513 1.1 christos
514 1.1 christos FlDeleteFile (ASL_FILE_AML_OUTPUT);
515 1.1 christos sprintf (MsgBuffer, "\"%s\" - %s", Filename, strerror (errno));
516 1.1 christos AslCommonError (ASL_ERROR, ASL_MSG_OPEN, 0, 0, 0, 0, NULL, MsgBuffer);
517 1.1 christos AslAbort ();
518 1.1 christos }
519 1.1 christos }
520 1.1 christos }
521 1.1 christos
522 1.1 christos
523 1.1 christos /*******************************************************************************
524 1.1 christos *
525 1.1 christos * FUNCTION: CvSetFileParent
526 1.1 christos *
527 1.1 christos * PARAMETERS: ChildFile - contains the filename of the child file
528 1.1 christos * ParentFile - contains the filename of the parent file.
529 1.1 christos *
530 1.1 christos * RETURN: none
531 1.1 christos *
532 1.1 christos * DESCRIPTION: point the parent pointer of the Child to the node that
533 1.1 christos * corresponds with the parent file node.
534 1.1 christos *
535 1.1 christos ******************************************************************************/
536 1.1 christos
537 1.1 christos static void
538 1.1 christos CvSetFileParent (
539 1.1 christos char *ChildFile,
540 1.1 christos char *ParentFile)
541 1.1 christos {
542 1.1 christos ACPI_FILE_NODE *Child;
543 1.1 christos ACPI_FILE_NODE *Parent;
544 1.1 christos
545 1.1 christos
546 1.1 christos Child = CvFilenameExists (ChildFile, AcpiGbl_FileTreeRoot);
547 1.1 christos Parent = CvFilenameExists (ParentFile, AcpiGbl_FileTreeRoot);
548 1.1 christos if (Child && Parent)
549 1.1 christos {
550 1.1 christos Child->Parent = Parent;
551 1.1 christos
552 1.1 christos while (Child->Parent)
553 1.1 christos {
554 1.1 christos if (Child->Parent->FileEnd < Child->FileStart)
555 1.1 christos {
556 1.1 christos Child->Parent->FileEnd = Child->FileStart;
557 1.1 christos }
558 1.1 christos Child = Child->Parent;
559 1.1 christos }
560 1.1 christos }
561 1.1 christos }
562 1.1 christos
563 1.1 christos
564 1.1 christos /*******************************************************************************
565 1.1 christos *
566 1.1 christos * FUNCTION: CvCaptureCommentsOnly
567 1.1 christos *
568 1.1 christos * PARAMETERS: ParserState - A parser state object
569 1.1 christos *
570 1.1 christos * RETURN: none
571 1.1 christos *
572 1.1 christos * DESCRIPTION: look at the aml that the parser state is pointing to,
573 1.1 christos * capture any AML_COMMENT_OP and it's arguments and increment the
574 1.1 christos * aml pointer past the comment. Comments are transferred to parse
575 1.1 christos * nodes through CvTransferComments() as well as
576 1.1 christos * AcpiPsBuildNamedOp().
577 1.1 christos * This is referred as ASL_CV_CAPTURE_COMMENTS_ONLY.
578 1.1 christos *
579 1.1 christos ******************************************************************************/
580 1.1 christos
581 1.1 christos void
582 1.1 christos CvCaptureCommentsOnly (
583 1.1 christos ACPI_PARSE_STATE *ParserState)
584 1.1 christos {
585 1.1 christos UINT8 *Aml = ParserState->Aml;
586 1.1 christos UINT16 Opcode = (UINT16) ACPI_GET8 (Aml);
587 1.1 christos UINT32 Length = 0;
588 1.1 christos UINT8 CommentOption = (UINT16) ACPI_GET8 (Aml+1);
589 1.1 christos BOOLEAN StdDefBlockFlag = FALSE;
590 1.1 christos ACPI_COMMENT_NODE *CommentNode;
591 1.1 christos ACPI_FILE_NODE *FileNode;
592 1.1 christos
593 1.1 christos
594 1.1 christos if (!Gbl_CaptureComments ||
595 1.1 christos Opcode != AML_COMMENT_OP)
596 1.1 christos {
597 1.1 christos return;
598 1.1 christos }
599 1.1 christos
600 1.1 christos while (Opcode == AML_COMMENT_OP)
601 1.1 christos {
602 1.1 christos CvDbgPrint ("comment aml address: %p\n", Aml);
603 1.1 christos
604 1.1 christos if (CvCommentExists(ParserState->Aml))
605 1.1 christos {
606 1.1 christos CvDbgPrint ("Avoiding capturing an existing comment.\n");
607 1.1 christos }
608 1.1 christos else
609 1.1 christos {
610 1.1 christos CommentOption = *(Aml+1);
611 1.1 christos
612 1.1 christos /* Increment past the comment option and point the approperiate char pointers.*/
613 1.1 christos
614 1.1 christos Aml += 2;
615 1.1 christos
616 1.1 christos /* found a comment. Now, set pointers to these comments. */
617 1.1 christos
618 1.1 christos switch (CommentOption)
619 1.1 christos {
620 1.1 christos case STD_DEFBLK_COMMENT:
621 1.1 christos
622 1.1 christos StdDefBlockFlag = TRUE;
623 1.1 christos
624 1.1 christos /* add to a linked list of nodes. This list will be taken by the parse node created next. */
625 1.1 christos
626 1.1 christos CommentNode = AcpiOsAcquireObject (AcpiGbl_RegCommentCache);
627 1.1 christos CommentNode->Comment = ACPI_CAST_PTR (char, Aml);
628 1.1 christos CommentNode->Next = NULL;
629 1.1 christos
630 1.1 christos if (!AcpiGbl_DefBlkCommentListHead)
631 1.1 christos {
632 1.1 christos AcpiGbl_DefBlkCommentListHead = CommentNode;
633 1.1 christos AcpiGbl_DefBlkCommentListTail = CommentNode;
634 1.1 christos }
635 1.1 christos else
636 1.1 christos {
637 1.1 christos AcpiGbl_DefBlkCommentListTail->Next = CommentNode;
638 1.1 christos AcpiGbl_DefBlkCommentListTail = AcpiGbl_DefBlkCommentListTail->Next;
639 1.1 christos }
640 1.1 christos break;
641 1.1 christos
642 1.1 christos case STANDARD_COMMENT:
643 1.1 christos
644 1.1 christos CvDbgPrint ("found regular comment.\n");
645 1.1 christos
646 1.1 christos /* add to a linked list of nodes. This list will be taken by the parse node created next. */
647 1.1 christos
648 1.1 christos CommentNode = AcpiOsAcquireObject (AcpiGbl_RegCommentCache);
649 1.1 christos CommentNode->Comment = ACPI_CAST_PTR (char, Aml);
650 1.1 christos CommentNode->Next = NULL;
651 1.1 christos
652 1.1 christos if (!AcpiGbl_RegCommentListHead)
653 1.1 christos {
654 1.1 christos AcpiGbl_RegCommentListHead = CommentNode;
655 1.1 christos AcpiGbl_RegCommentListTail = CommentNode;
656 1.1 christos }
657 1.1 christos else
658 1.1 christos {
659 1.1 christos AcpiGbl_RegCommentListTail->Next = CommentNode;
660 1.1 christos AcpiGbl_RegCommentListTail = AcpiGbl_RegCommentListTail->Next;
661 1.1 christos }
662 1.1 christos break;
663 1.1 christos
664 1.1 christos case ENDBLK_COMMENT:
665 1.1 christos
666 1.1 christos CvDbgPrint ("found endblk comment.\n");
667 1.1 christos
668 1.1 christos /* add to a linked list of nodes. This will be taken by the next created parse node. */
669 1.1 christos
670 1.1 christos CommentNode = AcpiOsAcquireObject (AcpiGbl_RegCommentCache);
671 1.1 christos CommentNode->Comment = ACPI_CAST_PTR (char, Aml);
672 1.1 christos CommentNode->Next = NULL;
673 1.1 christos
674 1.1 christos if (!AcpiGbl_EndBlkCommentListHead)
675 1.1 christos {
676 1.1 christos AcpiGbl_EndBlkCommentListHead = CommentNode;
677 1.1 christos AcpiGbl_EndBlkCommentListTail = CommentNode;
678 1.1 christos }
679 1.1 christos else
680 1.1 christos {
681 1.1 christos AcpiGbl_EndBlkCommentListTail->Next = CommentNode;
682 1.1 christos AcpiGbl_EndBlkCommentListTail = AcpiGbl_EndBlkCommentListTail->Next;
683 1.1 christos }
684 1.1 christos break;
685 1.1 christos
686 1.1 christos case INLINE_COMMENT:
687 1.1 christos
688 1.1 christos CvDbgPrint ("found inline comment.\n");
689 1.1 christos AcpiGbl_CurrentInlineComment = ACPI_CAST_PTR (char, Aml);
690 1.1 christos break;
691 1.1 christos
692 1.1 christos case ENDNODE_COMMENT:
693 1.1 christos
694 1.1 christos CvDbgPrint ("found EndNode comment.\n");
695 1.1 christos AcpiGbl_CurrentEndNodeComment = ACPI_CAST_PTR (char, Aml);
696 1.1 christos break;
697 1.1 christos
698 1.1 christos case CLOSE_BRACE_COMMENT:
699 1.1 christos
700 1.1 christos CvDbgPrint ("found close brace comment.\n");
701 1.1 christos AcpiGbl_CurrentCloseBraceComment = ACPI_CAST_PTR (char, Aml);
702 1.1 christos break;
703 1.1 christos
704 1.1 christos case END_DEFBLK_COMMENT:
705 1.1 christos
706 1.1 christos CvDbgPrint ("Found comment that belongs after the } for a definition block.\n");
707 1.1 christos AcpiGbl_CurrentScope->Common.CloseBraceComment = ACPI_CAST_PTR (char, Aml);
708 1.1 christos break;
709 1.1 christos
710 1.1 christos case FILENAME_COMMENT:
711 1.1 christos
712 1.1 christos CvDbgPrint ("Found a filename: %s\n", ACPI_CAST_PTR (char, Aml));
713 1.1 christos FileNode = CvFilenameExists (ACPI_CAST_PTR (char, Aml), AcpiGbl_FileTreeRoot);
714 1.1 christos
715 1.1 christos /*
716 1.1 christos * If there is an INCLUDE_COMMENT followed by a
717 1.1 christos * FILENAME_COMMENT, then the INCLUDE_COMMENT is a comment
718 1.1 christos * that is emitted before the #include for the file.
719 1.1 christos * We will save the IncludeComment within the FileNode
720 1.1 christos * associated with this FILENAME_COMMENT.
721 1.1 christos */
722 1.1 christos if (FileNode && AcpiGbl_IncCommentListHead)
723 1.1 christos {
724 1.1 christos FileNode->IncludeComment = AcpiGbl_IncCommentListHead;
725 1.1 christos AcpiGbl_IncCommentListHead = NULL;
726 1.1 christos AcpiGbl_IncCommentListTail = NULL;
727 1.1 christos }
728 1.1 christos break;
729 1.1 christos
730 1.1 christos case PARENTFILENAME_COMMENT:
731 1.1 christos CvDbgPrint (" Found a parent filename.\n");
732 1.1 christos break;
733 1.1 christos
734 1.1 christos case INCLUDE_COMMENT:
735 1.1 christos
736 1.1 christos /*
737 1.1 christos * Add to a linked list. This list will be taken by the
738 1.1 christos * parse node created next. See the FILENAME_COMMENT case
739 1.1 christos * for more details
740 1.1 christos */
741 1.1 christos CommentNode = AcpiOsAcquireObject (AcpiGbl_RegCommentCache);
742 1.1 christos CommentNode->Comment = ACPI_CAST_PTR (char, Aml);
743 1.1 christos CommentNode->Next = NULL;
744 1.1 christos
745 1.1 christos if (!AcpiGbl_IncCommentListHead)
746 1.1 christos {
747 1.1 christos AcpiGbl_IncCommentListHead = CommentNode;
748 1.1 christos AcpiGbl_IncCommentListTail = CommentNode;
749 1.1 christos }
750 1.1 christos else
751 1.1 christos {
752 1.1 christos AcpiGbl_IncCommentListTail->Next = CommentNode;
753 1.1 christos AcpiGbl_IncCommentListTail = AcpiGbl_IncCommentListTail->Next;
754 1.1 christos }
755 1.1 christos
756 1.1 christos CvDbgPrint ("Found a include comment: %s\n", CommentNode->Comment);
757 1.1 christos break;
758 1.1 christos
759 1.1 christos default:
760 1.1 christos
761 1.1 christos /* Not a valid comment option. Revert the AML */
762 1.1 christos
763 1.1 christos Aml -= 2;
764 1.1 christos goto DefBlock;
765 1.1 christos break;
766 1.1 christos
767 1.1 christos } /* end switch statement */
768 1.1 christos
769 1.1 christos } /* end else */
770 1.1 christos
771 1.1 christos /* determine the length and move forward that amount */
772 1.1 christos
773 1.1 christos Length = 0;
774 1.1 christos while (ParserState->Aml[Length])
775 1.1 christos {
776 1.1 christos Length++;
777 1.1 christos }
778 1.1 christos
779 1.1 christos ParserState->Aml += Length + 1;
780 1.1 christos
781 1.1 christos
782 1.1 christos /* Peek at the next Opcode. */
783 1.1 christos
784 1.1 christos Aml = ParserState->Aml;
785 1.1 christos Opcode = (UINT16) ACPI_GET8 (Aml);
786 1.1 christos
787 1.1 christos }
788 1.1 christos
789 1.1 christos DefBlock:
790 1.1 christos if (StdDefBlockFlag)
791 1.1 christos {
792 1.1 christos /*
793 1.1 christos * Give all of its comments to the current scope, which is known as
794 1.1 christos * the definition block, since STD_DEFBLK_COMMENT only appears after
795 1.1 christos * definition block headers.
796 1.1 christos */
797 1.1 christos AcpiGbl_CurrentScope->Common.CommentList
798 1.1 christos = AcpiGbl_DefBlkCommentListHead;
799 1.1 christos AcpiGbl_DefBlkCommentListHead = NULL;
800 1.1 christos AcpiGbl_DefBlkCommentListTail = NULL;
801 1.1 christos }
802 1.1 christos }
803 1.1 christos
804 1.1 christos
805 1.1 christos /*******************************************************************************
806 1.1 christos *
807 1.1 christos * FUNCTION: CvCaptureComments
808 1.1 christos *
809 1.1 christos * PARAMETERS: ParserState - A parser state object
810 1.1 christos *
811 1.1 christos * RETURN: none
812 1.1 christos *
813 1.1 christos * DESCRIPTION: Wrapper function for CvCaptureCommentsOnly
814 1.1 christos * This is referred as ASL_CV_CAPTURE_COMMENTS.
815 1.1 christos *
816 1.1 christos ******************************************************************************/
817 1.1 christos
818 1.1 christos void
819 1.1 christos CvCaptureComments (
820 1.1 christos ACPI_WALK_STATE *WalkState)
821 1.1 christos {
822 1.1 christos UINT8 *Aml;
823 1.1 christos UINT16 Opcode;
824 1.1 christos const ACPI_OPCODE_INFO *OpInfo;
825 1.1 christos
826 1.1 christos
827 1.1 christos if (!Gbl_CaptureComments)
828 1.1 christos {
829 1.1 christos return;
830 1.1 christos }
831 1.1 christos
832 1.1 christos /*
833 1.1 christos * Before parsing, check to see that comments that come directly after
834 1.1 christos * deferred opcodes aren't being processed.
835 1.1 christos */
836 1.1 christos Aml = WalkState->ParserState.Aml;
837 1.1 christos Opcode = (UINT16) ACPI_GET8 (Aml);
838 1.1 christos OpInfo = AcpiPsGetOpcodeInfo (Opcode);
839 1.1 christos
840 1.1 christos if (!(OpInfo->Flags & AML_DEFER) ||
841 1.1 christos ((OpInfo->Flags & AML_DEFER) &&
842 1.1 christos (WalkState->PassNumber != ACPI_IMODE_LOAD_PASS1)))
843 1.1 christos {
844 1.1 christos CvCaptureCommentsOnly (&WalkState->ParserState);
845 1.1 christos WalkState->Aml = WalkState->ParserState.Aml;
846 1.1 christos }
847 1.1 christos
848 1.1 christos }
849 1.1 christos
850 1.1 christos
851 1.1 christos /*******************************************************************************
852 1.1 christos *
853 1.1 christos * FUNCTION: CvTransferComments
854 1.1 christos *
855 1.1 christos * PARAMETERS: Op - Transfer comments to this Op
856 1.1 christos *
857 1.1 christos * RETURN: none
858 1.1 christos *
859 1.1 christos * DESCRIPTION: Transfer all of the commments stored in global containers to the
860 1.1 christos * given Op. This will be invoked shortly after the parser creates
861 1.1 christos * a ParseOp.
862 1.1 christos * This is referred as ASL_CV_TRANSFER_COMMENTS.
863 1.1 christos *
864 1.1 christos ******************************************************************************/
865 1.1 christos
866 1.1 christos void
867 1.1 christos CvTransferComments (
868 1.1 christos ACPI_PARSE_OBJECT *Op)
869 1.1 christos {
870 1.1 christos Op->Common.InlineComment = AcpiGbl_CurrentInlineComment;
871 1.1 christos AcpiGbl_CurrentInlineComment = NULL;
872 1.1 christos
873 1.1 christos Op->Common.EndNodeComment = AcpiGbl_CurrentEndNodeComment;
874 1.1 christos AcpiGbl_CurrentEndNodeComment = NULL;
875 1.1 christos
876 1.1 christos Op->Common.CloseBraceComment = AcpiGbl_CurrentCloseBraceComment;
877 1.1 christos AcpiGbl_CurrentCloseBraceComment = NULL;
878 1.1 christos
879 1.1 christos Op->Common.CommentList = AcpiGbl_RegCommentListHead;
880 1.1 christos AcpiGbl_RegCommentListHead = NULL;
881 1.1 christos AcpiGbl_RegCommentListTail = NULL;
882 1.1 christos
883 1.1 christos Op->Common.EndBlkComment = AcpiGbl_EndBlkCommentListHead;
884 1.1 christos AcpiGbl_EndBlkCommentListHead = NULL;
885 1.1 christos AcpiGbl_EndBlkCommentListTail = NULL;
886 1.1 christos
887 1.1 christos }
888