1 /****************************************************************************** 2 * 3 * Module Name: dtio.c - File I/O support for data table compiler 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/compiler/aslcompiler.h> 45 #include <contrib/dev/acpica/compiler/dtcompiler.h> 46 #include <contrib/dev/acpica/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 (!ACPI_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 + ACPI_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 (ACPI_STRLEN (Start)) 184 { 185 ACPI_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 ACPI_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 End++; 358 } 359 360 Length = ACPI_PTR_DIFF (End, Start); 361 TmpValue = UtLocalCalloc (Length + 1); 362 363 ACPI_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 379 DtLinkField (Field); 380 } 381 /* Else -- Ignore this field, it has no valid data */ 382 383 return (AE_OK); 384 } 385 386 387 /****************************************************************************** 388 * 389 * FUNCTION: DtGetNextLine 390 * 391 * PARAMETERS: Handle - Open file handle for the source file 392 * 393 * RETURN: Filled line buffer and offset of start-of-line (ASL_EOF on EOF) 394 * 395 * DESCRIPTION: Get the next valid source line. Removes all comments. 396 * Ignores empty lines. 397 * 398 * Handles both slash-asterisk and slash-slash comments. 399 * Also, quoted strings, but no escapes within. 400 * 401 * Line is returned in Gbl_CurrentLineBuffer. 402 * Line number in original file is returned in Gbl_CurrentLineNumber. 403 * 404 *****************************************************************************/ 405 406 UINT32 407 DtGetNextLine ( 408 FILE *Handle) 409 { 410 BOOLEAN LineNotAllBlanks = FALSE; 411 UINT32 State = DT_NORMAL_TEXT; 412 UINT32 CurrentLineOffset; 413 UINT32 i; 414 int c; 415 416 417 for (i = 0; ;) 418 { 419 /* 420 * If line is too long, expand the line buffers. Also increases 421 * Gbl_LineBufferSize. 422 */ 423 if (i >= Gbl_LineBufferSize) 424 { 425 UtExpandLineBuffers (); 426 } 427 428 c = getc (Handle); 429 if (c == EOF) 430 { 431 switch (State) 432 { 433 case DT_START_QUOTED_STRING: 434 case DT_SLASH_ASTERISK_COMMENT: 435 436 AcpiOsPrintf ("**** EOF within comment/string %u\n", State); 437 break; 438 439 default: 440 441 break; 442 } 443 444 /* Standalone EOF is OK */ 445 446 if (i == 0) 447 { 448 return (ASL_EOF); 449 } 450 451 /* 452 * Received an EOF in the middle of a line. Terminate the 453 * line with a newline. The next call to this function will 454 * return a standalone EOF. Thus, the upper parsing software 455 * never has to deal with an EOF within a valid line (or 456 * the last line does not get tossed on the floor.) 457 */ 458 c = '\n'; 459 State = DT_NORMAL_TEXT; 460 } 461 462 switch (State) 463 { 464 case DT_NORMAL_TEXT: 465 466 /* Normal text, insert char into line buffer */ 467 468 Gbl_CurrentLineBuffer[i] = (char) c; 469 switch (c) 470 { 471 case '/': 472 473 State = DT_START_COMMENT; 474 break; 475 476 case '"': 477 478 State = DT_START_QUOTED_STRING; 479 LineNotAllBlanks = TRUE; 480 i++; 481 break; 482 483 case '\\': 484 /* 485 * The continuation char MUST be last char on this line. 486 * Otherwise, it will be assumed to be a valid ASL char. 487 */ 488 State = DT_MERGE_LINES; 489 break; 490 491 case '\n': 492 493 CurrentLineOffset = Gbl_NextLineOffset; 494 Gbl_NextLineOffset = (UINT32) ftell (Handle); 495 Gbl_CurrentLineNumber++; 496 497 /* 498 * Exit if line is complete. Ignore empty lines (only \n) 499 * or lines that contain nothing but blanks. 500 */ 501 if ((i != 0) && LineNotAllBlanks) 502 { 503 if ((i + 1) >= Gbl_LineBufferSize) 504 { 505 UtExpandLineBuffers (); 506 } 507 508 Gbl_CurrentLineBuffer[i+1] = 0; /* Terminate string */ 509 return (CurrentLineOffset); 510 } 511 512 /* Toss this line and start a new one */ 513 514 i = 0; 515 LineNotAllBlanks = FALSE; 516 break; 517 518 default: 519 520 if (c != ' ') 521 { 522 LineNotAllBlanks = TRUE; 523 } 524 525 i++; 526 break; 527 } 528 break; 529 530 case DT_START_QUOTED_STRING: 531 532 /* Insert raw chars until end of quoted string */ 533 534 Gbl_CurrentLineBuffer[i] = (char) c; 535 i++; 536 537 switch (c) 538 { 539 case '"': 540 541 State = DT_NORMAL_TEXT; 542 break; 543 544 case '\\': 545 546 State = DT_ESCAPE_SEQUENCE; 547 break; 548 549 case '\n': 550 551 AcpiOsPrintf ("ERROR at line %u: Unterminated quoted string\n", 552 Gbl_CurrentLineNumber++); 553 State = DT_NORMAL_TEXT; 554 break; 555 556 default: /* Get next character */ 557 558 break; 559 } 560 break; 561 562 case DT_ESCAPE_SEQUENCE: 563 564 /* Just copy the escaped character. TBD: sufficient for table compiler? */ 565 566 Gbl_CurrentLineBuffer[i] = (char) c; 567 i++; 568 State = DT_START_QUOTED_STRING; 569 break; 570 571 case DT_START_COMMENT: 572 573 /* Open comment if this character is an asterisk or slash */ 574 575 switch (c) 576 { 577 case '*': 578 579 State = DT_SLASH_ASTERISK_COMMENT; 580 break; 581 582 case '/': 583 584 State = DT_SLASH_SLASH_COMMENT; 585 break; 586 587 default: /* Not a comment */ 588 589 i++; /* Save the preceding slash */ 590 if (i >= Gbl_LineBufferSize) 591 { 592 UtExpandLineBuffers (); 593 } 594 595 Gbl_CurrentLineBuffer[i] = (char) c; 596 i++; 597 State = DT_NORMAL_TEXT; 598 break; 599 } 600 break; 601 602 case DT_SLASH_ASTERISK_COMMENT: 603 604 /* Ignore chars until an asterisk-slash is found */ 605 606 switch (c) 607 { 608 case '\n': 609 610 Gbl_NextLineOffset = (UINT32) ftell (Handle); 611 Gbl_CurrentLineNumber++; 612 break; 613 614 case '*': 615 616 State = DT_END_COMMENT; 617 break; 618 619 default: 620 621 break; 622 } 623 break; 624 625 case DT_SLASH_SLASH_COMMENT: 626 627 /* Ignore chars until end-of-line */ 628 629 if (c == '\n') 630 { 631 /* We will exit via the NORMAL_TEXT path */ 632 633 ungetc (c, Handle); 634 State = DT_NORMAL_TEXT; 635 } 636 break; 637 638 case DT_END_COMMENT: 639 640 /* End comment if this char is a slash */ 641 642 switch (c) 643 { 644 case '/': 645 646 State = DT_NORMAL_TEXT; 647 break; 648 649 case '\n': 650 651 CurrentLineOffset = Gbl_NextLineOffset; 652 Gbl_NextLineOffset = (UINT32) ftell (Handle); 653 Gbl_CurrentLineNumber++; 654 break; 655 656 case '*': 657 658 /* Consume all adjacent asterisks */ 659 break; 660 661 default: 662 663 State = DT_SLASH_ASTERISK_COMMENT; 664 break; 665 } 666 break; 667 668 case DT_MERGE_LINES: 669 670 if (c != '\n') 671 { 672 /* 673 * This is not a continuation backslash, it is a normal 674 * normal ASL backslash - for example: Scope(\_SB_) 675 */ 676 i++; /* Keep the backslash that is already in the buffer */ 677 678 ungetc (c, Handle); 679 State = DT_NORMAL_TEXT; 680 } 681 else 682 { 683 /* 684 * This is a continuation line -- a backlash followed 685 * immediately by a newline. Insert a space between the 686 * lines (overwrite the backslash) 687 */ 688 Gbl_CurrentLineBuffer[i] = ' '; 689 i++; 690 691 /* Ignore newline, this will merge the lines */ 692 693 CurrentLineOffset = Gbl_NextLineOffset; 694 Gbl_NextLineOffset = (UINT32) ftell (Handle); 695 Gbl_CurrentLineNumber++; 696 State = DT_NORMAL_TEXT; 697 } 698 break; 699 700 default: 701 702 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, "Unknown input state"); 703 return (ASL_EOF); 704 } 705 } 706 } 707 708 709 /****************************************************************************** 710 * 711 * FUNCTION: DtScanFile 712 * 713 * PARAMETERS: Handle - Open file handle for the source file 714 * 715 * RETURN: Pointer to start of the constructed parse tree. 716 * 717 * DESCRIPTION: Scan source file, link all field names and values 718 * to the global parse tree: Gbl_FieldList 719 * 720 *****************************************************************************/ 721 722 DT_FIELD * 723 DtScanFile ( 724 FILE *Handle) 725 { 726 ACPI_STATUS Status; 727 UINT32 Offset; 728 729 730 ACPI_FUNCTION_NAME (DtScanFile); 731 732 733 /* Get the file size */ 734 735 Gbl_InputByteCount = CmGetFileSize (Handle); 736 if (Gbl_InputByteCount == ACPI_UINT32_MAX) 737 { 738 AslAbort (); 739 } 740 741 Gbl_CurrentLineNumber = 0; 742 Gbl_CurrentLineOffset = 0; 743 Gbl_NextLineOffset = 0; 744 745 /* Scan line-by-line */ 746 747 while ((Offset = DtGetNextLine (Handle)) != ASL_EOF) 748 { 749 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Line %2.2u/%4.4X - %s", 750 Gbl_CurrentLineNumber, Offset, Gbl_CurrentLineBuffer)); 751 752 Status = DtParseLine (Gbl_CurrentLineBuffer, Gbl_CurrentLineNumber, Offset); 753 if (Status == AE_NOT_FOUND) 754 { 755 break; 756 } 757 } 758 759 /* Dump the parse tree if debug enabled */ 760 761 DtDumpFieldList (Gbl_FieldList); 762 return (Gbl_FieldList); 763 } 764 765 766 /* 767 * Output functions 768 */ 769 770 /****************************************************************************** 771 * 772 * FUNCTION: DtWriteBinary 773 * 774 * PARAMETERS: DT_WALK_CALLBACK 775 * 776 * RETURN: Status 777 * 778 * DESCRIPTION: Write one subtable of a binary ACPI table 779 * 780 *****************************************************************************/ 781 782 static void 783 DtWriteBinary ( 784 DT_SUBTABLE *Subtable, 785 void *Context, 786 void *ReturnValue) 787 { 788 789 FlWriteFile (ASL_FILE_AML_OUTPUT, Subtable->Buffer, Subtable->Length); 790 } 791 792 793 /****************************************************************************** 794 * 795 * FUNCTION: DtOutputBinary 796 * 797 * PARAMETERS: 798 * 799 * RETURN: Status 800 * 801 * DESCRIPTION: Write entire binary ACPI table (result of compilation) 802 * 803 *****************************************************************************/ 804 805 void 806 DtOutputBinary ( 807 DT_SUBTABLE *RootTable) 808 { 809 810 if (!RootTable) 811 { 812 return; 813 } 814 815 /* Walk the entire parse tree, emitting the binary data */ 816 817 DtWalkTableTree (RootTable, DtWriteBinary, NULL, NULL); 818 819 Gbl_TableLength = CmGetFileSize (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle); 820 if (Gbl_TableLength == ACPI_UINT32_MAX) 821 { 822 AslAbort (); 823 } 824 } 825 826 827 /* 828 * Listing support 829 */ 830 831 /****************************************************************************** 832 * 833 * FUNCTION: DtDumpBuffer 834 * 835 * PARAMETERS: FileID - Where to write buffer data 836 * Buffer - Buffer to dump 837 * Offset - Offset in current table 838 * Length - Buffer Length 839 * 840 * RETURN: None 841 * 842 * DESCRIPTION: Another copy of DumpBuffer routine (unfortunately). 843 * 844 * TBD: merge dump buffer routines 845 * 846 *****************************************************************************/ 847 848 static void 849 DtDumpBuffer ( 850 UINT32 FileId, 851 UINT8 *Buffer, 852 UINT32 Offset, 853 UINT32 Length) 854 { 855 UINT32 i; 856 UINT32 j; 857 UINT8 BufChar; 858 859 860 FlPrintFile (FileId, "Output: [%3.3Xh %4.4d %3d] ", 861 Offset, Offset, Length); 862 863 i = 0; 864 while (i < Length) 865 { 866 if (i >= 16) 867 { 868 FlPrintFile (FileId, "%24s", ""); 869 } 870 871 /* Print 16 hex chars */ 872 873 for (j = 0; j < 16;) 874 { 875 if (i + j >= Length) 876 { 877 /* Dump fill spaces */ 878 879 FlPrintFile (FileId, " "); 880 j++; 881 continue; 882 } 883 884 FlPrintFile (FileId, "%02X ", Buffer[i+j]); 885 j++; 886 } 887 888 FlPrintFile (FileId, " "); 889 for (j = 0; j < 16; j++) 890 { 891 if (i + j >= Length) 892 { 893 FlPrintFile (FileId, "\n\n"); 894 return; 895 } 896 897 BufChar = Buffer[(ACPI_SIZE) i + j]; 898 if (ACPI_IS_PRINT (BufChar)) 899 { 900 FlPrintFile (FileId, "%c", BufChar); 901 } 902 else 903 { 904 FlPrintFile (FileId, "."); 905 } 906 } 907 908 /* Done with that line. */ 909 910 FlPrintFile (FileId, "\n"); 911 i += 16; 912 } 913 914 FlPrintFile (FileId, "\n\n"); 915 } 916 917 918 /****************************************************************************** 919 * 920 * FUNCTION: DtDumpFieldList 921 * 922 * PARAMETERS: Field - Root field 923 * 924 * RETURN: None 925 * 926 * DESCRIPTION: Dump the entire field list 927 * 928 *****************************************************************************/ 929 930 void 931 DtDumpFieldList ( 932 DT_FIELD *Field) 933 { 934 935 if (!Gbl_DebugFlag || !Field) 936 { 937 return; 938 } 939 940 DbgPrint (ASL_DEBUG_OUTPUT, "\nField List:\n" 941 "LineNo ByteOff NameCol Column TableOff " 942 "Flags %32s : %s\n\n", "Name", "Value"); 943 while (Field) 944 { 945 DbgPrint (ASL_DEBUG_OUTPUT, 946 "%.08X %.08X %.08X %.08X %.08X %.08X %32s : %s\n", 947 Field->Line, Field->ByteOffset, Field->NameColumn, 948 Field->Column, Field->TableOffset, Field->Flags, 949 Field->Name, Field->Value); 950 951 Field = Field->Next; 952 } 953 954 DbgPrint (ASL_DEBUG_OUTPUT, "\n\n"); 955 } 956 957 958 /****************************************************************************** 959 * 960 * FUNCTION: DtDumpSubtableInfo, DtDumpSubtableTree 961 * 962 * PARAMETERS: DT_WALK_CALLBACK 963 * 964 * RETURN: None 965 * 966 * DESCRIPTION: Info - dump a subtable tree entry with extra information. 967 * Tree - dump a subtable tree formatted by depth indentation. 968 * 969 *****************************************************************************/ 970 971 static void 972 DtDumpSubtableInfo ( 973 DT_SUBTABLE *Subtable, 974 void *Context, 975 void *ReturnValue) 976 { 977 978 DbgPrint (ASL_DEBUG_OUTPUT, 979 "[%.04X] %.08X %.08X %.08X %.08X %.08X %p %p %p\n", 980 Subtable->Depth, Subtable->Length, Subtable->TotalLength, 981 Subtable->SizeOfLengthField, Subtable->Flags, Subtable, 982 Subtable->Parent, Subtable->Child, Subtable->Peer); 983 } 984 985 static void 986 DtDumpSubtableTree ( 987 DT_SUBTABLE *Subtable, 988 void *Context, 989 void *ReturnValue) 990 { 991 992 DbgPrint (ASL_DEBUG_OUTPUT, 993 "[%.04X] %*s%08X (%.02X) - (%.02X)\n", 994 Subtable->Depth, (4 * Subtable->Depth), " ", 995 Subtable, Subtable->Length, Subtable->TotalLength); 996 } 997 998 999 /****************************************************************************** 1000 * 1001 * FUNCTION: DtDumpSubtableList 1002 * 1003 * PARAMETERS: None 1004 * 1005 * RETURN: None 1006 * 1007 * DESCRIPTION: Dump the raw list of subtables with information, and also 1008 * dump the subtable list in formatted tree format. Assists with 1009 * the development of new table code. 1010 * 1011 *****************************************************************************/ 1012 1013 void 1014 DtDumpSubtableList ( 1015 void) 1016 { 1017 1018 if (!Gbl_DebugFlag || !Gbl_RootTable) 1019 { 1020 return; 1021 } 1022 1023 DbgPrint (ASL_DEBUG_OUTPUT, 1024 "Subtable Info:\n" 1025 "Depth Length TotalLen LenSize Flags " 1026 "This Parent Child Peer\n\n"); 1027 DtWalkTableTree (Gbl_RootTable, DtDumpSubtableInfo, NULL, NULL); 1028 1029 DbgPrint (ASL_DEBUG_OUTPUT, 1030 "\nSubtable Tree: (Depth, Subtable, Length, TotalLength)\n\n"); 1031 DtWalkTableTree (Gbl_RootTable, DtDumpSubtableTree, NULL, NULL); 1032 1033 DbgPrint (ASL_DEBUG_OUTPUT, "\n"); 1034 } 1035 1036 1037 /****************************************************************************** 1038 * 1039 * FUNCTION: DtWriteFieldToListing 1040 * 1041 * PARAMETERS: Buffer - Contains the compiled data 1042 * Field - Field node for the input line 1043 * Length - Length of the output data 1044 * 1045 * RETURN: None 1046 * 1047 * DESCRIPTION: Write one field to the listing file (if listing is enabled). 1048 * 1049 *****************************************************************************/ 1050 1051 void 1052 DtWriteFieldToListing ( 1053 UINT8 *Buffer, 1054 DT_FIELD *Field, 1055 UINT32 Length) 1056 { 1057 UINT8 FileByte; 1058 1059 1060 if (!Gbl_ListingFlag || !Field) 1061 { 1062 return; 1063 } 1064 1065 /* Dump the original source line */ 1066 1067 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Input: "); 1068 FlSeekFile (ASL_FILE_INPUT, Field->ByteOffset); 1069 1070 while (FlReadFile (ASL_FILE_INPUT, &FileByte, 1) == AE_OK) 1071 { 1072 FlWriteFile (ASL_FILE_LISTING_OUTPUT, &FileByte, 1); 1073 if (FileByte == '\n') 1074 { 1075 break; 1076 } 1077 } 1078 1079 /* Dump the line as parsed and represented internally */ 1080 1081 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Parsed: %*s : %.64s", 1082 Field->Column-4, Field->Name, Field->Value); 1083 1084 if (strlen (Field->Value) > 64) 1085 { 1086 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "...Additional data, length 0x%X\n", 1087 strlen (Field->Value)); 1088 } 1089 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "\n"); 1090 1091 /* Dump the hex data that will be output for this field */ 1092 1093 DtDumpBuffer (ASL_FILE_LISTING_OUTPUT, Buffer, Field->TableOffset, Length); 1094 } 1095 1096 1097 /****************************************************************************** 1098 * 1099 * FUNCTION: DtWriteTableToListing 1100 * 1101 * PARAMETERS: None 1102 * 1103 * RETURN: None 1104 * 1105 * DESCRIPTION: Write the entire compiled table to the listing file 1106 * in hex format 1107 * 1108 *****************************************************************************/ 1109 1110 void 1111 DtWriteTableToListing ( 1112 void) 1113 { 1114 UINT8 *Buffer; 1115 1116 1117 if (!Gbl_ListingFlag) 1118 { 1119 return; 1120 } 1121 1122 /* Read the entire table from the output file */ 1123 1124 Buffer = UtLocalCalloc (Gbl_TableLength); 1125 FlSeekFile (ASL_FILE_AML_OUTPUT, 0); 1126 FlReadFile (ASL_FILE_AML_OUTPUT, Buffer, Gbl_TableLength); 1127 1128 /* Dump the raw table data */ 1129 1130 AcpiOsRedirectOutput (Gbl_Files[ASL_FILE_LISTING_OUTPUT].Handle); 1131 1132 AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n", 1133 ACPI_RAW_TABLE_DATA_HEADER, Gbl_TableLength, Gbl_TableLength); 1134 AcpiUtDumpBuffer (Buffer, Gbl_TableLength, DB_BYTE_DISPLAY, 0); 1135 1136 AcpiOsRedirectOutput (stdout); 1137 ACPI_FREE (Buffer); 1138 } 1139