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