1 /******************************************************************************
2 *
3 * Module Name: dtio.c - File I/O support for data table compiler
4 *
5 *****************************************************************************/
6
7 /******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2026, Intel Corp.
12 * All rights reserved.
13 *
14 * 2. License
15 *
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights. You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
19 * property rights.
20 *
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
27 *
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code. No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
36 *
37 * The above copyright and patent license is granted only if the following
38 * conditions are met:
39 *
40 * 3. Conditions
41 *
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision. In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change. Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee. Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
53 *
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution. In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
64 * make.
65 *
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3.4. Intel retains all right, title, and interest in and to the Original
73 * Intel Code.
74 *
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
79 *
80 * 4. Disclaimer and Export Compliance
81 *
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88 * PARTICULAR PURPOSE.
89 *
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97 * LIMITED REMEDY.
98 *
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government. In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
113 *
114 *****************************************************************************
115 *
116 * Alternatively, you may choose to be licensed under the terms of the
117 * following license:
118 *
119 * Redistribution and use in source and binary forms, with or without
120 * modification, are permitted provided that the following conditions
121 * are met:
122 * 1. Redistributions of source code must retain the above copyright
123 * notice, this list of conditions, and the following disclaimer,
124 * without modification.
125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126 * substantially similar to the "NO WARRANTY" disclaimer below
127 * ("Disclaimer") and any redistribution must be conditioned upon
128 * including a substantially similar Disclaimer requirement for further
129 * binary redistribution.
130 * 3. Neither the names of the above-listed copyright holders nor the names
131 * of any contributors may be used to endorse or promote products derived
132 * from this software without specific prior written permission.
133 *
134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145 *
146 * Alternatively, you may choose to be licensed under the terms of the
147 * GNU General Public License ("GPL") version 2 as published by the Free
148 * Software Foundation.
149 *
150 *****************************************************************************/
151
152 #include <contrib/dev/acpica/compiler/aslcompiler.h>
153 #include <contrib/dev/acpica/include/acapps.h>
154
155 #define _COMPONENT DT_COMPILER
156 ACPI_MODULE_NAME ("dtio")
157
158
159 /* Local prototypes */
160
161 static char *
162 DtTrim (
163 char *String);
164
165 static ACPI_STATUS
166 DtParseLine (
167 char *LineBuffer,
168 UINT32 Line,
169 UINT32 Offset);
170
171 static void
172 DtWriteBinary (
173 DT_SUBTABLE *Subtable,
174 void *Context,
175 void *ReturnValue);
176
177 static void
178 DtDumpBuffer (
179 UINT32 FileId,
180 UINT8 *Buffer,
181 UINT32 Offset,
182 UINT32 Length);
183
184 static void
185 DtDumpSubtableInfo (
186 DT_SUBTABLE *Subtable,
187 void *Context,
188 void *ReturnValue);
189
190 static void
191 DtDumpSubtableTree (
192 DT_SUBTABLE *Subtable,
193 void *Context,
194 void *ReturnValue);
195
196
197 /* States for DtGetNextLine */
198
199 #define DT_NORMAL_TEXT 0
200 #define DT_START_QUOTED_STRING 1
201 #define DT_START_COMMENT 2
202 #define DT_SLASH_ASTERISK_COMMENT 3
203 #define DT_SLASH_SLASH_COMMENT 4
204 #define DT_END_COMMENT 5
205 #define DT_MERGE_LINES 6
206 #define DT_ESCAPE_SEQUENCE 7
207
208 static UINT32 AslGbl_NextLineOffset;
209
210
211 /******************************************************************************
212 *
213 * FUNCTION: DtTrim
214 *
215 * PARAMETERS: String - Current source code line to trim
216 *
217 * RETURN: Trimmed line. Must be freed by caller.
218 *
219 * DESCRIPTION: Trim left and right spaces
220 *
221 *****************************************************************************/
222
223 static char *
DtTrim(char * String)224 DtTrim (
225 char *String)
226 {
227 char *Start;
228 char *End;
229 char *ReturnString;
230 ACPI_SIZE Length;
231
232
233 /* Skip lines that start with a space */
234
235 if (*String == 0 || !strcmp (String, " "))
236 {
237 ReturnString = UtLocalCacheCalloc (1);
238 return (ReturnString);
239 }
240
241 /* Setup pointers to start and end of input string */
242
243 Start = String;
244 End = String + strlen (String) - 1;
245
246 /* Find first non-whitespace character */
247
248 while ((Start <= End) && ((*Start == ' ') || (*Start == '\t')))
249 {
250 Start++;
251 }
252
253 /* Find last non-space character */
254
255 while (End >= Start)
256 {
257 if (*End == '\n')
258 {
259 End--;
260 continue;
261 }
262
263 if (*End != ' ')
264 {
265 break;
266 }
267
268 End--;
269 }
270
271 /* Remove any quotes around the string */
272
273 if (*Start == '\"')
274 {
275 Start++;
276 }
277 if (*End == '\"')
278 {
279 End--;
280 }
281
282 /* Create the trimmed return string */
283
284 Length = ACPI_PTR_DIFF (End, Start) + 1;
285 ReturnString = UtLocalCacheCalloc (Length + 1);
286 if (strlen (Start))
287 {
288 memcpy (ReturnString, Start, Length);
289 }
290
291 ReturnString[Length] = 0;
292 return (ReturnString);
293 }
294
295
296 /******************************************************************************
297 *
298 * FUNCTION: DtParseLine
299 *
300 * PARAMETERS: LineBuffer - Current source code line
301 * Line - Current line number in the source
302 * Offset - Current byte offset of the line
303 *
304 * RETURN: Status
305 *
306 * DESCRIPTION: Parse one source line
307 *
308 *****************************************************************************/
309
310 static ACPI_STATUS
DtParseLine(char * LineBuffer,UINT32 Line,UINT32 Offset)311 DtParseLine (
312 char *LineBuffer,
313 UINT32 Line,
314 UINT32 Offset)
315 {
316 char *Start;
317 char *End;
318 char *TmpName;
319 char *TmpValue;
320 char *Name;
321 char *Value;
322 char *Colon;
323 UINT32 Length;
324 DT_FIELD *Field;
325 UINT32 Column;
326 UINT32 NameColumn;
327 BOOLEAN IsNullString = FALSE;
328
329
330 if (!LineBuffer)
331 {
332 return (AE_OK);
333 }
334
335 /* All lines after "Raw Table Data" are ignored */
336
337 if (strstr (LineBuffer, ACPI_RAW_TABLE_DATA_HEADER))
338 {
339 return (AE_NOT_FOUND);
340 }
341
342 Colon = strchr (LineBuffer, ':');
343 if (!Colon)
344 {
345 return (AE_OK);
346 }
347
348 Start = LineBuffer;
349 End = Colon;
350
351 while (Start < Colon)
352 {
353 if (*Start == '[')
354 {
355 /* Found left bracket, go to the right bracket */
356
357 while (Start < Colon && *Start != ']')
358 {
359 Start++;
360 }
361 }
362 else if (*Start != ' ')
363 {
364 break;
365 }
366
367 Start++;
368 }
369
370 /*
371 * There are two column values. One for the field name,
372 * and one for the field value.
373 */
374 Column = ACPI_PTR_DIFF (Colon, LineBuffer) + 3;
375 NameColumn = ACPI_PTR_DIFF (Start, LineBuffer) + 1;
376
377 Length = ACPI_PTR_DIFF (End, Start);
378
379 TmpName = UtLocalCalloc (Length + 1);
380 memcpy (TmpName, Start, Length);
381 Name = DtTrim (TmpName);
382 ACPI_FREE (TmpName);
383
384 Start = End = (Colon + 1);
385 while (*End)
386 {
387 /* Found left quotation, go to the right quotation and break */
388
389 if (*End == '"')
390 {
391 End++;
392
393 /* Check for an explicit null string */
394
395 if (*End == '"')
396 {
397 IsNullString = TRUE;
398 }
399 while (*End && (*End != '"'))
400 {
401 End++;
402 }
403
404 End++;
405 break;
406 }
407
408 /*
409 * Special "comment" fields at line end, ignore them.
410 * Note: normal slash-slash and slash-asterisk comments are
411 * stripped already by the DtGetNextLine parser.
412 *
413 * TBD: Perhaps DtGetNextLine should parse the following type
414 * of comments also.
415 */
416 if (*End == '[')
417 {
418 End--;
419 break;
420 }
421
422 End++;
423 }
424
425 /* No value characters present */
426 if (End <= Start)
427 {
428 return (AE_OK);
429 }
430
431 Length = ACPI_PTR_DIFF (End, Start);
432 TmpValue = UtLocalCalloc (Length + 1);
433
434 memcpy (TmpValue, Start, Length);
435 Value = DtTrim (TmpValue);
436 ACPI_FREE (TmpValue);
437
438 /* Create a new field object only if we have a valid value field */
439
440 if ((Value && *Value) || IsNullString)
441 {
442 Field = UtFieldCacheCalloc ();
443 Field->Name = Name;
444 Field->Value = Value;
445 Field->Line = Line;
446 Field->ByteOffset = Offset;
447 Field->NameColumn = NameColumn;
448 Field->Column = Column;
449 Field->StringLength = Length;
450
451 DtLinkField (Field);
452 }
453 /* Else -- Ignore this field, it has no valid data */
454
455 return (AE_OK);
456 }
457
458
459 /******************************************************************************
460 *
461 * FUNCTION: DtGetNextLine
462 *
463 * PARAMETERS: Handle - Open file handle for the source file
464 *
465 * RETURN: Filled line buffer and offset of start-of-line (ASL_EOF on EOF)
466 *
467 * DESCRIPTION: Get the next valid source line. Removes all comments.
468 * Ignores empty lines.
469 *
470 * Handles both slash-asterisk and slash-slash comments.
471 * Also, quoted strings, but no escapes within.
472 *
473 * Line is returned in AslGbl_CurrentLineBuffer.
474 * Line number in original file is returned in AslGbl_CurrentLineNumber.
475 *
476 *****************************************************************************/
477
478 UINT32
DtGetNextLine(FILE * Handle,UINT32 Flags)479 DtGetNextLine (
480 FILE *Handle,
481 UINT32 Flags)
482 {
483 BOOLEAN LineNotAllBlanks = FALSE;
484 UINT32 State = DT_NORMAL_TEXT;
485 UINT32 CurrentLineOffset;
486 UINT32 i;
487 int c;
488 int c1;
489
490
491 memset (AslGbl_CurrentLineBuffer, 0, AslGbl_LineBufferSize);
492 for (i = 0; ;)
493 {
494 /*
495 * If line is too long, expand the line buffers. Also increases
496 * AslGbl_LineBufferSize.
497 */
498 if (i >= AslGbl_LineBufferSize)
499 {
500 UtExpandLineBuffers ();
501 }
502
503 c = getc (Handle);
504 if (c == EOF)
505 {
506 switch (State)
507 {
508 case DT_START_QUOTED_STRING:
509 case DT_SLASH_ASTERISK_COMMENT:
510
511 AcpiOsPrintf ("**** EOF within comment/string %u\n", State);
512 break;
513
514 default:
515
516 break;
517 }
518
519 /* Standalone EOF is OK */
520
521 if (i == 0)
522 {
523 return (ASL_EOF);
524 }
525
526 /*
527 * Received an EOF in the middle of a line. Terminate the
528 * line with a newline. The next call to this function will
529 * return a standalone EOF. Thus, the upper parsing software
530 * never has to deal with an EOF within a valid line (or
531 * the last line does not get tossed on the floor.)
532 */
533 c = '\n';
534 State = DT_NORMAL_TEXT;
535 }
536 else if (c == '\r')
537 {
538 c1 = getc (Handle);
539 if (c1 == '\n')
540 {
541 /*
542 * Skip the carriage return as if it didn't exist. This is
543 * onlt meant for input files in DOS format in unix. fopen in
544 * unix may not support "text mode" and leaves CRLF intact.
545 */
546 c = '\n';
547 }
548 else
549 {
550 /* This was not a CRLF. Only a CR */
551
552 ungetc(c1, Handle);
553
554 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL,
555 "Carriage return without linefeed detected");
556 return (ASL_EOF);
557 }
558 }
559
560 switch (State)
561 {
562 case DT_NORMAL_TEXT:
563
564 /* Normal text, insert char into line buffer */
565
566 AslGbl_CurrentLineBuffer[i] = (char) c;
567 switch (c)
568 {
569 case '/':
570
571 State = DT_START_COMMENT;
572 break;
573
574 case '"':
575
576 State = DT_START_QUOTED_STRING;
577 LineNotAllBlanks = TRUE;
578 i++;
579 break;
580
581 case '\\':
582 /*
583 * The continuation char MUST be last char on this line.
584 * Otherwise, it will be assumed to be a valid ASL char.
585 */
586 State = DT_MERGE_LINES;
587 break;
588
589 case '\n':
590
591 CurrentLineOffset = AslGbl_NextLineOffset;
592 AslGbl_NextLineOffset = (UINT32) ftell (Handle);
593 AslGbl_CurrentLineNumber++;
594
595 /*
596 * Exit if line is complete. Ignore empty lines (only \n)
597 * or lines that contain nothing but blanks.
598 */
599 if ((i != 0) && LineNotAllBlanks)
600 {
601 if ((i + 1) >= AslGbl_LineBufferSize)
602 {
603 UtExpandLineBuffers ();
604 }
605
606 AslGbl_CurrentLineBuffer[i+1] = 0; /* Terminate string */
607 return (CurrentLineOffset);
608 }
609
610 /* Toss this line and start a new one */
611
612 i = 0;
613 LineNotAllBlanks = FALSE;
614 break;
615
616 default:
617
618 if (c != ' ')
619 {
620 LineNotAllBlanks = TRUE;
621 }
622
623 i++;
624 break;
625 }
626 break;
627
628 case DT_START_QUOTED_STRING:
629
630 /* Insert raw chars until end of quoted string */
631
632 AslGbl_CurrentLineBuffer[i] = (char) c;
633 i++;
634
635 switch (c)
636 {
637 case '"':
638
639 State = DT_NORMAL_TEXT;
640 break;
641
642 case '\\':
643
644 State = DT_ESCAPE_SEQUENCE;
645 break;
646
647 case '\n':
648
649 if (!(Flags & DT_ALLOW_MULTILINE_QUOTES))
650 {
651 AcpiOsPrintf (
652 "ERROR at line %u: Unterminated quoted string\n",
653 AslGbl_CurrentLineNumber++);
654 State = DT_NORMAL_TEXT;
655 }
656 break;
657
658 default: /* Get next character */
659
660 break;
661 }
662 break;
663
664 case DT_ESCAPE_SEQUENCE:
665
666 /* Just copy the escaped character. TBD: sufficient for table compiler? */
667
668 AslGbl_CurrentLineBuffer[i] = (char) c;
669 i++;
670 State = DT_START_QUOTED_STRING;
671 break;
672
673 case DT_START_COMMENT:
674
675 /* Open comment if this character is an asterisk or slash */
676
677 switch (c)
678 {
679 case '*':
680
681 State = DT_SLASH_ASTERISK_COMMENT;
682 break;
683
684 case '/':
685
686 State = DT_SLASH_SLASH_COMMENT;
687 break;
688
689 default: /* Not a comment */
690
691 i++; /* Save the preceding slash */
692 if (i >= AslGbl_LineBufferSize)
693 {
694 UtExpandLineBuffers ();
695 }
696
697 AslGbl_CurrentLineBuffer[i] = (char) c;
698 i++;
699 State = DT_NORMAL_TEXT;
700 break;
701 }
702 break;
703
704 case DT_SLASH_ASTERISK_COMMENT:
705
706 /* Ignore chars until an asterisk-slash is found */
707
708 switch (c)
709 {
710 case '\n':
711
712 AslGbl_NextLineOffset = (UINT32) ftell (Handle);
713 AslGbl_CurrentLineNumber++;
714 break;
715
716 case '*':
717
718 State = DT_END_COMMENT;
719 break;
720
721 default:
722
723 break;
724 }
725 break;
726
727 case DT_SLASH_SLASH_COMMENT:
728
729 /* Ignore chars until end-of-line */
730
731 if (c == '\n')
732 {
733 /* We will exit via the NORMAL_TEXT path */
734
735 ungetc (c, Handle);
736 State = DT_NORMAL_TEXT;
737 }
738 break;
739
740 case DT_END_COMMENT:
741
742 /* End comment if this char is a slash */
743
744 switch (c)
745 {
746 case '/':
747
748 State = DT_NORMAL_TEXT;
749 break;
750
751 case '\n':
752
753 AslGbl_NextLineOffset = (UINT32) ftell (Handle);
754 AslGbl_CurrentLineNumber++;
755 break;
756
757 case '*':
758
759 /* Consume all adjacent asterisks */
760 break;
761
762 default:
763
764 State = DT_SLASH_ASTERISK_COMMENT;
765 break;
766 }
767 break;
768
769 case DT_MERGE_LINES:
770
771 if (c != '\n')
772 {
773 /*
774 * This is not a continuation backslash, it is a normal
775 * normal ASL backslash - for example: Scope(\_SB_)
776 */
777 i++; /* Keep the backslash that is already in the buffer */
778
779 ungetc (c, Handle);
780 State = DT_NORMAL_TEXT;
781 }
782 else
783 {
784 /*
785 * This is a continuation line -- a backlash followed
786 * immediately by a newline. Insert a space between the
787 * lines (overwrite the backslash)
788 */
789 AslGbl_CurrentLineBuffer[i] = ' ';
790 i++;
791
792 /* Ignore newline, this will merge the lines */
793
794 AslGbl_NextLineOffset = (UINT32) ftell (Handle);
795 AslGbl_CurrentLineNumber++;
796 State = DT_NORMAL_TEXT;
797 }
798 break;
799
800 default:
801
802 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, "Unknown input state");
803 return (ASL_EOF);
804 }
805 }
806 }
807
808
809 /******************************************************************************
810 *
811 * FUNCTION: DtScanFile
812 *
813 * PARAMETERS: Handle - Open file handle for the source file
814 *
815 * RETURN: Pointer to start of the constructed parse tree.
816 *
817 * DESCRIPTION: Scan source file, link all field names and values
818 * to the global parse tree: AslGbl_FieldList
819 *
820 *****************************************************************************/
821
822 DT_FIELD *
DtScanFile(FILE * Handle)823 DtScanFile (
824 FILE *Handle)
825 {
826 ACPI_STATUS Status;
827 UINT32 Offset;
828
829
830 ACPI_FUNCTION_NAME (DtScanFile);
831
832
833 /* Get the file size */
834
835 AslGbl_InputByteCount = CmGetFileSize (Handle);
836 if (AslGbl_InputByteCount == ACPI_UINT32_MAX)
837 {
838 AslAbort ();
839 }
840
841 AslGbl_CurrentLineNumber = 0;
842 AslGbl_CurrentLineOffset = 0;
843 AslGbl_NextLineOffset = 0;
844
845 /* Scan line-by-line */
846
847 while ((Offset = DtGetNextLine (Handle, 0)) != ASL_EOF)
848 {
849 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Line %2.2u/%4.4X - %s",
850 AslGbl_CurrentLineNumber, Offset, AslGbl_CurrentLineBuffer));
851
852 Status = DtParseLine (AslGbl_CurrentLineBuffer,
853 AslGbl_CurrentLineNumber, Offset);
854 if (Status == AE_NOT_FOUND)
855 {
856 break;
857 }
858 }
859
860 /* Dump the parse tree if debug enabled */
861
862 DtDumpFieldList (AslGbl_FieldList);
863 return (AslGbl_FieldList);
864 }
865
866
867 /*
868 * Output functions
869 */
870
871 /******************************************************************************
872 *
873 * FUNCTION: DtWriteBinary
874 *
875 * PARAMETERS: DT_WALK_CALLBACK
876 *
877 * RETURN: Status
878 *
879 * DESCRIPTION: Write one subtable of a binary ACPI table
880 *
881 *****************************************************************************/
882
883 static void
DtWriteBinary(DT_SUBTABLE * Subtable,void * Context,void * ReturnValue)884 DtWriteBinary (
885 DT_SUBTABLE *Subtable,
886 void *Context,
887 void *ReturnValue)
888 {
889
890 FlWriteFile (ASL_FILE_AML_OUTPUT, Subtable->Buffer, Subtable->Length);
891 }
892
893
894 /******************************************************************************
895 *
896 * FUNCTION: DtOutputBinary
897 *
898 * PARAMETERS:
899 *
900 * RETURN: Status
901 *
902 * DESCRIPTION: Write entire binary ACPI table (result of compilation)
903 *
904 *****************************************************************************/
905
906 void
DtOutputBinary(DT_SUBTABLE * RootTable)907 DtOutputBinary (
908 DT_SUBTABLE *RootTable)
909 {
910
911 if (!RootTable)
912 {
913 return;
914 }
915
916 /* Walk the entire parse tree, emitting the binary data */
917
918 DtWalkTableTree (RootTable, DtWriteBinary, NULL, NULL);
919
920 AslGbl_TableLength = CmGetFileSize (AslGbl_Files[ASL_FILE_AML_OUTPUT].Handle);
921 if (AslGbl_TableLength == ACPI_UINT32_MAX)
922 {
923 AslAbort ();
924 }
925 }
926
927
928 /*
929 * Listing support
930 */
931
932 /******************************************************************************
933 *
934 * FUNCTION: DtDumpBuffer
935 *
936 * PARAMETERS: FileID - Where to write buffer data
937 * Buffer - Buffer to dump
938 * Offset - Offset in current table
939 * Length - Buffer Length
940 *
941 * RETURN: None
942 *
943 * DESCRIPTION: Another copy of DumpBuffer routine (unfortunately).
944 *
945 * TBD: merge dump buffer routines
946 *
947 *****************************************************************************/
948
949 static void
DtDumpBuffer(UINT32 FileId,UINT8 * Buffer,UINT32 Offset,UINT32 Length)950 DtDumpBuffer (
951 UINT32 FileId,
952 UINT8 *Buffer,
953 UINT32 Offset,
954 UINT32 Length)
955 {
956 UINT32 i;
957 UINT32 j;
958 UINT8 BufChar;
959
960
961 FlPrintFile (FileId, "Output: [%3.3Xh %4.4d %3.3Xh] ",
962 Offset, Offset, Length);
963
964 i = 0;
965 while (i < Length)
966 {
967 if (i >= 16)
968 {
969 FlPrintFile (FileId, "%24s", "");
970 }
971
972 /* Print 16 hex chars */
973
974 for (j = 0; j < 16;)
975 {
976 if (i + j >= Length)
977 {
978 /* Dump fill spaces */
979
980 FlPrintFile (FileId, " ");
981 j++;
982 continue;
983 }
984
985 FlPrintFile (FileId, "%02X ", Buffer[i+j]);
986 j++;
987 }
988
989 FlPrintFile (FileId, " ");
990 for (j = 0; j < 16; j++)
991 {
992 if (i + j >= Length)
993 {
994 FlPrintFile (FileId, "\n\n");
995 return;
996 }
997
998 BufChar = Buffer[(ACPI_SIZE) i + j];
999 if (isprint (BufChar))
1000 {
1001 FlPrintFile (FileId, "%c", BufChar);
1002 }
1003 else
1004 {
1005 FlPrintFile (FileId, ".");
1006 }
1007 }
1008
1009 /* Done with that line. */
1010
1011 FlPrintFile (FileId, "\n");
1012 i += 16;
1013 }
1014
1015 FlPrintFile (FileId, "\n\n");
1016 }
1017
1018
1019 /******************************************************************************
1020 *
1021 * FUNCTION: DtDumpFieldList
1022 *
1023 * PARAMETERS: Field - Root field
1024 *
1025 * RETURN: None
1026 *
1027 * DESCRIPTION: Dump the entire field list
1028 *
1029 *****************************************************************************/
1030
1031 void
DtDumpFieldList(DT_FIELD * Field)1032 DtDumpFieldList (
1033 DT_FIELD *Field)
1034 {
1035
1036 if (!AslGbl_DebugFlag || !Field)
1037 {
1038 return;
1039 }
1040
1041 DbgPrint (ASL_DEBUG_OUTPUT, "\nField List:\n"
1042 "LineNo ByteOff NameCol Column TableOff "
1043 "Flags %32s : %s\n\n", "Name", "Value");
1044
1045 while (Field)
1046 {
1047 DbgPrint (ASL_DEBUG_OUTPUT,
1048 "%.08X %.08X %.08X %.08X %.08X %2.2X %32s : %s\n",
1049 Field->Line, Field->ByteOffset, Field->NameColumn,
1050 Field->Column, Field->TableOffset, Field->Flags,
1051 Field->Name, Field->Value);
1052
1053 Field = Field->Next;
1054 }
1055
1056 DbgPrint (ASL_DEBUG_OUTPUT, "\n\n");
1057 }
1058
1059
1060 /******************************************************************************
1061 *
1062 * FUNCTION: DtDumpSubtableInfo, DtDumpSubtableTree
1063 *
1064 * PARAMETERS: DT_WALK_CALLBACK
1065 *
1066 * RETURN: None
1067 *
1068 * DESCRIPTION: Info - dump a subtable tree entry with extra information.
1069 * Tree - dump a subtable tree formatted by depth indentation.
1070 *
1071 *****************************************************************************/
1072
1073 static void
DtDumpSubtableInfo(DT_SUBTABLE * Subtable,void * Context,void * ReturnValue)1074 DtDumpSubtableInfo (
1075 DT_SUBTABLE *Subtable,
1076 void *Context,
1077 void *ReturnValue)
1078 {
1079
1080 DbgPrint (ASL_DEBUG_OUTPUT,
1081 "[%.04X] %24s %.08X %.08X %.08X %.08X %p %p %p %p\n",
1082 Subtable->Depth, Subtable->Name, Subtable->Length, Subtable->TotalLength,
1083 Subtable->SizeOfLengthField, Subtable->Flags, Subtable,
1084 Subtable->Parent, Subtable->Child, Subtable->Peer);
1085 }
1086
1087 static void
DtDumpSubtableTree(DT_SUBTABLE * Subtable,void * Context,void * ReturnValue)1088 DtDumpSubtableTree (
1089 DT_SUBTABLE *Subtable,
1090 void *Context,
1091 void *ReturnValue)
1092 {
1093
1094 DbgPrint (ASL_DEBUG_OUTPUT,
1095 "[%.04X] %24s %*s%p (%.02X) - (%.02X) %.02X\n",
1096 Subtable->Depth, Subtable->Name, (4 * Subtable->Depth), " ",
1097 Subtable, Subtable->Length, Subtable->TotalLength, *Subtable->Buffer);
1098 }
1099
1100
1101 /******************************************************************************
1102 *
1103 * FUNCTION: DtDumpSubtableList
1104 *
1105 * PARAMETERS: None
1106 *
1107 * RETURN: None
1108 *
1109 * DESCRIPTION: Dump the raw list of subtables with information, and also
1110 * dump the subtable list in formatted tree format. Assists with
1111 * the development of new table code.
1112 *
1113 *****************************************************************************/
1114
1115 void
DtDumpSubtableList(void)1116 DtDumpSubtableList (
1117 void)
1118 {
1119
1120 if (!AslGbl_DebugFlag || !AslGbl_RootTable)
1121 {
1122 return;
1123 }
1124
1125 DbgPrint (ASL_DEBUG_OUTPUT,
1126 "Subtable Info:\n"
1127 "Depth Name Length TotalLen LenSize Flags "
1128 "This Parent Child Peer\n\n");
1129 DtWalkTableTree (AslGbl_RootTable, DtDumpSubtableInfo, NULL, NULL);
1130
1131 DbgPrint (ASL_DEBUG_OUTPUT,
1132 "\nSubtable Tree: (Depth, Name, Subtable, Length, TotalLength, Integer Value)\n\n");
1133 DtWalkTableTree (AslGbl_RootTable, DtDumpSubtableTree, NULL, NULL);
1134
1135 DbgPrint (ASL_DEBUG_OUTPUT, "\n");
1136 }
1137
1138
1139 /******************************************************************************
1140 *
1141 * FUNCTION: DtWriteFieldToListing
1142 *
1143 * PARAMETERS: Buffer - Contains the compiled data
1144 * Field - Field node for the input line
1145 * Length - Length of the output data
1146 *
1147 * RETURN: None
1148 *
1149 * DESCRIPTION: Write one field to the listing file (if listing is enabled).
1150 *
1151 *****************************************************************************/
1152
1153 void
DtWriteFieldToListing(UINT8 * Buffer,DT_FIELD * Field,UINT32 Length)1154 DtWriteFieldToListing (
1155 UINT8 *Buffer,
1156 DT_FIELD *Field,
1157 UINT32 Length)
1158 {
1159 UINT8 FileByte;
1160
1161
1162 if (!AslGbl_ListingFlag || !Field)
1163 {
1164 return;
1165 }
1166
1167 /* Dump the original source line */
1168
1169 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Input: ");
1170 FlSeekFile (ASL_FILE_INPUT, Field->ByteOffset);
1171
1172 while (FlReadFile (ASL_FILE_INPUT, &FileByte, 1) == AE_OK)
1173 {
1174 FlWriteFile (ASL_FILE_LISTING_OUTPUT, &FileByte, 1);
1175 if (FileByte == '\n')
1176 {
1177 break;
1178 }
1179 }
1180
1181 /* Dump the line as parsed and represented internally */
1182
1183 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Parsed: %*s : %.64s",
1184 Field->Column-4, Field->Name, Field->Value);
1185
1186 if (strlen (Field->Value) > 64)
1187 {
1188 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "...Additional data, length 0x%X\n",
1189 (UINT32) strlen (Field->Value));
1190 }
1191
1192 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "\n");
1193
1194 /* Dump the hex data that will be output for this field */
1195
1196 DtDumpBuffer (ASL_FILE_LISTING_OUTPUT, Buffer, Field->TableOffset, Length);
1197 }
1198
1199
1200 /******************************************************************************
1201 *
1202 * FUNCTION: DtWriteTableToListing
1203 *
1204 * PARAMETERS: None
1205 *
1206 * RETURN: None
1207 *
1208 * DESCRIPTION: Write the entire compiled table to the listing file
1209 * in hex format
1210 *
1211 *****************************************************************************/
1212
1213 void
DtWriteTableToListing(void)1214 DtWriteTableToListing (
1215 void)
1216 {
1217 UINT8 *Buffer;
1218
1219
1220 if (!AslGbl_ListingFlag)
1221 {
1222 return;
1223 }
1224
1225 /* Read the entire table from the output file */
1226
1227 Buffer = UtLocalCalloc (AslGbl_TableLength);
1228 FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
1229 FlReadFile (ASL_FILE_AML_OUTPUT, Buffer, AslGbl_TableLength);
1230
1231 /* Dump the raw table data */
1232
1233 AcpiOsRedirectOutput (AslGbl_Files[ASL_FILE_LISTING_OUTPUT].Handle);
1234
1235 AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n",
1236 ACPI_RAW_TABLE_DATA_HEADER, AslGbl_TableLength, AslGbl_TableLength);
1237 AcpiUtDumpBuffer (Buffer, AslGbl_TableLength, DB_BYTE_DISPLAY, 0);
1238
1239 AcpiOsRedirectOutput (stdout);
1240 ACPI_FREE (Buffer);
1241 }
1242