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