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