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