asllisting.c revision 151937
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
130static void
131LsDumpAscii (
132    UINT32                  FileId,
133    UINT32                  Count,
134    UINT8                   *Buffer);
135
136static void
137LsDumpAsciiInComment (
138    UINT32                  FileId,
139    UINT32                  Count,
140    UINT8                   *Buffer);
141
142static ACPI_STATUS
143LsAmlListingWalk (
144    ACPI_PARSE_OBJECT       *Op,
145    UINT32                  Level,
146    void                    *Context);
147
148static void
149LsGenerateListing (
150    UINT32                  FileId);
151
152static void
153LsPushNode (
154    char                    *Filename);
155
156static ASL_LISTING_NODE *
157LsPopNode (
158    void);
159
160static void
161LsCheckException (
162    UINT32                  LineNumber,
163    UINT32                  FileId);
164
165static void
166LsFlushListingBuffer (
167    UINT32                  FileId);
168
169static void
170LsWriteListingHexBytes (
171    UINT8                   *Buffer,
172    UINT32                  Length,
173    UINT32                  FileId);
174
175static UINT32
176LsWriteOneSourceLine (
177    UINT32                  FileId);
178
179static void
180LsFinishSourceListing (
181    UINT32                  FileId);
182
183static void
184LsWriteSourceLines (
185    UINT32                  ToLineNumber,
186    UINT32                  ToLogicalLineNumber,
187    UINT32                  FileId);
188
189static void
190LsWriteNodeToListing (
191    ACPI_PARSE_OBJECT       *Op,
192    UINT32                  FileId);
193
194static void
195LsDoHexOutputC (
196    void);
197
198static void
199LsDoHexOutputAsm (
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
217static void
218LsDumpAscii (
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
260static void
261LsDumpAsciiInComment (
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
314static ACPI_STATUS
315LsAmlListingWalk (
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
356static void
357LsGenerateListing (
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
392void
393LsDoListings (
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
439static void
440LsPushNode (
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
475static ASL_LISTING_NODE *
476LsPopNode (
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
518static void
519LsCheckException (
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
561static void
562LsFlushListingBuffer (
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
669static void
670LsWriteListingHexBytes (
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
745static UINT32
746LsWriteOneSourceLine (
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
824static void
825LsFinishSourceListing (
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
886static void
887LsWriteSourceLines (
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
955static void
956LsWriteNodeToListing (
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
1234void
1235LsDoHexOutput (
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
1272static void
1273LsDoHexOutputC (
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
1348static void
1349LsDoHexOutputAsm (
1350    void)
1351{
1352    UINT32                  j;
1353    UINT8                   FileByte[HEX_TABLE_LINE_SIZE];
1354    UINT8                   Buffer[4];
1355    UINT32                  Offset = 0;
1356    BOOLEAN                 DoComma = FALSE;
1357
1358
1359    FlPrintFile (ASL_FILE_HEX_OUTPUT, "; Assembly code source output\n;\n");
1360
1361    /* Start at the beginning of the AML file */
1362
1363    FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
1364
1365    /* Process all AML bytes in the AML file */
1366
1367    j = 0;
1368    while (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte[j], 1) == AE_OK)
1369    {
1370        if (j == 0)
1371        {
1372            FlPrintFile (ASL_FILE_HEX_OUTPUT, "  db  ");
1373        }
1374        else if (DoComma)
1375        {
1376            FlPrintFile (ASL_FILE_HEX_OUTPUT, ",");
1377            DoComma = FALSE;
1378        }
1379
1380        /* Convert each AML byte to hex */
1381
1382        UtConvertByteToAsmHex (FileByte[j], Buffer);
1383        FlWriteFile (ASL_FILE_HEX_OUTPUT, Buffer, 4);
1384
1385        /* An occasional linefeed improves readability */
1386
1387        Offset++;
1388        j++;
1389        if (j >= HEX_TABLE_LINE_SIZE)
1390        {
1391            FlPrintFile (ASL_FILE_HEX_OUTPUT,
1392                "  ;%8.8X", Offset - HEX_TABLE_LINE_SIZE);
1393
1394            /* Write the ASCII character associated with each of the bytes */
1395
1396            LsDumpAscii (ASL_FILE_HEX_OUTPUT, HEX_TABLE_LINE_SIZE, FileByte);
1397            FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n");
1398            j = 0;
1399        }
1400        else
1401        {
1402            DoComma = TRUE;
1403        }
1404    }
1405
1406    FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n");
1407    FlCloseFile (ASL_FILE_HEX_OUTPUT);
1408}
1409
1410
1411