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