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 596254745Sjkim /* Check for parse errors */ 597118611Snjl 598254745Sjkim Status = AslCheckForErrorExit (); 599254745Sjkim if (ACPI_FAILURE (Status)) 600254745Sjkim { 601254745Sjkim fprintf (stderr, "Compiler aborting due to parser-detected syntax error(s)\n"); 602254745Sjkim LsDumpParseTree (); 603254745Sjkim goto ErrorExit; 604254745Sjkim } 605118611Snjl 606118611Snjl /* Did the parse tree get successfully constructed? */ 607118611Snjl 608118611Snjl if (!RootNode) 609118611Snjl { 610234623Sjkim /* 611234623Sjkim * If there are no errors, then we have some sort of 612234623Sjkim * internal problem. 613234623Sjkim */ 614254745Sjkim AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, 615254745Sjkim NULL, "- Could not resolve parse tree root node"); 616234623Sjkim 617233250Sjkim goto ErrorExit; 618118611Snjl } 619118611Snjl 620254745Sjkim 621254745Sjkim /* Flush out any remaining source after parse tree is complete */ 622254745Sjkim 623254745Sjkim Event = UtBeginEvent ("Flush source input"); 624254745Sjkim CmFlushSourceCode (); 625254745Sjkim 626167802Sjkim /* Optional parse tree dump, compiler debug output only */ 627167802Sjkim 628167802Sjkim LsDumpParseTree (); 629167802Sjkim 630118611Snjl OpcGetIntegerWidth (RootNode); 631151937Sjkim UtEndEvent (Event); 632118611Snjl 633118611Snjl /* Pre-process parse tree for any operator transforms */ 634118611Snjl 635151937Sjkim Event = UtBeginEvent ("Parse tree transforms"); 636118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n"); 637151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 638151937Sjkim TrAmlTransformWalk, NULL, NULL); 639151937Sjkim UtEndEvent (Event); 640118611Snjl 641118611Snjl /* Generate AML opcodes corresponding to the parse tokens */ 642118611Snjl 643151937Sjkim Event = UtBeginEvent ("Generate AML opcodes"); 644118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n"); 645151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 646151937Sjkim OpcAmlOpcodeWalk, NULL); 647151937Sjkim UtEndEvent (Event); 648118611Snjl 649118611Snjl /* 650118611Snjl * Now that the input is parsed, we can open the AML output file. 651118611Snjl * Note: by default, the name of this file comes from the table descriptor 652118611Snjl * within the input file. 653118611Snjl */ 654151937Sjkim Event = UtBeginEvent ("Open AML output file"); 655118611Snjl Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix); 656233250Sjkim UtEndEvent (Event); 657118611Snjl if (ACPI_FAILURE (Status)) 658118611Snjl { 659118611Snjl AePrintErrorLog (ASL_FILE_STDERR); 660241973Sjkim return (-1); 661118611Snjl } 662118611Snjl 663118611Snjl /* Interpret and generate all compile-time constants */ 664118611Snjl 665151937Sjkim Event = UtBeginEvent ("Constant folding via AML interpreter"); 666151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 667151937Sjkim "\nInterpreting compile-time constant expressions\n\n"); 668151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 669151937Sjkim OpcAmlConstantWalk, NULL, NULL); 670151937Sjkim UtEndEvent (Event); 671118611Snjl 672151937Sjkim /* Update AML opcodes if necessary, after constant folding */ 673151937Sjkim 674151937Sjkim Event = UtBeginEvent ("Updating AML opcodes after constant folding"); 675151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 676151937Sjkim "\nUpdating AML opcodes after constant folding\n\n"); 677151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 678151937Sjkim NULL, OpcAmlOpcodeUpdateWalk, NULL); 679151937Sjkim UtEndEvent (Event); 680151937Sjkim 681118611Snjl /* Calculate all AML package lengths */ 682118611Snjl 683151937Sjkim Event = UtBeginEvent ("Generate AML package lengths"); 684118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n"); 685151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 686151937Sjkim LnPackageLengthWalk, NULL); 687151937Sjkim UtEndEvent (Event); 688118611Snjl 689118611Snjl if (Gbl_ParseOnlyFlag) 690118611Snjl { 691234623Sjkim AePrintErrorLog (ASL_FILE_STDERR); 692234623Sjkim UtDisplaySummary (ASL_FILE_STDERR); 693118611Snjl if (Gbl_DebugFlag) 694118611Snjl { 695234623Sjkim /* Print error summary to the stdout also */ 696118611Snjl 697234623Sjkim AePrintErrorLog (ASL_FILE_STDOUT); 698234623Sjkim UtDisplaySummary (ASL_FILE_STDOUT); 699118611Snjl } 700233250Sjkim UtEndEvent (FullCompile); 701241973Sjkim return (0); 702118611Snjl } 703118611Snjl 704118611Snjl /* 705118611Snjl * Create an internal namespace and use it as a symbol table 706118611Snjl */ 707118611Snjl 708118611Snjl /* Namespace loading */ 709118611Snjl 710151937Sjkim Event = UtBeginEvent ("Create ACPI Namespace"); 711118611Snjl Status = LdLoadNamespace (RootNode); 712151937Sjkim UtEndEvent (Event); 713118611Snjl if (ACPI_FAILURE (Status)) 714118611Snjl { 715233250Sjkim goto ErrorExit; 716118611Snjl } 717118611Snjl 718167802Sjkim /* Namespace cross-reference */ 719118611Snjl 720151937Sjkim AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace"); 721245582Sjkim Status = XfCrossReferenceNamespace (); 722118611Snjl if (ACPI_FAILURE (Status)) 723118611Snjl { 724233250Sjkim goto ErrorExit; 725118611Snjl } 726118611Snjl 727167802Sjkim /* Namespace - Check for non-referenced objects */ 728167802Sjkim 729167802Sjkim LkFindUnreferencedObjects (); 730167802Sjkim UtEndEvent (AslGbl_NamespaceEvent); 731167802Sjkim 732118611Snjl /* 733241973Sjkim * Semantic analysis. This can happen only after the 734118611Snjl * namespace has been loaded and cross-referenced. 735118611Snjl * 736118611Snjl * part one - check control methods 737118611Snjl */ 738151937Sjkim Event = UtBeginEvent ("Analyze control method return types"); 739118611Snjl AnalysisWalkInfo.MethodStack = NULL; 740118611Snjl 741118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n"); 742151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, 743245582Sjkim MtMethodAnalysisWalkBegin, 744245582Sjkim MtMethodAnalysisWalkEnd, &AnalysisWalkInfo); 745151937Sjkim UtEndEvent (Event); 746118611Snjl 747118611Snjl /* Semantic error checking part two - typing of method returns */ 748118611Snjl 749151937Sjkim Event = UtBeginEvent ("Determine object types returned by methods"); 750151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n"); 751218590Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 752218590Sjkim NULL, AnMethodTypingWalkEnd, NULL); 753151937Sjkim UtEndEvent (Event); 754118611Snjl 755118611Snjl /* Semantic error checking part three - operand type checking */ 756118611Snjl 757151937Sjkim Event = UtBeginEvent ("Analyze AML operand types"); 758151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n"); 759218590Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 760218590Sjkim NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo); 761151937Sjkim UtEndEvent (Event); 762118611Snjl 763118611Snjl /* Semantic error checking part four - other miscellaneous checks */ 764118611Snjl 765151937Sjkim Event = UtBeginEvent ("Miscellaneous analysis"); 766151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n"); 767218590Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 768151937Sjkim AnOtherSemanticAnalysisWalkBegin, 769218590Sjkim NULL, &AnalysisWalkInfo); 770151937Sjkim UtEndEvent (Event); 771118611Snjl 772118611Snjl /* Calculate all AML package lengths */ 773118611Snjl 774151937Sjkim Event = UtBeginEvent ("Finish AML package length generation"); 775118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n"); 776151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 777151937Sjkim LnInitLengthsWalk, NULL); 778151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 779151937Sjkim LnPackageLengthWalk, NULL); 780151937Sjkim UtEndEvent (Event); 781118611Snjl 782118611Snjl /* Code generation - emit the AML */ 783118611Snjl 784151937Sjkim Event = UtBeginEvent ("Generate AML code and write output files"); 785118611Snjl CgGenerateAmlOutput (); 786151937Sjkim UtEndEvent (Event); 787118611Snjl 788151937Sjkim Event = UtBeginEvent ("Write optional output files"); 789118611Snjl CmDoOutputFiles (); 790151937Sjkim UtEndEvent (Event); 791118611Snjl 792151937Sjkim UtEndEvent (FullCompile); 793118611Snjl CmCleanupAndExit (); 794241973Sjkim return (0); 795233250Sjkim 796233250SjkimErrorExit: 797233250Sjkim UtEndEvent (FullCompile); 798233250Sjkim CmCleanupAndExit (); 799233250Sjkim return (-1); 800118611Snjl} 801118611Snjl 802151937Sjkim 803151937Sjkim/******************************************************************************* 804151937Sjkim * 805151937Sjkim * FUNCTION: CmDoOutputFiles 806151937Sjkim * 807151937Sjkim * PARAMETERS: None 808151937Sjkim * 809151937Sjkim * RETURN: None. 810151937Sjkim * 811151937Sjkim * DESCRIPTION: Create all "listing" type files 812151937Sjkim * 813151937Sjkim ******************************************************************************/ 814151937Sjkim 815118611Snjlvoid 816151937SjkimCmDoOutputFiles ( 817151937Sjkim void) 818118611Snjl{ 819118611Snjl 820118611Snjl /* Create listings and hex files */ 821118611Snjl 822118611Snjl LsDoListings (); 823245582Sjkim HxDoHexOutput (); 824118611Snjl 825118611Snjl /* Dump the namespace to the .nsp file if requested */ 826118611Snjl 827245582Sjkim (void) NsDisplayNamespace (); 828118611Snjl} 829118611Snjl 830118611Snjl 831118611Snjl/******************************************************************************* 832118611Snjl * 833237412Sjkim * FUNCTION: CmDumpAllEvents 834151937Sjkim * 835237412Sjkim * PARAMETERS: None 836151937Sjkim * 837151937Sjkim * RETURN: None. 838151937Sjkim * 839237412Sjkim * DESCRIPTION: Dump all compiler events 840151937Sjkim * 841151937Sjkim ******************************************************************************/ 842151937Sjkim 843151937Sjkimstatic void 844237412SjkimCmDumpAllEvents ( 845237412Sjkim void) 846151937Sjkim{ 847237412Sjkim ASL_EVENT_INFO *Event; 848151937Sjkim UINT32 Delta; 849151937Sjkim UINT32 USec; 850151937Sjkim UINT32 MSec; 851237412Sjkim UINT32 i; 852151937Sjkim 853237412Sjkim 854237412Sjkim Event = AslGbl_Events; 855237412Sjkim 856237412Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n"); 857237412Sjkim if (Gbl_CompileTimesFlag) 858151937Sjkim { 859237412Sjkim printf ("\nElapsed time for major events\n\n"); 860151937Sjkim } 861151937Sjkim 862237412Sjkim for (i = 0; i < AslGbl_NextEvent; i++) 863237412Sjkim { 864237412Sjkim if (Event->Valid) 865237412Sjkim { 866237412Sjkim /* Delta will be in 100-nanosecond units */ 867151937Sjkim 868237412Sjkim Delta = (UINT32) (Event->EndTime - Event->StartTime); 869151937Sjkim 870245582Sjkim USec = Delta / ACPI_100NSEC_PER_USEC; 871245582Sjkim MSec = Delta / ACPI_100NSEC_PER_MSEC; 872151937Sjkim 873237412Sjkim /* Round milliseconds up */ 874151937Sjkim 875245582Sjkim if ((USec - (MSec * ACPI_USEC_PER_MSEC)) >= 500) 876237412Sjkim { 877237412Sjkim MSec++; 878237412Sjkim } 879237412Sjkim 880237412Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n", 881237412Sjkim USec, MSec, Event->EventName); 882237412Sjkim 883237412Sjkim if (Gbl_CompileTimesFlag) 884237412Sjkim { 885237412Sjkim printf ("%8u usec %8u msec - %s\n", 886237412Sjkim USec, MSec, Event->EventName); 887237412Sjkim } 888237412Sjkim } 889237412Sjkim 890237412Sjkim Event++; 891151937Sjkim } 892151937Sjkim} 893151937Sjkim 894151937Sjkim 895151937Sjkim/******************************************************************************* 896151937Sjkim * 897118611Snjl * FUNCTION: CmCleanupAndExit 898118611Snjl * 899118611Snjl * PARAMETERS: None 900118611Snjl * 901118611Snjl * RETURN: None. 902118611Snjl * 903118611Snjl * DESCRIPTION: Close all open files and exit the compiler 904118611Snjl * 905118611Snjl ******************************************************************************/ 906118611Snjl 907118611Snjlvoid 908151937SjkimCmCleanupAndExit ( 909151937Sjkim void) 910118611Snjl{ 911118611Snjl UINT32 i; 912240716Sjkim BOOLEAN DeleteAmlFile = FALSE; 913118611Snjl 914118611Snjl 915234623Sjkim AePrintErrorLog (ASL_FILE_STDERR); 916118611Snjl if (Gbl_DebugFlag) 917118611Snjl { 918234623Sjkim /* Print error summary to stdout also */ 919118611Snjl 920234623Sjkim AePrintErrorLog (ASL_FILE_STDOUT); 921118611Snjl } 922118611Snjl 923237412Sjkim /* Emit compile times if enabled */ 924118611Snjl 925237412Sjkim CmDumpAllEvents (); 926237412Sjkim 927118611Snjl if (Gbl_CompileTimesFlag) 928118611Snjl { 929118611Snjl printf ("\nMiscellaneous compile statistics\n\n"); 930118611Snjl printf ("%11u : %s\n", TotalParseNodes, "Parse nodes"); 931118611Snjl printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches"); 932118611Snjl printf ("%11u : %s\n", TotalNamedObjects, "Named objects"); 933118611Snjl printf ("%11u : %s\n", TotalMethods, "Control methods"); 934118611Snjl printf ("%11u : %s\n", TotalAllocations, "Memory Allocations"); 935118611Snjl printf ("%11u : %s\n", TotalAllocated, "Total allocated memory"); 936118611Snjl printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded"); 937118611Snjl printf ("\n"); 938118611Snjl } 939118611Snjl 940118611Snjl if (Gbl_NsLookupCount) 941118611Snjl { 942209746Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 943209746Sjkim "\n\nMiscellaneous compile statistics\n\n"); 944209746Sjkim 945209746Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 946209746Sjkim "%32s : %u\n", "Total Namespace searches", 947151937Sjkim Gbl_NsLookupCount); 948209746Sjkim 949209746Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 950209746Sjkim "%32s : %u usec\n", "Time per search", ((UINT32) 951209746Sjkim (AslGbl_Events[AslGbl_NamespaceEvent].EndTime - 952209746Sjkim AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) / 953209746Sjkim Gbl_NsLookupCount); 954118611Snjl } 955118611Snjl 956118611Snjl if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT) 957118611Snjl { 958209746Sjkim printf ("\nMaximum error count (%u) exceeded\n", 959209746Sjkim ASL_MAX_ERROR_COUNT); 960118611Snjl } 961118611Snjl 962118611Snjl UtDisplaySummary (ASL_FILE_STDOUT); 963199337Sjkim 964240716Sjkim /* 965240716Sjkim * We will delete the AML file if there are errors and the 966240716Sjkim * force AML output option has not been used. 967240716Sjkim */ 968240716Sjkim if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors) && 969240716Sjkim Gbl_Files[ASL_FILE_AML_OUTPUT].Handle) 970240716Sjkim { 971240716Sjkim DeleteAmlFile = TRUE; 972240716Sjkim } 973240716Sjkim 974199337Sjkim /* Close all open files */ 975199337Sjkim 976252279Sjkim /* 977252279Sjkim * Take care with the preprocessor file (.i), it might be the same 978252279Sjkim * as the "input" file, depending on where the compiler has terminated 979252279Sjkim * or aborted. Prevent attempt to close the same file twice in 980252279Sjkim * loop below. 981252279Sjkim */ 982252279Sjkim if (Gbl_Files[ASL_FILE_PREPROCESSOR].Handle == 983252279Sjkim Gbl_Files[ASL_FILE_INPUT].Handle) 984252279Sjkim { 985252279Sjkim Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; 986252279Sjkim } 987233250Sjkim 988252279Sjkim /* Close the standard I/O files */ 989252279Sjkim 990233250Sjkim for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++) 991199337Sjkim { 992199337Sjkim FlCloseFile (i); 993199337Sjkim } 994200553Sjkim 995200553Sjkim /* Delete AML file if there are errors */ 996200553Sjkim 997240716Sjkim if (DeleteAmlFile) 998200553Sjkim { 999240716Sjkim FlDeleteFile (ASL_FILE_AML_OUTPUT); 1000200553Sjkim } 1001200553Sjkim 1002233250Sjkim /* Delete the preprocessor output file (.i) unless -li flag is set */ 1003233250Sjkim 1004234623Sjkim if (!Gbl_PreprocessorOutputFlag && 1005240716Sjkim Gbl_PreprocessFlag) 1006233250Sjkim { 1007240716Sjkim FlDeleteFile (ASL_FILE_PREPROCESSOR); 1008233250Sjkim } 1009233250Sjkim 1010200553Sjkim /* 1011200553Sjkim * Delete intermediate ("combined") source file (if -ls flag not set) 1012209746Sjkim * This file is created during normal ASL/AML compiles. It is not 1013209746Sjkim * created by the data table compiler. 1014200553Sjkim * 1015209746Sjkim * If the -ls flag is set, then the .SRC file should not be deleted. 1016209746Sjkim * In this case, Gbl_SourceOutputFlag is set to TRUE. 1017209746Sjkim * 1018209746Sjkim * Note: Handles are cleared by FlCloseFile above, so we look at the 1019209746Sjkim * filename instead, to determine if the .SRC file was actually 1020209746Sjkim * created. 1021209746Sjkim * 1022200553Sjkim * TBD: SourceOutput should be .TMP, then rename if we want to keep it? 1023200553Sjkim */ 1024240716Sjkim if (!Gbl_SourceOutputFlag) 1025200553Sjkim { 1026240716Sjkim FlDeleteFile (ASL_FILE_SOURCE_OUTPUT); 1027200553Sjkim } 1028118611Snjl} 1029