1 2 /****************************************************************************** 3 * 4 * Module Name: asllisting - Listing file generation 5 * $Revision: 1.63 $ 6 * 7 *****************************************************************************/ 8 9 /****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999 - 2007, Intel Corp. 14 * All rights reserved. 15 * 16 * 2. License 17 * 18 * 2.1. This is your license from Intel Corp. under its intellectual property 19 * rights. You may have additional license terms from the party that provided 20 * you this software, covering your right to use that party's intellectual 21 * property rights. 22 * 23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24 * copy of the source code appearing in this file ("Covered Code") an 25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26 * base code distributed originally by Intel ("Original Intel Code") to copy, 27 * make derivatives, distribute, use and display any portion of the Covered 28 * Code in any form, with the right to sublicense such rights; and 29 * 30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31 * license (with the right to sublicense), under only those claims of Intel 32 * patents that are infringed by the Original Intel Code, to make, use, sell, 33 * offer to sell, and import the Covered Code and derivative works thereof 34 * solely to the minimum extent necessary to exercise the above copyright 35 * license, and in no event shall the patent license extend to any additions 36 * to or modifications of the Original Intel Code. No other license or right 37 * is granted directly or by implication, estoppel or otherwise; 38 * 39 * The above copyright and patent license is granted only if the following 40 * conditions are met: 41 * 42 * 3. Conditions 43 * 44 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45 * Redistribution of source code of any substantial portion of the Covered 46 * Code or modification with rights to further distribute source must include 47 * the above Copyright Notice, the above License, this list of Conditions, 48 * and the following Disclaimer and Export Compliance provision. In addition, 49 * Licensee must cause all Covered Code to which Licensee contributes to 50 * contain a file documenting the changes Licensee made to create that Covered 51 * Code and the date of any change. Licensee must include in that file the 52 * documentation of any changes made by any predecessor Licensee. Licensee 53 * must include a prominent statement that the modification is derived, 54 * directly or indirectly, from Original Intel Code. 55 * 56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57 * Redistribution of source code of any substantial portion of the Covered 58 * Code or modification without rights to further distribute source must 59 * include the following Disclaimer and Export Compliance provision in the 60 * documentation and/or other materials provided with distribution. In 61 * addition, Licensee may not authorize further sublicense of source of any 62 * portion of the Covered Code, and must include terms to the effect that the 63 * license from Licensee to its licensee is limited to the intellectual 64 * property embodied in the software Licensee provides to its licensee, and 65 * not to intellectual property embodied in modifications its licensee may 66 * make. 67 * 68 * 3.3. Redistribution of Executable. Redistribution in executable form of any 69 * substantial portion of the Covered Code or modification must reproduce the 70 * above Copyright Notice, and the following Disclaimer and Export Compliance 71 * provision in the documentation and/or other materials provided with the 72 * distribution. 73 * 74 * 3.4. Intel retains all right, title, and interest in and to the Original 75 * Intel Code. 76 * 77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78 * Intel shall be used in advertising or otherwise to promote the sale, use or 79 * other dealings in products derived from or relating to the Covered Code 80 * without prior written authorization from Intel. 81 * 82 * 4. Disclaimer and Export Compliance 83 * 84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90 * PARTICULAR PURPOSE. 91 * 92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99 * LIMITED REMEDY. 100 * 101 * 4.3. Licensee shall not export, either directly or indirectly, any of this 102 * software or system incorporating such software without first obtaining any 103 * required license or other approval from the U. S. Department of Commerce or 104 * any other agency or department of the United States Government. In the 105 * event Licensee exports any such software from the United States or 106 * re-exports any such software from a foreign destination, Licensee shall 107 * ensure that the distribution and export/re-export of the software is in 108 * compliance with all laws, regulations, orders, or other restrictions of the 109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110 * any of its subsidiaries will export/re-export any technical data, process, 111 * software, or service, directly or indirectly, to any country for which the 112 * United States government or any agency thereof requires an export license, 113 * other governmental approval, or letter of assurance, without first obtaining 114 * such license, approval or letter. 115 * 116 *****************************************************************************/ 117 118 119 #include <contrib/dev/acpica/compiler/aslcompiler.h> 120 #include "aslcompiler.y.h" 121 #include <contrib/dev/acpica/amlcode.h> 122 #include <contrib/dev/acpica/acparser.h> 123 #include <contrib/dev/acpica/acnamesp.h> 124 125 #define _COMPONENT ACPI_COMPILER 126 ACPI_MODULE_NAME ("aslisting") 127 128 /* Local prototypes */ 129 130 static void 131 LsDumpAscii ( 132 UINT32 FileId, 133 UINT32 Count, 134 UINT8 *Buffer); 135 136 static void 137 LsDumpAsciiInComment ( 138 UINT32 FileId, 139 UINT32 Count, 140 UINT8 *Buffer); 141 142 static ACPI_STATUS 143 LsAmlListingWalk ( 144 ACPI_PARSE_OBJECT *Op, 145 UINT32 Level, 146 void *Context); 147 148 static void 149 LsGenerateListing ( 150 UINT32 FileId); 151 152 static void 153 LsPushNode ( 154 char *Filename); 155 156 static ASL_LISTING_NODE * 157 LsPopNode ( 158 void); 159 160 static void 161 LsCheckException ( 162 UINT32 LineNumber, 163 UINT32 FileId); 164 165 static void 166 LsFlushListingBuffer ( 167 UINT32 FileId); 168 169 static void 170 LsWriteListingHexBytes ( 171 UINT8 *Buffer, 172 UINT32 Length, 173 UINT32 FileId); 174 175 static UINT32 176 LsWriteOneSourceLine ( 177 UINT32 FileId); 178 179 static void 180 LsFinishSourceListing ( 181 UINT32 FileId); 182 183 static void 184 LsWriteSourceLines ( 185 UINT32 ToLineNumber, 186 UINT32 ToLogicalLineNumber, 187 UINT32 FileId); 188 189 static void 190 LsWriteNodeToListing ( 191 ACPI_PARSE_OBJECT *Op, 192 UINT32 FileId); 193 194 static void 195 LsDoHexOutputC ( 196 void); 197 198 static void 199 LsDoHexOutputAsm ( 200 void); 201 202 203 /******************************************************************************* 204 * 205 * FUNCTION: LsTreeWriteWalk 206 * 207 * PARAMETERS: ASL_WALK_CALLBACK 208 * 209 * 210 * RETURN: None. 211 * 212 * DESCRIPTION: Dump entire parse tree, for compiler debug only 213 * 214 ******************************************************************************/ 215 216 ACPI_STATUS 217 LsTreeWriteWalk ( 218 ACPI_PARSE_OBJECT *Op, 219 UINT32 Level, 220 void *Context) 221 { 222 223 /* Debug output */ 224 225 DbgPrint (ASL_TREE_OUTPUT, 226 "%5.5d [%2d]", Op->Asl.LogicalLineNumber, Level); 227 UtPrintFormattedName (Op->Asl.ParseOpcode, Level); 228 229 230 DbgPrint (ASL_TREE_OUTPUT, "\n"); 231 return (AE_OK); 232 } 233 234 235 void 236 LsDumpParseTree ( 237 void) 238 { 239 240 if (!Gbl_DebugFlag) 241 { 242 return; 243 } 244 245 DbgPrint (ASL_TREE_OUTPUT, "\nOriginal parse tree from parser:\n\n"); 246 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 247 LsTreeWriteWalk, NULL, NULL); 248 } 249 250 251 /******************************************************************************* 252 * 253 * FUNCTION: LsDumpAscii 254 * 255 * PARAMETERS: FileId - ID of current listing file 256 * Count - Number of bytes to convert 257 * Buffer - Buffer of bytes to convert 258 * 259 * RETURN: None. 260 * 261 * DESCRIPTION: Convert hex bytes to ascii 262 * 263 ******************************************************************************/ 264 265 static void 266 LsDumpAscii ( 267 UINT32 FileId, 268 UINT32 Count, 269 UINT8 *Buffer) 270 { 271 UINT8 BufChar; 272 UINT32 i; 273 274 275 FlPrintFile (FileId, " \""); 276 for (i = 0; i < Count; i++) 277 { 278 BufChar = Buffer[i]; 279 if (isprint (BufChar)) 280 { 281 FlPrintFile (FileId, "%c", BufChar); 282 } 283 else 284 { 285 /* Not a printable character, just put out a dot */ 286 287 FlPrintFile (FileId, "."); 288 } 289 } 290 FlPrintFile (FileId, "\""); 291 } 292 293 294 /******************************************************************************* 295 * 296 * FUNCTION: LsDumpAsciiInComment 297 * 298 * PARAMETERS: FileId - ID of current listing file 299 * Count - Number of bytes to convert 300 * Buffer - Buffer of bytes to convert 301 * 302 * RETURN: None. 303 * 304 * DESCRIPTION: Convert hex bytes to ascii 305 * 306 ******************************************************************************/ 307 308 static void 309 LsDumpAsciiInComment ( 310 UINT32 FileId, 311 UINT32 Count, 312 UINT8 *Buffer) 313 { 314 UINT8 BufChar = 0; 315 UINT8 LastChar; 316 UINT32 i; 317 318 319 FlPrintFile (FileId, " \""); 320 for (i = 0; i < Count; i++) 321 { 322 LastChar = BufChar; 323 BufChar = Buffer[i]; 324 325 if (isprint (BufChar)) 326 { 327 /* Handle embedded C comment sequences */ 328 329 if (((LastChar == '*') && (BufChar == '/')) || 330 ((LastChar == '/') && (BufChar == '*'))) 331 { 332 /* Insert a space to break the sequence */ 333 334 FlPrintFile (FileId, ".", BufChar); 335 } 336 337 FlPrintFile (FileId, "%c", BufChar); 338 } 339 else 340 { 341 /* Not a printable character, just put out a dot */ 342 343 FlPrintFile (FileId, "."); 344 } 345 } 346 FlPrintFile (FileId, "\""); 347 } 348 349 350 /******************************************************************************* 351 * 352 * FUNCTION: LsAmlListingWalk 353 * 354 * PARAMETERS: ASL_WALK_CALLBACK 355 * 356 * RETURN: Status 357 * 358 * DESCRIPTION: Process one node during a listing file generation. 359 * 360 ******************************************************************************/ 361 362 static ACPI_STATUS 363 LsAmlListingWalk ( 364 ACPI_PARSE_OBJECT *Op, 365 UINT32 Level, 366 void *Context) 367 { 368 UINT8 FileByte; 369 UINT32 i; 370 UINT32 FileId = (UINT32) ACPI_TO_INTEGER (Context); 371 372 373 LsWriteNodeToListing (Op, FileId); 374 375 if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DATA) 376 { 377 /* Buffer is a resource template, don't dump the data all at once */ 378 379 return (AE_OK); 380 } 381 382 /* Write the hex bytes to the listing file(s) (if requested) */ 383 384 for (i = 0; i < Op->Asl.FinalAmlLength; i++) 385 { 386 if (ACPI_FAILURE (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte, 1))) 387 { 388 FlFileError (ASL_FILE_AML_OUTPUT, ASL_MSG_READ); 389 AslAbort (); 390 } 391 LsWriteListingHexBytes (&FileByte, 1, FileId); 392 } 393 394 return (AE_OK); 395 } 396 397 398 /******************************************************************************* 399 * 400 * FUNCTION: LsGenerateListing 401 * 402 * PARAMETERS: FileId - ID of listing file 403 * 404 * RETURN: None 405 * 406 * DESCRIPTION: Generate a listing file. This can be one of the several types 407 * of "listings" supported. 408 * 409 ******************************************************************************/ 410 411 static void 412 LsGenerateListing ( 413 UINT32 FileId) 414 { 415 416 /* Start at the beginning of both the source and AML files */ 417 418 FlSeekFile (ASL_FILE_SOURCE_OUTPUT, 0); 419 FlSeekFile (ASL_FILE_AML_OUTPUT, 0); 420 Gbl_SourceLine = 0; 421 Gbl_CurrentHexColumn = 0; 422 LsPushNode (Gbl_Files[ASL_FILE_INPUT].Filename); 423 424 /* Process all parse nodes */ 425 426 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, LsAmlListingWalk, 427 NULL, (void *) ACPI_TO_POINTER (FileId)); 428 429 /* Final processing */ 430 431 LsFinishSourceListing (FileId); 432 } 433 434 435 /******************************************************************************* 436 * 437 * FUNCTION: LsDoListings 438 * 439 * PARAMETERS: None. 440 * 441 * RETURN: None 442 * 443 * DESCRIPTION: Generate all requested listing files. 444 * 445 ******************************************************************************/ 446 447 void 448 LsDoListings ( 449 void) 450 { 451 452 if (Gbl_C_OutputFlag) 453 { 454 LsGenerateListing (ASL_FILE_C_SOURCE_OUTPUT); 455 } 456 457 if (Gbl_ListingFlag) 458 { 459 LsGenerateListing (ASL_FILE_LISTING_OUTPUT); 460 } 461 462 if (Gbl_AsmOutputFlag) 463 { 464 LsGenerateListing (ASL_FILE_ASM_SOURCE_OUTPUT); 465 } 466 467 if (Gbl_C_IncludeOutputFlag) 468 { 469 LsGenerateListing (ASL_FILE_C_INCLUDE_OUTPUT); 470 } 471 472 if (Gbl_AsmIncludeOutputFlag) 473 { 474 LsGenerateListing (ASL_FILE_ASM_INCLUDE_OUTPUT); 475 } 476 } 477 478 479 /******************************************************************************* 480 * 481 * FUNCTION: LsPushNode 482 * 483 * PARAMETERS: Filename - Pointer to the include filename 484 * 485 * RETURN: None 486 * 487 * DESCRIPTION: Push a listing node on the listing/include file stack. This 488 * stack enables tracking of include files (infinitely nested) 489 * and resumption of the listing of the parent file when the 490 * include file is finished. 491 * 492 ******************************************************************************/ 493 494 static void 495 LsPushNode ( 496 char *Filename) 497 { 498 ASL_LISTING_NODE *Lnode; 499 500 501 /* Create a new node */ 502 503 Lnode = UtLocalCalloc (sizeof (ASL_LISTING_NODE)); 504 505 /* Initialize */ 506 507 Lnode->Filename = Filename; 508 Lnode->LineNumber = 0; 509 510 /* Link (push) */ 511 512 Lnode->Next = Gbl_ListingNode; 513 Gbl_ListingNode = Lnode; 514 } 515 516 517 /******************************************************************************* 518 * 519 * FUNCTION: LsPopNode 520 * 521 * PARAMETERS: None 522 * 523 * RETURN: List head after current head is popped off 524 * 525 * DESCRIPTION: Pop the current head of the list, free it, and return the 526 * next node on the stack (the new current node). 527 * 528 ******************************************************************************/ 529 530 static ASL_LISTING_NODE * 531 LsPopNode ( 532 void) 533 { 534 ASL_LISTING_NODE *Lnode; 535 536 537 /* Just grab the node at the head of the list */ 538 539 Lnode = Gbl_ListingNode; 540 if ((!Lnode) || 541 (!Lnode->Next)) 542 { 543 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, NULL, 544 "Could not pop empty listing stack"); 545 return Gbl_ListingNode; 546 } 547 548 Gbl_ListingNode = Lnode->Next; 549 ACPI_FREE (Lnode); 550 551 /* New "Current" node is the new head */ 552 553 return (Gbl_ListingNode); 554 } 555 556 557 /******************************************************************************* 558 * 559 * FUNCTION: LsCheckException 560 * 561 * PARAMETERS: LineNumber - Current logical (cumulative) line # 562 * FileId - ID of output listing file 563 * 564 * RETURN: None 565 * 566 * DESCRIPTION: Check if there is an exception for this line, and if there is, 567 * put it in the listing immediately. Handles multiple errors 568 * per line. Gbl_NextError points to the next error in the 569 * sorted (by line #) list of compile errors/warnings. 570 * 571 ******************************************************************************/ 572 573 static void 574 LsCheckException ( 575 UINT32 LineNumber, 576 UINT32 FileId) 577 { 578 579 if ((!Gbl_NextError) || 580 (LineNumber < Gbl_NextError->LogicalLineNumber )) 581 { 582 return; 583 } 584 585 /* Handle multiple errors per line */ 586 587 if (FileId == ASL_FILE_LISTING_OUTPUT) 588 { 589 while (Gbl_NextError && 590 (LineNumber >= Gbl_NextError->LogicalLineNumber)) 591 { 592 AePrintException (FileId, Gbl_NextError, "\n[****iasl****]\n"); 593 594 Gbl_NextError = Gbl_NextError->Next; 595 } 596 597 FlPrintFile (FileId, "\n"); 598 } 599 } 600 601 602 /******************************************************************************* 603 * 604 * FUNCTION: LsFlushListingBuffer 605 * 606 * PARAMETERS: FileId - ID of the listing file 607 * 608 * RETURN: None 609 * 610 * DESCRIPTION: Flush out the current contents of the 16-byte hex AML code 611 * buffer. Usually called at the termination of a single line 612 * of source code or when the buffer is full. 613 * 614 ******************************************************************************/ 615 616 static void 617 LsFlushListingBuffer ( 618 UINT32 FileId) 619 { 620 UINT32 i; 621 622 623 if (Gbl_CurrentHexColumn == 0) 624 { 625 return; 626 } 627 628 /* Write the hex bytes */ 629 630 switch (FileId) 631 { 632 case ASL_FILE_LISTING_OUTPUT: 633 634 for (i = 0; i < Gbl_CurrentHexColumn; i++) 635 { 636 FlPrintFile (FileId, "%2.2X ", Gbl_AmlBuffer[i]); 637 } 638 639 for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 3); i++) 640 { 641 FlWriteFile (FileId, ".", 1); 642 } 643 644 /* Write the ASCII character associated with each of the bytes */ 645 646 LsDumpAscii (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer); 647 break; 648 649 650 case ASL_FILE_ASM_SOURCE_OUTPUT: 651 652 for (i = 0; i < Gbl_CurrentHexColumn; i++) 653 { 654 if (i > 0) 655 { 656 FlPrintFile (FileId, ","); 657 } 658 FlPrintFile (FileId, "0%2.2Xh", Gbl_AmlBuffer[i]); 659 } 660 661 for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 5); i++) 662 { 663 FlWriteFile (FileId, " ", 1); 664 } 665 666 FlPrintFile (FileId, " ;%8.8X", 667 Gbl_CurrentAmlOffset - HEX_LISTING_LINE_SIZE); 668 669 /* Write the ASCII character associated with each of the bytes */ 670 671 LsDumpAscii (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer); 672 break; 673 674 675 case ASL_FILE_C_SOURCE_OUTPUT: 676 677 for (i = 0; i < Gbl_CurrentHexColumn; i++) 678 { 679 FlPrintFile (FileId, "0x%2.2X,", Gbl_AmlBuffer[i]); 680 } 681 682 for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 5); i++) 683 { 684 FlWriteFile (FileId, " ", 1); 685 } 686 687 FlPrintFile (FileId, " /* %8.8X", 688 Gbl_CurrentAmlOffset - HEX_LISTING_LINE_SIZE); 689 690 /* Write the ASCII character associated with each of the bytes */ 691 692 LsDumpAsciiInComment (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer); 693 FlPrintFile (FileId, " */"); 694 break; 695 696 default: 697 /* No other types supported */ 698 return; 699 } 700 701 FlPrintFile (FileId, "\n"); 702 703 Gbl_CurrentHexColumn = 0; 704 Gbl_HexBytesWereWritten = TRUE; 705 } 706 707 708 /******************************************************************************* 709 * 710 * FUNCTION: LsWriteListingHexBytes 711 * 712 * PARAMETERS: Buffer - AML code buffer 713 * Length - Number of AML bytes to write 714 * FileId - ID of current listing file. 715 * 716 * RETURN: None 717 * 718 * DESCRIPTION: Write the contents of the AML buffer to the listing file via 719 * the listing buffer. The listing buffer is flushed every 16 720 * AML bytes. 721 * 722 ******************************************************************************/ 723 724 static void 725 LsWriteListingHexBytes ( 726 UINT8 *Buffer, 727 UINT32 Length, 728 UINT32 FileId) 729 { 730 UINT32 i; 731 732 733 /* Transfer all requested bytes */ 734 735 for (i = 0; i < Length; i++) 736 { 737 /* Print line header when buffer is empty */ 738 739 if (Gbl_CurrentHexColumn == 0) 740 { 741 if (Gbl_HasIncludeFiles) 742 { 743 FlPrintFile (FileId, "%*s", 10, " "); 744 } 745 746 switch (FileId) 747 { 748 case ASL_FILE_LISTING_OUTPUT: 749 750 FlPrintFile (FileId, "%8.8X....", Gbl_CurrentAmlOffset); 751 break; 752 753 case ASL_FILE_ASM_SOURCE_OUTPUT: 754 755 FlPrintFile (FileId, " db "); 756 break; 757 758 case ASL_FILE_C_SOURCE_OUTPUT: 759 760 FlPrintFile (FileId, " "); 761 break; 762 763 default: 764 /* No other types supported */ 765 return; 766 } 767 } 768 769 /* Transfer AML byte and update counts */ 770 771 Gbl_AmlBuffer[Gbl_CurrentHexColumn] = Buffer[i]; 772 773 Gbl_CurrentHexColumn++; 774 Gbl_CurrentAmlOffset++; 775 776 /* Flush buffer when it is full */ 777 778 if (Gbl_CurrentHexColumn >= HEX_LISTING_LINE_SIZE) 779 { 780 LsFlushListingBuffer (FileId); 781 } 782 } 783 } 784 785 786 /******************************************************************************* 787 * 788 * FUNCTION: LsWriteOneSourceLine 789 * 790 * PARAMETERS: FileID - ID of current listing file 791 * 792 * RETURN: FALSE on EOF (input source file), TRUE otherwise 793 * 794 * DESCRIPTION: Read one line from the input source file and echo it to the 795 * listing file, prefixed with the line number, and if the source 796 * file contains include files, prefixed with the current filename 797 * 798 ******************************************************************************/ 799 800 static UINT32 801 LsWriteOneSourceLine ( 802 UINT32 FileId) 803 { 804 UINT8 FileByte; 805 806 807 Gbl_SourceLine++; 808 Gbl_ListingNode->LineNumber++; 809 810 if (FileId == ASL_FILE_C_SOURCE_OUTPUT) 811 { 812 FlPrintFile (FileId, " *"); 813 } 814 if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT) 815 { 816 FlPrintFile (FileId, "; "); 817 } 818 819 if (Gbl_HasIncludeFiles) 820 { 821 /* 822 * This file contains "include" statements, print the current 823 * filename and line number within the current file 824 */ 825 FlPrintFile (FileId, "%12s %5d....", 826 Gbl_ListingNode->Filename, Gbl_ListingNode->LineNumber); 827 } 828 else 829 { 830 /* No include files, just print the line number */ 831 832 FlPrintFile (FileId, "%8d....", Gbl_SourceLine); 833 } 834 835 /* Read one line (up to a newline or EOF) */ 836 837 while (FlReadFile (ASL_FILE_SOURCE_OUTPUT, &FileByte, 1) == AE_OK) 838 { 839 if (FileId == ASL_FILE_C_SOURCE_OUTPUT) 840 { 841 if (FileByte == '/') 842 { 843 FileByte = '*'; 844 } 845 } 846 847 FlWriteFile (FileId, &FileByte, 1); 848 if (FileByte == '\n') 849 { 850 /* 851 * Check if an error occurred on this source line during the compile. 852 * If so, we print the error message after the source line. 853 */ 854 LsCheckException (Gbl_SourceLine, FileId); 855 return (1); 856 } 857 } 858 859 /* EOF on the input file was reached */ 860 861 return (0); 862 } 863 864 865 /******************************************************************************* 866 * 867 * FUNCTION: LsFinishSourceListing 868 * 869 * PARAMETERS: FileId - ID of current listing file. 870 * 871 * RETURN: None 872 * 873 * DESCRIPTION: Cleanup routine for the listing file. Flush the hex AML 874 * listing buffer, and flush out any remaining lines in the 875 * source input file. 876 * 877 ******************************************************************************/ 878 879 static void 880 LsFinishSourceListing ( 881 UINT32 FileId) 882 { 883 884 if ((FileId == ASL_FILE_ASM_INCLUDE_OUTPUT) || 885 (FileId == ASL_FILE_C_INCLUDE_OUTPUT)) 886 { 887 return; 888 } 889 890 LsFlushListingBuffer (FileId); 891 Gbl_CurrentAmlOffset = 0; 892 893 /* Flush any remaining text in the source file */ 894 895 if (FileId == ASL_FILE_C_SOURCE_OUTPUT) 896 { 897 FlPrintFile (FileId, " /*\n"); 898 } 899 900 while (LsWriteOneSourceLine (FileId)) 901 { ; } 902 903 if (FileId == ASL_FILE_C_SOURCE_OUTPUT) 904 { 905 FlPrintFile (FileId, "\n */\n };\n"); 906 } 907 908 FlPrintFile (FileId, "\n"); 909 910 if (FileId == ASL_FILE_LISTING_OUTPUT) 911 { 912 /* Print a summary of the compile exceptions */ 913 914 FlPrintFile (FileId, "\n\nSummary of errors and warnings\n\n"); 915 AePrintErrorLog (FileId); 916 FlPrintFile (FileId, "\n\n"); 917 UtDisplaySummary (FileId); 918 FlPrintFile (FileId, "\n\n"); 919 } 920 } 921 922 923 /******************************************************************************* 924 * 925 * FUNCTION: LsWriteSourceLines 926 * 927 * PARAMETERS: ToLineNumber - 928 * ToLogicalLineNumber - Write up to this source line number 929 * FileId - ID of current listing file 930 * 931 * RETURN: None 932 * 933 * DESCRIPTION: Read then write source lines to the listing file until we have 934 * reached the specified logical (cumulative) line number. This 935 * automatically echos out comment blocks and other non-AML 936 * generating text until we get to the actual AML-generating line 937 * of ASL code specified by the logical line number. 938 * 939 ******************************************************************************/ 940 941 static void 942 LsWriteSourceLines ( 943 UINT32 ToLineNumber, 944 UINT32 ToLogicalLineNumber, 945 UINT32 FileId) 946 { 947 948 if ((FileId == ASL_FILE_ASM_INCLUDE_OUTPUT) || 949 (FileId == ASL_FILE_C_INCLUDE_OUTPUT)) 950 { 951 return; 952 } 953 954 Gbl_CurrentLine = ToLogicalLineNumber; 955 956 /* Flush any hex bytes remaining from the last opcode */ 957 958 LsFlushListingBuffer (FileId); 959 960 /* Read lines and write them as long as we are not caught up */ 961 962 if (Gbl_SourceLine < Gbl_CurrentLine) 963 { 964 /* 965 * If we just completed writing some AML hex bytes, output a linefeed 966 * to add some whitespace for readability. 967 */ 968 if (Gbl_HexBytesWereWritten) 969 { 970 FlPrintFile (FileId, "\n"); 971 Gbl_HexBytesWereWritten = FALSE; 972 } 973 974 if (FileId == ASL_FILE_C_SOURCE_OUTPUT) 975 { 976 FlPrintFile (FileId, " /*\n"); 977 } 978 979 /* Write one line at a time until we have reached the target line # */ 980 981 while ((Gbl_SourceLine < Gbl_CurrentLine) && 982 LsWriteOneSourceLine (FileId)) 983 { ; } 984 985 if (FileId == ASL_FILE_C_SOURCE_OUTPUT) 986 { 987 FlPrintFile (FileId, " */"); 988 } 989 FlPrintFile (FileId, "\n"); 990 } 991 } 992 993 994 /******************************************************************************* 995 * 996 * FUNCTION: LsWriteNodeToListing 997 * 998 * PARAMETERS: Op - Parse node to write to the listing file. 999 * FileId - ID of current listing file 1000 * 1001 * RETURN: None. 1002 * 1003 * DESCRIPTION: Write "a node" to the listing file. This means to 1004 * 1) Write out all of the source text associated with the node 1005 * 2) Write out all of the AML bytes associated with the node 1006 * 3) Write any compiler exceptions associated with the node 1007 * 1008 ******************************************************************************/ 1009 1010 static void 1011 LsWriteNodeToListing ( 1012 ACPI_PARSE_OBJECT *Op, 1013 UINT32 FileId) 1014 { 1015 const ACPI_OPCODE_INFO *OpInfo; 1016 UINT32 OpClass; 1017 char *Pathname; 1018 UINT32 Length; 1019 UINT32 i; 1020 1021 1022 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 1023 OpClass = OpInfo->Class; 1024 1025 /* TBD: clean this up with a single flag that says: 1026 * I start a named output block 1027 */ 1028 if (FileId == ASL_FILE_C_SOURCE_OUTPUT) 1029 { 1030 switch (Op->Asl.ParseOpcode) 1031 { 1032 case PARSEOP_DEFINITIONBLOCK: 1033 case PARSEOP_METHODCALL: 1034 case PARSEOP_INCLUDE: 1035 case PARSEOP_INCLUDE_END: 1036 case PARSEOP_DEFAULT_ARG: 1037 1038 break; 1039 1040 default: 1041 switch (OpClass) 1042 { 1043 case AML_CLASS_NAMED_OBJECT: 1044 switch (Op->Asl.AmlOpcode) 1045 { 1046 case AML_SCOPE_OP: 1047 case AML_ALIAS_OP: 1048 break; 1049 1050 default: 1051 if (Op->Asl.ExternalName) 1052 { 1053 LsFlushListingBuffer (FileId); 1054 FlPrintFile (FileId, " };\n"); 1055 } 1056 break; 1057 } 1058 break; 1059 1060 default: 1061 /* Don't care about other objects */ 1062 break; 1063 } 1064 break; 1065 } 1066 } 1067 1068 /* These cases do not have a corresponding AML opcode */ 1069 1070 switch (Op->Asl.ParseOpcode) 1071 { 1072 case PARSEOP_DEFINITIONBLOCK: 1073 1074 LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine, FileId); 1075 1076 /* Use the table Signature and TableId to build a unique name */ 1077 1078 if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT) 1079 { 1080 FlPrintFile (FileId, 1081 "%s_%s_Header \\\n", 1082 Gbl_TableSignature, Gbl_TableId); 1083 } 1084 if (FileId == ASL_FILE_C_SOURCE_OUTPUT) 1085 { 1086 FlPrintFile (FileId, 1087 " unsigned char %s_%s_Header [] =\n {\n", 1088 Gbl_TableSignature, Gbl_TableId); 1089 } 1090 if (FileId == ASL_FILE_ASM_INCLUDE_OUTPUT) 1091 { 1092 FlPrintFile (FileId, 1093 "extrn %s_%s_Header : byte\n", 1094 Gbl_TableSignature, Gbl_TableId); 1095 } 1096 if (FileId == ASL_FILE_C_INCLUDE_OUTPUT) 1097 { 1098 FlPrintFile (FileId, 1099 "extern unsigned char %s_%s_Header [];\n", 1100 Gbl_TableSignature, Gbl_TableId); 1101 } 1102 return; 1103 1104 1105 case PARSEOP_METHODCALL: 1106 1107 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, 1108 FileId); 1109 return; 1110 1111 1112 case PARSEOP_INCLUDE: 1113 1114 /* Flush everything up to and including the include source line */ 1115 1116 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, 1117 FileId); 1118 1119 /* Create a new listing node and push it */ 1120 1121 LsPushNode (Op->Asl.Child->Asl.Value.String); 1122 return; 1123 1124 1125 case PARSEOP_INCLUDE_END: 1126 1127 /* Flush out the rest of the include file */ 1128 1129 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, 1130 FileId); 1131 1132 /* Pop off this listing node and go back to the parent file */ 1133 1134 (void) LsPopNode (); 1135 return; 1136 1137 1138 case PARSEOP_DEFAULT_ARG: 1139 1140 if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 1141 { 1142 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.EndLogicalLine, 1143 FileId); 1144 } 1145 return; 1146 1147 1148 default: 1149 /* All other opcodes have an AML opcode */ 1150 break; 1151 } 1152 1153 /* 1154 * Otherwise, we look at the AML opcode because we can 1155 * switch on the opcode type, getting an entire class 1156 * at once 1157 */ 1158 switch (OpClass) 1159 { 1160 case AML_CLASS_ARGUMENT: /* argument type only */ 1161 case AML_CLASS_INTERNAL: 1162 1163 break; 1164 1165 1166 case AML_CLASS_NAMED_OBJECT: 1167 1168 switch (Op->Asl.AmlOpcode) 1169 { 1170 case AML_FIELD_OP: 1171 case AML_INDEX_FIELD_OP: 1172 case AML_BANK_FIELD_OP: 1173 1174 /* 1175 * For fields, we want to dump all the AML after the 1176 * entire definition 1177 */ 1178 LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine, 1179 FileId); 1180 break; 1181 1182 case AML_NAME_OP: 1183 1184 if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 1185 { 1186 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, 1187 FileId); 1188 } 1189 else 1190 { 1191 /* 1192 * For fields, we want to dump all the AML after the 1193 * entire definition 1194 */ 1195 LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine, 1196 FileId); 1197 } 1198 break; 1199 1200 default: 1201 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, 1202 FileId); 1203 break; 1204 } 1205 1206 switch (Op->Asl.AmlOpcode) 1207 { 1208 case AML_SCOPE_OP: 1209 case AML_ALIAS_OP: 1210 1211 /* These opcodes do not declare a new object, ignore them */ 1212 1213 break; 1214 1215 default: 1216 1217 /* All other named object opcodes come here */ 1218 1219 switch (FileId) 1220 { 1221 case ASL_FILE_ASM_SOURCE_OUTPUT: 1222 case ASL_FILE_C_SOURCE_OUTPUT: 1223 case ASL_FILE_ASM_INCLUDE_OUTPUT: 1224 case ASL_FILE_C_INCLUDE_OUTPUT: 1225 1226 /* 1227 * For named objects, we will create a valid symbol so that the 1228 * AML code can be referenced from C or ASM 1229 */ 1230 if (Op->Asl.ExternalName) 1231 { 1232 /* Get the full pathname associated with this node */ 1233 1234 Pathname = AcpiNsGetExternalPathname (Op->Asl.Node); 1235 Length = strlen (Pathname); 1236 if (Length >= 4) 1237 { 1238 /* Convert all dots in the path to underscores */ 1239 1240 for (i = 0; i < Length; i++) 1241 { 1242 if (Pathname[i] == '.') 1243 { 1244 Pathname[i] = '_'; 1245 } 1246 } 1247 1248 /* Create the appropriate symbol in the output file */ 1249 1250 if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT) 1251 { 1252 FlPrintFile (FileId, 1253 "%s_%s_%s \\\n", 1254 Gbl_TableSignature, Gbl_TableId, &Pathname[1]); 1255 } 1256 if (FileId == ASL_FILE_C_SOURCE_OUTPUT) 1257 { 1258 FlPrintFile (FileId, 1259 " unsigned char %s_%s_%s [] =\n {\n", 1260 Gbl_TableSignature, Gbl_TableId, &Pathname[1]); 1261 } 1262 if (FileId == ASL_FILE_ASM_INCLUDE_OUTPUT) 1263 { 1264 FlPrintFile (FileId, 1265 "extrn %s_%s_%s : byte\n", 1266 Gbl_TableSignature, Gbl_TableId, &Pathname[1]); 1267 } 1268 if (FileId == ASL_FILE_C_INCLUDE_OUTPUT) 1269 { 1270 FlPrintFile (FileId, 1271 "extern unsigned char %s_%s_%s [];\n", 1272 Gbl_TableSignature, Gbl_TableId, &Pathname[1]); 1273 } 1274 } 1275 ACPI_FREE (Pathname); 1276 } 1277 break; 1278 1279 default: 1280 /* Nothing to do for listing file */ 1281 break; 1282 } 1283 } 1284 break; 1285 1286 case AML_CLASS_EXECUTE: 1287 case AML_CLASS_CREATE: 1288 default: 1289 1290 if ((Op->Asl.ParseOpcode == PARSEOP_BUFFER) && 1291 (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)) 1292 { 1293 return; 1294 } 1295 1296 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, 1297 FileId); 1298 break; 1299 1300 case AML_CLASS_UNKNOWN: 1301 break; 1302 } 1303 } 1304 1305 1306 /******************************************************************************* 1307 * 1308 * FUNCTION: LsDoHexOutput 1309 * 1310 * PARAMETERS: None 1311 * 1312 * RETURN: None. 1313 * 1314 * DESCRIPTION: Create the hex output file. 1315 * 1316 ******************************************************************************/ 1317 1318 void 1319 LsDoHexOutput ( 1320 void) 1321 { 1322 1323 switch (Gbl_HexOutputFlag) 1324 { 1325 case HEX_OUTPUT_C: 1326 1327 LsDoHexOutputC (); 1328 break; 1329 1330 case HEX_OUTPUT_ASM: 1331 1332 LsDoHexOutputAsm (); 1333 break; 1334 1335 default: 1336 /* No other output types supported */ 1337 break; 1338 } 1339 } 1340 1341 1342 /******************************************************************************* 1343 * 1344 * FUNCTION: LsDoHexOutputC 1345 * 1346 * PARAMETERS: None 1347 * 1348 * RETURN: None. 1349 * 1350 * DESCRIPTION: Create the hex output file. This is the same data as the AML 1351 * output file, but formatted into hex/ascii bytes suitable for 1352 * inclusion into a C source file. 1353 * 1354 ******************************************************************************/ 1355 1356 static void 1357 LsDoHexOutputC ( 1358 void) 1359 { 1360 UINT32 j; 1361 UINT8 FileByte[HEX_TABLE_LINE_SIZE]; 1362 UINT8 Buffer[4]; 1363 UINT32 Offset = 0; 1364 1365 1366 FlPrintFile (ASL_FILE_HEX_OUTPUT, " * C source code output\n *\n */\n"); 1367 FlPrintFile (ASL_FILE_HEX_OUTPUT, "unsigned char AmlCode[] =\n{\n"); 1368 1369 /* Start at the beginning of the AML file */ 1370 1371 FlSeekFile (ASL_FILE_AML_OUTPUT, 0); 1372 1373 /* Process all AML bytes in the AML file */ 1374 1375 j = 0; 1376 while (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte[j], 1) == AE_OK) 1377 { 1378 if (j == 0) 1379 { 1380 FlPrintFile (ASL_FILE_HEX_OUTPUT, " "); 1381 } 1382 1383 /* Convert each AML byte to hex */ 1384 1385 UtConvertByteToHex (FileByte[j], Buffer); 1386 FlWriteFile (ASL_FILE_HEX_OUTPUT, Buffer, 4); 1387 FlPrintFile (ASL_FILE_HEX_OUTPUT, ","); 1388 1389 /* An occasional linefeed improves readability */ 1390 1391 Offset++; 1392 j++; 1393 1394 if (j >= HEX_TABLE_LINE_SIZE) 1395 { 1396 /* End of line, emit the ascii dump of the entire line */ 1397 1398 FlPrintFile (ASL_FILE_HEX_OUTPUT, 1399 " /* %8.8X", Offset - HEX_TABLE_LINE_SIZE); 1400 1401 /* Write the ASCII character associated with each of the bytes */ 1402 1403 LsDumpAsciiInComment (ASL_FILE_HEX_OUTPUT, 1404 HEX_TABLE_LINE_SIZE, FileByte); 1405 FlPrintFile (ASL_FILE_HEX_OUTPUT, " */\n"); 1406 1407 /* Start new line */ 1408 1409 j = 0; 1410 } 1411 } 1412 1413 FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n};\n"); 1414 FlCloseFile (ASL_FILE_HEX_OUTPUT); 1415 } 1416 1417 1418 /******************************************************************************* 1419 * 1420 * FUNCTION: LsDoHexOutputAsm 1421 * 1422 * PARAMETERS: None 1423 * 1424 * RETURN: None. 1425 * 1426 * DESCRIPTION: Create the hex output file. This is the same data as the AML 1427 * output file, but formatted into hex/ascii bytes suitable for 1428 * inclusion into a ASM source file. 1429 * 1430 ******************************************************************************/ 1431 1432 static void 1433 LsDoHexOutputAsm ( 1434 void) 1435 { 1436 UINT32 j; 1437 UINT8 FileByte[HEX_TABLE_LINE_SIZE]; 1438 UINT8 Buffer[4]; 1439 UINT32 Offset = 0; 1440 BOOLEAN DoComma = FALSE; 1441 1442 1443 FlPrintFile (ASL_FILE_HEX_OUTPUT, "; Assembly code source output\n;\n"); 1444 1445 /* Start at the beginning of the AML file */ 1446 1447 FlSeekFile (ASL_FILE_AML_OUTPUT, 0); 1448 1449 /* Process all AML bytes in the AML file */ 1450 1451 j = 0; 1452 while (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte[j], 1) == AE_OK) 1453 { 1454 if (j == 0) 1455 { 1456 FlPrintFile (ASL_FILE_HEX_OUTPUT, " db "); 1457 } 1458 else if (DoComma) 1459 { 1460 FlPrintFile (ASL_FILE_HEX_OUTPUT, ","); 1461 DoComma = FALSE; 1462 } 1463 1464 /* Convert each AML byte to hex */ 1465 1466 UtConvertByteToAsmHex (FileByte[j], Buffer); 1467 FlWriteFile (ASL_FILE_HEX_OUTPUT, Buffer, 4); 1468 1469 /* An occasional linefeed improves readability */ 1470 1471 Offset++; 1472 j++; 1473 if (j >= HEX_TABLE_LINE_SIZE) 1474 { 1475 FlPrintFile (ASL_FILE_HEX_OUTPUT, 1476 " ;%8.8X", Offset - HEX_TABLE_LINE_SIZE); 1477 1478 /* Write the ASCII character associated with each of the bytes */ 1479 1480 LsDumpAscii (ASL_FILE_HEX_OUTPUT, HEX_TABLE_LINE_SIZE, FileByte); 1481 FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n"); 1482 j = 0; 1483 } 1484 else 1485 { 1486 DoComma = TRUE; 1487 } 1488 } 1489 1490 FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n"); 1491 FlCloseFile (ASL_FILE_HEX_OUTPUT); 1492 } 1493 1494 1495