]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/acpica/compiler/asllisting.c
This commit was generated by cvs2svn to compensate for changes in r161389,
[FreeBSD/FreeBSD.git] / sys / contrib / dev / acpica / compiler / asllisting.c
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