1 2 /****************************************************************************** 3 * 4 * Module Name: asllisting - Listing file generation 5 * $Revision: 1.58 $ 6 * 7 *****************************************************************************/ 8 9 /****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999 - 2005, 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: LsDumpAscii 206 * 207 * PARAMETERS: FileId - ID of current listing file 208 * Count - Number of bytes to convert 209 * Buffer - Buffer of bytes to convert 210 * 211 * RETURN: None. 212 * 213 * DESCRIPTION: Convert hex bytes to ascii 214 * 215 ******************************************************************************/ 216 217 static void 218 LsDumpAscii ( 219 UINT32 FileId, 220 UINT32 Count, 221 UINT8 *Buffer) 222 { 223 UINT8 BufChar; 224 UINT32 i; 225 226 227 FlPrintFile (FileId, " \""); 228 for (i = 0; i < Count; i++) 229 { 230 BufChar = Buffer[i]; 231 if (isprint (BufChar)) 232 { 233 FlPrintFile (FileId, "%c", BufChar); 234 } 235 else 236 { 237 /* Not a printable character, just put out a dot */ 238 239 FlPrintFile (FileId, "."); 240 } 241 } 242 FlPrintFile (FileId, "\""); 243 } 244 245 246 /******************************************************************************* 247 * 248 * FUNCTION: LsDumpAsciiInComment 249 * 250 * PARAMETERS: FileId - ID of current listing file 251 * Count - Number of bytes to convert 252 * Buffer - Buffer of bytes to convert 253 * 254 * RETURN: None. 255 * 256 * DESCRIPTION: Convert hex bytes to ascii 257 * 258 ******************************************************************************/ 259 260 static void 261 LsDumpAsciiInComment ( 262 UINT32 FileId, 263 UINT32 Count, 264 UINT8 *Buffer) 265 { 266 UINT8 BufChar = 0; 267 UINT8 LastChar; 268 UINT32 i; 269 270 271 FlPrintFile (FileId, " \""); 272 for (i = 0; i < Count; i++) 273 { 274 LastChar = BufChar; 275 BufChar = Buffer[i]; 276 277 if (isprint (BufChar)) 278 { 279 /* Handle embedded C comment sequences */ 280 281 if (((LastChar == '*') && (BufChar == '/')) || 282 ((LastChar == '/') && (BufChar == '*'))) 283 { 284 /* Insert a space to break the sequence */ 285 286 FlPrintFile (FileId, ".", BufChar); 287 } 288 289 FlPrintFile (FileId, "%c", BufChar); 290 } 291 else 292 { 293 /* Not a printable character, just put out a dot */ 294 295 FlPrintFile (FileId, "."); 296 } 297 } 298 FlPrintFile (FileId, "\""); 299 } 300 301 302 /******************************************************************************* 303 * 304 * FUNCTION: LsAmlListingWalk 305 * 306 * PARAMETERS: ASL_WALK_CALLBACK 307 * 308 * RETURN: Status 309 * 310 * DESCRIPTION: Process one node during a listing file generation. 311 * 312 ******************************************************************************/ 313 314 static ACPI_STATUS 315 LsAmlListingWalk ( 316 ACPI_PARSE_OBJECT *Op, 317 UINT32 Level, 318 void *Context) 319 { 320 UINT8 FileByte; 321 UINT32 i; 322 UINT32 FileId = (UINT32) Context; 323 324 325 LsWriteNodeToListing (Op, FileId); 326 327 /* Write the hex bytes to the listing file(s) (if requested) */ 328 329 for (i = 0; i < Op->Asl.FinalAmlLength; i++) 330 { 331 if (ACPI_FAILURE (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte, 1))) 332 { 333 FlFileError (ASL_FILE_AML_OUTPUT, ASL_MSG_READ); 334 AslAbort (); 335 } 336 LsWriteListingHexBytes (&FileByte, 1, FileId); 337 } 338 339 return (AE_OK); 340 } 341 342 343 /******************************************************************************* 344 * 345 * FUNCTION: LsGenerateListing 346 * 347 * PARAMETERS: FileId - ID of listing file 348 * 349 * RETURN: None 350 * 351 * DESCRIPTION: Generate a listing file. This can be one of the several types 352 * of "listings" supported. 353 * 354 ******************************************************************************/ 355 356 static void 357 LsGenerateListing ( 358 UINT32 FileId) 359 { 360 361 /* Start at the beginning of both the source and AML files */ 362 363 FlSeekFile (ASL_FILE_SOURCE_OUTPUT, 0); 364 FlSeekFile (ASL_FILE_AML_OUTPUT, 0); 365 Gbl_SourceLine = 0; 366 Gbl_CurrentHexColumn = 0; 367 LsPushNode (Gbl_Files[ASL_FILE_INPUT].Filename); 368 369 /* Process all parse nodes */ 370 371 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, LsAmlListingWalk, 372 NULL, (void *) ACPI_TO_POINTER (FileId)); 373 374 /* Final processing */ 375 376 LsFinishSourceListing (FileId); 377 } 378 379 380 /******************************************************************************* 381 * 382 * FUNCTION: LsDoListings 383 * 384 * PARAMETERS: None. 385 * 386 * RETURN: None 387 * 388 * DESCRIPTION: Generate all requested listing files. 389 * 390 ******************************************************************************/ 391 392 void 393 LsDoListings ( 394 void) 395 { 396 397 if (Gbl_C_OutputFlag) 398 { 399 LsGenerateListing (ASL_FILE_C_SOURCE_OUTPUT); 400 } 401 402 if (Gbl_ListingFlag) 403 { 404 LsGenerateListing (ASL_FILE_LISTING_OUTPUT); 405 } 406 407 if (Gbl_AsmOutputFlag) 408 { 409 LsGenerateListing (ASL_FILE_ASM_SOURCE_OUTPUT); 410 } 411 412 if (Gbl_C_IncludeOutputFlag) 413 { 414 LsGenerateListing (ASL_FILE_C_INCLUDE_OUTPUT); 415 } 416 417 if (Gbl_AsmIncludeOutputFlag) 418 { 419 LsGenerateListing (ASL_FILE_ASM_INCLUDE_OUTPUT); 420 } 421 } 422 423 424 /******************************************************************************* 425 * 426 * FUNCTION: LsPushNode 427 * 428 * PARAMETERS: Filename - Pointer to the include filename 429 * 430 * RETURN: None 431 * 432 * DESCRIPTION: Push a listing node on the listing/include file stack. This 433 * stack enables tracking of include files (infinitely nested) 434 * and resumption of the listing of the parent file when the 435 * include file is finished. 436 * 437 ******************************************************************************/ 438 439 static void 440 LsPushNode ( 441 char *Filename) 442 { 443 ASL_LISTING_NODE *Lnode; 444 445 446 /* Create a new node */ 447 448 Lnode = UtLocalCalloc (sizeof (ASL_LISTING_NODE)); 449 450 /* Initialize */ 451 452 Lnode->Filename = Filename; 453 Lnode->LineNumber = 0; 454 455 /* Link (push) */ 456 457 Lnode->Next = Gbl_ListingNode; 458 Gbl_ListingNode = Lnode; 459 } 460 461 462 /******************************************************************************* 463 * 464 * FUNCTION: LsPopNode 465 * 466 * PARAMETERS: None 467 * 468 * RETURN: List head after current head is popped off 469 * 470 * DESCRIPTION: Pop the current head of the list, free it, and return the 471 * next node on the stack (the new current node). 472 * 473 ******************************************************************************/ 474 475 static ASL_LISTING_NODE * 476 LsPopNode ( 477 void) 478 { 479 ASL_LISTING_NODE *Lnode; 480 481 482 /* Just grab the node at the head of the list */ 483 484 Lnode = Gbl_ListingNode; 485 if ((!Lnode) || 486 (!Lnode->Next)) 487 { 488 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, NULL, 489 "Could not pop empty listing stack"); 490 return Gbl_ListingNode; 491 } 492 493 Gbl_ListingNode = Lnode->Next; 494 ACPI_MEM_FREE (Lnode); 495 496 /* New "Current" node is the new head */ 497 498 return (Gbl_ListingNode); 499 } 500 501 502 /******************************************************************************* 503 * 504 * FUNCTION: LsCheckException 505 * 506 * PARAMETERS: LineNumber - Current logical (cumulative) line # 507 * FileId - ID of output listing file 508 * 509 * RETURN: None 510 * 511 * DESCRIPTION: Check if there is an exception for this line, and if there is, 512 * put it in the listing immediately. Handles multiple errors 513 * per line. Gbl_NextError points to the next error in the 514 * sorted (by line #) list of compile errors/warnings. 515 * 516 ******************************************************************************/ 517 518 static void 519 LsCheckException ( 520 UINT32 LineNumber, 521 UINT32 FileId) 522 { 523 524 if ((!Gbl_NextError) || 525 (LineNumber < Gbl_NextError->LogicalLineNumber )) 526 { 527 return; 528 } 529 530 /* Handle multiple errors per line */ 531 532 if (FileId == ASL_FILE_LISTING_OUTPUT) 533 { 534 while (Gbl_NextError && 535 (LineNumber >= Gbl_NextError->LogicalLineNumber)) 536 { 537 AePrintException (FileId, Gbl_NextError, "\n[****iasl****]\n"); 538 539 Gbl_NextError = Gbl_NextError->Next; 540 } 541 542 FlPrintFile (FileId, "\n"); 543 } 544 } 545 546 547 /******************************************************************************* 548 * 549 * FUNCTION: LsFlushListingBuffer 550 * 551 * PARAMETERS: FileId - ID of the listing file 552 * 553 * RETURN: None 554 * 555 * DESCRIPTION: Flush out the current contents of the 16-byte hex AML code 556 * buffer. Usually called at the termination of a single line 557 * of source code or when the buffer is full. 558 * 559 ******************************************************************************/ 560 561 static void 562 LsFlushListingBuffer ( 563 UINT32 FileId) 564 { 565 UINT32 i; 566 567 568 if (Gbl_CurrentHexColumn == 0) 569 { 570 return; 571 } 572 573 /* Write the hex bytes */ 574 575 switch (FileId) 576 { 577 case ASL_FILE_LISTING_OUTPUT: 578 579 for (i = 0; i < Gbl_CurrentHexColumn; i++) 580 { 581 FlPrintFile (FileId, "%2.2X ", Gbl_AmlBuffer[i]); 582 } 583 584 for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 3); i++) 585 { 586 FlWriteFile (FileId, ".", 1); 587 } 588 589 /* Write the ASCII character associated with each of the bytes */ 590 591 LsDumpAscii (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer); 592 break; 593 594 595 case ASL_FILE_ASM_SOURCE_OUTPUT: 596 597 for (i = 0; i < Gbl_CurrentHexColumn; i++) 598 { 599 if (i > 0) 600 { 601 FlPrintFile (FileId, ","); 602 } 603 FlPrintFile (FileId, "0%2.2Xh", Gbl_AmlBuffer[i]); 604 } 605 606 for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 5); i++) 607 { 608 FlWriteFile (FileId, " ", 1); 609 } 610 611 FlPrintFile (FileId, " ;%8.8X", 612 Gbl_CurrentAmlOffset - HEX_LISTING_LINE_SIZE); 613 614 /* Write the ASCII character associated with each of the bytes */ 615 616 LsDumpAscii (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer); 617 break; 618 619 620 case ASL_FILE_C_SOURCE_OUTPUT: 621 622 for (i = 0; i < Gbl_CurrentHexColumn; i++) 623 { 624 FlPrintFile (FileId, "0x%2.2X,", Gbl_AmlBuffer[i]); 625 } 626 627 for (i = 0; i < ((HEX_LISTING_LINE_SIZE - Gbl_CurrentHexColumn) * 5); i++) 628 { 629 FlWriteFile (FileId, " ", 1); 630 } 631 632 FlPrintFile (FileId, " /* %8.8X", 633 Gbl_CurrentAmlOffset - HEX_LISTING_LINE_SIZE); 634 635 /* Write the ASCII character associated with each of the bytes */ 636 637 LsDumpAsciiInComment (FileId, Gbl_CurrentHexColumn, Gbl_AmlBuffer); 638 FlPrintFile (FileId, " */"); 639 break; 640 641 default: 642 /* No other types supported */ 643 return; 644 } 645 646 FlPrintFile (FileId, "\n"); 647 648 Gbl_CurrentHexColumn = 0; 649 Gbl_HexBytesWereWritten = TRUE; 650 } 651 652 653 /******************************************************************************* 654 * 655 * FUNCTION: LsWriteListingHexBytes 656 * 657 * PARAMETERS: Buffer - AML code buffer 658 * Length - Number of AML bytes to write 659 * FileId - ID of current listing file. 660 * 661 * RETURN: None 662 * 663 * DESCRIPTION: Write the contents of the AML buffer to the listing file via 664 * the listing buffer. The listing buffer is flushed every 16 665 * AML bytes. 666 * 667 ******************************************************************************/ 668 669 static void 670 LsWriteListingHexBytes ( 671 UINT8 *Buffer, 672 UINT32 Length, 673 UINT32 FileId) 674 { 675 UINT32 i; 676 677 678 /* Transfer all requested bytes */ 679 680 for (i = 0; i < Length; i++) 681 { 682 /* Print line header when buffer is empty */ 683 684 if (Gbl_CurrentHexColumn == 0) 685 { 686 if (Gbl_HasIncludeFiles) 687 { 688 FlPrintFile (FileId, "%*s", 10, " "); 689 } 690 691 switch (FileId) 692 { 693 case ASL_FILE_LISTING_OUTPUT: 694 695 FlPrintFile (FileId, "%8.8X....", Gbl_CurrentAmlOffset); 696 break; 697 698 case ASL_FILE_ASM_SOURCE_OUTPUT: 699 700 FlPrintFile (FileId, " db "); 701 break; 702 703 case ASL_FILE_C_SOURCE_OUTPUT: 704 705 FlPrintFile (FileId, " "); 706 break; 707 708 default: 709 /* No other types supported */ 710 return; 711 } 712 } 713 714 /* Transfer AML byte and update counts */ 715 716 Gbl_AmlBuffer[Gbl_CurrentHexColumn] = Buffer[i]; 717 718 Gbl_CurrentHexColumn++; 719 Gbl_CurrentAmlOffset++; 720 721 /* Flush buffer when it is full */ 722 723 if (Gbl_CurrentHexColumn >= HEX_LISTING_LINE_SIZE) 724 { 725 LsFlushListingBuffer (FileId); 726 } 727 } 728 } 729 730 731 /******************************************************************************* 732 * 733 * FUNCTION: LsWriteOneSourceLine 734 * 735 * PARAMETERS: FileID - ID of current listing file 736 * 737 * RETURN: FALSE on EOF (input source file), TRUE otherwise 738 * 739 * DESCRIPTION: Read one line from the input source file and echo it to the 740 * listing file, prefixed with the line number, and if the source 741 * file contains include files, prefixed with the current filename 742 * 743 ******************************************************************************/ 744 745 static UINT32 746 LsWriteOneSourceLine ( 747 UINT32 FileId) 748 { 749 UINT8 FileByte; 750 751 752 Gbl_SourceLine++; 753 Gbl_ListingNode->LineNumber++; 754 755 if (FileId == ASL_FILE_C_SOURCE_OUTPUT) 756 { 757 FlPrintFile (FileId, " *"); 758 } 759 if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT) 760 { 761 FlPrintFile (FileId, "; "); 762 } 763 764 if (Gbl_HasIncludeFiles) 765 { 766 /* 767 * This file contains "include" statements, print the current 768 * filename and line number within the current file 769 */ 770 FlPrintFile (FileId, "%12s %5d....", 771 Gbl_ListingNode->Filename, Gbl_ListingNode->LineNumber); 772 } 773 else 774 { 775 /* No include files, just print the line number */ 776 777 FlPrintFile (FileId, "%8d....", Gbl_SourceLine); 778 } 779 780 /* Read one line (up to a newline or EOF) */ 781 782 while (FlReadFile (ASL_FILE_SOURCE_OUTPUT, &FileByte, 1) == AE_OK) 783 { 784 if (FileId == ASL_FILE_C_SOURCE_OUTPUT) 785 { 786 if (FileByte == '/') 787 { 788 FileByte = '*'; 789 } 790 } 791 792 FlWriteFile (FileId, &FileByte, 1); 793 if (FileByte == '\n') 794 { 795 /* 796 * Check if an error occurred on this source line during the compile. 797 * If so, we print the error message after the source line. 798 */ 799 LsCheckException (Gbl_SourceLine, FileId); 800 return (1); 801 } 802 } 803 804 /* EOF on the input file was reached */ 805 806 return (0); 807 } 808 809 810 /******************************************************************************* 811 * 812 * FUNCTION: LsFinishSourceListing 813 * 814 * PARAMETERS: FileId - ID of current listing file. 815 * 816 * RETURN: None 817 * 818 * DESCRIPTION: Cleanup routine for the listing file. Flush the hex AML 819 * listing buffer, and flush out any remaining lines in the 820 * source input file. 821 * 822 ******************************************************************************/ 823 824 static void 825 LsFinishSourceListing ( 826 UINT32 FileId) 827 { 828 829 if ((FileId == ASL_FILE_ASM_INCLUDE_OUTPUT) || 830 (FileId == ASL_FILE_C_INCLUDE_OUTPUT)) 831 { 832 return; 833 } 834 835 LsFlushListingBuffer (FileId); 836 Gbl_CurrentAmlOffset = 0; 837 838 /* Flush any remaining text in the source file */ 839 840 if (FileId == ASL_FILE_C_SOURCE_OUTPUT) 841 { 842 FlPrintFile (FileId, " /*\n"); 843 } 844 845 while (LsWriteOneSourceLine (FileId)) 846 { ; } 847 848 if (FileId == ASL_FILE_C_SOURCE_OUTPUT) 849 { 850 FlPrintFile (FileId, "\n */\n };\n"); 851 } 852 853 FlPrintFile (FileId, "\n"); 854 855 if (FileId == ASL_FILE_LISTING_OUTPUT) 856 { 857 /* Print a summary of the compile exceptions */ 858 859 FlPrintFile (FileId, "\n\nSummary of errors and warnings\n\n"); 860 AePrintErrorLog (FileId); 861 FlPrintFile (FileId, "\n\n"); 862 UtDisplaySummary (FileId); 863 FlPrintFile (FileId, "\n\n"); 864 } 865 } 866 867 868 /******************************************************************************* 869 * 870 * FUNCTION: LsWriteSourceLines 871 * 872 * PARAMETERS: ToLineNumber - 873 * ToLogicalLineNumber - Write up to this source line number 874 * FileId - ID of current listing file 875 * 876 * RETURN: None 877 * 878 * DESCRIPTION: Read then write source lines to the listing file until we have 879 * reached the specified logical (cumulative) line number. This 880 * automatically echos out comment blocks and other non-AML 881 * generating text until we get to the actual AML-generating line 882 * of ASL code specified by the logical line number. 883 * 884 ******************************************************************************/ 885 886 static void 887 LsWriteSourceLines ( 888 UINT32 ToLineNumber, 889 UINT32 ToLogicalLineNumber, 890 UINT32 FileId) 891 { 892 893 if ((FileId == ASL_FILE_ASM_INCLUDE_OUTPUT) || 894 (FileId == ASL_FILE_C_INCLUDE_OUTPUT)) 895 { 896 return; 897 } 898 899 Gbl_CurrentLine = ToLogicalLineNumber; 900 901 /* Flush any hex bytes remaining from the last opcode */ 902 903 LsFlushListingBuffer (FileId); 904 905 /* Read lines and write them as long as we are not caught up */ 906 907 if (Gbl_SourceLine < Gbl_CurrentLine) 908 { 909 /* 910 * If we just completed writing some AML hex bytes, output a linefeed 911 * to add some whitespace for readability. 912 */ 913 if (Gbl_HexBytesWereWritten) 914 { 915 FlPrintFile (FileId, "\n"); 916 Gbl_HexBytesWereWritten = FALSE; 917 } 918 919 if (FileId == ASL_FILE_C_SOURCE_OUTPUT) 920 { 921 FlPrintFile (FileId, " /*\n"); 922 } 923 924 /* Write one line at a time until we have reached the target line # */ 925 926 while ((Gbl_SourceLine < Gbl_CurrentLine) && 927 LsWriteOneSourceLine (FileId)) 928 { ; } 929 930 if (FileId == ASL_FILE_C_SOURCE_OUTPUT) 931 { 932 FlPrintFile (FileId, " */"); 933 } 934 FlPrintFile (FileId, "\n"); 935 } 936 } 937 938 939 /******************************************************************************* 940 * 941 * FUNCTION: LsWriteNodeToListing 942 * 943 * PARAMETERS: Op - Parse node to write to the listing file. 944 * FileId - ID of current listing file 945 * 946 * RETURN: None. 947 * 948 * DESCRIPTION: Write "a node" to the listing file. This means to 949 * 1) Write out all of the source text associated with the node 950 * 2) Write out all of the AML bytes associated with the node 951 * 3) Write any compiler exceptions associated with the node 952 * 953 ******************************************************************************/ 954 955 static void 956 LsWriteNodeToListing ( 957 ACPI_PARSE_OBJECT *Op, 958 UINT32 FileId) 959 { 960 const ACPI_OPCODE_INFO *OpInfo; 961 UINT32 OpClass; 962 char *Pathname; 963 UINT32 Length; 964 UINT32 i; 965 966 967 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 968 OpClass = OpInfo->Class; 969 970 /* TBD: clean this up with a single flag that says: 971 * I start a named output block 972 */ 973 if (FileId == ASL_FILE_C_SOURCE_OUTPUT) 974 { 975 switch (Op->Asl.ParseOpcode) 976 { 977 case PARSEOP_DEFINITIONBLOCK: 978 case PARSEOP_METHODCALL: 979 case PARSEOP_INCLUDE: 980 case PARSEOP_INCLUDE_END: 981 case PARSEOP_DEFAULT_ARG: 982 983 break; 984 985 default: 986 switch (OpClass) 987 { 988 case AML_CLASS_NAMED_OBJECT: 989 switch (Op->Asl.AmlOpcode) 990 { 991 case AML_SCOPE_OP: 992 case AML_ALIAS_OP: 993 break; 994 995 default: 996 if (Op->Asl.ExternalName) 997 { 998 LsFlushListingBuffer (FileId); 999 FlPrintFile (FileId, " };\n"); 1000 } 1001 break; 1002 } 1003 break; 1004 1005 default: 1006 /* Don't care about other objects */ 1007 break; 1008 } 1009 break; 1010 } 1011 } 1012 1013 /* These cases do not have a corresponding AML opcode */ 1014 1015 switch (Op->Asl.ParseOpcode) 1016 { 1017 case PARSEOP_DEFINITIONBLOCK: 1018 1019 LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine, FileId); 1020 1021 /* Use the table Signature and TableId to build a unique name */ 1022 1023 if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT) 1024 { 1025 FlPrintFile (FileId, 1026 "%s_%s_Header \\\n", 1027 Gbl_TableSignature, Gbl_TableId); 1028 } 1029 if (FileId == ASL_FILE_C_SOURCE_OUTPUT) 1030 { 1031 FlPrintFile (FileId, 1032 " unsigned char %s_%s_Header [] =\n {\n", 1033 Gbl_TableSignature, Gbl_TableId); 1034 } 1035 if (FileId == ASL_FILE_ASM_INCLUDE_OUTPUT) 1036 { 1037 FlPrintFile (FileId, 1038 "extrn %s_%s_Header : byte\n", 1039 Gbl_TableSignature, Gbl_TableId); 1040 } 1041 if (FileId == ASL_FILE_C_INCLUDE_OUTPUT) 1042 { 1043 FlPrintFile (FileId, 1044 "extern unsigned char %s_%s_Header [];\n", 1045 Gbl_TableSignature, Gbl_TableId); 1046 } 1047 return; 1048 1049 1050 case PARSEOP_METHODCALL: 1051 1052 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, 1053 FileId); 1054 return; 1055 1056 1057 case PARSEOP_INCLUDE: 1058 1059 /* Flush everything up to and including the include source line */ 1060 1061 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, 1062 FileId); 1063 1064 /* Create a new listing node and push it */ 1065 1066 LsPushNode (Op->Asl.Child->Asl.Value.String); 1067 return; 1068 1069 1070 case PARSEOP_INCLUDE_END: 1071 1072 /* Flush out the rest of the include file */ 1073 1074 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, 1075 FileId); 1076 1077 /* Pop off this listing node and go back to the parent file */ 1078 1079 (void) LsPopNode (); 1080 return; 1081 1082 1083 case PARSEOP_DEFAULT_ARG: 1084 return; 1085 1086 1087 default: 1088 /* All other opcodes have an AML opcode */ 1089 break; 1090 } 1091 1092 /* 1093 * Otherwise, we look at the AML opcode because we can 1094 * switch on the opcode type, getting an entire class 1095 * at once 1096 */ 1097 switch (OpClass) 1098 { 1099 case AML_CLASS_ARGUMENT: /* argument type only */ 1100 case AML_CLASS_INTERNAL: 1101 1102 break; 1103 1104 1105 case AML_CLASS_NAMED_OBJECT: 1106 1107 switch (Op->Asl.AmlOpcode) 1108 { 1109 case AML_FIELD_OP: 1110 case AML_INDEX_FIELD_OP: 1111 case AML_BANK_FIELD_OP: 1112 case AML_NAME_OP: 1113 1114 /* 1115 * For fields, we want to dump all the AML after the 1116 * entire definition 1117 */ 1118 LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine, 1119 FileId); 1120 break; 1121 1122 default: 1123 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, 1124 FileId); 1125 break; 1126 } 1127 1128 switch (Op->Asl.AmlOpcode) 1129 { 1130 case AML_SCOPE_OP: 1131 case AML_ALIAS_OP: 1132 1133 /* These opcodes do not declare a new object, ignore them */ 1134 1135 break; 1136 1137 default: 1138 1139 /* All other named object opcodes come here */ 1140 1141 switch (FileId) 1142 { 1143 case ASL_FILE_ASM_SOURCE_OUTPUT: 1144 case ASL_FILE_C_SOURCE_OUTPUT: 1145 case ASL_FILE_ASM_INCLUDE_OUTPUT: 1146 case ASL_FILE_C_INCLUDE_OUTPUT: 1147 1148 /* 1149 * For named objects, we will create a valid symbol so that the 1150 * AML code can be referenced from C or ASM 1151 */ 1152 if (Op->Asl.ExternalName) 1153 { 1154 /* Get the full pathname associated with this node */ 1155 1156 Pathname = AcpiNsGetExternalPathname (Op->Asl.Node); 1157 Length = strlen (Pathname); 1158 if (Length >= 4) 1159 { 1160 /* Convert all dots in the path to underscores */ 1161 1162 for (i = 0; i < Length; i++) 1163 { 1164 if (Pathname[i] == '.') 1165 { 1166 Pathname[i] = '_'; 1167 } 1168 } 1169 1170 /* Create the appropriate symbol in the output file */ 1171 1172 if (FileId == ASL_FILE_ASM_SOURCE_OUTPUT) 1173 { 1174 FlPrintFile (FileId, 1175 "%s_%s_%s \\\n", 1176 Gbl_TableSignature, Gbl_TableId, &Pathname[1]); 1177 } 1178 if (FileId == ASL_FILE_C_SOURCE_OUTPUT) 1179 { 1180 FlPrintFile (FileId, 1181 " unsigned char %s_%s_%s [] =\n {\n", 1182 Gbl_TableSignature, Gbl_TableId, &Pathname[1]); 1183 } 1184 if (FileId == ASL_FILE_ASM_INCLUDE_OUTPUT) 1185 { 1186 FlPrintFile (FileId, 1187 "extrn %s_%s_%s : byte\n", 1188 Gbl_TableSignature, Gbl_TableId, &Pathname[1]); 1189 } 1190 if (FileId == ASL_FILE_C_INCLUDE_OUTPUT) 1191 { 1192 FlPrintFile (FileId, 1193 "extern unsigned char %s_%s_%s [];\n", 1194 Gbl_TableSignature, Gbl_TableId, &Pathname[1]); 1195 } 1196 } 1197 ACPI_MEM_FREE (Pathname); 1198 } 1199 break; 1200 1201 default: 1202 /* Nothing to do for listing file */ 1203 break; 1204 } 1205 } 1206 break; 1207 1208 case AML_CLASS_EXECUTE: 1209 case AML_CLASS_CREATE: 1210 default: 1211 1212 LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, 1213 FileId); 1214 break; 1215 1216 case AML_CLASS_UNKNOWN: 1217 break; 1218 } 1219 } 1220 1221 1222 /******************************************************************************* 1223 * 1224 * FUNCTION: LsDoHexOutput 1225 * 1226 * PARAMETERS: None 1227 * 1228 * RETURN: None. 1229 * 1230 * DESCRIPTION: Create the hex output file. 1231 * 1232 ******************************************************************************/ 1233 1234 void 1235 LsDoHexOutput ( 1236 void) 1237 { 1238 1239 switch (Gbl_HexOutputFlag) 1240 { 1241 case HEX_OUTPUT_C: 1242 1243 LsDoHexOutputC (); 1244 break; 1245 1246 case HEX_OUTPUT_ASM: 1247 1248 LsDoHexOutputAsm (); 1249 break; 1250 1251 default: 1252 /* No other output types supported */ 1253 break; 1254 } 1255 } 1256 1257 1258 /******************************************************************************* 1259 * 1260 * FUNCTION: LsDoHexOutputC 1261 * 1262 * PARAMETERS: None 1263 * 1264 * RETURN: None. 1265 * 1266 * DESCRIPTION: Create the hex output file. This is the same data as the AML 1267 * output file, but formatted into hex/ascii bytes suitable for 1268 * inclusion into a C source file. 1269 * 1270 ******************************************************************************/ 1271 1272 static void 1273 LsDoHexOutputC ( 1274 void) 1275 { 1276 UINT32 j; 1277 UINT8 FileByte[HEX_TABLE_LINE_SIZE]; 1278 UINT8 Buffer[4]; 1279 UINT32 Offset = 0; 1280 1281 1282 FlPrintFile (ASL_FILE_HEX_OUTPUT, " * C source code output\n *\n */\n"); 1283 FlPrintFile (ASL_FILE_HEX_OUTPUT, "unsigned char AmlCode[] =\n{\n"); 1284 1285 /* Start at the beginning of the AML file */ 1286 1287 FlSeekFile (ASL_FILE_AML_OUTPUT, 0); 1288 1289 /* Process all AML bytes in the AML file */ 1290 1291 j = 0; 1292 while (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte[j], 1) == AE_OK) 1293 { 1294 if (j == 0) 1295 { 1296 FlPrintFile (ASL_FILE_HEX_OUTPUT, " "); 1297 } 1298 1299 /* Convert each AML byte to hex */ 1300 1301 UtConvertByteToHex (FileByte[j], Buffer); 1302 FlWriteFile (ASL_FILE_HEX_OUTPUT, Buffer, 4); 1303 FlPrintFile (ASL_FILE_HEX_OUTPUT, ","); 1304 1305 /* An occasional linefeed improves readability */ 1306 1307 Offset++; 1308 j++; 1309 1310 if (j >= HEX_TABLE_LINE_SIZE) 1311 { 1312 /* End of line, emit the ascii dump of the entire line */ 1313 1314 FlPrintFile (ASL_FILE_HEX_OUTPUT, 1315 " /* %8.8X", Offset - HEX_TABLE_LINE_SIZE); 1316 1317 /* Write the ASCII character associated with each of the bytes */ 1318 1319 LsDumpAsciiInComment (ASL_FILE_HEX_OUTPUT, 1320 HEX_TABLE_LINE_SIZE, FileByte); 1321 FlPrintFile (ASL_FILE_HEX_OUTPUT, " */\n"); 1322 1323 /* Start new line */ 1324 1325 j = 0; 1326 } 1327 } 1328 1329 FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n};\n"); 1330 FlCloseFile (ASL_FILE_HEX_OUTPUT); 1331 } 1332 1333 1334 /******************************************************************************* 1335 * 1336 * FUNCTION: LsDoHexOutputAsm 1337 * 1338 * PARAMETERS: None 1339 * 1340 * RETURN: None. 1341 * 1342 * DESCRIPTION: Create the hex output file. This is the same data as the AML 1343 * output file, but formatted into hex/ascii bytes suitable for 1344 * inclusion into a ASM source file. 1345 * 1346 ******************************************************************************/ 1347 1348 static void 1349 LsDoHexOutputAsm ( 1350 void) 1351 { 1352 UINT32 j; 1353 UINT8 FileByte[HEX_TABLE_LINE_SIZE]; 1354 UINT8 Buffer[4]; 1355 UINT32 Offset = 0; 1356 BOOLEAN DoComma = FALSE; 1357 1358 1359 FlPrintFile (ASL_FILE_HEX_OUTPUT, "; Assembly code source output\n;\n"); 1360 1361 /* Start at the beginning of the AML file */ 1362 1363 FlSeekFile (ASL_FILE_AML_OUTPUT, 0); 1364 1365 /* Process all AML bytes in the AML file */ 1366 1367 j = 0; 1368 while (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte[j], 1) == AE_OK) 1369 { 1370 if (j == 0) 1371 { 1372 FlPrintFile (ASL_FILE_HEX_OUTPUT, " db "); 1373 } 1374 else if (DoComma) 1375 { 1376 FlPrintFile (ASL_FILE_HEX_OUTPUT, ","); 1377 DoComma = FALSE; 1378 } 1379 1380 /* Convert each AML byte to hex */ 1381 1382 UtConvertByteToAsmHex (FileByte[j], Buffer); 1383 FlWriteFile (ASL_FILE_HEX_OUTPUT, Buffer, 4); 1384 1385 /* An occasional linefeed improves readability */ 1386 1387 Offset++; 1388 j++; 1389 if (j >= HEX_TABLE_LINE_SIZE) 1390 { 1391 FlPrintFile (ASL_FILE_HEX_OUTPUT, 1392 " ;%8.8X", Offset - HEX_TABLE_LINE_SIZE); 1393 1394 /* Write the ASCII character associated with each of the bytes */ 1395 1396 LsDumpAscii (ASL_FILE_HEX_OUTPUT, HEX_TABLE_LINE_SIZE, FileByte); 1397 FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n"); 1398 j = 0; 1399 } 1400 else 1401 { 1402 DoComma = TRUE; 1403 } 1404 } 1405 1406 FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n"); 1407 FlCloseFile (ASL_FILE_HEX_OUTPUT); 1408 } 1409 1410 1411