xref: /freebsd/sys/contrib/dev/acpica/compiler/dtio.c (revision f8146b882bc156c1d8ddf14bbea67253ebc064bb)
1a88e22b7SJung-uk Kim /******************************************************************************
2a88e22b7SJung-uk Kim  *
3a88e22b7SJung-uk Kim  * Module Name: dtio.c - File I/O support for data table compiler
4a88e22b7SJung-uk Kim  *
5a88e22b7SJung-uk Kim  *****************************************************************************/
6a88e22b7SJung-uk Kim 
7d244b227SJung-uk Kim /*
8*f8146b88SJung-uk Kim  * Copyright (C) 2000 - 2016, Intel Corp.
9a88e22b7SJung-uk Kim  * All rights reserved.
10a88e22b7SJung-uk Kim  *
11d244b227SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
12d244b227SJung-uk Kim  * modification, are permitted provided that the following conditions
13d244b227SJung-uk Kim  * are met:
14d244b227SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
15d244b227SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
16d244b227SJung-uk Kim  *    without modification.
17d244b227SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18d244b227SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
19d244b227SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
20d244b227SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
21d244b227SJung-uk Kim  *    binary redistribution.
22d244b227SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
23d244b227SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
24d244b227SJung-uk Kim  *    from this software without specific prior written permission.
25a88e22b7SJung-uk Kim  *
26d244b227SJung-uk Kim  * Alternatively, this software may be distributed under the terms of the
27d244b227SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
28d244b227SJung-uk Kim  * Software Foundation.
29a88e22b7SJung-uk Kim  *
30d244b227SJung-uk Kim  * NO WARRANTY
31d244b227SJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32d244b227SJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33d244b227SJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34d244b227SJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35d244b227SJung-uk Kim  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36d244b227SJung-uk Kim  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37d244b227SJung-uk Kim  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38d244b227SJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39d244b227SJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40d244b227SJung-uk Kim  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41d244b227SJung-uk Kim  * POSSIBILITY OF SUCH DAMAGES.
42d244b227SJung-uk Kim  */
43a88e22b7SJung-uk Kim 
44a88e22b7SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h>
45a88e22b7SJung-uk Kim #include <contrib/dev/acpica/compiler/dtcompiler.h>
46313a0c13SJung-uk Kim #include <contrib/dev/acpica/include/acapps.h>
47a88e22b7SJung-uk Kim 
48a88e22b7SJung-uk Kim #define _COMPONENT          DT_COMPILER
49a88e22b7SJung-uk Kim         ACPI_MODULE_NAME    ("dtio")
50a88e22b7SJung-uk Kim 
51a88e22b7SJung-uk Kim 
52a88e22b7SJung-uk Kim /* Local prototypes */
53a88e22b7SJung-uk Kim 
54a88e22b7SJung-uk Kim static char *
55a88e22b7SJung-uk Kim DtTrim (
56a88e22b7SJung-uk Kim     char                    *String);
57a88e22b7SJung-uk Kim 
58a88e22b7SJung-uk Kim static void
59a88e22b7SJung-uk Kim DtLinkField (
60a88e22b7SJung-uk Kim     DT_FIELD                *Field);
61a88e22b7SJung-uk Kim 
62d244b227SJung-uk Kim static ACPI_STATUS
63a88e22b7SJung-uk Kim DtParseLine (
64a88e22b7SJung-uk Kim     char                    *LineBuffer,
65a88e22b7SJung-uk Kim     UINT32                  Line,
66a88e22b7SJung-uk Kim     UINT32                  Offset);
67a88e22b7SJung-uk Kim 
68a88e22b7SJung-uk Kim static void
69a88e22b7SJung-uk Kim DtWriteBinary (
70a88e22b7SJung-uk Kim     DT_SUBTABLE             *Subtable,
71a88e22b7SJung-uk Kim     void                    *Context,
72a88e22b7SJung-uk Kim     void                    *ReturnValue);
73a88e22b7SJung-uk Kim 
74d244b227SJung-uk Kim static void
75d244b227SJung-uk Kim DtDumpBuffer (
76d244b227SJung-uk Kim     UINT32                  FileId,
77d244b227SJung-uk Kim     UINT8                   *Buffer,
780b94ba42SJung-uk Kim     UINT32                  Offset,
79d244b227SJung-uk Kim     UINT32                  Length);
80a88e22b7SJung-uk Kim 
81efcc2a30SJung-uk Kim static void
82efcc2a30SJung-uk Kim DtDumpSubtableInfo (
83efcc2a30SJung-uk Kim     DT_SUBTABLE             *Subtable,
84efcc2a30SJung-uk Kim     void                    *Context,
85efcc2a30SJung-uk Kim     void                    *ReturnValue);
86efcc2a30SJung-uk Kim 
87efcc2a30SJung-uk Kim static void
88efcc2a30SJung-uk Kim DtDumpSubtableTree (
89efcc2a30SJung-uk Kim     DT_SUBTABLE             *Subtable,
90efcc2a30SJung-uk Kim     void                    *Context,
91efcc2a30SJung-uk Kim     void                    *ReturnValue);
92efcc2a30SJung-uk Kim 
930b94ba42SJung-uk Kim 
94a88e22b7SJung-uk Kim /* States for DtGetNextLine */
95a88e22b7SJung-uk Kim 
96a88e22b7SJung-uk Kim #define DT_NORMAL_TEXT              0
97a88e22b7SJung-uk Kim #define DT_START_QUOTED_STRING      1
98a88e22b7SJung-uk Kim #define DT_START_COMMENT            2
99a88e22b7SJung-uk Kim #define DT_SLASH_ASTERISK_COMMENT   3
100a88e22b7SJung-uk Kim #define DT_SLASH_SLASH_COMMENT      4
101a88e22b7SJung-uk Kim #define DT_END_COMMENT              5
102d052a1ccSJung-uk Kim #define DT_MERGE_LINES              6
103eef1b955SJung-uk Kim #define DT_ESCAPE_SEQUENCE          7
104a88e22b7SJung-uk Kim 
10542fecd12SJung-uk Kim static UINT32               Gbl_NextLineOffset;
106a88e22b7SJung-uk Kim 
107a88e22b7SJung-uk Kim 
108a88e22b7SJung-uk Kim /******************************************************************************
109a88e22b7SJung-uk Kim  *
110a88e22b7SJung-uk Kim  * FUNCTION:    DtTrim
111a88e22b7SJung-uk Kim  *
112a88e22b7SJung-uk Kim  * PARAMETERS:  String              - Current source code line to trim
113a88e22b7SJung-uk Kim  *
114a88e22b7SJung-uk Kim  * RETURN:      Trimmed line. Must be freed by caller.
115a88e22b7SJung-uk Kim  *
116a88e22b7SJung-uk Kim  * DESCRIPTION: Trim left and right spaces
117a88e22b7SJung-uk Kim  *
118a88e22b7SJung-uk Kim  *****************************************************************************/
119a88e22b7SJung-uk Kim 
120a88e22b7SJung-uk Kim static char *
121a88e22b7SJung-uk Kim DtTrim (
122a88e22b7SJung-uk Kim     char                    *String)
123a88e22b7SJung-uk Kim {
124a88e22b7SJung-uk Kim     char                    *Start;
125a88e22b7SJung-uk Kim     char                    *End;
126a88e22b7SJung-uk Kim     char                    *ReturnString;
127a88e22b7SJung-uk Kim     ACPI_SIZE               Length;
128a88e22b7SJung-uk Kim 
129a88e22b7SJung-uk Kim 
130a88e22b7SJung-uk Kim     /* Skip lines that start with a space */
131a88e22b7SJung-uk Kim 
1325ef50723SJung-uk Kim     if (!strcmp (String, " "))
133a88e22b7SJung-uk Kim     {
134313a0c13SJung-uk Kim         ReturnString = UtStringCacheCalloc (1);
135a88e22b7SJung-uk Kim         return (ReturnString);
136a88e22b7SJung-uk Kim     }
137a88e22b7SJung-uk Kim 
138a88e22b7SJung-uk Kim     /* Setup pointers to start and end of input string */
139a88e22b7SJung-uk Kim 
140a88e22b7SJung-uk Kim     Start = String;
1415ef50723SJung-uk Kim     End = String + strlen (String) - 1;
142a88e22b7SJung-uk Kim 
143a88e22b7SJung-uk Kim     /* Find first non-whitespace character */
144a88e22b7SJung-uk Kim 
145a88e22b7SJung-uk Kim     while ((Start <= End) && ((*Start == ' ') || (*Start == '\t')))
146a88e22b7SJung-uk Kim     {
147a88e22b7SJung-uk Kim         Start++;
148a88e22b7SJung-uk Kim     }
149a88e22b7SJung-uk Kim 
150a88e22b7SJung-uk Kim     /* Find last non-space character */
151a88e22b7SJung-uk Kim 
152a88e22b7SJung-uk Kim     while (End >= Start)
153a88e22b7SJung-uk Kim     {
154a88e22b7SJung-uk Kim         if (*End == '\r' || *End == '\n')
155a88e22b7SJung-uk Kim         {
156a88e22b7SJung-uk Kim             End--;
157a88e22b7SJung-uk Kim             continue;
158a88e22b7SJung-uk Kim         }
159a88e22b7SJung-uk Kim 
160a88e22b7SJung-uk Kim         if (*End != ' ')
161a88e22b7SJung-uk Kim         {
162a88e22b7SJung-uk Kim             break;
163a88e22b7SJung-uk Kim         }
164a88e22b7SJung-uk Kim 
165a88e22b7SJung-uk Kim         End--;
166a88e22b7SJung-uk Kim     }
167a88e22b7SJung-uk Kim 
168a88e22b7SJung-uk Kim     /* Remove any quotes around the string */
169a88e22b7SJung-uk Kim 
170a88e22b7SJung-uk Kim     if (*Start == '\"')
171a88e22b7SJung-uk Kim     {
172a88e22b7SJung-uk Kim         Start++;
173a88e22b7SJung-uk Kim     }
174a88e22b7SJung-uk Kim     if (*End == '\"')
175a88e22b7SJung-uk Kim     {
176a88e22b7SJung-uk Kim         End--;
177a88e22b7SJung-uk Kim     }
178a88e22b7SJung-uk Kim 
179a88e22b7SJung-uk Kim     /* Create the trimmed return string */
180a88e22b7SJung-uk Kim 
181a88e22b7SJung-uk Kim     Length = ACPI_PTR_DIFF (End, Start) + 1;
182313a0c13SJung-uk Kim     ReturnString = UtStringCacheCalloc (Length + 1);
1835ef50723SJung-uk Kim     if (strlen (Start))
184a88e22b7SJung-uk Kim     {
1855ef50723SJung-uk Kim         strncpy (ReturnString, Start, Length);
186a88e22b7SJung-uk Kim     }
187a88e22b7SJung-uk Kim 
188a88e22b7SJung-uk Kim     ReturnString[Length] = 0;
189a88e22b7SJung-uk Kim     return (ReturnString);
190a88e22b7SJung-uk Kim }
191a88e22b7SJung-uk Kim 
192a88e22b7SJung-uk Kim 
193a88e22b7SJung-uk Kim /******************************************************************************
194a88e22b7SJung-uk Kim  *
195a88e22b7SJung-uk Kim  * FUNCTION:    DtLinkField
196a88e22b7SJung-uk Kim  *
197a88e22b7SJung-uk Kim  * PARAMETERS:  Field               - New field object to link
198a88e22b7SJung-uk Kim  *
199a88e22b7SJung-uk Kim  * RETURN:      None
200a88e22b7SJung-uk Kim  *
201a88e22b7SJung-uk Kim  * DESCRIPTION: Link one field name and value to the list
202a88e22b7SJung-uk Kim  *
203a88e22b7SJung-uk Kim  *****************************************************************************/
204a88e22b7SJung-uk Kim 
205a88e22b7SJung-uk Kim static void
206a88e22b7SJung-uk Kim DtLinkField (
207a88e22b7SJung-uk Kim     DT_FIELD                *Field)
208a88e22b7SJung-uk Kim {
209a88e22b7SJung-uk Kim     DT_FIELD                *Prev;
210a88e22b7SJung-uk Kim     DT_FIELD                *Next;
211a88e22b7SJung-uk Kim 
212a88e22b7SJung-uk Kim 
213a88e22b7SJung-uk Kim     Prev = Next = Gbl_FieldList;
214a88e22b7SJung-uk Kim 
215a88e22b7SJung-uk Kim     while (Next)
216a88e22b7SJung-uk Kim     {
217a88e22b7SJung-uk Kim         Prev = Next;
218a88e22b7SJung-uk Kim         Next = Next->Next;
219a88e22b7SJung-uk Kim     }
220a88e22b7SJung-uk Kim 
221a88e22b7SJung-uk Kim     if (Prev)
222a88e22b7SJung-uk Kim     {
223a88e22b7SJung-uk Kim         Prev->Next = Field;
224a88e22b7SJung-uk Kim     }
225a88e22b7SJung-uk Kim     else
226a88e22b7SJung-uk Kim     {
227a88e22b7SJung-uk Kim         Gbl_FieldList = Field;
228a88e22b7SJung-uk Kim     }
229a88e22b7SJung-uk Kim }
230a88e22b7SJung-uk Kim 
231a88e22b7SJung-uk Kim 
232a88e22b7SJung-uk Kim /******************************************************************************
233a88e22b7SJung-uk Kim  *
234a88e22b7SJung-uk Kim  * FUNCTION:    DtParseLine
235a88e22b7SJung-uk Kim  *
236a88e22b7SJung-uk Kim  * PARAMETERS:  LineBuffer          - Current source code line
237a88e22b7SJung-uk Kim  *              Line                - Current line number in the source
238a88e22b7SJung-uk Kim  *              Offset              - Current byte offset of the line
239a88e22b7SJung-uk Kim  *
240d244b227SJung-uk Kim  * RETURN:      Status
241a88e22b7SJung-uk Kim  *
242a88e22b7SJung-uk Kim  * DESCRIPTION: Parse one source line
243a88e22b7SJung-uk Kim  *
244a88e22b7SJung-uk Kim  *****************************************************************************/
245a88e22b7SJung-uk Kim 
246d244b227SJung-uk Kim static ACPI_STATUS
247a88e22b7SJung-uk Kim DtParseLine (
248a88e22b7SJung-uk Kim     char                    *LineBuffer,
249a88e22b7SJung-uk Kim     UINT32                  Line,
250a88e22b7SJung-uk Kim     UINT32                  Offset)
251a88e22b7SJung-uk Kim {
252a88e22b7SJung-uk Kim     char                    *Start;
253a88e22b7SJung-uk Kim     char                    *End;
254a88e22b7SJung-uk Kim     char                    *TmpName;
255a88e22b7SJung-uk Kim     char                    *TmpValue;
256a88e22b7SJung-uk Kim     char                    *Name;
257a88e22b7SJung-uk Kim     char                    *Value;
258a88e22b7SJung-uk Kim     char                    *Colon;
259a88e22b7SJung-uk Kim     UINT32                  Length;
260a88e22b7SJung-uk Kim     DT_FIELD                *Field;
261a88e22b7SJung-uk Kim     UINT32                  Column;
262a88e22b7SJung-uk Kim     UINT32                  NameColumn;
263d052a1ccSJung-uk Kim     BOOLEAN                 IsNullString = FALSE;
264a88e22b7SJung-uk Kim 
265a88e22b7SJung-uk Kim 
266a88e22b7SJung-uk Kim     if (!LineBuffer)
267a88e22b7SJung-uk Kim     {
268d244b227SJung-uk Kim         return (AE_OK);
269d244b227SJung-uk Kim     }
270d244b227SJung-uk Kim 
271d244b227SJung-uk Kim     /* All lines after "Raw Table Data" are ingored */
272d244b227SJung-uk Kim 
273d244b227SJung-uk Kim     if (strstr (LineBuffer, ACPI_RAW_TABLE_DATA_HEADER))
274d244b227SJung-uk Kim     {
275d244b227SJung-uk Kim         return (AE_NOT_FOUND);
276a88e22b7SJung-uk Kim     }
277a88e22b7SJung-uk Kim 
278a88e22b7SJung-uk Kim     Colon = strchr (LineBuffer, ':');
279d244b227SJung-uk Kim     if (!Colon)
280a88e22b7SJung-uk Kim     {
281d244b227SJung-uk Kim         return (AE_OK);
282a88e22b7SJung-uk Kim     }
283a88e22b7SJung-uk Kim 
284a88e22b7SJung-uk Kim     Start = LineBuffer;
285a88e22b7SJung-uk Kim     End = Colon;
286a88e22b7SJung-uk Kim 
287a88e22b7SJung-uk Kim     while (Start < Colon)
288a88e22b7SJung-uk Kim     {
289a88e22b7SJung-uk Kim         if (*Start == '[')
290a88e22b7SJung-uk Kim         {
2918d744e47SJung-uk Kim             /* Found left bracket, go to the right bracket */
2928d744e47SJung-uk Kim 
293a88e22b7SJung-uk Kim             while (Start < Colon && *Start != ']')
294a88e22b7SJung-uk Kim             {
295a88e22b7SJung-uk Kim                 Start++;
296a88e22b7SJung-uk Kim             }
2978d744e47SJung-uk Kim         }
2988d744e47SJung-uk Kim         else if (*Start != ' ')
299a88e22b7SJung-uk Kim         {
300a88e22b7SJung-uk Kim             break;
301a88e22b7SJung-uk Kim         }
302a88e22b7SJung-uk Kim 
303a88e22b7SJung-uk Kim         Start++;
304a88e22b7SJung-uk Kim     }
305a88e22b7SJung-uk Kim 
306a88e22b7SJung-uk Kim     /*
307a88e22b7SJung-uk Kim      * There are two column values. One for the field name,
308a88e22b7SJung-uk Kim      * and one for the field value.
309a88e22b7SJung-uk Kim      */
310a88e22b7SJung-uk Kim     Column = ACPI_PTR_DIFF (Colon, LineBuffer) + 3;
311a88e22b7SJung-uk Kim     NameColumn = ACPI_PTR_DIFF (Start, LineBuffer) + 1;
312a88e22b7SJung-uk Kim 
313a88e22b7SJung-uk Kim     Length = ACPI_PTR_DIFF (End, Start);
314a88e22b7SJung-uk Kim 
315a88e22b7SJung-uk Kim     TmpName = UtLocalCalloc (Length + 1);
3165ef50723SJung-uk Kim     strncpy (TmpName, Start, Length);
317a88e22b7SJung-uk Kim     Name = DtTrim (TmpName);
318a88e22b7SJung-uk Kim     ACPI_FREE (TmpName);
319a88e22b7SJung-uk Kim 
320a88e22b7SJung-uk Kim     Start = End = (Colon + 1);
321a88e22b7SJung-uk Kim     while (*End)
322a88e22b7SJung-uk Kim     {
323a88e22b7SJung-uk Kim         /* Found left quotation, go to the right quotation and break */
324a88e22b7SJung-uk Kim 
325a88e22b7SJung-uk Kim         if (*End == '"')
326a88e22b7SJung-uk Kim         {
327a88e22b7SJung-uk Kim             End++;
328d052a1ccSJung-uk Kim 
329d052a1ccSJung-uk Kim             /* Check for an explicit null string */
330d052a1ccSJung-uk Kim 
331d052a1ccSJung-uk Kim             if (*End == '"')
332d052a1ccSJung-uk Kim             {
333d052a1ccSJung-uk Kim                 IsNullString = TRUE;
334d052a1ccSJung-uk Kim             }
3350b94ba42SJung-uk Kim             while (*End && (*End != '"'))
336a88e22b7SJung-uk Kim             {
337a88e22b7SJung-uk Kim                 End++;
338a88e22b7SJung-uk Kim             }
339a88e22b7SJung-uk Kim 
340a88e22b7SJung-uk Kim             End++;
341a88e22b7SJung-uk Kim             break;
342a88e22b7SJung-uk Kim         }
343a88e22b7SJung-uk Kim 
3440b94ba42SJung-uk Kim         /*
3450b94ba42SJung-uk Kim          * Special "comment" fields at line end, ignore them.
3460b94ba42SJung-uk Kim          * Note: normal slash-slash and slash-asterisk comments are
3470b94ba42SJung-uk Kim          * stripped already by the DtGetNextLine parser.
3480b94ba42SJung-uk Kim          *
3490b94ba42SJung-uk Kim          * TBD: Perhaps DtGetNextLine should parse the following type
3500b94ba42SJung-uk Kim          * of comments also.
3510b94ba42SJung-uk Kim          */
352d052a1ccSJung-uk Kim         if (*End == '[')
353a88e22b7SJung-uk Kim         {
354d052a1ccSJung-uk Kim             End--;
355a88e22b7SJung-uk Kim             break;
356a88e22b7SJung-uk Kim         }
357*f8146b88SJung-uk Kim 
358a88e22b7SJung-uk Kim         End++;
359a88e22b7SJung-uk Kim     }
360a88e22b7SJung-uk Kim 
361a88e22b7SJung-uk Kim     Length = ACPI_PTR_DIFF (End, Start);
362a88e22b7SJung-uk Kim     TmpValue = UtLocalCalloc (Length + 1);
363dcbce41eSJung-uk Kim 
3645ef50723SJung-uk Kim     strncpy (TmpValue, Start, Length);
365a88e22b7SJung-uk Kim     Value = DtTrim (TmpValue);
366a88e22b7SJung-uk Kim     ACPI_FREE (TmpValue);
367a88e22b7SJung-uk Kim 
368d052a1ccSJung-uk Kim     /* Create a new field object only if we have a valid value field */
369d052a1ccSJung-uk Kim 
370d052a1ccSJung-uk Kim     if ((Value && *Value) || IsNullString)
371a88e22b7SJung-uk Kim     {
372313a0c13SJung-uk Kim         Field = UtFieldCacheCalloc ();
373a88e22b7SJung-uk Kim         Field->Name = Name;
374a88e22b7SJung-uk Kim         Field->Value = Value;
375a88e22b7SJung-uk Kim         Field->Line = Line;
376a88e22b7SJung-uk Kim         Field->ByteOffset = Offset;
377a88e22b7SJung-uk Kim         Field->NameColumn = NameColumn;
378a88e22b7SJung-uk Kim         Field->Column = Column;
3797cf3e94aSJung-uk Kim         Field->StringLength = Length;
380a88e22b7SJung-uk Kim 
381a88e22b7SJung-uk Kim         DtLinkField (Field);
382a88e22b7SJung-uk Kim     }
383313a0c13SJung-uk Kim     /* Else -- Ignore this field, it has no valid data */
384d244b227SJung-uk Kim 
385d244b227SJung-uk Kim     return (AE_OK);
386a88e22b7SJung-uk Kim }
387a88e22b7SJung-uk Kim 
388a88e22b7SJung-uk Kim 
389a88e22b7SJung-uk Kim /******************************************************************************
390a88e22b7SJung-uk Kim  *
391a88e22b7SJung-uk Kim  * FUNCTION:    DtGetNextLine
392a88e22b7SJung-uk Kim  *
393a88e22b7SJung-uk Kim  * PARAMETERS:  Handle              - Open file handle for the source file
394a88e22b7SJung-uk Kim  *
395d052a1ccSJung-uk Kim  * RETURN:      Filled line buffer and offset of start-of-line (ASL_EOF on EOF)
396a88e22b7SJung-uk Kim  *
397a88e22b7SJung-uk Kim  * DESCRIPTION: Get the next valid source line. Removes all comments.
398a88e22b7SJung-uk Kim  *              Ignores empty lines.
399a88e22b7SJung-uk Kim  *
400a88e22b7SJung-uk Kim  * Handles both slash-asterisk and slash-slash comments.
401a88e22b7SJung-uk Kim  * Also, quoted strings, but no escapes within.
402a88e22b7SJung-uk Kim  *
403a88e22b7SJung-uk Kim  * Line is returned in Gbl_CurrentLineBuffer.
404a88e22b7SJung-uk Kim  * Line number in original file is returned in Gbl_CurrentLineNumber.
405a88e22b7SJung-uk Kim  *
406a88e22b7SJung-uk Kim  *****************************************************************************/
407a88e22b7SJung-uk Kim 
4080b94ba42SJung-uk Kim UINT32
409a88e22b7SJung-uk Kim DtGetNextLine (
4105ef50723SJung-uk Kim     FILE                    *Handle,
4115ef50723SJung-uk Kim     UINT32                  Flags)
412a88e22b7SJung-uk Kim {
413d052a1ccSJung-uk Kim     BOOLEAN                 LineNotAllBlanks = FALSE;
414a88e22b7SJung-uk Kim     UINT32                  State = DT_NORMAL_TEXT;
415a88e22b7SJung-uk Kim     UINT32                  CurrentLineOffset;
416a88e22b7SJung-uk Kim     UINT32                  i;
417a9d8d09cSJung-uk Kim     int                     c;
418a88e22b7SJung-uk Kim 
419a88e22b7SJung-uk Kim 
4205ef50723SJung-uk Kim     memset (Gbl_CurrentLineBuffer, 0, Gbl_LineBufferSize);
421042ff955SJung-uk Kim     for (i = 0; ;)
422a88e22b7SJung-uk Kim     {
423042ff955SJung-uk Kim         /*
424042ff955SJung-uk Kim          * If line is too long, expand the line buffers. Also increases
425042ff955SJung-uk Kim          * Gbl_LineBufferSize.
426042ff955SJung-uk Kim          */
427042ff955SJung-uk Kim         if (i >= Gbl_LineBufferSize)
428042ff955SJung-uk Kim         {
429042ff955SJung-uk Kim             UtExpandLineBuffers ();
430042ff955SJung-uk Kim         }
431042ff955SJung-uk Kim 
432a9d8d09cSJung-uk Kim         c = getc (Handle);
433a88e22b7SJung-uk Kim         if (c == EOF)
434a88e22b7SJung-uk Kim         {
4350b94ba42SJung-uk Kim             switch (State)
4360b94ba42SJung-uk Kim             {
4370b94ba42SJung-uk Kim             case DT_START_QUOTED_STRING:
4380b94ba42SJung-uk Kim             case DT_SLASH_ASTERISK_COMMENT:
4390b94ba42SJung-uk Kim 
4400b94ba42SJung-uk Kim                 AcpiOsPrintf ("**** EOF within comment/string %u\n", State);
4410b94ba42SJung-uk Kim                 break;
4420b94ba42SJung-uk Kim 
4430b94ba42SJung-uk Kim             default:
444a9d8d09cSJung-uk Kim 
4450b94ba42SJung-uk Kim                 break;
4460b94ba42SJung-uk Kim             }
4470b94ba42SJung-uk Kim 
448a7a3b383SJung-uk Kim             /* Standalone EOF is OK */
449a7a3b383SJung-uk Kim 
450a7a3b383SJung-uk Kim             if (i == 0)
451a7a3b383SJung-uk Kim             {
452d052a1ccSJung-uk Kim                 return (ASL_EOF);
453a88e22b7SJung-uk Kim             }
454a88e22b7SJung-uk Kim 
455a7a3b383SJung-uk Kim             /*
456a7a3b383SJung-uk Kim              * Received an EOF in the middle of a line. Terminate the
457a7a3b383SJung-uk Kim              * line with a newline. The next call to this function will
458a7a3b383SJung-uk Kim              * return a standalone EOF. Thus, the upper parsing software
459a7a3b383SJung-uk Kim              * never has to deal with an EOF within a valid line (or
460a7a3b383SJung-uk Kim              * the last line does not get tossed on the floor.)
461a7a3b383SJung-uk Kim              */
462a7a3b383SJung-uk Kim             c = '\n';
463a7a3b383SJung-uk Kim             State = DT_NORMAL_TEXT;
464a7a3b383SJung-uk Kim         }
465a7a3b383SJung-uk Kim 
466a88e22b7SJung-uk Kim         switch (State)
467a88e22b7SJung-uk Kim         {
468a88e22b7SJung-uk Kim         case DT_NORMAL_TEXT:
469a88e22b7SJung-uk Kim 
470a88e22b7SJung-uk Kim             /* Normal text, insert char into line buffer */
471a88e22b7SJung-uk Kim 
472a9d8d09cSJung-uk Kim             Gbl_CurrentLineBuffer[i] = (char) c;
473a88e22b7SJung-uk Kim             switch (c)
474a88e22b7SJung-uk Kim             {
475a88e22b7SJung-uk Kim             case '/':
476a9d8d09cSJung-uk Kim 
477a88e22b7SJung-uk Kim                 State = DT_START_COMMENT;
478a88e22b7SJung-uk Kim                 break;
479a88e22b7SJung-uk Kim 
480a88e22b7SJung-uk Kim             case '"':
481a9d8d09cSJung-uk Kim 
482a88e22b7SJung-uk Kim                 State = DT_START_QUOTED_STRING;
483d052a1ccSJung-uk Kim                 LineNotAllBlanks = TRUE;
484a88e22b7SJung-uk Kim                 i++;
485a88e22b7SJung-uk Kim                 break;
486a88e22b7SJung-uk Kim 
487d052a1ccSJung-uk Kim             case '\\':
488d052a1ccSJung-uk Kim                 /*
489d052a1ccSJung-uk Kim                  * The continuation char MUST be last char on this line.
490d052a1ccSJung-uk Kim                  * Otherwise, it will be assumed to be a valid ASL char.
491d052a1ccSJung-uk Kim                  */
492d052a1ccSJung-uk Kim                 State = DT_MERGE_LINES;
493d052a1ccSJung-uk Kim                 break;
494d052a1ccSJung-uk Kim 
495a88e22b7SJung-uk Kim             case '\n':
496a9d8d09cSJung-uk Kim 
497a88e22b7SJung-uk Kim                 CurrentLineOffset = Gbl_NextLineOffset;
498a88e22b7SJung-uk Kim                 Gbl_NextLineOffset = (UINT32) ftell (Handle);
499a88e22b7SJung-uk Kim                 Gbl_CurrentLineNumber++;
500a88e22b7SJung-uk Kim 
501d052a1ccSJung-uk Kim                 /*
502d052a1ccSJung-uk Kim                  * Exit if line is complete. Ignore empty lines (only \n)
503d052a1ccSJung-uk Kim                  * or lines that contain nothing but blanks.
504d052a1ccSJung-uk Kim                  */
505d052a1ccSJung-uk Kim                 if ((i != 0) && LineNotAllBlanks)
506a88e22b7SJung-uk Kim                 {
507042ff955SJung-uk Kim                     if ((i + 1) >= Gbl_LineBufferSize)
508042ff955SJung-uk Kim                     {
509042ff955SJung-uk Kim                         UtExpandLineBuffers ();
510042ff955SJung-uk Kim                     }
511042ff955SJung-uk Kim 
512d052a1ccSJung-uk Kim                     Gbl_CurrentLineBuffer[i+1] = 0; /* Terminate string */
513a88e22b7SJung-uk Kim                     return (CurrentLineOffset);
514a88e22b7SJung-uk Kim                 }
515d052a1ccSJung-uk Kim 
516d052a1ccSJung-uk Kim                 /* Toss this line and start a new one */
517d052a1ccSJung-uk Kim 
518d052a1ccSJung-uk Kim                 i = 0;
519d052a1ccSJung-uk Kim                 LineNotAllBlanks = FALSE;
520a88e22b7SJung-uk Kim                 break;
521a88e22b7SJung-uk Kim 
522a88e22b7SJung-uk Kim             default:
523a9d8d09cSJung-uk Kim 
524d052a1ccSJung-uk Kim                 if (c != ' ')
525d052a1ccSJung-uk Kim                 {
526d052a1ccSJung-uk Kim                     LineNotAllBlanks = TRUE;
527d052a1ccSJung-uk Kim                 }
528d052a1ccSJung-uk Kim 
529a88e22b7SJung-uk Kim                 i++;
530a88e22b7SJung-uk Kim                 break;
531a88e22b7SJung-uk Kim             }
532a88e22b7SJung-uk Kim             break;
533a88e22b7SJung-uk Kim 
534a88e22b7SJung-uk Kim         case DT_START_QUOTED_STRING:
535a88e22b7SJung-uk Kim 
536a88e22b7SJung-uk Kim             /* Insert raw chars until end of quoted string */
537a88e22b7SJung-uk Kim 
538a9d8d09cSJung-uk Kim             Gbl_CurrentLineBuffer[i] = (char) c;
539a88e22b7SJung-uk Kim             i++;
540a88e22b7SJung-uk Kim 
541eef1b955SJung-uk Kim             switch (c)
542a88e22b7SJung-uk Kim             {
543eef1b955SJung-uk Kim             case '"':
544a9d8d09cSJung-uk Kim 
545a88e22b7SJung-uk Kim                 State = DT_NORMAL_TEXT;
546eef1b955SJung-uk Kim                 break;
547eef1b955SJung-uk Kim 
548eef1b955SJung-uk Kim             case '\\':
549a9d8d09cSJung-uk Kim 
550eef1b955SJung-uk Kim                 State = DT_ESCAPE_SEQUENCE;
551eef1b955SJung-uk Kim                 break;
552eef1b955SJung-uk Kim 
553eef1b955SJung-uk Kim             case '\n':
554a9d8d09cSJung-uk Kim 
5555ef50723SJung-uk Kim                 if (!(Flags & DT_ALLOW_MULTILINE_QUOTES))
5565ef50723SJung-uk Kim                 {
557*f8146b88SJung-uk Kim                     AcpiOsPrintf (
558*f8146b88SJung-uk Kim                         "ERROR at line %u: Unterminated quoted string\n",
559eef1b955SJung-uk Kim                         Gbl_CurrentLineNumber++);
560eef1b955SJung-uk Kim                     State = DT_NORMAL_TEXT;
5615ef50723SJung-uk Kim                 }
562eef1b955SJung-uk Kim                 break;
563eef1b955SJung-uk Kim 
564eef1b955SJung-uk Kim             default:    /* Get next character */
565a9d8d09cSJung-uk Kim 
566eef1b955SJung-uk Kim                 break;
567a88e22b7SJung-uk Kim             }
568a88e22b7SJung-uk Kim             break;
569a88e22b7SJung-uk Kim 
570eef1b955SJung-uk Kim         case DT_ESCAPE_SEQUENCE:
571eef1b955SJung-uk Kim 
572eef1b955SJung-uk Kim             /* Just copy the escaped character. TBD: sufficient for table compiler? */
573eef1b955SJung-uk Kim 
574a9d8d09cSJung-uk Kim             Gbl_CurrentLineBuffer[i] = (char) c;
575eef1b955SJung-uk Kim             i++;
576eef1b955SJung-uk Kim             State = DT_START_QUOTED_STRING;
577eef1b955SJung-uk Kim             break;
578eef1b955SJung-uk Kim 
579a88e22b7SJung-uk Kim         case DT_START_COMMENT:
580a88e22b7SJung-uk Kim 
581a88e22b7SJung-uk Kim             /* Open comment if this character is an asterisk or slash */
582a88e22b7SJung-uk Kim 
583a88e22b7SJung-uk Kim             switch (c)
584a88e22b7SJung-uk Kim             {
585a88e22b7SJung-uk Kim             case '*':
586a9d8d09cSJung-uk Kim 
587a88e22b7SJung-uk Kim                 State = DT_SLASH_ASTERISK_COMMENT;
588a88e22b7SJung-uk Kim                 break;
589a88e22b7SJung-uk Kim 
590a88e22b7SJung-uk Kim             case '/':
591a9d8d09cSJung-uk Kim 
592a88e22b7SJung-uk Kim                 State = DT_SLASH_SLASH_COMMENT;
593a88e22b7SJung-uk Kim                 break;
594a88e22b7SJung-uk Kim 
595a88e22b7SJung-uk Kim             default:    /* Not a comment */
596a9d8d09cSJung-uk Kim 
5978ef1a331SJung-uk Kim                 i++;    /* Save the preceding slash */
598042ff955SJung-uk Kim                 if (i >= Gbl_LineBufferSize)
599042ff955SJung-uk Kim                 {
600042ff955SJung-uk Kim                     UtExpandLineBuffers ();
601042ff955SJung-uk Kim                 }
602042ff955SJung-uk Kim 
603a9d8d09cSJung-uk Kim                 Gbl_CurrentLineBuffer[i] = (char) c;
604a88e22b7SJung-uk Kim                 i++;
605a88e22b7SJung-uk Kim                 State = DT_NORMAL_TEXT;
606a88e22b7SJung-uk Kim                 break;
607a88e22b7SJung-uk Kim             }
608a88e22b7SJung-uk Kim             break;
609a88e22b7SJung-uk Kim 
610a88e22b7SJung-uk Kim         case DT_SLASH_ASTERISK_COMMENT:
611a88e22b7SJung-uk Kim 
612a88e22b7SJung-uk Kim             /* Ignore chars until an asterisk-slash is found */
613a88e22b7SJung-uk Kim 
614a88e22b7SJung-uk Kim             switch (c)
615a88e22b7SJung-uk Kim             {
616a88e22b7SJung-uk Kim             case '\n':
617a9d8d09cSJung-uk Kim 
618a88e22b7SJung-uk Kim                 Gbl_NextLineOffset = (UINT32) ftell (Handle);
619a88e22b7SJung-uk Kim                 Gbl_CurrentLineNumber++;
620a88e22b7SJung-uk Kim                 break;
621a88e22b7SJung-uk Kim 
622a88e22b7SJung-uk Kim             case '*':
623a9d8d09cSJung-uk Kim 
624a88e22b7SJung-uk Kim                 State = DT_END_COMMENT;
625a88e22b7SJung-uk Kim                 break;
626a88e22b7SJung-uk Kim 
627a88e22b7SJung-uk Kim             default:
628a9d8d09cSJung-uk Kim 
629a88e22b7SJung-uk Kim                 break;
630a88e22b7SJung-uk Kim             }
631a88e22b7SJung-uk Kim             break;
632a88e22b7SJung-uk Kim 
633a88e22b7SJung-uk Kim         case DT_SLASH_SLASH_COMMENT:
634a88e22b7SJung-uk Kim 
635a88e22b7SJung-uk Kim             /* Ignore chars until end-of-line */
636a88e22b7SJung-uk Kim 
637a88e22b7SJung-uk Kim             if (c == '\n')
638a88e22b7SJung-uk Kim             {
639a88e22b7SJung-uk Kim                 /* We will exit via the NORMAL_TEXT path */
640a88e22b7SJung-uk Kim 
641a88e22b7SJung-uk Kim                 ungetc (c, Handle);
642a88e22b7SJung-uk Kim                 State = DT_NORMAL_TEXT;
643a88e22b7SJung-uk Kim             }
644a88e22b7SJung-uk Kim             break;
645a88e22b7SJung-uk Kim 
646a88e22b7SJung-uk Kim         case DT_END_COMMENT:
647a88e22b7SJung-uk Kim 
648a88e22b7SJung-uk Kim             /* End comment if this char is a slash */
649a88e22b7SJung-uk Kim 
650a88e22b7SJung-uk Kim             switch (c)
651a88e22b7SJung-uk Kim             {
652a88e22b7SJung-uk Kim             case '/':
653a9d8d09cSJung-uk Kim 
654a88e22b7SJung-uk Kim                 State = DT_NORMAL_TEXT;
655a88e22b7SJung-uk Kim                 break;
656a88e22b7SJung-uk Kim 
6570b94ba42SJung-uk Kim             case '\n':
658a9d8d09cSJung-uk Kim 
6590b94ba42SJung-uk Kim                 CurrentLineOffset = Gbl_NextLineOffset;
6600b94ba42SJung-uk Kim                 Gbl_NextLineOffset = (UINT32) ftell (Handle);
6610b94ba42SJung-uk Kim                 Gbl_CurrentLineNumber++;
6620b94ba42SJung-uk Kim                 break;
6630b94ba42SJung-uk Kim 
6640b94ba42SJung-uk Kim             case '*':
665a9d8d09cSJung-uk Kim 
6660b94ba42SJung-uk Kim                 /* Consume all adjacent asterisks */
6670b94ba42SJung-uk Kim                 break;
6680b94ba42SJung-uk Kim 
669a88e22b7SJung-uk Kim             default:
670a9d8d09cSJung-uk Kim 
671a88e22b7SJung-uk Kim                 State = DT_SLASH_ASTERISK_COMMENT;
672a88e22b7SJung-uk Kim                 break;
673a88e22b7SJung-uk Kim             }
674a88e22b7SJung-uk Kim             break;
675a88e22b7SJung-uk Kim 
676d052a1ccSJung-uk Kim         case DT_MERGE_LINES:
677d052a1ccSJung-uk Kim 
678d052a1ccSJung-uk Kim             if (c != '\n')
679d052a1ccSJung-uk Kim             {
680d052a1ccSJung-uk Kim                 /*
681d052a1ccSJung-uk Kim                  * This is not a continuation backslash, it is a normal
682d052a1ccSJung-uk Kim                  * normal ASL backslash - for example: Scope(\_SB_)
683d052a1ccSJung-uk Kim                  */
684d052a1ccSJung-uk Kim                 i++; /* Keep the backslash that is already in the buffer */
685d052a1ccSJung-uk Kim 
686d052a1ccSJung-uk Kim                 ungetc (c, Handle);
687d052a1ccSJung-uk Kim                 State = DT_NORMAL_TEXT;
688d052a1ccSJung-uk Kim             }
689d052a1ccSJung-uk Kim             else
690d052a1ccSJung-uk Kim             {
691d052a1ccSJung-uk Kim                 /*
692d052a1ccSJung-uk Kim                  * This is a continuation line -- a backlash followed
693d052a1ccSJung-uk Kim                  * immediately by a newline. Insert a space between the
694d052a1ccSJung-uk Kim                  * lines (overwrite the backslash)
695d052a1ccSJung-uk Kim                  */
696d052a1ccSJung-uk Kim                 Gbl_CurrentLineBuffer[i] = ' ';
697d052a1ccSJung-uk Kim                 i++;
698d052a1ccSJung-uk Kim 
699d052a1ccSJung-uk Kim                 /* Ignore newline, this will merge the lines */
700d052a1ccSJung-uk Kim 
701d052a1ccSJung-uk Kim                 CurrentLineOffset = Gbl_NextLineOffset;
702d052a1ccSJung-uk Kim                 Gbl_NextLineOffset = (UINT32) ftell (Handle);
703d052a1ccSJung-uk Kim                 Gbl_CurrentLineNumber++;
704d052a1ccSJung-uk Kim                 State = DT_NORMAL_TEXT;
705d052a1ccSJung-uk Kim             }
706d052a1ccSJung-uk Kim             break;
707d052a1ccSJung-uk Kim 
708a88e22b7SJung-uk Kim         default:
709a9d8d09cSJung-uk Kim 
710a88e22b7SJung-uk Kim             DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, "Unknown input state");
711d052a1ccSJung-uk Kim             return (ASL_EOF);
712a88e22b7SJung-uk Kim         }
713a88e22b7SJung-uk Kim     }
714a88e22b7SJung-uk Kim }
715a88e22b7SJung-uk Kim 
716a88e22b7SJung-uk Kim 
717a88e22b7SJung-uk Kim /******************************************************************************
718a88e22b7SJung-uk Kim  *
719a88e22b7SJung-uk Kim  * FUNCTION:    DtScanFile
720a88e22b7SJung-uk Kim  *
721a88e22b7SJung-uk Kim  * PARAMETERS:  Handle              - Open file handle for the source file
722a88e22b7SJung-uk Kim  *
723a88e22b7SJung-uk Kim  * RETURN:      Pointer to start of the constructed parse tree.
724a88e22b7SJung-uk Kim  *
725a88e22b7SJung-uk Kim  * DESCRIPTION: Scan source file, link all field names and values
726a88e22b7SJung-uk Kim  *              to the global parse tree: Gbl_FieldList
727a88e22b7SJung-uk Kim  *
728a88e22b7SJung-uk Kim  *****************************************************************************/
729a88e22b7SJung-uk Kim 
730a88e22b7SJung-uk Kim DT_FIELD *
731a88e22b7SJung-uk Kim DtScanFile (
732a88e22b7SJung-uk Kim     FILE                    *Handle)
733a88e22b7SJung-uk Kim {
734d244b227SJung-uk Kim     ACPI_STATUS             Status;
735a88e22b7SJung-uk Kim     UINT32                  Offset;
736a88e22b7SJung-uk Kim 
737a88e22b7SJung-uk Kim 
738a88e22b7SJung-uk Kim     ACPI_FUNCTION_NAME (DtScanFile);
739a88e22b7SJung-uk Kim 
740a88e22b7SJung-uk Kim 
741a88e22b7SJung-uk Kim     /* Get the file size */
742a88e22b7SJung-uk Kim 
743313a0c13SJung-uk Kim     Gbl_InputByteCount = CmGetFileSize (Handle);
744313a0c13SJung-uk Kim     if (Gbl_InputByteCount == ACPI_UINT32_MAX)
745313a0c13SJung-uk Kim     {
746313a0c13SJung-uk Kim         AslAbort ();
747313a0c13SJung-uk Kim     }
748a88e22b7SJung-uk Kim 
749a88e22b7SJung-uk Kim     Gbl_CurrentLineNumber = 0;
750a88e22b7SJung-uk Kim     Gbl_CurrentLineOffset = 0;
751a88e22b7SJung-uk Kim     Gbl_NextLineOffset = 0;
752a88e22b7SJung-uk Kim 
753a88e22b7SJung-uk Kim     /* Scan line-by-line */
754a88e22b7SJung-uk Kim 
7555ef50723SJung-uk Kim     while ((Offset = DtGetNextLine (Handle, 0)) != ASL_EOF)
756a88e22b7SJung-uk Kim     {
757a88e22b7SJung-uk Kim         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Line %2.2u/%4.4X - %s",
758a88e22b7SJung-uk Kim             Gbl_CurrentLineNumber, Offset, Gbl_CurrentLineBuffer));
759a88e22b7SJung-uk Kim 
760*f8146b88SJung-uk Kim         Status = DtParseLine (Gbl_CurrentLineBuffer,
761*f8146b88SJung-uk Kim             Gbl_CurrentLineNumber, Offset);
762d244b227SJung-uk Kim         if (Status == AE_NOT_FOUND)
763d244b227SJung-uk Kim         {
764d244b227SJung-uk Kim             break;
765d244b227SJung-uk Kim         }
766a88e22b7SJung-uk Kim     }
767a88e22b7SJung-uk Kim 
768d052a1ccSJung-uk Kim     /* Dump the parse tree if debug enabled */
769d052a1ccSJung-uk Kim 
770efcc2a30SJung-uk Kim     DtDumpFieldList (Gbl_FieldList);
771a88e22b7SJung-uk Kim     return (Gbl_FieldList);
772a88e22b7SJung-uk Kim }
773a88e22b7SJung-uk Kim 
774a88e22b7SJung-uk Kim 
775a88e22b7SJung-uk Kim /*
776a88e22b7SJung-uk Kim  * Output functions
777a88e22b7SJung-uk Kim  */
778a88e22b7SJung-uk Kim 
779a88e22b7SJung-uk Kim /******************************************************************************
780a88e22b7SJung-uk Kim  *
781a88e22b7SJung-uk Kim  * FUNCTION:    DtWriteBinary
782a88e22b7SJung-uk Kim  *
783a88e22b7SJung-uk Kim  * PARAMETERS:  DT_WALK_CALLBACK
784a88e22b7SJung-uk Kim  *
785a88e22b7SJung-uk Kim  * RETURN:      Status
786a88e22b7SJung-uk Kim  *
787a88e22b7SJung-uk Kim  * DESCRIPTION: Write one subtable of a binary ACPI table
788a88e22b7SJung-uk Kim  *
789a88e22b7SJung-uk Kim  *****************************************************************************/
790a88e22b7SJung-uk Kim 
791a88e22b7SJung-uk Kim static void
792a88e22b7SJung-uk Kim DtWriteBinary (
793a88e22b7SJung-uk Kim     DT_SUBTABLE             *Subtable,
794a88e22b7SJung-uk Kim     void                    *Context,
795a88e22b7SJung-uk Kim     void                    *ReturnValue)
796a88e22b7SJung-uk Kim {
797a88e22b7SJung-uk Kim 
798a88e22b7SJung-uk Kim     FlWriteFile (ASL_FILE_AML_OUTPUT, Subtable->Buffer, Subtable->Length);
799a88e22b7SJung-uk Kim }
800a88e22b7SJung-uk Kim 
801a88e22b7SJung-uk Kim 
802a88e22b7SJung-uk Kim /******************************************************************************
803a88e22b7SJung-uk Kim  *
804a88e22b7SJung-uk Kim  * FUNCTION:    DtOutputBinary
805a88e22b7SJung-uk Kim  *
806a88e22b7SJung-uk Kim  * PARAMETERS:
807a88e22b7SJung-uk Kim  *
808a88e22b7SJung-uk Kim  * RETURN:      Status
809a88e22b7SJung-uk Kim  *
810a88e22b7SJung-uk Kim  * DESCRIPTION: Write entire binary ACPI table (result of compilation)
811a88e22b7SJung-uk Kim  *
812a88e22b7SJung-uk Kim  *****************************************************************************/
813a88e22b7SJung-uk Kim 
814a88e22b7SJung-uk Kim void
815a88e22b7SJung-uk Kim DtOutputBinary (
816a88e22b7SJung-uk Kim     DT_SUBTABLE             *RootTable)
817a88e22b7SJung-uk Kim {
818a88e22b7SJung-uk Kim 
819a88e22b7SJung-uk Kim     if (!RootTable)
820a88e22b7SJung-uk Kim     {
821a88e22b7SJung-uk Kim         return;
822a88e22b7SJung-uk Kim     }
823a88e22b7SJung-uk Kim 
824a88e22b7SJung-uk Kim     /* Walk the entire parse tree, emitting the binary data */
825a88e22b7SJung-uk Kim 
826a88e22b7SJung-uk Kim     DtWalkTableTree (RootTable, DtWriteBinary, NULL, NULL);
827313a0c13SJung-uk Kim 
828313a0c13SJung-uk Kim     Gbl_TableLength = CmGetFileSize (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle);
829313a0c13SJung-uk Kim     if (Gbl_TableLength == ACPI_UINT32_MAX)
830313a0c13SJung-uk Kim     {
831313a0c13SJung-uk Kim         AslAbort ();
832313a0c13SJung-uk Kim     }
833a88e22b7SJung-uk Kim }
834d244b227SJung-uk Kim 
835d244b227SJung-uk Kim 
836d244b227SJung-uk Kim /*
837d244b227SJung-uk Kim  * Listing support
838d244b227SJung-uk Kim  */
839d244b227SJung-uk Kim 
840d244b227SJung-uk Kim /******************************************************************************
841d244b227SJung-uk Kim  *
842d244b227SJung-uk Kim  * FUNCTION:    DtDumpBuffer
843d244b227SJung-uk Kim  *
844d244b227SJung-uk Kim  * PARAMETERS:  FileID              - Where to write buffer data
845d244b227SJung-uk Kim  *              Buffer              - Buffer to dump
8460b94ba42SJung-uk Kim  *              Offset              - Offset in current table
847d244b227SJung-uk Kim  *              Length              - Buffer Length
848d244b227SJung-uk Kim  *
849d244b227SJung-uk Kim  * RETURN:      None
850d244b227SJung-uk Kim  *
851d244b227SJung-uk Kim  * DESCRIPTION: Another copy of DumpBuffer routine (unfortunately).
852d244b227SJung-uk Kim  *
853d244b227SJung-uk Kim  * TBD: merge dump buffer routines
854d244b227SJung-uk Kim  *
855d244b227SJung-uk Kim  *****************************************************************************/
856d244b227SJung-uk Kim 
857d244b227SJung-uk Kim static void
858d244b227SJung-uk Kim DtDumpBuffer (
859d244b227SJung-uk Kim     UINT32                  FileId,
860d244b227SJung-uk Kim     UINT8                   *Buffer,
8610b94ba42SJung-uk Kim     UINT32                  Offset,
862d244b227SJung-uk Kim     UINT32                  Length)
863d244b227SJung-uk Kim {
864d244b227SJung-uk Kim     UINT32                  i;
865d244b227SJung-uk Kim     UINT32                  j;
866d244b227SJung-uk Kim     UINT8                   BufChar;
867d244b227SJung-uk Kim 
868d244b227SJung-uk Kim 
8690b94ba42SJung-uk Kim     FlPrintFile (FileId, "Output: [%3.3Xh %4.4d %3d] ",
8700b94ba42SJung-uk Kim         Offset, Offset, Length);
8710b94ba42SJung-uk Kim 
872d244b227SJung-uk Kim     i = 0;
873d244b227SJung-uk Kim     while (i < Length)
874d244b227SJung-uk Kim     {
8750b94ba42SJung-uk Kim         if (i >= 16)
8760b94ba42SJung-uk Kim         {
877d052a1ccSJung-uk Kim             FlPrintFile (FileId, "%24s", "");
8780b94ba42SJung-uk Kim         }
879d244b227SJung-uk Kim 
8800b94ba42SJung-uk Kim         /* Print 16 hex chars */
881d244b227SJung-uk Kim 
882d244b227SJung-uk Kim         for (j = 0; j < 16;)
883d244b227SJung-uk Kim         {
884d244b227SJung-uk Kim             if (i + j >= Length)
885d244b227SJung-uk Kim             {
886d244b227SJung-uk Kim                 /* Dump fill spaces */
887d244b227SJung-uk Kim 
888d244b227SJung-uk Kim                 FlPrintFile (FileId, "   ");
889d244b227SJung-uk Kim                 j++;
890d244b227SJung-uk Kim                 continue;
891d244b227SJung-uk Kim             }
892d244b227SJung-uk Kim 
893d244b227SJung-uk Kim             FlPrintFile (FileId, "%02X ", Buffer[i+j]);
894d244b227SJung-uk Kim             j++;
895d244b227SJung-uk Kim         }
896d244b227SJung-uk Kim 
897d244b227SJung-uk Kim         FlPrintFile (FileId, " ");
898d244b227SJung-uk Kim         for (j = 0; j < 16; j++)
899d244b227SJung-uk Kim         {
900d244b227SJung-uk Kim             if (i + j >= Length)
901d244b227SJung-uk Kim             {
902d244b227SJung-uk Kim                 FlPrintFile (FileId, "\n\n");
903d244b227SJung-uk Kim                 return;
904d244b227SJung-uk Kim             }
905d244b227SJung-uk Kim 
906d244b227SJung-uk Kim             BufChar = Buffer[(ACPI_SIZE) i + j];
9075ef50723SJung-uk Kim             if (isprint (BufChar))
908d244b227SJung-uk Kim             {
909d244b227SJung-uk Kim                 FlPrintFile (FileId, "%c", BufChar);
910d244b227SJung-uk Kim             }
911d244b227SJung-uk Kim             else
912d244b227SJung-uk Kim             {
913d244b227SJung-uk Kim                 FlPrintFile (FileId, ".");
914d244b227SJung-uk Kim             }
915d244b227SJung-uk Kim         }
916d244b227SJung-uk Kim 
917d244b227SJung-uk Kim         /* Done with that line. */
918d244b227SJung-uk Kim 
919d244b227SJung-uk Kim         FlPrintFile (FileId, "\n");
920d244b227SJung-uk Kim         i += 16;
921d244b227SJung-uk Kim     }
922d244b227SJung-uk Kim 
923d244b227SJung-uk Kim     FlPrintFile (FileId, "\n\n");
924d244b227SJung-uk Kim }
925d244b227SJung-uk Kim 
926d244b227SJung-uk Kim 
927d244b227SJung-uk Kim /******************************************************************************
928d244b227SJung-uk Kim  *
929efcc2a30SJung-uk Kim  * FUNCTION:    DtDumpFieldList
930efcc2a30SJung-uk Kim  *
931efcc2a30SJung-uk Kim  * PARAMETERS:  Field               - Root field
932efcc2a30SJung-uk Kim  *
933efcc2a30SJung-uk Kim  * RETURN:      None
934efcc2a30SJung-uk Kim  *
935efcc2a30SJung-uk Kim  * DESCRIPTION: Dump the entire field list
936efcc2a30SJung-uk Kim  *
937efcc2a30SJung-uk Kim  *****************************************************************************/
938efcc2a30SJung-uk Kim 
939efcc2a30SJung-uk Kim void
940efcc2a30SJung-uk Kim DtDumpFieldList (
941efcc2a30SJung-uk Kim     DT_FIELD                *Field)
942efcc2a30SJung-uk Kim {
943efcc2a30SJung-uk Kim 
944efcc2a30SJung-uk Kim     if (!Gbl_DebugFlag || !Field)
945efcc2a30SJung-uk Kim     {
946efcc2a30SJung-uk Kim         return;
947efcc2a30SJung-uk Kim     }
948efcc2a30SJung-uk Kim 
949efcc2a30SJung-uk Kim     DbgPrint (ASL_DEBUG_OUTPUT,  "\nField List:\n"
950efcc2a30SJung-uk Kim         "LineNo   ByteOff  NameCol  Column   TableOff "
951efcc2a30SJung-uk Kim         "Flags %32s : %s\n\n", "Name", "Value");
952*f8146b88SJung-uk Kim 
953efcc2a30SJung-uk Kim     while (Field)
954efcc2a30SJung-uk Kim     {
955efcc2a30SJung-uk Kim         DbgPrint (ASL_DEBUG_OUTPUT,
9567cf3e94aSJung-uk Kim             "%.08X %.08X %.08X %.08X %.08X %2.2X    %32s : %s\n",
957efcc2a30SJung-uk Kim             Field->Line, Field->ByteOffset, Field->NameColumn,
958efcc2a30SJung-uk Kim             Field->Column, Field->TableOffset, Field->Flags,
959efcc2a30SJung-uk Kim             Field->Name, Field->Value);
960efcc2a30SJung-uk Kim 
961efcc2a30SJung-uk Kim         Field = Field->Next;
962efcc2a30SJung-uk Kim     }
963efcc2a30SJung-uk Kim 
964efcc2a30SJung-uk Kim     DbgPrint (ASL_DEBUG_OUTPUT,  "\n\n");
965efcc2a30SJung-uk Kim }
966efcc2a30SJung-uk Kim 
967efcc2a30SJung-uk Kim 
968efcc2a30SJung-uk Kim /******************************************************************************
969efcc2a30SJung-uk Kim  *
970efcc2a30SJung-uk Kim  * FUNCTION:    DtDumpSubtableInfo, DtDumpSubtableTree
971efcc2a30SJung-uk Kim  *
972efcc2a30SJung-uk Kim  * PARAMETERS:  DT_WALK_CALLBACK
973efcc2a30SJung-uk Kim  *
974efcc2a30SJung-uk Kim  * RETURN:      None
975efcc2a30SJung-uk Kim  *
976efcc2a30SJung-uk Kim  * DESCRIPTION: Info - dump a subtable tree entry with extra information.
977efcc2a30SJung-uk Kim  *              Tree - dump a subtable tree formatted by depth indentation.
978efcc2a30SJung-uk Kim  *
979efcc2a30SJung-uk Kim  *****************************************************************************/
980efcc2a30SJung-uk Kim 
981efcc2a30SJung-uk Kim static void
982efcc2a30SJung-uk Kim DtDumpSubtableInfo (
983efcc2a30SJung-uk Kim     DT_SUBTABLE             *Subtable,
984efcc2a30SJung-uk Kim     void                    *Context,
985efcc2a30SJung-uk Kim     void                    *ReturnValue)
986efcc2a30SJung-uk Kim {
987efcc2a30SJung-uk Kim 
988efcc2a30SJung-uk Kim     DbgPrint (ASL_DEBUG_OUTPUT,
989a371a5fdSJung-uk Kim         "[%.04X] %24s %.08X %.08X %.08X %.08X %.08X %p %p %p\n",
990a371a5fdSJung-uk Kim         Subtable->Depth, Subtable->Name, Subtable->Length, Subtable->TotalLength,
991efcc2a30SJung-uk Kim         Subtable->SizeOfLengthField, Subtable->Flags, Subtable,
992efcc2a30SJung-uk Kim         Subtable->Parent, Subtable->Child, Subtable->Peer);
993efcc2a30SJung-uk Kim }
994efcc2a30SJung-uk Kim 
995efcc2a30SJung-uk Kim static void
996efcc2a30SJung-uk Kim DtDumpSubtableTree (
997efcc2a30SJung-uk Kim     DT_SUBTABLE             *Subtable,
998efcc2a30SJung-uk Kim     void                    *Context,
999efcc2a30SJung-uk Kim     void                    *ReturnValue)
1000efcc2a30SJung-uk Kim {
1001efcc2a30SJung-uk Kim 
1002efcc2a30SJung-uk Kim     DbgPrint (ASL_DEBUG_OUTPUT,
1003a371a5fdSJung-uk Kim         "[%.04X] %24s %*s%08X (%.02X) - (%.02X)\n",
1004a371a5fdSJung-uk Kim         Subtable->Depth, Subtable->Name, (4 * Subtable->Depth), " ",
1005efcc2a30SJung-uk Kim         Subtable, Subtable->Length, Subtable->TotalLength);
1006efcc2a30SJung-uk Kim }
1007efcc2a30SJung-uk Kim 
1008efcc2a30SJung-uk Kim 
1009efcc2a30SJung-uk Kim /******************************************************************************
1010efcc2a30SJung-uk Kim  *
1011efcc2a30SJung-uk Kim  * FUNCTION:    DtDumpSubtableList
1012efcc2a30SJung-uk Kim  *
1013efcc2a30SJung-uk Kim  * PARAMETERS:  None
1014efcc2a30SJung-uk Kim  *
1015efcc2a30SJung-uk Kim  * RETURN:      None
1016efcc2a30SJung-uk Kim  *
1017efcc2a30SJung-uk Kim  * DESCRIPTION: Dump the raw list of subtables with information, and also
1018efcc2a30SJung-uk Kim  *              dump the subtable list in formatted tree format. Assists with
1019efcc2a30SJung-uk Kim  *              the development of new table code.
1020efcc2a30SJung-uk Kim  *
1021efcc2a30SJung-uk Kim  *****************************************************************************/
1022efcc2a30SJung-uk Kim 
1023efcc2a30SJung-uk Kim void
1024efcc2a30SJung-uk Kim DtDumpSubtableList (
1025efcc2a30SJung-uk Kim     void)
1026efcc2a30SJung-uk Kim {
1027efcc2a30SJung-uk Kim 
1028efcc2a30SJung-uk Kim     if (!Gbl_DebugFlag || !Gbl_RootTable)
1029efcc2a30SJung-uk Kim     {
1030efcc2a30SJung-uk Kim         return;
1031efcc2a30SJung-uk Kim     }
1032efcc2a30SJung-uk Kim 
1033efcc2a30SJung-uk Kim     DbgPrint (ASL_DEBUG_OUTPUT,
1034efcc2a30SJung-uk Kim         "Subtable Info:\n"
1035a371a5fdSJung-uk Kim         "Depth                      Name Length   TotalLen LenSize  Flags    "
1036efcc2a30SJung-uk Kim         "This     Parent   Child    Peer\n\n");
1037efcc2a30SJung-uk Kim     DtWalkTableTree (Gbl_RootTable, DtDumpSubtableInfo, NULL, NULL);
1038efcc2a30SJung-uk Kim 
1039efcc2a30SJung-uk Kim     DbgPrint (ASL_DEBUG_OUTPUT,
1040a371a5fdSJung-uk Kim         "\nSubtable Tree: (Depth, Name, Subtable, Length, TotalLength)\n\n");
1041efcc2a30SJung-uk Kim     DtWalkTableTree (Gbl_RootTable, DtDumpSubtableTree, NULL, NULL);
1042313a0c13SJung-uk Kim 
1043313a0c13SJung-uk Kim     DbgPrint (ASL_DEBUG_OUTPUT, "\n");
1044efcc2a30SJung-uk Kim }
1045efcc2a30SJung-uk Kim 
1046efcc2a30SJung-uk Kim 
1047efcc2a30SJung-uk Kim /******************************************************************************
1048efcc2a30SJung-uk Kim  *
1049d244b227SJung-uk Kim  * FUNCTION:    DtWriteFieldToListing
1050d244b227SJung-uk Kim  *
1051d244b227SJung-uk Kim  * PARAMETERS:  Buffer              - Contains the compiled data
1052d244b227SJung-uk Kim  *              Field               - Field node for the input line
1053d244b227SJung-uk Kim  *              Length              - Length of the output data
1054d244b227SJung-uk Kim  *
1055d244b227SJung-uk Kim  * RETURN:      None
1056d244b227SJung-uk Kim  *
1057d244b227SJung-uk Kim  * DESCRIPTION: Write one field to the listing file (if listing is enabled).
1058d244b227SJung-uk Kim  *
1059d244b227SJung-uk Kim  *****************************************************************************/
1060d244b227SJung-uk Kim 
1061d244b227SJung-uk Kim void
1062d244b227SJung-uk Kim DtWriteFieldToListing (
1063d244b227SJung-uk Kim     UINT8                   *Buffer,
1064d244b227SJung-uk Kim     DT_FIELD                *Field,
1065d244b227SJung-uk Kim     UINT32                  Length)
1066d244b227SJung-uk Kim {
1067d244b227SJung-uk Kim     UINT8                   FileByte;
1068d244b227SJung-uk Kim 
1069d244b227SJung-uk Kim 
1070d244b227SJung-uk Kim     if (!Gbl_ListingFlag || !Field)
1071d244b227SJung-uk Kim     {
1072d244b227SJung-uk Kim         return;
1073d244b227SJung-uk Kim     }
1074d244b227SJung-uk Kim 
1075d244b227SJung-uk Kim     /* Dump the original source line */
1076d244b227SJung-uk Kim 
1077d244b227SJung-uk Kim     FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Input:  ");
1078d244b227SJung-uk Kim     FlSeekFile (ASL_FILE_INPUT, Field->ByteOffset);
1079d244b227SJung-uk Kim 
1080d244b227SJung-uk Kim     while (FlReadFile (ASL_FILE_INPUT, &FileByte, 1) == AE_OK)
1081d244b227SJung-uk Kim     {
1082d244b227SJung-uk Kim         FlWriteFile (ASL_FILE_LISTING_OUTPUT, &FileByte, 1);
1083d244b227SJung-uk Kim         if (FileByte == '\n')
1084d244b227SJung-uk Kim         {
1085d244b227SJung-uk Kim             break;
1086d244b227SJung-uk Kim         }
1087d244b227SJung-uk Kim     }
1088d244b227SJung-uk Kim 
1089d244b227SJung-uk Kim     /* Dump the line as parsed and represented internally */
1090d244b227SJung-uk Kim 
1091d052a1ccSJung-uk Kim     FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Parsed: %*s : %.64s",
1092d244b227SJung-uk Kim         Field->Column-4, Field->Name, Field->Value);
1093d244b227SJung-uk Kim 
1094d052a1ccSJung-uk Kim     if (strlen (Field->Value) > 64)
1095d052a1ccSJung-uk Kim     {
1096d052a1ccSJung-uk Kim         FlPrintFile (ASL_FILE_LISTING_OUTPUT, "...Additional data, length 0x%X\n",
1097d052a1ccSJung-uk Kim             strlen (Field->Value));
1098d052a1ccSJung-uk Kim     }
1099*f8146b88SJung-uk Kim 
1100d052a1ccSJung-uk Kim     FlPrintFile (ASL_FILE_LISTING_OUTPUT, "\n");
1101d052a1ccSJung-uk Kim 
1102d244b227SJung-uk Kim     /* Dump the hex data that will be output for this field */
1103d244b227SJung-uk Kim 
11040b94ba42SJung-uk Kim     DtDumpBuffer (ASL_FILE_LISTING_OUTPUT, Buffer, Field->TableOffset, Length);
1105d244b227SJung-uk Kim }
1106d244b227SJung-uk Kim 
1107d244b227SJung-uk Kim 
1108d244b227SJung-uk Kim /******************************************************************************
1109d244b227SJung-uk Kim  *
1110d244b227SJung-uk Kim  * FUNCTION:    DtWriteTableToListing
1111d244b227SJung-uk Kim  *
1112d244b227SJung-uk Kim  * PARAMETERS:  None
1113d244b227SJung-uk Kim  *
1114d244b227SJung-uk Kim  * RETURN:      None
1115d244b227SJung-uk Kim  *
1116d244b227SJung-uk Kim  * DESCRIPTION: Write the entire compiled table to the listing file
1117d244b227SJung-uk Kim  *              in hex format
1118d244b227SJung-uk Kim  *
1119d244b227SJung-uk Kim  *****************************************************************************/
1120d244b227SJung-uk Kim 
1121d244b227SJung-uk Kim void
1122d244b227SJung-uk Kim DtWriteTableToListing (
1123d244b227SJung-uk Kim     void)
1124d244b227SJung-uk Kim {
1125d244b227SJung-uk Kim     UINT8                   *Buffer;
1126d244b227SJung-uk Kim 
1127d244b227SJung-uk Kim 
1128d244b227SJung-uk Kim     if (!Gbl_ListingFlag)
1129d244b227SJung-uk Kim     {
1130d244b227SJung-uk Kim         return;
1131d244b227SJung-uk Kim     }
1132d244b227SJung-uk Kim 
1133d244b227SJung-uk Kim     /* Read the entire table from the output file */
1134d244b227SJung-uk Kim 
1135d244b227SJung-uk Kim     Buffer = UtLocalCalloc (Gbl_TableLength);
1136d244b227SJung-uk Kim     FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
1137d244b227SJung-uk Kim     FlReadFile (ASL_FILE_AML_OUTPUT, Buffer, Gbl_TableLength);
1138d244b227SJung-uk Kim 
1139d244b227SJung-uk Kim     /* Dump the raw table data */
1140d244b227SJung-uk Kim 
1141d244b227SJung-uk Kim     AcpiOsRedirectOutput (Gbl_Files[ASL_FILE_LISTING_OUTPUT].Handle);
1142d244b227SJung-uk Kim 
1143d244b227SJung-uk Kim     AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n",
1144d244b227SJung-uk Kim         ACPI_RAW_TABLE_DATA_HEADER, Gbl_TableLength, Gbl_TableLength);
11458ef1a331SJung-uk Kim     AcpiUtDumpBuffer (Buffer, Gbl_TableLength, DB_BYTE_DISPLAY, 0);
1146d244b227SJung-uk Kim 
1147d244b227SJung-uk Kim     AcpiOsRedirectOutput (stdout);
11488d744e47SJung-uk Kim     ACPI_FREE (Buffer);
1149d244b227SJung-uk Kim }
1150