aslcompile.c revision 252279
1118611Snjl/******************************************************************************
2118611Snjl *
3118611Snjl * Module Name: aslcompile - top level compile module
4118611Snjl *
5118611Snjl *****************************************************************************/
6118611Snjl
7217365Sjkim/*
8245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp.
9118611Snjl * All rights reserved.
10118611Snjl *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
25118611Snjl *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
29118611Snjl *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
43118611Snjl
44217365Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
45246849Sjkim#include <contrib/dev/acpica/compiler/dtcompiler.h>
46217365Sjkim
47118611Snjl#include <stdio.h>
48151937Sjkim#include <time.h>
49213806Sjkim#include <contrib/dev/acpica/include/acapps.h>
50118611Snjl
51118611Snjl#define _COMPONENT          ACPI_COMPILER
52118611Snjl        ACPI_MODULE_NAME    ("aslcompile")
53118611Snjl
54243347Sjkim/*
55243347Sjkim * Main parser entry
56243347Sjkim * External is here in case the parser emits the same external in the
57243347Sjkim * generated header. (Newer versions of Bison)
58243347Sjkim */
59243347Sjkimint
60243347SjkimAslCompilerparse(
61243347Sjkim    void);
62243347Sjkim
63151937Sjkim/* Local prototypes */
64118611Snjl
65151937Sjkimstatic void
66151937SjkimCmFlushSourceCode (
67151937Sjkim    void);
68151937Sjkim
69212761Sjkimstatic void
70193529SjkimFlConsumeAnsiComment (
71235945Sjkim    FILE                    *Handle,
72193529Sjkim    ASL_FILE_STATUS         *Status);
73151937Sjkim
74212761Sjkimstatic void
75193529SjkimFlConsumeNewComment (
76235945Sjkim    FILE                    *Handle,
77193529Sjkim    ASL_FILE_STATUS         *Status);
78193529Sjkim
79237412Sjkimstatic void
80237412SjkimCmDumpAllEvents (
81237412Sjkim    void);
82193529Sjkim
83237412Sjkim
84118611Snjl/*******************************************************************************
85118611Snjl *
86118611Snjl * FUNCTION:    AslCompilerSignon
87118611Snjl *
88118611Snjl * PARAMETERS:  FileId      - ID of the output file
89118611Snjl *
90118611Snjl * RETURN:      None
91118611Snjl *
92118611Snjl * DESCRIPTION: Display compiler signon
93118611Snjl *
94118611Snjl ******************************************************************************/
95118611Snjl
96118611Snjlvoid
97118611SnjlAslCompilerSignon (
98118611Snjl    UINT32                  FileId)
99118611Snjl{
100118611Snjl    char                    *Prefix = "";
101213806Sjkim    char                    *UtilityName;
102118611Snjl
103118611Snjl
104151937Sjkim    /* Set line prefix depending on the destination file type */
105151937Sjkim
106118611Snjl    switch (FileId)
107118611Snjl    {
108118611Snjl    case ASL_FILE_ASM_SOURCE_OUTPUT:
109118611Snjl    case ASL_FILE_ASM_INCLUDE_OUTPUT:
110118611Snjl
111118611Snjl        Prefix = "; ";
112118611Snjl        break;
113118611Snjl
114118611Snjl    case ASL_FILE_HEX_OUTPUT:
115118611Snjl
116118611Snjl        if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
117118611Snjl        {
118118611Snjl            Prefix = "; ";
119118611Snjl        }
120207344Sjkim        else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
121207344Sjkim                 (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
122118611Snjl        {
123118611Snjl            FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n");
124118611Snjl            Prefix = " * ";
125118611Snjl        }
126118611Snjl        break;
127118611Snjl
128118611Snjl    case ASL_FILE_C_SOURCE_OUTPUT:
129249112Sjkim    case ASL_FILE_C_OFFSET_OUTPUT:
130118611Snjl    case ASL_FILE_C_INCLUDE_OUTPUT:
131118611Snjl
132118611Snjl        Prefix = " * ";
133118611Snjl        break;
134118611Snjl
135118611Snjl    default:
136250838Sjkim
137118611Snjl        /* No other output types supported */
138250838Sjkim
139118611Snjl        break;
140118611Snjl    }
141118611Snjl
142151937Sjkim    /* Running compiler or disassembler? */
143151937Sjkim
144151937Sjkim    if (Gbl_DisasmFlag)
145151937Sjkim    {
146213806Sjkim        UtilityName = AML_DISASSEMBLER_NAME;
147151937Sjkim    }
148151937Sjkim    else
149151937Sjkim    {
150213806Sjkim        UtilityName = ASL_COMPILER_NAME;
151151937Sjkim    }
152151937Sjkim
153213806Sjkim    /* Compiler signon with copyright */
154151937Sjkim
155213806Sjkim    FlPrintFile (FileId, "%s\n", Prefix);
156213806Sjkim    FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix));
157118611Snjl}
158118611Snjl
159118611Snjl
160118611Snjl/*******************************************************************************
161118611Snjl *
162118611Snjl * FUNCTION:    AslCompilerFileHeader
163118611Snjl *
164118611Snjl * PARAMETERS:  FileId      - ID of the output file
165118611Snjl *
166118611Snjl * RETURN:      None
167118611Snjl *
168118611Snjl * DESCRIPTION: Header used at the beginning of output files
169118611Snjl *
170118611Snjl ******************************************************************************/
171118611Snjl
172118611Snjlvoid
173118611SnjlAslCompilerFileHeader (
174118611Snjl    UINT32                  FileId)
175118611Snjl{
176118611Snjl    struct tm               *NewTime;
177118611Snjl    time_t                  Aclock;
178118611Snjl    char                    *Prefix = "";
179118611Snjl
180118611Snjl
181151937Sjkim    /* Set line prefix depending on the destination file type */
182151937Sjkim
183118611Snjl    switch (FileId)
184118611Snjl    {
185118611Snjl    case ASL_FILE_ASM_SOURCE_OUTPUT:
186118611Snjl    case ASL_FILE_ASM_INCLUDE_OUTPUT:
187118611Snjl
188118611Snjl        Prefix = "; ";
189118611Snjl        break;
190118611Snjl
191118611Snjl    case ASL_FILE_HEX_OUTPUT:
192118611Snjl
193118611Snjl        if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
194118611Snjl        {
195118611Snjl            Prefix = "; ";
196118611Snjl        }
197207344Sjkim        else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
198207344Sjkim                 (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
199118611Snjl        {
200118611Snjl            Prefix = " * ";
201118611Snjl        }
202118611Snjl        break;
203118611Snjl
204118611Snjl    case ASL_FILE_C_SOURCE_OUTPUT:
205249112Sjkim    case ASL_FILE_C_OFFSET_OUTPUT:
206118611Snjl    case ASL_FILE_C_INCLUDE_OUTPUT:
207118611Snjl
208118611Snjl        Prefix = " * ";
209118611Snjl        break;
210118611Snjl
211118611Snjl    default:
212250838Sjkim
213118611Snjl        /* No other output types supported */
214250838Sjkim
215118611Snjl        break;
216118611Snjl    }
217118611Snjl
218118611Snjl    /* Compilation header with timestamp */
219118611Snjl
220118611Snjl    (void) time (&Aclock);
221118611Snjl    NewTime = localtime (&Aclock);
222118611Snjl
223118611Snjl    FlPrintFile (FileId,
224118611Snjl        "%sCompilation of \"%s\" - %s%s\n",
225118611Snjl        Prefix, Gbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime),
226118611Snjl        Prefix);
227118611Snjl
228118611Snjl    switch (FileId)
229118611Snjl    {
230118611Snjl    case ASL_FILE_C_SOURCE_OUTPUT:
231249112Sjkim    case ASL_FILE_C_OFFSET_OUTPUT:
232118611Snjl    case ASL_FILE_C_INCLUDE_OUTPUT:
233250838Sjkim
234118611Snjl        FlPrintFile (FileId, " */\n");
235118611Snjl        break;
236118611Snjl
237118611Snjl    default:
238250838Sjkim
239118611Snjl        /* Nothing to do for other output types */
240250838Sjkim
241118611Snjl        break;
242118611Snjl    }
243118611Snjl}
244118611Snjl
245118611Snjl
246118611Snjl/*******************************************************************************
247118611Snjl *
248118611Snjl * FUNCTION:    CmFlushSourceCode
249118611Snjl *
250118611Snjl * PARAMETERS:  None
251118611Snjl *
252118611Snjl * RETURN:      None
253118611Snjl *
254118611Snjl * DESCRIPTION: Read in any remaining source code after the parse tree
255118611Snjl *              has been constructed.
256118611Snjl *
257118611Snjl ******************************************************************************/
258118611Snjl
259151937Sjkimstatic void
260151937SjkimCmFlushSourceCode (
261151937Sjkim    void)
262118611Snjl{
263118611Snjl    char                    Buffer;
264118611Snjl
265118611Snjl
266118611Snjl    while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR)
267118611Snjl    {
268234623Sjkim        AslInsertLineBuffer ((int) Buffer);
269118611Snjl    }
270118611Snjl
271234623Sjkim    AslResetCurrentLineBuffer ();
272118611Snjl}
273118611Snjl
274118611Snjl
275118611Snjl/*******************************************************************************
276118611Snjl *
277167802Sjkim * FUNCTION:    FlConsume*
278167802Sjkim *
279235945Sjkim * PARAMETERS:  Handle              - Open input file
280235945Sjkim *              Status              - File current status struct
281167802Sjkim *
282167802Sjkim * RETURN:      Number of lines consumed
283167802Sjkim *
284167802Sjkim * DESCRIPTION: Step over both types of comment during check for ascii chars
285167802Sjkim *
286167802Sjkim ******************************************************************************/
287167802Sjkim
288212761Sjkimstatic void
289167802SjkimFlConsumeAnsiComment (
290235945Sjkim    FILE                    *Handle,
291167802Sjkim    ASL_FILE_STATUS         *Status)
292167802Sjkim{
293167802Sjkim    UINT8                   Byte;
294167802Sjkim    BOOLEAN                 ClosingComment = FALSE;
295167802Sjkim
296167802Sjkim
297243347Sjkim    while (fread (&Byte, 1, 1, Handle) == 1)
298167802Sjkim    {
299167802Sjkim        /* Scan until comment close is found */
300167802Sjkim
301167802Sjkim        if (ClosingComment)
302167802Sjkim        {
303167802Sjkim            if (Byte == '/')
304167802Sjkim            {
305167802Sjkim                return;
306167802Sjkim            }
307167802Sjkim
308167802Sjkim            if (Byte != '*')
309167802Sjkim            {
310167802Sjkim                /* Reset */
311167802Sjkim
312167802Sjkim                ClosingComment = FALSE;
313167802Sjkim            }
314167802Sjkim        }
315167802Sjkim        else if (Byte == '*')
316167802Sjkim        {
317167802Sjkim            ClosingComment = TRUE;
318167802Sjkim        }
319167802Sjkim
320167802Sjkim        /* Maintain line count */
321167802Sjkim
322167802Sjkim        if (Byte == 0x0A)
323167802Sjkim        {
324167802Sjkim            Status->Line++;
325167802Sjkim        }
326167802Sjkim
327167802Sjkim        Status->Offset++;
328167802Sjkim    }
329167802Sjkim}
330167802Sjkim
331167802Sjkim
332212761Sjkimstatic void
333167802SjkimFlConsumeNewComment (
334235945Sjkim    FILE                    *Handle,
335167802Sjkim    ASL_FILE_STATUS         *Status)
336167802Sjkim{
337167802Sjkim    UINT8                   Byte;
338167802Sjkim
339167802Sjkim
340243347Sjkim    while (fread (&Byte, 1, 1, Handle) == 1)
341167802Sjkim    {
342167802Sjkim        Status->Offset++;
343167802Sjkim
344167802Sjkim        /* Comment ends at newline */
345167802Sjkim
346167802Sjkim        if (Byte == 0x0A)
347167802Sjkim        {
348167802Sjkim            Status->Line++;
349167802Sjkim            return;
350167802Sjkim        }
351167802Sjkim    }
352167802Sjkim}
353167802Sjkim
354167802Sjkim
355167802Sjkim/*******************************************************************************
356167802Sjkim *
357246849Sjkim * FUNCTION:    FlCheckForAcpiTable
358246849Sjkim *
359246849Sjkim * PARAMETERS:  Handle              - Open input file
360246849Sjkim *
361246849Sjkim * RETURN:      Status
362246849Sjkim *
363246849Sjkim * DESCRIPTION: Determine if a file seems to be a binary ACPI table, via the
364246849Sjkim *              following checks on what would be the table header:
365246849Sjkim *              0) File must be at least as long as an ACPI_TABLE_HEADER
366246849Sjkim *              1) The header length field must match the file size
367246849Sjkim *              2) Signature, OemId, OemTableId, AslCompilerId must be ASCII
368246849Sjkim *
369246849Sjkim ******************************************************************************/
370246849Sjkim
371246849SjkimACPI_STATUS
372246849SjkimFlCheckForAcpiTable (
373246849Sjkim    FILE                    *Handle)
374246849Sjkim{
375246849Sjkim    ACPI_TABLE_HEADER       Table;
376246849Sjkim    UINT32                  FileSize;
377246849Sjkim    size_t                  Actual;
378246849Sjkim    UINT32                  i;
379246849Sjkim
380246849Sjkim
381246849Sjkim    /* Read a potential table header */
382246849Sjkim
383246849Sjkim    Actual = fread (&Table, 1, sizeof (ACPI_TABLE_HEADER), Handle);
384246849Sjkim    fseek (Handle, 0, SEEK_SET);
385246849Sjkim
386246849Sjkim    if (Actual < sizeof (ACPI_TABLE_HEADER))
387246849Sjkim    {
388246849Sjkim        return (AE_ERROR);
389246849Sjkim    }
390246849Sjkim
391246849Sjkim    /* Header length field must match the file size */
392246849Sjkim
393246849Sjkim    FileSize = DtGetFileSize (Handle);
394246849Sjkim    if (Table.Length != FileSize)
395246849Sjkim    {
396246849Sjkim        return (AE_ERROR);
397246849Sjkim    }
398246849Sjkim
399246849Sjkim    /*
400246849Sjkim     * These fields must be ASCII:
401246849Sjkim     * Signature, OemId, OemTableId, AslCompilerId.
402246849Sjkim     * We allow a NULL terminator in OemId and OemTableId.
403246849Sjkim     */
404246849Sjkim    for (i = 0; i < ACPI_NAME_SIZE; i++)
405246849Sjkim    {
406246849Sjkim        if (!ACPI_IS_ASCII ((UINT8) Table.Signature[i]))
407246849Sjkim        {
408246849Sjkim            return (AE_ERROR);
409246849Sjkim        }
410246849Sjkim
411246849Sjkim        if (!ACPI_IS_ASCII ((UINT8) Table.AslCompilerId[i]))
412246849Sjkim        {
413246849Sjkim            return (AE_ERROR);
414246849Sjkim        }
415246849Sjkim    }
416246849Sjkim
417246849Sjkim    for (i = 0; (i < ACPI_OEM_ID_SIZE) && (Table.OemId[i]); i++)
418246849Sjkim    {
419246849Sjkim        if (!ACPI_IS_ASCII ((UINT8) Table.OemId[i]))
420246849Sjkim        {
421246849Sjkim            return (AE_ERROR);
422246849Sjkim        }
423246849Sjkim    }
424246849Sjkim
425246849Sjkim    for (i = 0; (i < ACPI_OEM_TABLE_ID_SIZE) && (Table.OemTableId[i]); i++)
426246849Sjkim    {
427246849Sjkim        if (!ACPI_IS_ASCII ((UINT8) Table.OemTableId[i]))
428246849Sjkim        {
429246849Sjkim            return (AE_ERROR);
430246849Sjkim        }
431246849Sjkim    }
432246849Sjkim
433246849Sjkim    printf ("Binary file appears to be a valid ACPI table, disassembling\n");
434246849Sjkim    return (AE_OK);
435246849Sjkim}
436246849Sjkim
437246849Sjkim
438246849Sjkim/*******************************************************************************
439246849Sjkim *
440123315Snjl * FUNCTION:    FlCheckForAscii
441123315Snjl *
442235945Sjkim * PARAMETERS:  Handle              - Open input file
443235945Sjkim *              Filename            - Input filename
444235945Sjkim *              DisplayErrors       - TRUE if error messages desired
445123315Snjl *
446151937Sjkim * RETURN:      Status
447123315Snjl *
448167802Sjkim * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters
449167802Sjkim *              within comments. Note: does not handle nested comments and does
450167802Sjkim *              not handle comment delimiters within string literals. However,
451167802Sjkim *              on the rare chance this happens and an invalid character is
452167802Sjkim *              missed, the parser will catch the error by failing in some
453167802Sjkim *              spectactular manner.
454123315Snjl *
455123315Snjl ******************************************************************************/
456123315Snjl
457209746SjkimACPI_STATUS
458123315SnjlFlCheckForAscii (
459235945Sjkim    FILE                    *Handle,
460235945Sjkim    char                    *Filename,
461235945Sjkim    BOOLEAN                 DisplayErrors)
462123315Snjl{
463123315Snjl    UINT8                   Byte;
464123315Snjl    ACPI_SIZE               BadBytes = 0;
465167802Sjkim    BOOLEAN                 OpeningComment = FALSE;
466167802Sjkim    ASL_FILE_STATUS         Status;
467123315Snjl
468123315Snjl
469167802Sjkim    Status.Line = 1;
470167802Sjkim    Status.Offset = 0;
471167802Sjkim
472123315Snjl    /* Read the entire file */
473123315Snjl
474243347Sjkim    while (fread (&Byte, 1, 1, Handle) == 1)
475123315Snjl    {
476167802Sjkim        /* Ignore comment fields (allow non-ascii within) */
477167802Sjkim
478167802Sjkim        if (OpeningComment)
479167802Sjkim        {
480167802Sjkim            /* Check for second comment open delimiter */
481167802Sjkim
482167802Sjkim            if (Byte == '*')
483167802Sjkim            {
484235945Sjkim                FlConsumeAnsiComment (Handle, &Status);
485167802Sjkim            }
486167802Sjkim
487167802Sjkim            if (Byte == '/')
488167802Sjkim            {
489235945Sjkim                FlConsumeNewComment (Handle, &Status);
490167802Sjkim            }
491167802Sjkim
492167802Sjkim            /* Reset */
493167802Sjkim
494167802Sjkim            OpeningComment = FALSE;
495167802Sjkim        }
496167802Sjkim        else if (Byte == '/')
497167802Sjkim        {
498167802Sjkim            OpeningComment = TRUE;
499167802Sjkim        }
500167802Sjkim
501123315Snjl        /* Check for an ASCII character */
502123315Snjl
503193529Sjkim        if (!ACPI_IS_ASCII (Byte))
504123315Snjl        {
505235945Sjkim            if ((BadBytes < 10) && (DisplayErrors))
506123315Snjl            {
507151937Sjkim                AcpiOsPrintf (
508167802Sjkim                    "Non-ASCII character [0x%2.2X] found in line %u, file offset 0x%.2X\n",
509167802Sjkim                    Byte, Status.Line, Status.Offset);
510123315Snjl            }
511167802Sjkim
512123315Snjl            BadBytes++;
513123315Snjl        }
514167802Sjkim
515167802Sjkim        /* Update line counter */
516167802Sjkim
517167802Sjkim        else if (Byte == 0x0A)
518167802Sjkim        {
519167802Sjkim            Status.Line++;
520167802Sjkim        }
521167802Sjkim
522167802Sjkim        Status.Offset++;
523123315Snjl    }
524123315Snjl
525151937Sjkim    /* Seek back to the beginning of the source file */
526151937Sjkim
527235945Sjkim    fseek (Handle, 0, SEEK_SET);
528151937Sjkim
529123315Snjl    /* Were there any non-ASCII characters in the file? */
530123315Snjl
531123315Snjl    if (BadBytes)
532123315Snjl    {
533235945Sjkim        if (DisplayErrors)
534235945Sjkim        {
535235945Sjkim            AcpiOsPrintf (
536235945Sjkim                "%u non-ASCII characters found in input source text, could be a binary file\n",
537235945Sjkim                BadBytes);
538235945Sjkim            AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename);
539235945Sjkim        }
540235945Sjkim
541123315Snjl        return (AE_BAD_CHARACTER);
542123315Snjl    }
543123315Snjl
544235945Sjkim    /* File is OK (100% ASCII) */
545123315Snjl
546123315Snjl    return (AE_OK);
547123315Snjl}
548123315Snjl
549123315Snjl
550123315Snjl/*******************************************************************************
551123315Snjl *
552118611Snjl * FUNCTION:    CmDoCompile
553118611Snjl *
554118611Snjl * PARAMETERS:  None
555118611Snjl *
556118611Snjl * RETURN:      Status (0 = OK)
557118611Snjl *
558118611Snjl * DESCRIPTION: This procedure performs the entire compile
559118611Snjl *
560118611Snjl ******************************************************************************/
561118611Snjl
562118611Snjlint
563151937SjkimCmDoCompile (
564151937Sjkim    void)
565118611Snjl{
566118611Snjl    ACPI_STATUS             Status;
567151937Sjkim    UINT8                   FullCompile;
568151937Sjkim    UINT8                   Event;
569118611Snjl
570118611Snjl
571151937Sjkim    FullCompile = UtBeginEvent ("*** Total Compile time ***");
572151937Sjkim    Event = UtBeginEvent ("Open input and output files");
573151937Sjkim    UtEndEvent (Event);
574118611Snjl
575233250Sjkim    Event = UtBeginEvent ("Preprocess input file");
576234623Sjkim    if (Gbl_PreprocessFlag)
577233250Sjkim    {
578234623Sjkim        /* Preprocessor */
579234623Sjkim
580234623Sjkim        PrDoPreprocess ();
581234623Sjkim        if (Gbl_PreprocessOnly)
582234623Sjkim        {
583234623Sjkim            UtEndEvent (Event);
584234623Sjkim            CmCleanupAndExit ();
585241973Sjkim            return (0);
586234623Sjkim        }
587233250Sjkim    }
588234623Sjkim    UtEndEvent (Event);
589233250Sjkim
590118611Snjl    /* Build the parse tree */
591118611Snjl
592151937Sjkim    Event = UtBeginEvent ("Parse source code and build parse tree");
593118611Snjl    AslCompilerparse();
594151937Sjkim    UtEndEvent (Event);
595118611Snjl
596118611Snjl    /* Flush out any remaining source after parse tree is complete */
597118611Snjl
598151937Sjkim    Event = UtBeginEvent ("Flush source input");
599118611Snjl    CmFlushSourceCode ();
600118611Snjl
601118611Snjl    /* Did the parse tree get successfully constructed? */
602118611Snjl
603118611Snjl    if (!RootNode)
604118611Snjl    {
605234623Sjkim        /*
606234623Sjkim         * If there are no errors, then we have some sort of
607234623Sjkim         * internal problem.
608234623Sjkim         */
609234623Sjkim        Status = AslCheckForErrorExit ();
610234623Sjkim        if (Status == AE_OK)
611234623Sjkim        {
612234623Sjkim            AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
613234623Sjkim                NULL, "- Could not resolve parse tree root node");
614234623Sjkim        }
615234623Sjkim
616233250Sjkim        goto ErrorExit;
617118611Snjl    }
618118611Snjl
619167802Sjkim    /* Optional parse tree dump, compiler debug output only */
620167802Sjkim
621167802Sjkim    LsDumpParseTree ();
622167802Sjkim
623118611Snjl    OpcGetIntegerWidth (RootNode);
624151937Sjkim    UtEndEvent (Event);
625118611Snjl
626118611Snjl    /* Pre-process parse tree for any operator transforms */
627118611Snjl
628151937Sjkim    Event = UtBeginEvent ("Parse tree transforms");
629118611Snjl    DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n");
630151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
631151937Sjkim        TrAmlTransformWalk, NULL, NULL);
632151937Sjkim    UtEndEvent (Event);
633118611Snjl
634118611Snjl    /* Generate AML opcodes corresponding to the parse tokens */
635118611Snjl
636151937Sjkim    Event = UtBeginEvent ("Generate AML opcodes");
637118611Snjl    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n");
638151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
639151937Sjkim        OpcAmlOpcodeWalk, NULL);
640151937Sjkim    UtEndEvent (Event);
641118611Snjl
642118611Snjl    /*
643118611Snjl     * Now that the input is parsed, we can open the AML output file.
644118611Snjl     * Note: by default, the name of this file comes from the table descriptor
645118611Snjl     * within the input file.
646118611Snjl     */
647151937Sjkim    Event = UtBeginEvent ("Open AML output file");
648118611Snjl    Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
649233250Sjkim    UtEndEvent (Event);
650118611Snjl    if (ACPI_FAILURE (Status))
651118611Snjl    {
652118611Snjl        AePrintErrorLog (ASL_FILE_STDERR);
653241973Sjkim        return (-1);
654118611Snjl    }
655118611Snjl
656118611Snjl    /* Interpret and generate all compile-time constants */
657118611Snjl
658151937Sjkim    Event = UtBeginEvent ("Constant folding via AML interpreter");
659151937Sjkim    DbgPrint (ASL_DEBUG_OUTPUT,
660151937Sjkim        "\nInterpreting compile-time constant expressions\n\n");
661151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
662151937Sjkim        OpcAmlConstantWalk, NULL, NULL);
663151937Sjkim    UtEndEvent (Event);
664118611Snjl
665151937Sjkim    /* Update AML opcodes if necessary, after constant folding */
666151937Sjkim
667151937Sjkim    Event = UtBeginEvent ("Updating AML opcodes after constant folding");
668151937Sjkim    DbgPrint (ASL_DEBUG_OUTPUT,
669151937Sjkim        "\nUpdating AML opcodes after constant folding\n\n");
670151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
671151937Sjkim        NULL, OpcAmlOpcodeUpdateWalk, NULL);
672151937Sjkim    UtEndEvent (Event);
673151937Sjkim
674118611Snjl    /* Calculate all AML package lengths */
675118611Snjl
676151937Sjkim    Event = UtBeginEvent ("Generate AML package lengths");
677118611Snjl    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
678151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
679151937Sjkim        LnPackageLengthWalk, NULL);
680151937Sjkim    UtEndEvent (Event);
681118611Snjl
682118611Snjl    if (Gbl_ParseOnlyFlag)
683118611Snjl    {
684234623Sjkim        AePrintErrorLog (ASL_FILE_STDERR);
685234623Sjkim        UtDisplaySummary (ASL_FILE_STDERR);
686118611Snjl        if (Gbl_DebugFlag)
687118611Snjl        {
688234623Sjkim            /* Print error summary to the stdout also */
689118611Snjl
690234623Sjkim            AePrintErrorLog (ASL_FILE_STDOUT);
691234623Sjkim            UtDisplaySummary (ASL_FILE_STDOUT);
692118611Snjl        }
693233250Sjkim        UtEndEvent (FullCompile);
694241973Sjkim        return (0);
695118611Snjl    }
696118611Snjl
697118611Snjl    /*
698118611Snjl     * Create an internal namespace and use it as a symbol table
699118611Snjl     */
700118611Snjl
701118611Snjl    /* Namespace loading */
702118611Snjl
703151937Sjkim    Event = UtBeginEvent ("Create ACPI Namespace");
704118611Snjl    Status = LdLoadNamespace (RootNode);
705151937Sjkim    UtEndEvent (Event);
706118611Snjl    if (ACPI_FAILURE (Status))
707118611Snjl    {
708233250Sjkim        goto ErrorExit;
709118611Snjl    }
710118611Snjl
711167802Sjkim    /* Namespace cross-reference */
712118611Snjl
713151937Sjkim    AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace");
714245582Sjkim    Status = XfCrossReferenceNamespace ();
715118611Snjl    if (ACPI_FAILURE (Status))
716118611Snjl    {
717233250Sjkim        goto ErrorExit;
718118611Snjl    }
719118611Snjl
720167802Sjkim    /* Namespace - Check for non-referenced objects */
721167802Sjkim
722167802Sjkim    LkFindUnreferencedObjects ();
723167802Sjkim    UtEndEvent (AslGbl_NamespaceEvent);
724167802Sjkim
725118611Snjl    /*
726241973Sjkim     * Semantic analysis. This can happen only after the
727118611Snjl     * namespace has been loaded and cross-referenced.
728118611Snjl     *
729118611Snjl     * part one - check control methods
730118611Snjl     */
731151937Sjkim    Event = UtBeginEvent ("Analyze control method return types");
732118611Snjl    AnalysisWalkInfo.MethodStack = NULL;
733118611Snjl
734118611Snjl    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n");
735151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
736245582Sjkim        MtMethodAnalysisWalkBegin,
737245582Sjkim        MtMethodAnalysisWalkEnd, &AnalysisWalkInfo);
738151937Sjkim    UtEndEvent (Event);
739118611Snjl
740118611Snjl    /* Semantic error checking part two - typing of method returns */
741118611Snjl
742151937Sjkim    Event = UtBeginEvent ("Determine object types returned by methods");
743151937Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n");
744218590Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
745218590Sjkim        NULL, AnMethodTypingWalkEnd, NULL);
746151937Sjkim    UtEndEvent (Event);
747118611Snjl
748118611Snjl    /* Semantic error checking part three - operand type checking */
749118611Snjl
750151937Sjkim    Event = UtBeginEvent ("Analyze AML operand types");
751151937Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n");
752218590Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
753218590Sjkim        NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo);
754151937Sjkim    UtEndEvent (Event);
755118611Snjl
756118611Snjl    /* Semantic error checking part four - other miscellaneous checks */
757118611Snjl
758151937Sjkim    Event = UtBeginEvent ("Miscellaneous analysis");
759151937Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n");
760218590Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
761151937Sjkim        AnOtherSemanticAnalysisWalkBegin,
762218590Sjkim        NULL, &AnalysisWalkInfo);
763151937Sjkim    UtEndEvent (Event);
764118611Snjl
765118611Snjl    /* Calculate all AML package lengths */
766118611Snjl
767151937Sjkim    Event = UtBeginEvent ("Finish AML package length generation");
768118611Snjl    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
769151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
770151937Sjkim        LnInitLengthsWalk, NULL);
771151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
772151937Sjkim        LnPackageLengthWalk, NULL);
773151937Sjkim    UtEndEvent (Event);
774118611Snjl
775118611Snjl    /* Code generation - emit the AML */
776118611Snjl
777151937Sjkim    Event = UtBeginEvent ("Generate AML code and write output files");
778118611Snjl    CgGenerateAmlOutput ();
779151937Sjkim    UtEndEvent (Event);
780118611Snjl
781151937Sjkim    Event = UtBeginEvent ("Write optional output files");
782118611Snjl    CmDoOutputFiles ();
783151937Sjkim    UtEndEvent (Event);
784118611Snjl
785151937Sjkim    UtEndEvent (FullCompile);
786118611Snjl    CmCleanupAndExit ();
787241973Sjkim    return (0);
788233250Sjkim
789233250SjkimErrorExit:
790233250Sjkim    UtEndEvent (FullCompile);
791233250Sjkim    CmCleanupAndExit ();
792233250Sjkim    return (-1);
793118611Snjl}
794118611Snjl
795151937Sjkim
796151937Sjkim/*******************************************************************************
797151937Sjkim *
798151937Sjkim * FUNCTION:    CmDoOutputFiles
799151937Sjkim *
800151937Sjkim * PARAMETERS:  None
801151937Sjkim *
802151937Sjkim * RETURN:      None.
803151937Sjkim *
804151937Sjkim * DESCRIPTION: Create all "listing" type files
805151937Sjkim *
806151937Sjkim ******************************************************************************/
807151937Sjkim
808118611Snjlvoid
809151937SjkimCmDoOutputFiles (
810151937Sjkim    void)
811118611Snjl{
812118611Snjl
813118611Snjl    /* Create listings and hex files */
814118611Snjl
815118611Snjl    LsDoListings ();
816245582Sjkim    HxDoHexOutput ();
817118611Snjl
818118611Snjl    /* Dump the namespace to the .nsp file if requested */
819118611Snjl
820245582Sjkim    (void) NsDisplayNamespace ();
821118611Snjl}
822118611Snjl
823118611Snjl
824118611Snjl/*******************************************************************************
825118611Snjl *
826237412Sjkim * FUNCTION:    CmDumpAllEvents
827151937Sjkim *
828237412Sjkim * PARAMETERS:  None
829151937Sjkim *
830151937Sjkim * RETURN:      None.
831151937Sjkim *
832237412Sjkim * DESCRIPTION: Dump all compiler events
833151937Sjkim *
834151937Sjkim ******************************************************************************/
835151937Sjkim
836151937Sjkimstatic void
837237412SjkimCmDumpAllEvents (
838237412Sjkim    void)
839151937Sjkim{
840237412Sjkim    ASL_EVENT_INFO          *Event;
841151937Sjkim    UINT32                  Delta;
842151937Sjkim    UINT32                  USec;
843151937Sjkim    UINT32                  MSec;
844237412Sjkim    UINT32                  i;
845151937Sjkim
846237412Sjkim
847237412Sjkim    Event = AslGbl_Events;
848237412Sjkim
849237412Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
850237412Sjkim    if (Gbl_CompileTimesFlag)
851151937Sjkim    {
852237412Sjkim        printf ("\nElapsed time for major events\n\n");
853151937Sjkim    }
854151937Sjkim
855237412Sjkim    for (i = 0; i < AslGbl_NextEvent; i++)
856237412Sjkim    {
857237412Sjkim        if (Event->Valid)
858237412Sjkim        {
859237412Sjkim            /* Delta will be in 100-nanosecond units */
860151937Sjkim
861237412Sjkim            Delta = (UINT32) (Event->EndTime - Event->StartTime);
862151937Sjkim
863245582Sjkim            USec = Delta / ACPI_100NSEC_PER_USEC;
864245582Sjkim            MSec = Delta / ACPI_100NSEC_PER_MSEC;
865151937Sjkim
866237412Sjkim            /* Round milliseconds up */
867151937Sjkim
868245582Sjkim            if ((USec - (MSec * ACPI_USEC_PER_MSEC)) >= 500)
869237412Sjkim            {
870237412Sjkim                MSec++;
871237412Sjkim            }
872237412Sjkim
873237412Sjkim            DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
874237412Sjkim                USec, MSec, Event->EventName);
875237412Sjkim
876237412Sjkim            if (Gbl_CompileTimesFlag)
877237412Sjkim            {
878237412Sjkim                printf ("%8u usec %8u msec - %s\n",
879237412Sjkim                    USec, MSec, Event->EventName);
880237412Sjkim            }
881237412Sjkim        }
882237412Sjkim
883237412Sjkim        Event++;
884151937Sjkim    }
885151937Sjkim}
886151937Sjkim
887151937Sjkim
888151937Sjkim/*******************************************************************************
889151937Sjkim *
890118611Snjl * FUNCTION:    CmCleanupAndExit
891118611Snjl *
892118611Snjl * PARAMETERS:  None
893118611Snjl *
894118611Snjl * RETURN:      None.
895118611Snjl *
896118611Snjl * DESCRIPTION: Close all open files and exit the compiler
897118611Snjl *
898118611Snjl ******************************************************************************/
899118611Snjl
900118611Snjlvoid
901151937SjkimCmCleanupAndExit (
902151937Sjkim    void)
903118611Snjl{
904118611Snjl    UINT32                  i;
905240716Sjkim    BOOLEAN                 DeleteAmlFile = FALSE;
906118611Snjl
907118611Snjl
908234623Sjkim    AePrintErrorLog (ASL_FILE_STDERR);
909118611Snjl    if (Gbl_DebugFlag)
910118611Snjl    {
911234623Sjkim        /* Print error summary to stdout also */
912118611Snjl
913234623Sjkim        AePrintErrorLog (ASL_FILE_STDOUT);
914118611Snjl    }
915118611Snjl
916237412Sjkim    /* Emit compile times if enabled */
917118611Snjl
918237412Sjkim    CmDumpAllEvents ();
919237412Sjkim
920118611Snjl    if (Gbl_CompileTimesFlag)
921118611Snjl    {
922118611Snjl        printf ("\nMiscellaneous compile statistics\n\n");
923118611Snjl        printf ("%11u : %s\n", TotalParseNodes, "Parse nodes");
924118611Snjl        printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches");
925118611Snjl        printf ("%11u : %s\n", TotalNamedObjects, "Named objects");
926118611Snjl        printf ("%11u : %s\n", TotalMethods, "Control methods");
927118611Snjl        printf ("%11u : %s\n", TotalAllocations, "Memory Allocations");
928118611Snjl        printf ("%11u : %s\n", TotalAllocated, "Total allocated memory");
929118611Snjl        printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded");
930118611Snjl        printf ("\n");
931118611Snjl    }
932118611Snjl
933118611Snjl    if (Gbl_NsLookupCount)
934118611Snjl    {
935209746Sjkim        DbgPrint (ASL_DEBUG_OUTPUT,
936209746Sjkim            "\n\nMiscellaneous compile statistics\n\n");
937209746Sjkim
938209746Sjkim        DbgPrint (ASL_DEBUG_OUTPUT,
939209746Sjkim            "%32s : %u\n", "Total Namespace searches",
940151937Sjkim            Gbl_NsLookupCount);
941209746Sjkim
942209746Sjkim        DbgPrint (ASL_DEBUG_OUTPUT,
943209746Sjkim            "%32s : %u usec\n", "Time per search", ((UINT32)
944209746Sjkim            (AslGbl_Events[AslGbl_NamespaceEvent].EndTime -
945209746Sjkim                AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) /
946209746Sjkim                Gbl_NsLookupCount);
947118611Snjl    }
948118611Snjl
949118611Snjl    if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
950118611Snjl    {
951209746Sjkim        printf ("\nMaximum error count (%u) exceeded\n",
952209746Sjkim            ASL_MAX_ERROR_COUNT);
953118611Snjl    }
954118611Snjl
955118611Snjl    UtDisplaySummary (ASL_FILE_STDOUT);
956199337Sjkim
957240716Sjkim    /*
958240716Sjkim     * We will delete the AML file if there are errors and the
959240716Sjkim     * force AML output option has not been used.
960240716Sjkim     */
961240716Sjkim    if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors) &&
962240716Sjkim        Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)
963240716Sjkim    {
964240716Sjkim        DeleteAmlFile = TRUE;
965240716Sjkim    }
966240716Sjkim
967199337Sjkim    /* Close all open files */
968199337Sjkim
969252279Sjkim    /*
970252279Sjkim     * Take care with the preprocessor file (.i), it might be the same
971252279Sjkim     * as the "input" file, depending on where the compiler has terminated
972252279Sjkim     * or aborted. Prevent attempt to close the same file twice in
973252279Sjkim     * loop below.
974252279Sjkim     */
975252279Sjkim    if (Gbl_Files[ASL_FILE_PREPROCESSOR].Handle ==
976252279Sjkim        Gbl_Files[ASL_FILE_INPUT].Handle)
977252279Sjkim    {
978252279Sjkim        Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL;
979252279Sjkim    }
980233250Sjkim
981252279Sjkim    /* Close the standard I/O files */
982252279Sjkim
983233250Sjkim    for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++)
984199337Sjkim    {
985199337Sjkim        FlCloseFile (i);
986199337Sjkim    }
987200553Sjkim
988200553Sjkim    /* Delete AML file if there are errors */
989200553Sjkim
990240716Sjkim    if (DeleteAmlFile)
991200553Sjkim    {
992240716Sjkim        FlDeleteFile (ASL_FILE_AML_OUTPUT);
993200553Sjkim    }
994200553Sjkim
995233250Sjkim    /* Delete the preprocessor output file (.i) unless -li flag is set */
996233250Sjkim
997234623Sjkim    if (!Gbl_PreprocessorOutputFlag &&
998240716Sjkim        Gbl_PreprocessFlag)
999233250Sjkim    {
1000240716Sjkim        FlDeleteFile (ASL_FILE_PREPROCESSOR);
1001233250Sjkim    }
1002233250Sjkim
1003200553Sjkim    /*
1004200553Sjkim     * Delete intermediate ("combined") source file (if -ls flag not set)
1005209746Sjkim     * This file is created during normal ASL/AML compiles. It is not
1006209746Sjkim     * created by the data table compiler.
1007200553Sjkim     *
1008209746Sjkim     * If the -ls flag is set, then the .SRC file should not be deleted.
1009209746Sjkim     * In this case, Gbl_SourceOutputFlag is set to TRUE.
1010209746Sjkim     *
1011209746Sjkim     * Note: Handles are cleared by FlCloseFile above, so we look at the
1012209746Sjkim     * filename instead, to determine if the .SRC file was actually
1013209746Sjkim     * created.
1014209746Sjkim     *
1015200553Sjkim     * TBD: SourceOutput should be .TMP, then rename if we want to keep it?
1016200553Sjkim     */
1017240716Sjkim    if (!Gbl_SourceOutputFlag)
1018200553Sjkim    {
1019240716Sjkim        FlDeleteFile (ASL_FILE_SOURCE_OUTPUT);
1020200553Sjkim    }
1021118611Snjl}
1022