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