aslcompile.c revision 246849
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: 129118611Snjl case ASL_FILE_C_INCLUDE_OUTPUT: 130118611Snjl 131118611Snjl Prefix = " * "; 132118611Snjl break; 133118611Snjl 134118611Snjl default: 135118611Snjl /* No other output types supported */ 136118611Snjl break; 137118611Snjl } 138118611Snjl 139151937Sjkim /* Running compiler or disassembler? */ 140151937Sjkim 141151937Sjkim if (Gbl_DisasmFlag) 142151937Sjkim { 143213806Sjkim UtilityName = AML_DISASSEMBLER_NAME; 144151937Sjkim } 145151937Sjkim else 146151937Sjkim { 147213806Sjkim UtilityName = ASL_COMPILER_NAME; 148151937Sjkim } 149151937Sjkim 150213806Sjkim /* Compiler signon with copyright */ 151151937Sjkim 152213806Sjkim FlPrintFile (FileId, "%s\n", Prefix); 153213806Sjkim FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix)); 154118611Snjl} 155118611Snjl 156118611Snjl 157118611Snjl/******************************************************************************* 158118611Snjl * 159118611Snjl * FUNCTION: AslCompilerFileHeader 160118611Snjl * 161118611Snjl * PARAMETERS: FileId - ID of the output file 162118611Snjl * 163118611Snjl * RETURN: None 164118611Snjl * 165118611Snjl * DESCRIPTION: Header used at the beginning of output files 166118611Snjl * 167118611Snjl ******************************************************************************/ 168118611Snjl 169118611Snjlvoid 170118611SnjlAslCompilerFileHeader ( 171118611Snjl UINT32 FileId) 172118611Snjl{ 173118611Snjl struct tm *NewTime; 174118611Snjl time_t Aclock; 175118611Snjl char *Prefix = ""; 176118611Snjl 177118611Snjl 178151937Sjkim /* Set line prefix depending on the destination file type */ 179151937Sjkim 180118611Snjl switch (FileId) 181118611Snjl { 182118611Snjl case ASL_FILE_ASM_SOURCE_OUTPUT: 183118611Snjl case ASL_FILE_ASM_INCLUDE_OUTPUT: 184118611Snjl 185118611Snjl Prefix = "; "; 186118611Snjl break; 187118611Snjl 188118611Snjl case ASL_FILE_HEX_OUTPUT: 189118611Snjl 190118611Snjl if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM) 191118611Snjl { 192118611Snjl Prefix = "; "; 193118611Snjl } 194207344Sjkim else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) || 195207344Sjkim (Gbl_HexOutputFlag == HEX_OUTPUT_ASL)) 196118611Snjl { 197118611Snjl Prefix = " * "; 198118611Snjl } 199118611Snjl break; 200118611Snjl 201118611Snjl case ASL_FILE_C_SOURCE_OUTPUT: 202118611Snjl case ASL_FILE_C_INCLUDE_OUTPUT: 203118611Snjl 204118611Snjl Prefix = " * "; 205118611Snjl break; 206118611Snjl 207118611Snjl default: 208118611Snjl /* No other output types supported */ 209118611Snjl break; 210118611Snjl } 211118611Snjl 212118611Snjl /* Compilation header with timestamp */ 213118611Snjl 214118611Snjl (void) time (&Aclock); 215118611Snjl NewTime = localtime (&Aclock); 216118611Snjl 217118611Snjl FlPrintFile (FileId, 218118611Snjl "%sCompilation of \"%s\" - %s%s\n", 219118611Snjl Prefix, Gbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime), 220118611Snjl Prefix); 221118611Snjl 222118611Snjl switch (FileId) 223118611Snjl { 224118611Snjl case ASL_FILE_C_SOURCE_OUTPUT: 225118611Snjl case ASL_FILE_C_INCLUDE_OUTPUT: 226118611Snjl FlPrintFile (FileId, " */\n"); 227118611Snjl break; 228118611Snjl 229118611Snjl default: 230118611Snjl /* Nothing to do for other output types */ 231118611Snjl break; 232118611Snjl } 233118611Snjl} 234118611Snjl 235118611Snjl 236118611Snjl/******************************************************************************* 237118611Snjl * 238118611Snjl * FUNCTION: CmFlushSourceCode 239118611Snjl * 240118611Snjl * PARAMETERS: None 241118611Snjl * 242118611Snjl * RETURN: None 243118611Snjl * 244118611Snjl * DESCRIPTION: Read in any remaining source code after the parse tree 245118611Snjl * has been constructed. 246118611Snjl * 247118611Snjl ******************************************************************************/ 248118611Snjl 249151937Sjkimstatic void 250151937SjkimCmFlushSourceCode ( 251151937Sjkim void) 252118611Snjl{ 253118611Snjl char Buffer; 254118611Snjl 255118611Snjl 256118611Snjl while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR) 257118611Snjl { 258234623Sjkim AslInsertLineBuffer ((int) Buffer); 259118611Snjl } 260118611Snjl 261234623Sjkim AslResetCurrentLineBuffer (); 262118611Snjl} 263118611Snjl 264118611Snjl 265118611Snjl/******************************************************************************* 266118611Snjl * 267167802Sjkim * FUNCTION: FlConsume* 268167802Sjkim * 269235945Sjkim * PARAMETERS: Handle - Open input file 270235945Sjkim * Status - File current status struct 271167802Sjkim * 272167802Sjkim * RETURN: Number of lines consumed 273167802Sjkim * 274167802Sjkim * DESCRIPTION: Step over both types of comment during check for ascii chars 275167802Sjkim * 276167802Sjkim ******************************************************************************/ 277167802Sjkim 278212761Sjkimstatic void 279167802SjkimFlConsumeAnsiComment ( 280235945Sjkim FILE *Handle, 281167802Sjkim ASL_FILE_STATUS *Status) 282167802Sjkim{ 283167802Sjkim UINT8 Byte; 284167802Sjkim BOOLEAN ClosingComment = FALSE; 285167802Sjkim 286167802Sjkim 287243347Sjkim while (fread (&Byte, 1, 1, Handle) == 1) 288167802Sjkim { 289167802Sjkim /* Scan until comment close is found */ 290167802Sjkim 291167802Sjkim if (ClosingComment) 292167802Sjkim { 293167802Sjkim if (Byte == '/') 294167802Sjkim { 295167802Sjkim return; 296167802Sjkim } 297167802Sjkim 298167802Sjkim if (Byte != '*') 299167802Sjkim { 300167802Sjkim /* Reset */ 301167802Sjkim 302167802Sjkim ClosingComment = FALSE; 303167802Sjkim } 304167802Sjkim } 305167802Sjkim else if (Byte == '*') 306167802Sjkim { 307167802Sjkim ClosingComment = TRUE; 308167802Sjkim } 309167802Sjkim 310167802Sjkim /* Maintain line count */ 311167802Sjkim 312167802Sjkim if (Byte == 0x0A) 313167802Sjkim { 314167802Sjkim Status->Line++; 315167802Sjkim } 316167802Sjkim 317167802Sjkim Status->Offset++; 318167802Sjkim } 319167802Sjkim} 320167802Sjkim 321167802Sjkim 322212761Sjkimstatic void 323167802SjkimFlConsumeNewComment ( 324235945Sjkim FILE *Handle, 325167802Sjkim ASL_FILE_STATUS *Status) 326167802Sjkim{ 327167802Sjkim UINT8 Byte; 328167802Sjkim 329167802Sjkim 330243347Sjkim while (fread (&Byte, 1, 1, Handle) == 1) 331167802Sjkim { 332167802Sjkim Status->Offset++; 333167802Sjkim 334167802Sjkim /* Comment ends at newline */ 335167802Sjkim 336167802Sjkim if (Byte == 0x0A) 337167802Sjkim { 338167802Sjkim Status->Line++; 339167802Sjkim return; 340167802Sjkim } 341167802Sjkim } 342167802Sjkim} 343167802Sjkim 344167802Sjkim 345167802Sjkim/******************************************************************************* 346167802Sjkim * 347246849Sjkim * FUNCTION: FlCheckForAcpiTable 348246849Sjkim * 349246849Sjkim * PARAMETERS: Handle - Open input file 350246849Sjkim * 351246849Sjkim * RETURN: Status 352246849Sjkim * 353246849Sjkim * DESCRIPTION: Determine if a file seems to be a binary ACPI table, via the 354246849Sjkim * following checks on what would be the table header: 355246849Sjkim * 0) File must be at least as long as an ACPI_TABLE_HEADER 356246849Sjkim * 1) The header length field must match the file size 357246849Sjkim * 2) Signature, OemId, OemTableId, AslCompilerId must be ASCII 358246849Sjkim * 359246849Sjkim ******************************************************************************/ 360246849Sjkim 361246849SjkimACPI_STATUS 362246849SjkimFlCheckForAcpiTable ( 363246849Sjkim FILE *Handle) 364246849Sjkim{ 365246849Sjkim ACPI_TABLE_HEADER Table; 366246849Sjkim UINT32 FileSize; 367246849Sjkim size_t Actual; 368246849Sjkim UINT32 i; 369246849Sjkim 370246849Sjkim 371246849Sjkim /* Read a potential table header */ 372246849Sjkim 373246849Sjkim Actual = fread (&Table, 1, sizeof (ACPI_TABLE_HEADER), Handle); 374246849Sjkim fseek (Handle, 0, SEEK_SET); 375246849Sjkim 376246849Sjkim if (Actual < sizeof (ACPI_TABLE_HEADER)) 377246849Sjkim { 378246849Sjkim return (AE_ERROR); 379246849Sjkim } 380246849Sjkim 381246849Sjkim /* Header length field must match the file size */ 382246849Sjkim 383246849Sjkim FileSize = DtGetFileSize (Handle); 384246849Sjkim if (Table.Length != FileSize) 385246849Sjkim { 386246849Sjkim return (AE_ERROR); 387246849Sjkim } 388246849Sjkim 389246849Sjkim /* 390246849Sjkim * These fields must be ASCII: 391246849Sjkim * Signature, OemId, OemTableId, AslCompilerId. 392246849Sjkim * We allow a NULL terminator in OemId and OemTableId. 393246849Sjkim */ 394246849Sjkim for (i = 0; i < ACPI_NAME_SIZE; i++) 395246849Sjkim { 396246849Sjkim if (!ACPI_IS_ASCII ((UINT8) Table.Signature[i])) 397246849Sjkim { 398246849Sjkim return (AE_ERROR); 399246849Sjkim } 400246849Sjkim 401246849Sjkim if (!ACPI_IS_ASCII ((UINT8) Table.AslCompilerId[i])) 402246849Sjkim { 403246849Sjkim return (AE_ERROR); 404246849Sjkim } 405246849Sjkim } 406246849Sjkim 407246849Sjkim for (i = 0; (i < ACPI_OEM_ID_SIZE) && (Table.OemId[i]); i++) 408246849Sjkim { 409246849Sjkim if (!ACPI_IS_ASCII ((UINT8) Table.OemId[i])) 410246849Sjkim { 411246849Sjkim return (AE_ERROR); 412246849Sjkim } 413246849Sjkim } 414246849Sjkim 415246849Sjkim for (i = 0; (i < ACPI_OEM_TABLE_ID_SIZE) && (Table.OemTableId[i]); i++) 416246849Sjkim { 417246849Sjkim if (!ACPI_IS_ASCII ((UINT8) Table.OemTableId[i])) 418246849Sjkim { 419246849Sjkim return (AE_ERROR); 420246849Sjkim } 421246849Sjkim } 422246849Sjkim 423246849Sjkim printf ("Binary file appears to be a valid ACPI table, disassembling\n"); 424246849Sjkim return (AE_OK); 425246849Sjkim} 426246849Sjkim 427246849Sjkim 428246849Sjkim/******************************************************************************* 429246849Sjkim * 430123315Snjl * FUNCTION: FlCheckForAscii 431123315Snjl * 432235945Sjkim * PARAMETERS: Handle - Open input file 433235945Sjkim * Filename - Input filename 434235945Sjkim * DisplayErrors - TRUE if error messages desired 435123315Snjl * 436151937Sjkim * RETURN: Status 437123315Snjl * 438167802Sjkim * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters 439167802Sjkim * within comments. Note: does not handle nested comments and does 440167802Sjkim * not handle comment delimiters within string literals. However, 441167802Sjkim * on the rare chance this happens and an invalid character is 442167802Sjkim * missed, the parser will catch the error by failing in some 443167802Sjkim * spectactular manner. 444123315Snjl * 445123315Snjl ******************************************************************************/ 446123315Snjl 447209746SjkimACPI_STATUS 448123315SnjlFlCheckForAscii ( 449235945Sjkim FILE *Handle, 450235945Sjkim char *Filename, 451235945Sjkim BOOLEAN DisplayErrors) 452123315Snjl{ 453123315Snjl UINT8 Byte; 454123315Snjl ACPI_SIZE BadBytes = 0; 455167802Sjkim BOOLEAN OpeningComment = FALSE; 456167802Sjkim ASL_FILE_STATUS Status; 457123315Snjl 458123315Snjl 459167802Sjkim Status.Line = 1; 460167802Sjkim Status.Offset = 0; 461167802Sjkim 462123315Snjl /* Read the entire file */ 463123315Snjl 464243347Sjkim while (fread (&Byte, 1, 1, Handle) == 1) 465123315Snjl { 466167802Sjkim /* Ignore comment fields (allow non-ascii within) */ 467167802Sjkim 468167802Sjkim if (OpeningComment) 469167802Sjkim { 470167802Sjkim /* Check for second comment open delimiter */ 471167802Sjkim 472167802Sjkim if (Byte == '*') 473167802Sjkim { 474235945Sjkim FlConsumeAnsiComment (Handle, &Status); 475167802Sjkim } 476167802Sjkim 477167802Sjkim if (Byte == '/') 478167802Sjkim { 479235945Sjkim FlConsumeNewComment (Handle, &Status); 480167802Sjkim } 481167802Sjkim 482167802Sjkim /* Reset */ 483167802Sjkim 484167802Sjkim OpeningComment = FALSE; 485167802Sjkim } 486167802Sjkim else if (Byte == '/') 487167802Sjkim { 488167802Sjkim OpeningComment = TRUE; 489167802Sjkim } 490167802Sjkim 491123315Snjl /* Check for an ASCII character */ 492123315Snjl 493193529Sjkim if (!ACPI_IS_ASCII (Byte)) 494123315Snjl { 495235945Sjkim if ((BadBytes < 10) && (DisplayErrors)) 496123315Snjl { 497151937Sjkim AcpiOsPrintf ( 498167802Sjkim "Non-ASCII character [0x%2.2X] found in line %u, file offset 0x%.2X\n", 499167802Sjkim Byte, Status.Line, Status.Offset); 500123315Snjl } 501167802Sjkim 502123315Snjl BadBytes++; 503123315Snjl } 504167802Sjkim 505167802Sjkim /* Update line counter */ 506167802Sjkim 507167802Sjkim else if (Byte == 0x0A) 508167802Sjkim { 509167802Sjkim Status.Line++; 510167802Sjkim } 511167802Sjkim 512167802Sjkim Status.Offset++; 513123315Snjl } 514123315Snjl 515151937Sjkim /* Seek back to the beginning of the source file */ 516151937Sjkim 517235945Sjkim fseek (Handle, 0, SEEK_SET); 518151937Sjkim 519123315Snjl /* Were there any non-ASCII characters in the file? */ 520123315Snjl 521123315Snjl if (BadBytes) 522123315Snjl { 523235945Sjkim if (DisplayErrors) 524235945Sjkim { 525235945Sjkim AcpiOsPrintf ( 526235945Sjkim "%u non-ASCII characters found in input source text, could be a binary file\n", 527235945Sjkim BadBytes); 528235945Sjkim AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename); 529235945Sjkim } 530235945Sjkim 531123315Snjl return (AE_BAD_CHARACTER); 532123315Snjl } 533123315Snjl 534235945Sjkim /* File is OK (100% ASCII) */ 535123315Snjl 536123315Snjl return (AE_OK); 537123315Snjl} 538123315Snjl 539123315Snjl 540123315Snjl/******************************************************************************* 541123315Snjl * 542118611Snjl * FUNCTION: CmDoCompile 543118611Snjl * 544118611Snjl * PARAMETERS: None 545118611Snjl * 546118611Snjl * RETURN: Status (0 = OK) 547118611Snjl * 548118611Snjl * DESCRIPTION: This procedure performs the entire compile 549118611Snjl * 550118611Snjl ******************************************************************************/ 551118611Snjl 552118611Snjlint 553151937SjkimCmDoCompile ( 554151937Sjkim void) 555118611Snjl{ 556118611Snjl ACPI_STATUS Status; 557151937Sjkim UINT8 FullCompile; 558151937Sjkim UINT8 Event; 559118611Snjl 560118611Snjl 561151937Sjkim FullCompile = UtBeginEvent ("*** Total Compile time ***"); 562151937Sjkim Event = UtBeginEvent ("Open input and output files"); 563151937Sjkim UtEndEvent (Event); 564118611Snjl 565233250Sjkim Event = UtBeginEvent ("Preprocess input file"); 566234623Sjkim if (Gbl_PreprocessFlag) 567233250Sjkim { 568234623Sjkim /* Preprocessor */ 569234623Sjkim 570234623Sjkim PrDoPreprocess (); 571234623Sjkim if (Gbl_PreprocessOnly) 572234623Sjkim { 573234623Sjkim UtEndEvent (Event); 574234623Sjkim CmCleanupAndExit (); 575241973Sjkim return (0); 576234623Sjkim } 577233250Sjkim } 578234623Sjkim UtEndEvent (Event); 579233250Sjkim 580118611Snjl /* Build the parse tree */ 581118611Snjl 582151937Sjkim Event = UtBeginEvent ("Parse source code and build parse tree"); 583118611Snjl AslCompilerparse(); 584151937Sjkim UtEndEvent (Event); 585118611Snjl 586118611Snjl /* Flush out any remaining source after parse tree is complete */ 587118611Snjl 588151937Sjkim Event = UtBeginEvent ("Flush source input"); 589118611Snjl CmFlushSourceCode (); 590118611Snjl 591118611Snjl /* Did the parse tree get successfully constructed? */ 592118611Snjl 593118611Snjl if (!RootNode) 594118611Snjl { 595234623Sjkim /* 596234623Sjkim * If there are no errors, then we have some sort of 597234623Sjkim * internal problem. 598234623Sjkim */ 599234623Sjkim Status = AslCheckForErrorExit (); 600234623Sjkim if (Status == AE_OK) 601234623Sjkim { 602234623Sjkim AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, 603234623Sjkim NULL, "- Could not resolve parse tree root node"); 604234623Sjkim } 605234623Sjkim 606233250Sjkim goto ErrorExit; 607118611Snjl } 608118611Snjl 609167802Sjkim /* Optional parse tree dump, compiler debug output only */ 610167802Sjkim 611167802Sjkim LsDumpParseTree (); 612167802Sjkim 613118611Snjl OpcGetIntegerWidth (RootNode); 614151937Sjkim UtEndEvent (Event); 615118611Snjl 616118611Snjl /* Pre-process parse tree for any operator transforms */ 617118611Snjl 618151937Sjkim Event = UtBeginEvent ("Parse tree transforms"); 619118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n"); 620151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 621151937Sjkim TrAmlTransformWalk, NULL, NULL); 622151937Sjkim UtEndEvent (Event); 623118611Snjl 624118611Snjl /* Generate AML opcodes corresponding to the parse tokens */ 625118611Snjl 626151937Sjkim Event = UtBeginEvent ("Generate AML opcodes"); 627118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n"); 628151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 629151937Sjkim OpcAmlOpcodeWalk, NULL); 630151937Sjkim UtEndEvent (Event); 631118611Snjl 632118611Snjl /* 633118611Snjl * Now that the input is parsed, we can open the AML output file. 634118611Snjl * Note: by default, the name of this file comes from the table descriptor 635118611Snjl * within the input file. 636118611Snjl */ 637151937Sjkim Event = UtBeginEvent ("Open AML output file"); 638118611Snjl Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix); 639233250Sjkim UtEndEvent (Event); 640118611Snjl if (ACPI_FAILURE (Status)) 641118611Snjl { 642118611Snjl AePrintErrorLog (ASL_FILE_STDERR); 643241973Sjkim return (-1); 644118611Snjl } 645118611Snjl 646118611Snjl /* Interpret and generate all compile-time constants */ 647118611Snjl 648151937Sjkim Event = UtBeginEvent ("Constant folding via AML interpreter"); 649151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 650151937Sjkim "\nInterpreting compile-time constant expressions\n\n"); 651151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 652151937Sjkim OpcAmlConstantWalk, NULL, NULL); 653151937Sjkim UtEndEvent (Event); 654118611Snjl 655151937Sjkim /* Update AML opcodes if necessary, after constant folding */ 656151937Sjkim 657151937Sjkim Event = UtBeginEvent ("Updating AML opcodes after constant folding"); 658151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 659151937Sjkim "\nUpdating AML opcodes after constant folding\n\n"); 660151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 661151937Sjkim NULL, OpcAmlOpcodeUpdateWalk, NULL); 662151937Sjkim UtEndEvent (Event); 663151937Sjkim 664118611Snjl /* Calculate all AML package lengths */ 665118611Snjl 666151937Sjkim Event = UtBeginEvent ("Generate AML package lengths"); 667118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n"); 668151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 669151937Sjkim LnPackageLengthWalk, NULL); 670151937Sjkim UtEndEvent (Event); 671118611Snjl 672118611Snjl if (Gbl_ParseOnlyFlag) 673118611Snjl { 674234623Sjkim AePrintErrorLog (ASL_FILE_STDERR); 675234623Sjkim UtDisplaySummary (ASL_FILE_STDERR); 676118611Snjl if (Gbl_DebugFlag) 677118611Snjl { 678234623Sjkim /* Print error summary to the stdout also */ 679118611Snjl 680234623Sjkim AePrintErrorLog (ASL_FILE_STDOUT); 681234623Sjkim UtDisplaySummary (ASL_FILE_STDOUT); 682118611Snjl } 683233250Sjkim UtEndEvent (FullCompile); 684241973Sjkim return (0); 685118611Snjl } 686118611Snjl 687118611Snjl /* 688118611Snjl * Create an internal namespace and use it as a symbol table 689118611Snjl */ 690118611Snjl 691118611Snjl /* Namespace loading */ 692118611Snjl 693151937Sjkim Event = UtBeginEvent ("Create ACPI Namespace"); 694118611Snjl Status = LdLoadNamespace (RootNode); 695151937Sjkim UtEndEvent (Event); 696118611Snjl if (ACPI_FAILURE (Status)) 697118611Snjl { 698233250Sjkim goto ErrorExit; 699118611Snjl } 700118611Snjl 701167802Sjkim /* Namespace cross-reference */ 702118611Snjl 703151937Sjkim AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace"); 704245582Sjkim Status = XfCrossReferenceNamespace (); 705118611Snjl if (ACPI_FAILURE (Status)) 706118611Snjl { 707233250Sjkim goto ErrorExit; 708118611Snjl } 709118611Snjl 710167802Sjkim /* Namespace - Check for non-referenced objects */ 711167802Sjkim 712167802Sjkim LkFindUnreferencedObjects (); 713167802Sjkim UtEndEvent (AslGbl_NamespaceEvent); 714167802Sjkim 715118611Snjl /* 716241973Sjkim * Semantic analysis. This can happen only after the 717118611Snjl * namespace has been loaded and cross-referenced. 718118611Snjl * 719118611Snjl * part one - check control methods 720118611Snjl */ 721151937Sjkim Event = UtBeginEvent ("Analyze control method return types"); 722118611Snjl AnalysisWalkInfo.MethodStack = NULL; 723118611Snjl 724118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n"); 725151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, 726245582Sjkim MtMethodAnalysisWalkBegin, 727245582Sjkim MtMethodAnalysisWalkEnd, &AnalysisWalkInfo); 728151937Sjkim UtEndEvent (Event); 729118611Snjl 730118611Snjl /* Semantic error checking part two - typing of method returns */ 731118611Snjl 732151937Sjkim Event = UtBeginEvent ("Determine object types returned by methods"); 733151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n"); 734218590Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 735218590Sjkim NULL, AnMethodTypingWalkEnd, NULL); 736151937Sjkim UtEndEvent (Event); 737118611Snjl 738118611Snjl /* Semantic error checking part three - operand type checking */ 739118611Snjl 740151937Sjkim Event = UtBeginEvent ("Analyze AML operand types"); 741151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n"); 742218590Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 743218590Sjkim NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo); 744151937Sjkim UtEndEvent (Event); 745118611Snjl 746118611Snjl /* Semantic error checking part four - other miscellaneous checks */ 747118611Snjl 748151937Sjkim Event = UtBeginEvent ("Miscellaneous analysis"); 749151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n"); 750218590Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 751151937Sjkim AnOtherSemanticAnalysisWalkBegin, 752218590Sjkim NULL, &AnalysisWalkInfo); 753151937Sjkim UtEndEvent (Event); 754118611Snjl 755118611Snjl /* Calculate all AML package lengths */ 756118611Snjl 757151937Sjkim Event = UtBeginEvent ("Finish AML package length generation"); 758118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n"); 759151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 760151937Sjkim LnInitLengthsWalk, NULL); 761151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 762151937Sjkim LnPackageLengthWalk, NULL); 763151937Sjkim UtEndEvent (Event); 764118611Snjl 765118611Snjl /* Code generation - emit the AML */ 766118611Snjl 767151937Sjkim Event = UtBeginEvent ("Generate AML code and write output files"); 768118611Snjl CgGenerateAmlOutput (); 769151937Sjkim UtEndEvent (Event); 770118611Snjl 771151937Sjkim Event = UtBeginEvent ("Write optional output files"); 772118611Snjl CmDoOutputFiles (); 773151937Sjkim UtEndEvent (Event); 774118611Snjl 775151937Sjkim UtEndEvent (FullCompile); 776118611Snjl CmCleanupAndExit (); 777241973Sjkim return (0); 778233250Sjkim 779233250SjkimErrorExit: 780233250Sjkim UtEndEvent (FullCompile); 781233250Sjkim CmCleanupAndExit (); 782233250Sjkim return (-1); 783118611Snjl} 784118611Snjl 785151937Sjkim 786151937Sjkim/******************************************************************************* 787151937Sjkim * 788151937Sjkim * FUNCTION: CmDoOutputFiles 789151937Sjkim * 790151937Sjkim * PARAMETERS: None 791151937Sjkim * 792151937Sjkim * RETURN: None. 793151937Sjkim * 794151937Sjkim * DESCRIPTION: Create all "listing" type files 795151937Sjkim * 796151937Sjkim ******************************************************************************/ 797151937Sjkim 798118611Snjlvoid 799151937SjkimCmDoOutputFiles ( 800151937Sjkim void) 801118611Snjl{ 802118611Snjl 803118611Snjl /* Create listings and hex files */ 804118611Snjl 805118611Snjl LsDoListings (); 806245582Sjkim HxDoHexOutput (); 807118611Snjl 808118611Snjl /* Dump the namespace to the .nsp file if requested */ 809118611Snjl 810245582Sjkim (void) NsDisplayNamespace (); 811118611Snjl} 812118611Snjl 813118611Snjl 814118611Snjl/******************************************************************************* 815118611Snjl * 816237412Sjkim * FUNCTION: CmDumpAllEvents 817151937Sjkim * 818237412Sjkim * PARAMETERS: None 819151937Sjkim * 820151937Sjkim * RETURN: None. 821151937Sjkim * 822237412Sjkim * DESCRIPTION: Dump all compiler events 823151937Sjkim * 824151937Sjkim ******************************************************************************/ 825151937Sjkim 826151937Sjkimstatic void 827237412SjkimCmDumpAllEvents ( 828237412Sjkim void) 829151937Sjkim{ 830237412Sjkim ASL_EVENT_INFO *Event; 831151937Sjkim UINT32 Delta; 832151937Sjkim UINT32 USec; 833151937Sjkim UINT32 MSec; 834237412Sjkim UINT32 i; 835151937Sjkim 836237412Sjkim 837237412Sjkim Event = AslGbl_Events; 838237412Sjkim 839237412Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n"); 840237412Sjkim if (Gbl_CompileTimesFlag) 841151937Sjkim { 842237412Sjkim printf ("\nElapsed time for major events\n\n"); 843151937Sjkim } 844151937Sjkim 845237412Sjkim for (i = 0; i < AslGbl_NextEvent; i++) 846237412Sjkim { 847237412Sjkim if (Event->Valid) 848237412Sjkim { 849237412Sjkim /* Delta will be in 100-nanosecond units */ 850151937Sjkim 851237412Sjkim Delta = (UINT32) (Event->EndTime - Event->StartTime); 852151937Sjkim 853245582Sjkim USec = Delta / ACPI_100NSEC_PER_USEC; 854245582Sjkim MSec = Delta / ACPI_100NSEC_PER_MSEC; 855151937Sjkim 856237412Sjkim /* Round milliseconds up */ 857151937Sjkim 858245582Sjkim if ((USec - (MSec * ACPI_USEC_PER_MSEC)) >= 500) 859237412Sjkim { 860237412Sjkim MSec++; 861237412Sjkim } 862237412Sjkim 863237412Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n", 864237412Sjkim USec, MSec, Event->EventName); 865237412Sjkim 866237412Sjkim if (Gbl_CompileTimesFlag) 867237412Sjkim { 868237412Sjkim printf ("%8u usec %8u msec - %s\n", 869237412Sjkim USec, MSec, Event->EventName); 870237412Sjkim } 871237412Sjkim } 872237412Sjkim 873237412Sjkim Event++; 874151937Sjkim } 875151937Sjkim} 876151937Sjkim 877151937Sjkim 878151937Sjkim/******************************************************************************* 879151937Sjkim * 880118611Snjl * FUNCTION: CmCleanupAndExit 881118611Snjl * 882118611Snjl * PARAMETERS: None 883118611Snjl * 884118611Snjl * RETURN: None. 885118611Snjl * 886118611Snjl * DESCRIPTION: Close all open files and exit the compiler 887118611Snjl * 888118611Snjl ******************************************************************************/ 889118611Snjl 890118611Snjlvoid 891151937SjkimCmCleanupAndExit ( 892151937Sjkim void) 893118611Snjl{ 894118611Snjl UINT32 i; 895240716Sjkim BOOLEAN DeleteAmlFile = FALSE; 896118611Snjl 897118611Snjl 898234623Sjkim AePrintErrorLog (ASL_FILE_STDERR); 899118611Snjl if (Gbl_DebugFlag) 900118611Snjl { 901234623Sjkim /* Print error summary to stdout also */ 902118611Snjl 903234623Sjkim AePrintErrorLog (ASL_FILE_STDOUT); 904118611Snjl } 905118611Snjl 906237412Sjkim /* Emit compile times if enabled */ 907118611Snjl 908237412Sjkim CmDumpAllEvents (); 909237412Sjkim 910118611Snjl if (Gbl_CompileTimesFlag) 911118611Snjl { 912118611Snjl printf ("\nMiscellaneous compile statistics\n\n"); 913118611Snjl printf ("%11u : %s\n", TotalParseNodes, "Parse nodes"); 914118611Snjl printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches"); 915118611Snjl printf ("%11u : %s\n", TotalNamedObjects, "Named objects"); 916118611Snjl printf ("%11u : %s\n", TotalMethods, "Control methods"); 917118611Snjl printf ("%11u : %s\n", TotalAllocations, "Memory Allocations"); 918118611Snjl printf ("%11u : %s\n", TotalAllocated, "Total allocated memory"); 919118611Snjl printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded"); 920118611Snjl printf ("\n"); 921118611Snjl } 922118611Snjl 923118611Snjl if (Gbl_NsLookupCount) 924118611Snjl { 925209746Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 926209746Sjkim "\n\nMiscellaneous compile statistics\n\n"); 927209746Sjkim 928209746Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 929209746Sjkim "%32s : %u\n", "Total Namespace searches", 930151937Sjkim Gbl_NsLookupCount); 931209746Sjkim 932209746Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 933209746Sjkim "%32s : %u usec\n", "Time per search", ((UINT32) 934209746Sjkim (AslGbl_Events[AslGbl_NamespaceEvent].EndTime - 935209746Sjkim AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) / 936209746Sjkim Gbl_NsLookupCount); 937118611Snjl } 938118611Snjl 939118611Snjl if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT) 940118611Snjl { 941209746Sjkim printf ("\nMaximum error count (%u) exceeded\n", 942209746Sjkim ASL_MAX_ERROR_COUNT); 943118611Snjl } 944118611Snjl 945118611Snjl UtDisplaySummary (ASL_FILE_STDOUT); 946199337Sjkim 947240716Sjkim /* 948240716Sjkim * We will delete the AML file if there are errors and the 949240716Sjkim * force AML output option has not been used. 950240716Sjkim */ 951240716Sjkim if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors) && 952240716Sjkim Gbl_Files[ASL_FILE_AML_OUTPUT].Handle) 953240716Sjkim { 954240716Sjkim DeleteAmlFile = TRUE; 955240716Sjkim } 956240716Sjkim 957199337Sjkim /* Close all open files */ 958199337Sjkim 959233250Sjkim Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; /* the .i file is same as source file */ 960233250Sjkim 961233250Sjkim for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++) 962199337Sjkim { 963199337Sjkim FlCloseFile (i); 964199337Sjkim } 965200553Sjkim 966200553Sjkim /* Delete AML file if there are errors */ 967200553Sjkim 968240716Sjkim if (DeleteAmlFile) 969200553Sjkim { 970240716Sjkim FlDeleteFile (ASL_FILE_AML_OUTPUT); 971200553Sjkim } 972200553Sjkim 973233250Sjkim /* Delete the preprocessor output file (.i) unless -li flag is set */ 974233250Sjkim 975234623Sjkim if (!Gbl_PreprocessorOutputFlag && 976240716Sjkim Gbl_PreprocessFlag) 977233250Sjkim { 978240716Sjkim FlDeleteFile (ASL_FILE_PREPROCESSOR); 979233250Sjkim } 980233250Sjkim 981200553Sjkim /* 982200553Sjkim * Delete intermediate ("combined") source file (if -ls flag not set) 983209746Sjkim * This file is created during normal ASL/AML compiles. It is not 984209746Sjkim * created by the data table compiler. 985200553Sjkim * 986209746Sjkim * If the -ls flag is set, then the .SRC file should not be deleted. 987209746Sjkim * In this case, Gbl_SourceOutputFlag is set to TRUE. 988209746Sjkim * 989209746Sjkim * Note: Handles are cleared by FlCloseFile above, so we look at the 990209746Sjkim * filename instead, to determine if the .SRC file was actually 991209746Sjkim * created. 992209746Sjkim * 993200553Sjkim * TBD: SourceOutput should be .TMP, then rename if we want to keep it? 994200553Sjkim */ 995240716Sjkim if (!Gbl_SourceOutputFlag) 996200553Sjkim { 997240716Sjkim FlDeleteFile (ASL_FILE_SOURCE_OUTPUT); 998200553Sjkim } 999118611Snjl} 1000