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