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