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