dtio.c revision 1.1.1.3 1 /******************************************************************************
2 *
3 * Module Name: dtio.c - File I/O support for data table compiler
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2011, 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 #define __DTIO_C__
45
46 #include "aslcompiler.h"
47 #include "dtcompiler.h"
48
49 #define _COMPONENT DT_COMPILER
50 ACPI_MODULE_NAME ("dtio")
51
52
53 /* Local prototypes */
54
55 static char *
56 DtTrim (
57 char *String);
58
59 static void
60 DtLinkField (
61 DT_FIELD *Field);
62
63 static ACPI_STATUS
64 DtParseLine (
65 char *LineBuffer,
66 UINT32 Line,
67 UINT32 Offset);
68
69 UINT32
70 DtGetNextLine (
71 FILE *Handle);
72
73 static void
74 DtWriteBinary (
75 DT_SUBTABLE *Subtable,
76 void *Context,
77 void *ReturnValue);
78
79 static void
80 DtDumpBuffer (
81 UINT32 FileId,
82 UINT8 *Buffer,
83 UINT32 Offset,
84 UINT32 Length);
85
86
87 /* States for DtGetNextLine */
88
89 #define DT_NORMAL_TEXT 0
90 #define DT_START_QUOTED_STRING 1
91 #define DT_START_COMMENT 2
92 #define DT_SLASH_ASTERISK_COMMENT 3
93 #define DT_SLASH_SLASH_COMMENT 4
94 #define DT_END_COMMENT 5
95 #define DT_MERGE_LINES 6
96
97 static UINT32 Gbl_NextLineOffset;
98
99
100 /******************************************************************************
101 *
102 * FUNCTION: DtTrim
103 *
104 * PARAMETERS: String - Current source code line to trim
105 *
106 * RETURN: Trimmed line. Must be freed by caller.
107 *
108 * DESCRIPTION: Trim left and right spaces
109 *
110 *****************************************************************************/
111
112 static char *
113 DtTrim (
114 char *String)
115 {
116 char *Start;
117 char *End;
118 char *ReturnString;
119 ACPI_SIZE Length;
120
121
122 /* Skip lines that start with a space */
123
124 if (!ACPI_STRCMP (String, " "))
125 {
126 ReturnString = UtLocalCalloc (1);
127 return (ReturnString);
128 }
129
130 /* Setup pointers to start and end of input string */
131
132 Start = String;
133 End = String + ACPI_STRLEN (String) - 1;
134
135 /* Find first non-whitespace character */
136
137 while ((Start <= End) && ((*Start == ' ') || (*Start == '\t')))
138 {
139 Start++;
140 }
141
142 /* Find last non-space character */
143
144 while (End >= Start)
145 {
146 if (*End == '\r' || *End == '\n')
147 {
148 End--;
149 continue;
150 }
151
152 if (*End != ' ')
153 {
154 break;
155 }
156
157 End--;
158 }
159
160 /* Remove any quotes around the string */
161
162 if (*Start == '\"')
163 {
164 Start++;
165 }
166 if (*End == '\"')
167 {
168 End--;
169 }
170
171 /* Create the trimmed return string */
172
173 Length = ACPI_PTR_DIFF (End, Start) + 1;
174 ReturnString = UtLocalCalloc (Length + 1);
175 if (ACPI_STRLEN (Start))
176 {
177 ACPI_STRNCPY (ReturnString, Start, Length);
178 }
179
180 ReturnString[Length] = 0;
181 return (ReturnString);
182 }
183
184
185 /******************************************************************************
186 *
187 * FUNCTION: DtLinkField
188 *
189 * PARAMETERS: Field - New field object to link
190 *
191 * RETURN: None
192 *
193 * DESCRIPTION: Link one field name and value to the list
194 *
195 *****************************************************************************/
196
197 static void
198 DtLinkField (
199 DT_FIELD *Field)
200 {
201 DT_FIELD *Prev;
202 DT_FIELD *Next;
203
204
205 Prev = Next = Gbl_FieldList;
206
207 while (Next)
208 {
209 Prev = Next;
210 Next = Next->Next;
211 }
212
213 if (Prev)
214 {
215 Prev->Next = Field;
216 }
217 else
218 {
219 Gbl_FieldList = Field;
220 }
221 }
222
223
224 /******************************************************************************
225 *
226 * FUNCTION: DtParseLine
227 *
228 * PARAMETERS: LineBuffer - Current source code line
229 * Line - Current line number in the source
230 * Offset - Current byte offset of the line
231 *
232 * RETURN: Status
233 *
234 * DESCRIPTION: Parse one source line
235 *
236 *****************************************************************************/
237
238 static ACPI_STATUS
239 DtParseLine (
240 char *LineBuffer,
241 UINT32 Line,
242 UINT32 Offset)
243 {
244 char *Start;
245 char *End;
246 char *TmpName;
247 char *TmpValue;
248 char *Name;
249 char *Value;
250 char *Colon;
251 UINT32 Length;
252 DT_FIELD *Field;
253 UINT32 Column;
254 UINT32 NameColumn;
255 BOOLEAN IsNullString = FALSE;
256
257
258 if (!LineBuffer)
259 {
260 return (AE_OK);
261 }
262
263 /* All lines after "Raw Table Data" are ingored */
264
265 if (strstr (LineBuffer, ACPI_RAW_TABLE_DATA_HEADER))
266 {
267 return (AE_NOT_FOUND);
268 }
269
270 Colon = strchr (LineBuffer, ':');
271 if (!Colon)
272 {
273 return (AE_OK);
274 }
275
276 Start = LineBuffer;
277 End = Colon;
278
279 while (Start < Colon)
280 {
281 if (*Start == ' ')
282 {
283 Start++;
284 continue;
285 }
286
287 /* Found left bracket, go to the right bracket */
288
289 if (*Start == '[')
290 {
291 while (Start < Colon && *Start != ']')
292 {
293 Start++;
294 }
295
296 if (Start == Colon)
297 {
298 break;
299 }
300
301 Start++;
302 continue;
303 }
304
305 break;
306 }
307
308 /*
309 * There are two column values. One for the field name,
310 * and one for the field value.
311 */
312 Column = ACPI_PTR_DIFF (Colon, LineBuffer) + 3;
313 NameColumn = ACPI_PTR_DIFF (Start, LineBuffer) + 1;
314
315 Length = ACPI_PTR_DIFF (End, Start);
316
317 TmpName = UtLocalCalloc (Length + 1);
318 ACPI_STRNCPY (TmpName, Start, Length);
319 Name = DtTrim (TmpName);
320 ACPI_FREE (TmpName);
321
322 Start = End = (Colon + 1);
323 while (*End)
324 {
325 /* Found left quotation, go to the right quotation and break */
326
327 if (*End == '"')
328 {
329 End++;
330
331 /* Check for an explicit null string */
332
333 if (*End == '"')
334 {
335 IsNullString = TRUE;
336 }
337 while (*End && (*End != '"'))
338 {
339 End++;
340 }
341
342 End++;
343 break;
344 }
345
346 /*
347 * Special "comment" fields at line end, ignore them.
348 * Note: normal slash-slash and slash-asterisk comments are
349 * stripped already by the DtGetNextLine parser.
350 *
351 * TBD: Perhaps DtGetNextLine should parse the following type
352 * of comments also.
353 */
354 if (*End == '[')
355 {
356 End--;
357 break;
358 }
359 End++;
360 }
361
362 Length = ACPI_PTR_DIFF (End, Start);
363 TmpValue = UtLocalCalloc (Length + 1);
364
365 ACPI_STRNCPY (TmpValue, Start, Length);
366 Value = DtTrim (TmpValue);
367 ACPI_FREE (TmpValue);
368
369 /* Create a new field object only if we have a valid value field */
370
371 if ((Value && *Value) || IsNullString)
372 {
373 Field = UtLocalCalloc (sizeof (DT_FIELD));
374 Field->Name = Name;
375 Field->Value = Value;
376 Field->Line = Line;
377 Field->ByteOffset = Offset;
378 Field->NameColumn = NameColumn;
379 Field->Column = Column;
380
381 DtLinkField (Field);
382 }
383 else /* Ignore this field, it has no valid data */
384 {
385 ACPI_FREE (Name);
386 ACPI_FREE (Value);
387 }
388
389 return (AE_OK);
390 }
391
392
393 /******************************************************************************
394 *
395 * FUNCTION: DtGetNextLine
396 *
397 * PARAMETERS: Handle - Open file handle for the source file
398 *
399 * RETURN: Filled line buffer and offset of start-of-line (ASL_EOF on EOF)
400 *
401 * DESCRIPTION: Get the next valid source line. Removes all comments.
402 * Ignores empty lines.
403 *
404 * Handles both slash-asterisk and slash-slash comments.
405 * Also, quoted strings, but no escapes within.
406 *
407 * Line is returned in Gbl_CurrentLineBuffer.
408 * Line number in original file is returned in Gbl_CurrentLineNumber.
409 *
410 *****************************************************************************/
411
412 UINT32
413 DtGetNextLine (
414 FILE *Handle)
415 {
416 BOOLEAN LineNotAllBlanks = FALSE;
417 UINT32 State = DT_NORMAL_TEXT;
418 UINT32 CurrentLineOffset;
419 UINT32 i;
420 char c;
421
422
423 for (i = 0; i < ASL_LINE_BUFFER_SIZE;)
424 {
425 c = (char) getc (Handle);
426 if (c == EOF)
427 {
428 switch (State)
429 {
430 case DT_START_QUOTED_STRING:
431 case DT_SLASH_ASTERISK_COMMENT:
432 case DT_SLASH_SLASH_COMMENT:
433
434 AcpiOsPrintf ("**** EOF within comment/string %u\n", State);
435 break;
436
437 default:
438 break;
439 }
440
441 return (ASL_EOF);
442 }
443
444 switch (State)
445 {
446 case DT_NORMAL_TEXT:
447
448 /* Normal text, insert char into line buffer */
449
450 Gbl_CurrentLineBuffer[i] = c;
451 switch (c)
452 {
453 case '/':
454 State = DT_START_COMMENT;
455 break;
456
457 case '"':
458 State = DT_START_QUOTED_STRING;
459 LineNotAllBlanks = TRUE;
460 i++;
461 break;
462
463 case '\\':
464 /*
465 * The continuation char MUST be last char on this line.
466 * Otherwise, it will be assumed to be a valid ASL char.
467 */
468 State = DT_MERGE_LINES;
469 break;
470
471 case '\n':
472 CurrentLineOffset = Gbl_NextLineOffset;
473 Gbl_NextLineOffset = (UINT32) ftell (Handle);
474 Gbl_CurrentLineNumber++;
475
476 /*
477 * Exit if line is complete. Ignore empty lines (only \n)
478 * or lines that contain nothing but blanks.
479 */
480 if ((i != 0) && LineNotAllBlanks)
481 {
482 Gbl_CurrentLineBuffer[i+1] = 0; /* Terminate string */
483 return (CurrentLineOffset);
484 }
485
486 /* Toss this line and start a new one */
487
488 i = 0;
489 LineNotAllBlanks = FALSE;
490 break;
491
492 default:
493 if (c != ' ')
494 {
495 LineNotAllBlanks = TRUE;
496 }
497
498 i++;
499 break;
500 }
501 break;
502
503 case DT_START_QUOTED_STRING:
504
505 /* Insert raw chars until end of quoted string */
506
507 Gbl_CurrentLineBuffer[i] = c;
508 i++;
509
510 if (c == '"')
511 {
512 State = DT_NORMAL_TEXT;
513 }
514 break;
515
516 case DT_START_COMMENT:
517
518 /* Open comment if this character is an asterisk or slash */
519
520 switch (c)
521 {
522 case '*':
523 State = DT_SLASH_ASTERISK_COMMENT;
524 break;
525
526 case '/':
527 State = DT_SLASH_SLASH_COMMENT;
528 break;
529
530 default: /* Not a comment */
531 i++; /* Save the preceeding slash */
532 Gbl_CurrentLineBuffer[i] = c;
533 i++;
534 State = DT_NORMAL_TEXT;
535 break;
536 }
537 break;
538
539 case DT_SLASH_ASTERISK_COMMENT:
540
541 /* Ignore chars until an asterisk-slash is found */
542
543 switch (c)
544 {
545 case '\n':
546 Gbl_NextLineOffset = (UINT32) ftell (Handle);
547 Gbl_CurrentLineNumber++;
548 break;
549
550 case '*':
551 State = DT_END_COMMENT;
552 break;
553
554 default:
555 break;
556 }
557 break;
558
559 case DT_SLASH_SLASH_COMMENT:
560
561 /* Ignore chars until end-of-line */
562
563 if (c == '\n')
564 {
565 /* We will exit via the NORMAL_TEXT path */
566
567 ungetc (c, Handle);
568 State = DT_NORMAL_TEXT;
569 }
570 break;
571
572 case DT_END_COMMENT:
573
574 /* End comment if this char is a slash */
575
576 switch (c)
577 {
578 case '/':
579 State = DT_NORMAL_TEXT;
580 break;
581
582 case '\n':
583 CurrentLineOffset = Gbl_NextLineOffset;
584 Gbl_NextLineOffset = (UINT32) ftell (Handle);
585 Gbl_CurrentLineNumber++;
586 break;
587
588 case '*':
589 /* Consume all adjacent asterisks */
590 break;
591
592 default:
593 State = DT_SLASH_ASTERISK_COMMENT;
594 break;
595 }
596 break;
597
598 case DT_MERGE_LINES:
599
600 if (c != '\n')
601 {
602 /*
603 * This is not a continuation backslash, it is a normal
604 * normal ASL backslash - for example: Scope(\_SB_)
605 */
606 i++; /* Keep the backslash that is already in the buffer */
607
608 ungetc (c, Handle);
609 State = DT_NORMAL_TEXT;
610 }
611 else
612 {
613 /*
614 * This is a continuation line -- a backlash followed
615 * immediately by a newline. Insert a space between the
616 * lines (overwrite the backslash)
617 */
618 Gbl_CurrentLineBuffer[i] = ' ';
619 i++;
620
621 /* Ignore newline, this will merge the lines */
622
623 CurrentLineOffset = Gbl_NextLineOffset;
624 Gbl_NextLineOffset = (UINT32) ftell (Handle);
625 Gbl_CurrentLineNumber++;
626 State = DT_NORMAL_TEXT;
627 }
628 break;
629
630 default:
631 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, "Unknown input state");
632 return (ASL_EOF);
633 }
634 }
635
636 printf ("ERROR - Input line is too long (max %u)\n", ASL_LINE_BUFFER_SIZE);
637 return (ASL_EOF);
638 }
639
640
641 /******************************************************************************
642 *
643 * FUNCTION: DtScanFile
644 *
645 * PARAMETERS: Handle - Open file handle for the source file
646 *
647 * RETURN: Pointer to start of the constructed parse tree.
648 *
649 * DESCRIPTION: Scan source file, link all field names and values
650 * to the global parse tree: Gbl_FieldList
651 *
652 *****************************************************************************/
653
654 DT_FIELD *
655 DtScanFile (
656 FILE *Handle)
657 {
658 ACPI_STATUS Status;
659 UINT32 Offset;
660 DT_FIELD *Next;
661
662
663 ACPI_FUNCTION_NAME (DtScanFile);
664
665
666 /* Get the file size */
667
668 Gbl_InputByteCount = DtGetFileSize (Handle);
669
670 Gbl_CurrentLineNumber = 0;
671 Gbl_CurrentLineOffset = 0;
672 Gbl_NextLineOffset = 0;
673
674 /* Scan line-by-line */
675
676 while ((Offset = DtGetNextLine (Handle)) != ASL_EOF)
677 {
678 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Line %2.2u/%4.4X - %s",
679 Gbl_CurrentLineNumber, Offset, Gbl_CurrentLineBuffer));
680
681 Status = DtParseLine (Gbl_CurrentLineBuffer, Gbl_CurrentLineNumber, Offset);
682 if (Status == AE_NOT_FOUND)
683 {
684 break;
685 }
686 }
687
688 /* Dump the parse tree if debug enabled */
689
690 if (Gbl_DebugFlag)
691 {
692 Next = Gbl_FieldList;
693 DbgPrint (ASL_DEBUG_OUTPUT, "Tree: %32s %32s %8s %8s %8s %8s %8s %8s\n\n",
694 "Name", "Value", "Line", "ByteOff", "NameCol", "Column", "TableOff", "Flags");
695
696 while (Next)
697 {
698 DbgPrint (ASL_DEBUG_OUTPUT, "Field: %32.32s %32.32s %.8X %.8X %.8X %.8X %.8X %.8X\n",
699 Next->Name,
700 Next->Value,
701 Next->Line,
702 Next->ByteOffset,
703 Next->NameColumn,
704 Next->Column,
705 Next->TableOffset,
706 Next->Flags);
707
708 Next = Next->Next;
709 }
710 }
711
712 return (Gbl_FieldList);
713 }
714
715
716 /*
717 * Output functions
718 */
719
720 /******************************************************************************
721 *
722 * FUNCTION: DtWriteBinary
723 *
724 * PARAMETERS: DT_WALK_CALLBACK
725 *
726 * RETURN: Status
727 *
728 * DESCRIPTION: Write one subtable of a binary ACPI table
729 *
730 *****************************************************************************/
731
732 static void
733 DtWriteBinary (
734 DT_SUBTABLE *Subtable,
735 void *Context,
736 void *ReturnValue)
737 {
738
739 FlWriteFile (ASL_FILE_AML_OUTPUT, Subtable->Buffer, Subtable->Length);
740 }
741
742
743 /******************************************************************************
744 *
745 * FUNCTION: DtOutputBinary
746 *
747 * PARAMETERS:
748 *
749 * RETURN: Status
750 *
751 * DESCRIPTION: Write entire binary ACPI table (result of compilation)
752 *
753 *****************************************************************************/
754
755 void
756 DtOutputBinary (
757 DT_SUBTABLE *RootTable)
758 {
759
760 if (!RootTable)
761 {
762 return;
763 }
764
765 /* Walk the entire parse tree, emitting the binary data */
766
767 DtWalkTableTree (RootTable, DtWriteBinary, NULL, NULL);
768 Gbl_TableLength = DtGetFileSize (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle);
769 }
770
771
772 /*
773 * Listing support
774 */
775
776 /******************************************************************************
777 *
778 * FUNCTION: DtDumpBuffer
779 *
780 * PARAMETERS: FileID - Where to write buffer data
781 * Buffer - Buffer to dump
782 * Offset - Offset in current table
783 * Length - Buffer Length
784 *
785 * RETURN: None
786 *
787 * DESCRIPTION: Another copy of DumpBuffer routine (unfortunately).
788 *
789 * TBD: merge dump buffer routines
790 *
791 *****************************************************************************/
792
793 static void
794 DtDumpBuffer (
795 UINT32 FileId,
796 UINT8 *Buffer,
797 UINT32 Offset,
798 UINT32 Length)
799 {
800 UINT32 i;
801 UINT32 j;
802 UINT8 BufChar;
803
804
805 FlPrintFile (FileId, "Output: [%3.3Xh %4.4d %3d] ",
806 Offset, Offset, Length);
807
808 i = 0;
809 while (i < Length)
810 {
811 if (i >= 16)
812 {
813 FlPrintFile (FileId, "%24s", "");
814 }
815
816 /* Print 16 hex chars */
817
818 for (j = 0; j < 16;)
819 {
820 if (i + j >= Length)
821 {
822 /* Dump fill spaces */
823
824 FlPrintFile (FileId, " ");
825 j++;
826 continue;
827 }
828
829 FlPrintFile (FileId, "%02X ", Buffer[i+j]);
830 j++;
831 }
832
833 FlPrintFile (FileId, " ");
834 for (j = 0; j < 16; j++)
835 {
836 if (i + j >= Length)
837 {
838 FlPrintFile (FileId, "\n\n");
839 return;
840 }
841
842 BufChar = Buffer[(ACPI_SIZE) i + j];
843 if (ACPI_IS_PRINT (BufChar))
844 {
845 FlPrintFile (FileId, "%c", BufChar);
846 }
847 else
848 {
849 FlPrintFile (FileId, ".");
850 }
851 }
852
853 /* Done with that line. */
854
855 FlPrintFile (FileId, "\n");
856 i += 16;
857 }
858
859 FlPrintFile (FileId, "\n\n");
860 }
861
862
863 /******************************************************************************
864 *
865 * FUNCTION: DtWriteFieldToListing
866 *
867 * PARAMETERS: Buffer - Contains the compiled data
868 * Field - Field node for the input line
869 * Length - Length of the output data
870 *
871 * RETURN: None
872 *
873 * DESCRIPTION: Write one field to the listing file (if listing is enabled).
874 *
875 *****************************************************************************/
876
877 void
878 DtWriteFieldToListing (
879 UINT8 *Buffer,
880 DT_FIELD *Field,
881 UINT32 Length)
882 {
883 UINT8 FileByte;
884
885
886 if (!Gbl_ListingFlag || !Field)
887 {
888 return;
889 }
890
891 /* Dump the original source line */
892
893 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Input: ");
894 FlSeekFile (ASL_FILE_INPUT, Field->ByteOffset);
895
896 while (FlReadFile (ASL_FILE_INPUT, &FileByte, 1) == AE_OK)
897 {
898 FlWriteFile (ASL_FILE_LISTING_OUTPUT, &FileByte, 1);
899 if (FileByte == '\n')
900 {
901 break;
902 }
903 }
904
905 /* Dump the line as parsed and represented internally */
906
907 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Parsed: %*s : %.64s",
908 Field->Column-4, Field->Name, Field->Value);
909
910 if (strlen (Field->Value) > 64)
911 {
912 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "...Additional data, length 0x%X\n",
913 strlen (Field->Value));
914 }
915 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "\n");
916
917 /* Dump the hex data that will be output for this field */
918
919 DtDumpBuffer (ASL_FILE_LISTING_OUTPUT, Buffer, Field->TableOffset, Length);
920 }
921
922
923 /******************************************************************************
924 *
925 * FUNCTION: DtWriteTableToListing
926 *
927 * PARAMETERS: None
928 *
929 * RETURN: None
930 *
931 * DESCRIPTION: Write the entire compiled table to the listing file
932 * in hex format
933 *
934 *****************************************************************************/
935
936 void
937 DtWriteTableToListing (
938 void)
939 {
940 UINT8 *Buffer;
941
942
943 if (!Gbl_ListingFlag)
944 {
945 return;
946 }
947
948 /* Read the entire table from the output file */
949
950 Buffer = UtLocalCalloc (Gbl_TableLength);
951 FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
952 FlReadFile (ASL_FILE_AML_OUTPUT, Buffer, Gbl_TableLength);
953
954 /* Dump the raw table data */
955
956 AcpiOsRedirectOutput (Gbl_Files[ASL_FILE_LISTING_OUTPUT].Handle);
957
958 AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n",
959 ACPI_RAW_TABLE_DATA_HEADER, Gbl_TableLength, Gbl_TableLength);
960 AcpiUtDumpBuffer2 (Buffer, Gbl_TableLength, DB_BYTE_DISPLAY);
961
962 AcpiOsRedirectOutput (stdout);
963 }
964