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