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