1/****************************************************************************** 2 * 3 * Module Name: dtio.c - File I/O support for data table compiler 4 * 5 *****************************************************************************/ 6 7/****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2016, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 *****************************************************************************/ 115 116#include "aslcompiler.h" 117#include "dtcompiler.h" 118#include "acapps.h" 119 120#define _COMPONENT DT_COMPILER 121 ACPI_MODULE_NAME ("dtio") 122 123 124/* Local prototypes */ 125 126static char * 127DtTrim ( 128 char *String); 129 130static void 131DtLinkField ( 132 DT_FIELD *Field); 133 134static ACPI_STATUS 135DtParseLine ( 136 char *LineBuffer, 137 UINT32 Line, 138 UINT32 Offset); 139 140static void 141DtWriteBinary ( 142 DT_SUBTABLE *Subtable, 143 void *Context, 144 void *ReturnValue); 145 146static void 147DtDumpBuffer ( 148 UINT32 FileId, 149 UINT8 *Buffer, 150 UINT32 Offset, 151 UINT32 Length); 152 153static void 154DtDumpSubtableInfo ( 155 DT_SUBTABLE *Subtable, 156 void *Context, 157 void *ReturnValue); 158 159static void 160DtDumpSubtableTree ( 161 DT_SUBTABLE *Subtable, 162 void *Context, 163 void *ReturnValue); 164 165 166/* States for DtGetNextLine */ 167 168#define DT_NORMAL_TEXT 0 169#define DT_START_QUOTED_STRING 1 170#define DT_START_COMMENT 2 171#define DT_SLASH_ASTERISK_COMMENT 3 172#define DT_SLASH_SLASH_COMMENT 4 173#define DT_END_COMMENT 5 174#define DT_MERGE_LINES 6 175#define DT_ESCAPE_SEQUENCE 7 176 177static UINT32 Gbl_NextLineOffset; 178 179 180/****************************************************************************** 181 * 182 * FUNCTION: DtTrim 183 * 184 * PARAMETERS: String - Current source code line to trim 185 * 186 * RETURN: Trimmed line. Must be freed by caller. 187 * 188 * DESCRIPTION: Trim left and right spaces 189 * 190 *****************************************************************************/ 191 192static char * 193DtTrim ( 194 char *String) 195{ 196 char *Start; 197 char *End; 198 char *ReturnString; 199 ACPI_SIZE Length; 200 201 202 /* Skip lines that start with a space */ 203 204 if (!strcmp (String, " ")) 205 { 206 ReturnString = UtStringCacheCalloc (1); 207 return (ReturnString); 208 } 209 210 /* Setup pointers to start and end of input string */ 211 212 Start = String; 213 End = String + strlen (String) - 1; 214 215 /* Find first non-whitespace character */ 216 217 while ((Start <= End) && ((*Start == ' ') || (*Start == '\t'))) 218 { 219 Start++; 220 } 221 222 /* Find last non-space character */ 223 224 while (End >= Start) 225 { 226 if (*End == '\r' || *End == '\n') 227 { 228 End--; 229 continue; 230 } 231 232 if (*End != ' ') 233 { 234 break; 235 } 236 237 End--; 238 } 239 240 /* Remove any quotes around the string */ 241 242 if (*Start == '\"') 243 { 244 Start++; 245 } 246 if (*End == '\"') 247 { 248 End--; 249 } 250 251 /* Create the trimmed return string */ 252 253 Length = ACPI_PTR_DIFF (End, Start) + 1; 254 ReturnString = UtStringCacheCalloc (Length + 1); 255 if (strlen (Start)) 256 { 257 strncpy (ReturnString, Start, Length); 258 } 259 260 ReturnString[Length] = 0; 261 return (ReturnString); 262} 263 264 265/****************************************************************************** 266 * 267 * FUNCTION: DtLinkField 268 * 269 * PARAMETERS: Field - New field object to link 270 * 271 * RETURN: None 272 * 273 * DESCRIPTION: Link one field name and value to the list 274 * 275 *****************************************************************************/ 276 277static void 278DtLinkField ( 279 DT_FIELD *Field) 280{ 281 DT_FIELD *Prev; 282 DT_FIELD *Next; 283 284 285 Prev = Next = Gbl_FieldList; 286 287 while (Next) 288 { 289 Prev = Next; 290 Next = Next->Next; 291 } 292 293 if (Prev) 294 { 295 Prev->Next = Field; 296 } 297 else 298 { 299 Gbl_FieldList = Field; 300 } 301} 302 303 304/****************************************************************************** 305 * 306 * FUNCTION: DtParseLine 307 * 308 * PARAMETERS: LineBuffer - Current source code line 309 * Line - Current line number in the source 310 * Offset - Current byte offset of the line 311 * 312 * RETURN: Status 313 * 314 * DESCRIPTION: Parse one source line 315 * 316 *****************************************************************************/ 317 318static ACPI_STATUS 319DtParseLine ( 320 char *LineBuffer, 321 UINT32 Line, 322 UINT32 Offset) 323{ 324 char *Start; 325 char *End; 326 char *TmpName; 327 char *TmpValue; 328 char *Name; 329 char *Value; 330 char *Colon; 331 UINT32 Length; 332 DT_FIELD *Field; 333 UINT32 Column; 334 UINT32 NameColumn; 335 BOOLEAN IsNullString = FALSE; 336 337 338 if (!LineBuffer) 339 { 340 return (AE_OK); 341 } 342 343 /* All lines after "Raw Table Data" are ingored */ 344 345 if (strstr (LineBuffer, ACPI_RAW_TABLE_DATA_HEADER)) 346 { 347 return (AE_NOT_FOUND); 348 } 349 350 Colon = strchr (LineBuffer, ':'); 351 if (!Colon) 352 { 353 return (AE_OK); 354 } 355 356 Start = LineBuffer; 357 End = Colon; 358 359 while (Start < Colon) 360 { 361 if (*Start == '[') 362 { 363 /* Found left bracket, go to the right bracket */ 364 365 while (Start < Colon && *Start != ']') 366 { 367 Start++; 368 } 369 } 370 else if (*Start != ' ') 371 { 372 break; 373 } 374 375 Start++; 376 } 377 378 /* 379 * There are two column values. One for the field name, 380 * and one for the field value. 381 */ 382 Column = ACPI_PTR_DIFF (Colon, LineBuffer) + 3; 383 NameColumn = ACPI_PTR_DIFF (Start, LineBuffer) + 1; 384 385 Length = ACPI_PTR_DIFF (End, Start); 386 387 TmpName = UtLocalCalloc (Length + 1); 388 strncpy (TmpName, Start, Length); 389 Name = DtTrim (TmpName); 390 ACPI_FREE (TmpName); 391 392 Start = End = (Colon + 1); 393 while (*End) 394 { 395 /* Found left quotation, go to the right quotation and break */ 396 397 if (*End == '"') 398 { 399 End++; 400 401 /* Check for an explicit null string */ 402 403 if (*End == '"') 404 { 405 IsNullString = TRUE; 406 } 407 while (*End && (*End != '"')) 408 { 409 End++; 410 } 411 412 End++; 413 break; 414 } 415 416 /* 417 * Special "comment" fields at line end, ignore them. 418 * Note: normal slash-slash and slash-asterisk comments are 419 * stripped already by the DtGetNextLine parser. 420 * 421 * TBD: Perhaps DtGetNextLine should parse the following type 422 * of comments also. 423 */ 424 if (*End == '[') 425 { 426 End--; 427 break; 428 } 429 430 End++; 431 } 432 433 Length = ACPI_PTR_DIFF (End, Start); 434 TmpValue = UtLocalCalloc (Length + 1); 435 436 strncpy (TmpValue, Start, Length); 437 Value = DtTrim (TmpValue); 438 ACPI_FREE (TmpValue); 439 440 /* Create a new field object only if we have a valid value field */ 441 442 if ((Value && *Value) || IsNullString) 443 { 444 Field = UtFieldCacheCalloc (); 445 Field->Name = Name; 446 Field->Value = Value; 447 Field->Line = Line; 448 Field->ByteOffset = Offset; 449 Field->NameColumn = NameColumn; 450 Field->Column = Column; 451 Field->StringLength = Length; 452 453 DtLinkField (Field); 454 } 455 /* Else -- Ignore this field, it has no valid data */ 456 457 return (AE_OK); 458} 459 460 461/****************************************************************************** 462 * 463 * FUNCTION: DtGetNextLine 464 * 465 * PARAMETERS: Handle - Open file handle for the source file 466 * 467 * RETURN: Filled line buffer and offset of start-of-line (ASL_EOF on EOF) 468 * 469 * DESCRIPTION: Get the next valid source line. Removes all comments. 470 * Ignores empty lines. 471 * 472 * Handles both slash-asterisk and slash-slash comments. 473 * Also, quoted strings, but no escapes within. 474 * 475 * Line is returned in Gbl_CurrentLineBuffer. 476 * Line number in original file is returned in Gbl_CurrentLineNumber. 477 * 478 *****************************************************************************/ 479 480UINT32 481DtGetNextLine ( 482 FILE *Handle, 483 UINT32 Flags) 484{ 485 BOOLEAN LineNotAllBlanks = FALSE; 486 UINT32 State = DT_NORMAL_TEXT; 487 UINT32 CurrentLineOffset; 488 UINT32 i; 489 int c; 490 491 492 memset (Gbl_CurrentLineBuffer, 0, Gbl_LineBufferSize); 493 for (i = 0; ;) 494 { 495 /* 496 * If line is too long, expand the line buffers. Also increases 497 * Gbl_LineBufferSize. 498 */ 499 if (i >= Gbl_LineBufferSize) 500 { 501 UtExpandLineBuffers (); 502 } 503 504 c = getc (Handle); 505 if (c == EOF) 506 { 507 switch (State) 508 { 509 case DT_START_QUOTED_STRING: 510 case DT_SLASH_ASTERISK_COMMENT: 511 512 AcpiOsPrintf ("**** EOF within comment/string %u\n", State); 513 break; 514 515 default: 516 517 break; 518 } 519 520 /* Standalone EOF is OK */ 521 522 if (i == 0) 523 { 524 return (ASL_EOF); 525 } 526 527 /* 528 * Received an EOF in the middle of a line. Terminate the 529 * line with a newline. The next call to this function will 530 * return a standalone EOF. Thus, the upper parsing software 531 * never has to deal with an EOF within a valid line (or 532 * the last line does not get tossed on the floor.) 533 */ 534 c = '\n'; 535 State = DT_NORMAL_TEXT; 536 } 537 538 switch (State) 539 { 540 case DT_NORMAL_TEXT: 541 542 /* Normal text, insert char into line buffer */ 543 544 Gbl_CurrentLineBuffer[i] = (char) c; 545 switch (c) 546 { 547 case '/': 548 549 State = DT_START_COMMENT; 550 break; 551 552 case '"': 553 554 State = DT_START_QUOTED_STRING; 555 LineNotAllBlanks = TRUE; 556 i++; 557 break; 558 559 case '\\': 560 /* 561 * The continuation char MUST be last char on this line. 562 * Otherwise, it will be assumed to be a valid ASL char. 563 */ 564 State = DT_MERGE_LINES; 565 break; 566 567 case '\n': 568 569 CurrentLineOffset = Gbl_NextLineOffset; 570 Gbl_NextLineOffset = (UINT32) ftell (Handle); 571 Gbl_CurrentLineNumber++; 572 573 /* 574 * Exit if line is complete. Ignore empty lines (only \n) 575 * or lines that contain nothing but blanks. 576 */ 577 if ((i != 0) && LineNotAllBlanks) 578 { 579 if ((i + 1) >= Gbl_LineBufferSize) 580 { 581 UtExpandLineBuffers (); 582 } 583 584 Gbl_CurrentLineBuffer[i+1] = 0; /* Terminate string */ 585 return (CurrentLineOffset); 586 } 587 588 /* Toss this line and start a new one */ 589 590 i = 0; 591 LineNotAllBlanks = FALSE; 592 break; 593 594 default: 595 596 if (c != ' ') 597 { 598 LineNotAllBlanks = TRUE; 599 } 600 601 i++; 602 break; 603 } 604 break; 605 606 case DT_START_QUOTED_STRING: 607 608 /* Insert raw chars until end of quoted string */ 609 610 Gbl_CurrentLineBuffer[i] = (char) c; 611 i++; 612 613 switch (c) 614 { 615 case '"': 616 617 State = DT_NORMAL_TEXT; 618 break; 619 620 case '\\': 621 622 State = DT_ESCAPE_SEQUENCE; 623 break; 624 625 case '\n': 626 627 if (!(Flags & DT_ALLOW_MULTILINE_QUOTES)) 628 { 629 AcpiOsPrintf ( 630 "ERROR at line %u: Unterminated quoted string\n", 631 Gbl_CurrentLineNumber++); 632 State = DT_NORMAL_TEXT; 633 } 634 break; 635 636 default: /* Get next character */ 637 638 break; 639 } 640 break; 641 642 case DT_ESCAPE_SEQUENCE: 643 644 /* Just copy the escaped character. TBD: sufficient for table compiler? */ 645 646 Gbl_CurrentLineBuffer[i] = (char) c; 647 i++; 648 State = DT_START_QUOTED_STRING; 649 break; 650 651 case DT_START_COMMENT: 652 653 /* Open comment if this character is an asterisk or slash */ 654 655 switch (c) 656 { 657 case '*': 658 659 State = DT_SLASH_ASTERISK_COMMENT; 660 break; 661 662 case '/': 663 664 State = DT_SLASH_SLASH_COMMENT; 665 break; 666 667 default: /* Not a comment */ 668 669 i++; /* Save the preceding slash */ 670 if (i >= Gbl_LineBufferSize) 671 { 672 UtExpandLineBuffers (); 673 } 674 675 Gbl_CurrentLineBuffer[i] = (char) c; 676 i++; 677 State = DT_NORMAL_TEXT; 678 break; 679 } 680 break; 681 682 case DT_SLASH_ASTERISK_COMMENT: 683 684 /* Ignore chars until an asterisk-slash is found */ 685 686 switch (c) 687 { 688 case '\n': 689 690 Gbl_NextLineOffset = (UINT32) ftell (Handle); 691 Gbl_CurrentLineNumber++; 692 break; 693 694 case '*': 695 696 State = DT_END_COMMENT; 697 break; 698 699 default: 700 701 break; 702 } 703 break; 704 705 case DT_SLASH_SLASH_COMMENT: 706 707 /* Ignore chars until end-of-line */ 708 709 if (c == '\n') 710 { 711 /* We will exit via the NORMAL_TEXT path */ 712 713 ungetc (c, Handle); 714 State = DT_NORMAL_TEXT; 715 } 716 break; 717 718 case DT_END_COMMENT: 719 720 /* End comment if this char is a slash */ 721 722 switch (c) 723 { 724 case '/': 725 726 State = DT_NORMAL_TEXT; 727 break; 728 729 case '\n': 730 731 CurrentLineOffset = Gbl_NextLineOffset; 732 Gbl_NextLineOffset = (UINT32) ftell (Handle); 733 Gbl_CurrentLineNumber++; 734 break; 735 736 case '*': 737 738 /* Consume all adjacent asterisks */ 739 break; 740 741 default: 742 743 State = DT_SLASH_ASTERISK_COMMENT; 744 break; 745 } 746 break; 747 748 case DT_MERGE_LINES: 749 750 if (c != '\n') 751 { 752 /* 753 * This is not a continuation backslash, it is a normal 754 * normal ASL backslash - for example: Scope(\_SB_) 755 */ 756 i++; /* Keep the backslash that is already in the buffer */ 757 758 ungetc (c, Handle); 759 State = DT_NORMAL_TEXT; 760 } 761 else 762 { 763 /* 764 * This is a continuation line -- a backlash followed 765 * immediately by a newline. Insert a space between the 766 * lines (overwrite the backslash) 767 */ 768 Gbl_CurrentLineBuffer[i] = ' '; 769 i++; 770 771 /* Ignore newline, this will merge the lines */ 772 773 CurrentLineOffset = Gbl_NextLineOffset; 774 Gbl_NextLineOffset = (UINT32) ftell (Handle); 775 Gbl_CurrentLineNumber++; 776 State = DT_NORMAL_TEXT; 777 } 778 break; 779 780 default: 781 782 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, "Unknown input state"); 783 return (ASL_EOF); 784 } 785 } 786} 787 788 789/****************************************************************************** 790 * 791 * FUNCTION: DtScanFile 792 * 793 * PARAMETERS: Handle - Open file handle for the source file 794 * 795 * RETURN: Pointer to start of the constructed parse tree. 796 * 797 * DESCRIPTION: Scan source file, link all field names and values 798 * to the global parse tree: Gbl_FieldList 799 * 800 *****************************************************************************/ 801 802DT_FIELD * 803DtScanFile ( 804 FILE *Handle) 805{ 806 ACPI_STATUS Status; 807 UINT32 Offset; 808 809 810 ACPI_FUNCTION_NAME (DtScanFile); 811 812 813 /* Get the file size */ 814 815 Gbl_InputByteCount = CmGetFileSize (Handle); 816 if (Gbl_InputByteCount == ACPI_UINT32_MAX) 817 { 818 AslAbort (); 819 } 820 821 Gbl_CurrentLineNumber = 0; 822 Gbl_CurrentLineOffset = 0; 823 Gbl_NextLineOffset = 0; 824 825 /* Scan line-by-line */ 826 827 while ((Offset = DtGetNextLine (Handle, 0)) != ASL_EOF) 828 { 829 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Line %2.2u/%4.4X - %s", 830 Gbl_CurrentLineNumber, Offset, Gbl_CurrentLineBuffer)); 831 832 Status = DtParseLine (Gbl_CurrentLineBuffer, 833 Gbl_CurrentLineNumber, Offset); 834 if (Status == AE_NOT_FOUND) 835 { 836 break; 837 } 838 } 839 840 /* Dump the parse tree if debug enabled */ 841 842 DtDumpFieldList (Gbl_FieldList); 843 return (Gbl_FieldList); 844} 845 846 847/* 848 * Output functions 849 */ 850 851/****************************************************************************** 852 * 853 * FUNCTION: DtWriteBinary 854 * 855 * PARAMETERS: DT_WALK_CALLBACK 856 * 857 * RETURN: Status 858 * 859 * DESCRIPTION: Write one subtable of a binary ACPI table 860 * 861 *****************************************************************************/ 862 863static void 864DtWriteBinary ( 865 DT_SUBTABLE *Subtable, 866 void *Context, 867 void *ReturnValue) 868{ 869 870 FlWriteFile (ASL_FILE_AML_OUTPUT, Subtable->Buffer, Subtable->Length); 871} 872 873 874/****************************************************************************** 875 * 876 * FUNCTION: DtOutputBinary 877 * 878 * PARAMETERS: 879 * 880 * RETURN: Status 881 * 882 * DESCRIPTION: Write entire binary ACPI table (result of compilation) 883 * 884 *****************************************************************************/ 885 886void 887DtOutputBinary ( 888 DT_SUBTABLE *RootTable) 889{ 890 891 if (!RootTable) 892 { 893 return; 894 } 895 896 /* Walk the entire parse tree, emitting the binary data */ 897 898 DtWalkTableTree (RootTable, DtWriteBinary, NULL, NULL); 899 900 Gbl_TableLength = CmGetFileSize (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle); 901 if (Gbl_TableLength == ACPI_UINT32_MAX) 902 { 903 AslAbort (); 904 } 905} 906 907 908/* 909 * Listing support 910 */ 911 912/****************************************************************************** 913 * 914 * FUNCTION: DtDumpBuffer 915 * 916 * PARAMETERS: FileID - Where to write buffer data 917 * Buffer - Buffer to dump 918 * Offset - Offset in current table 919 * Length - Buffer Length 920 * 921 * RETURN: None 922 * 923 * DESCRIPTION: Another copy of DumpBuffer routine (unfortunately). 924 * 925 * TBD: merge dump buffer routines 926 * 927 *****************************************************************************/ 928 929static void 930DtDumpBuffer ( 931 UINT32 FileId, 932 UINT8 *Buffer, 933 UINT32 Offset, 934 UINT32 Length) 935{ 936 UINT32 i; 937 UINT32 j; 938 UINT8 BufChar; 939 940 941 FlPrintFile (FileId, "Output: [%3.3Xh %4.4d %3d] ", 942 Offset, Offset, Length); 943 944 i = 0; 945 while (i < Length) 946 { 947 if (i >= 16) 948 { 949 FlPrintFile (FileId, "%24s", ""); 950 } 951 952 /* Print 16 hex chars */ 953 954 for (j = 0; j < 16;) 955 { 956 if (i + j >= Length) 957 { 958 /* Dump fill spaces */ 959 960 FlPrintFile (FileId, " "); 961 j++; 962 continue; 963 } 964 965 FlPrintFile (FileId, "%02X ", Buffer[i+j]); 966 j++; 967 } 968 969 FlPrintFile (FileId, " "); 970 for (j = 0; j < 16; j++) 971 { 972 if (i + j >= Length) 973 { 974 FlPrintFile (FileId, "\n\n"); 975 return; 976 } 977 978 BufChar = Buffer[(ACPI_SIZE) i + j]; 979 if (isprint (BufChar)) 980 { 981 FlPrintFile (FileId, "%c", BufChar); 982 } 983 else 984 { 985 FlPrintFile (FileId, "."); 986 } 987 } 988 989 /* Done with that line. */ 990 991 FlPrintFile (FileId, "\n"); 992 i += 16; 993 } 994 995 FlPrintFile (FileId, "\n\n"); 996} 997 998 999/****************************************************************************** 1000 * 1001 * FUNCTION: DtDumpFieldList 1002 * 1003 * PARAMETERS: Field - Root field 1004 * 1005 * RETURN: None 1006 * 1007 * DESCRIPTION: Dump the entire field list 1008 * 1009 *****************************************************************************/ 1010 1011void 1012DtDumpFieldList ( 1013 DT_FIELD *Field) 1014{ 1015 1016 if (!Gbl_DebugFlag || !Field) 1017 { 1018 return; 1019 } 1020 1021 DbgPrint (ASL_DEBUG_OUTPUT, "\nField List:\n" 1022 "LineNo ByteOff NameCol Column TableOff " 1023 "Flags %32s : %s\n\n", "Name", "Value"); 1024 1025 while (Field) 1026 { 1027 DbgPrint (ASL_DEBUG_OUTPUT, 1028 "%.08X %.08X %.08X %.08X %.08X %2.2X %32s : %s\n", 1029 Field->Line, Field->ByteOffset, Field->NameColumn, 1030 Field->Column, Field->TableOffset, Field->Flags, 1031 Field->Name, Field->Value); 1032 1033 Field = Field->Next; 1034 } 1035 1036 DbgPrint (ASL_DEBUG_OUTPUT, "\n\n"); 1037} 1038 1039 1040/****************************************************************************** 1041 * 1042 * FUNCTION: DtDumpSubtableInfo, DtDumpSubtableTree 1043 * 1044 * PARAMETERS: DT_WALK_CALLBACK 1045 * 1046 * RETURN: None 1047 * 1048 * DESCRIPTION: Info - dump a subtable tree entry with extra information. 1049 * Tree - dump a subtable tree formatted by depth indentation. 1050 * 1051 *****************************************************************************/ 1052 1053static void 1054DtDumpSubtableInfo ( 1055 DT_SUBTABLE *Subtable, 1056 void *Context, 1057 void *ReturnValue) 1058{ 1059 1060 DbgPrint (ASL_DEBUG_OUTPUT, 1061 "[%.04X] %24s %.08X %.08X %.08X %.08X %.08X %p %p %p\n", 1062 Subtable->Depth, Subtable->Name, Subtable->Length, Subtable->TotalLength, 1063 Subtable->SizeOfLengthField, Subtable->Flags, Subtable, 1064 Subtable->Parent, Subtable->Child, Subtable->Peer); 1065} 1066 1067static void 1068DtDumpSubtableTree ( 1069 DT_SUBTABLE *Subtable, 1070 void *Context, 1071 void *ReturnValue) 1072{ 1073 1074 DbgPrint (ASL_DEBUG_OUTPUT, 1075 "[%.04X] %24s %*s%08X (%.02X) - (%.02X)\n", 1076 Subtable->Depth, Subtable->Name, (4 * Subtable->Depth), " ", 1077 Subtable, Subtable->Length, Subtable->TotalLength); 1078} 1079 1080 1081/****************************************************************************** 1082 * 1083 * FUNCTION: DtDumpSubtableList 1084 * 1085 * PARAMETERS: None 1086 * 1087 * RETURN: None 1088 * 1089 * DESCRIPTION: Dump the raw list of subtables with information, and also 1090 * dump the subtable list in formatted tree format. Assists with 1091 * the development of new table code. 1092 * 1093 *****************************************************************************/ 1094 1095void 1096DtDumpSubtableList ( 1097 void) 1098{ 1099 1100 if (!Gbl_DebugFlag || !Gbl_RootTable) 1101 { 1102 return; 1103 } 1104 1105 DbgPrint (ASL_DEBUG_OUTPUT, 1106 "Subtable Info:\n" 1107 "Depth Name Length TotalLen LenSize Flags " 1108 "This Parent Child Peer\n\n"); 1109 DtWalkTableTree (Gbl_RootTable, DtDumpSubtableInfo, NULL, NULL); 1110 1111 DbgPrint (ASL_DEBUG_OUTPUT, 1112 "\nSubtable Tree: (Depth, Name, Subtable, Length, TotalLength)\n\n"); 1113 DtWalkTableTree (Gbl_RootTable, DtDumpSubtableTree, NULL, NULL); 1114 1115 DbgPrint (ASL_DEBUG_OUTPUT, "\n"); 1116} 1117 1118 1119/****************************************************************************** 1120 * 1121 * FUNCTION: DtWriteFieldToListing 1122 * 1123 * PARAMETERS: Buffer - Contains the compiled data 1124 * Field - Field node for the input line 1125 * Length - Length of the output data 1126 * 1127 * RETURN: None 1128 * 1129 * DESCRIPTION: Write one field to the listing file (if listing is enabled). 1130 * 1131 *****************************************************************************/ 1132 1133void 1134DtWriteFieldToListing ( 1135 UINT8 *Buffer, 1136 DT_FIELD *Field, 1137 UINT32 Length) 1138{ 1139 UINT8 FileByte; 1140 1141 1142 if (!Gbl_ListingFlag || !Field) 1143 { 1144 return; 1145 } 1146 1147 /* Dump the original source line */ 1148 1149 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Input: "); 1150 FlSeekFile (ASL_FILE_INPUT, Field->ByteOffset); 1151 1152 while (FlReadFile (ASL_FILE_INPUT, &FileByte, 1) == AE_OK) 1153 { 1154 FlWriteFile (ASL_FILE_LISTING_OUTPUT, &FileByte, 1); 1155 if (FileByte == '\n') 1156 { 1157 break; 1158 } 1159 } 1160 1161 /* Dump the line as parsed and represented internally */ 1162 1163 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Parsed: %*s : %.64s", 1164 Field->Column-4, Field->Name, Field->Value); 1165 1166 if (strlen (Field->Value) > 64) 1167 { 1168 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "...Additional data, length 0x%X\n", 1169 strlen (Field->Value)); 1170 } 1171 1172 FlPrintFile (ASL_FILE_LISTING_OUTPUT, "\n"); 1173 1174 /* Dump the hex data that will be output for this field */ 1175 1176 DtDumpBuffer (ASL_FILE_LISTING_OUTPUT, Buffer, Field->TableOffset, Length); 1177} 1178 1179 1180/****************************************************************************** 1181 * 1182 * FUNCTION: DtWriteTableToListing 1183 * 1184 * PARAMETERS: None 1185 * 1186 * RETURN: None 1187 * 1188 * DESCRIPTION: Write the entire compiled table to the listing file 1189 * in hex format 1190 * 1191 *****************************************************************************/ 1192 1193void 1194DtWriteTableToListing ( 1195 void) 1196{ 1197 UINT8 *Buffer; 1198 1199 1200 if (!Gbl_ListingFlag) 1201 { 1202 return; 1203 } 1204 1205 /* Read the entire table from the output file */ 1206 1207 Buffer = UtLocalCalloc (Gbl_TableLength); 1208 FlSeekFile (ASL_FILE_AML_OUTPUT, 0); 1209 FlReadFile (ASL_FILE_AML_OUTPUT, Buffer, Gbl_TableLength); 1210 1211 /* Dump the raw table data */ 1212 1213 AcpiOsRedirectOutput (Gbl_Files[ASL_FILE_LISTING_OUTPUT].Handle); 1214 1215 AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n", 1216 ACPI_RAW_TABLE_DATA_HEADER, Gbl_TableLength, Gbl_TableLength); 1217 AcpiUtDumpBuffer (Buffer, Gbl_TableLength, DB_BYTE_DISPLAY, 0); 1218 1219 AcpiOsRedirectOutput (stdout); 1220 ACPI_FREE (Buffer); 1221} 1222