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