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 <contrib/dev/acpica/compiler/aslcompiler.h> 47 #include <contrib/dev/acpica/compiler/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