From b81dc021b3e3311e46f9e81de4f09855536e8147 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Tue, 20 Mar 2012 18:17:33 +0000 Subject: [PATCH] Import ACPICA 20120320. --- changes.txt | 92 +++ generate/unix/iasl/Makefile | 39 +- source/common/adisasm.c | 48 +- source/common/getopt.c | 31 +- source/compiler/Makefile | 39 +- source/compiler/aslcodegen.c | 2 +- source/compiler/aslcompile.c | 42 +- source/compiler/aslcompiler.h | 13 +- source/compiler/aslcompiler.y | 5 + source/compiler/aslerror.c | 215 +++++-- source/compiler/aslfiles.c | 34 +- source/compiler/aslglobal.h | 9 +- source/compiler/aslmain.c | 115 ++-- source/compiler/aslmessages.h | 31 +- source/compiler/aslstartup.c | 30 +- source/compiler/asltypes.h | 6 +- source/compiler/aslutils.c | 8 + source/compiler/dtcompile.c | 11 + source/compiler/dtcompiler.h | 4 + source/compiler/dtexpress.c | 11 +- source/compiler/dtio.c | 4 - source/compiler/dtparser.y | 4 + source/compiler/preprocess.h | 290 ++++++++++ source/compiler/prexpress.c | 305 ++++++++++ source/compiler/prmacros.c | 574 +++++++++++++++++++ source/compiler/prparser.l | 153 +++++ source/compiler/prparser.y | 284 ++++++++++ source/compiler/prscan.c | 749 +++++++++++++++++++++++++ source/compiler/prutils.c | 550 ++++++++++++++++++ source/compiler/readme.txt | 41 +- source/components/debugger/dbcmds.c | 4 +- source/components/hardware/hwesleep.c | 40 +- source/components/hardware/hwsleep.c | 32 +- source/components/hardware/hwxfsleep.c | 28 +- source/components/namespace/nsdump.c | 16 +- source/components/namespace/nsdumpdv.c | 2 +- source/components/namespace/nspredef.c | 2 +- source/components/namespace/nsrepair.c | 161 ++---- source/components/namespace/nsutils.c | 2 +- source/components/tables/tbfadt.c | 11 +- source/components/tables/tbinstal.c | 4 +- source/components/tables/tbutils.c | 19 +- source/include/achware.h | 18 +- source/include/aclocal.h | 1 + source/include/acnames.h | 12 +- source/include/acnamesp.h | 3 +- source/include/acoutput.h | 1 + source/include/acpixf.h | 8 +- source/include/actypes.h | 10 +- source/tools/acpisrc/astable.c | 9 + 50 files changed, 3779 insertions(+), 343 deletions(-) create mode 100644 source/compiler/preprocess.h create mode 100644 source/compiler/prexpress.c create mode 100644 source/compiler/prmacros.c create mode 100644 source/compiler/prparser.l create mode 100644 source/compiler/prparser.y create mode 100644 source/compiler/prscan.c create mode 100644 source/compiler/prutils.c diff --git a/changes.txt b/changes.txt index f328ad1f847c..69dcdf708ca4 100644 --- a/changes.txt +++ b/changes.txt @@ -1,3 +1,95 @@ +---------------------------------------- +20 March 2012. Summary of changes for version 20120320: + +This release is available at www.acpica.org/downloads. +The ACPI 5.0 specification is available at www.acpi.info. + +1) ACPICA Core Subsystem: + +Enhanced the sleep/wake interfaces to optionally execute the _GTS method +(Going To Sleep) and the _BFS method (Back From Sleep). Windows apparently +does not execute these methods, and therefore these methods are often +untested. It has been seen on some systems where the execution of these +methods causes errors and also prevents the machine from entering S5. It is +therefore suggested that host operating systems do not execute these methods +by default. In the future, perhaps these methods can be optionally executed +based on the age of the system and/or what is the newest version of Windows +that the BIOS asks for via _OSI. Changed interfaces: AcpiEnterSleepState and +AcpileaveSleepStatePrep. See the ACPICA reference and Linux BZ 13041. Lin +Ming. + +Fixed a problem where the length of the local/common FADT was set too early. +The local FADT table length cannot be set to the common length until the +original length has been examined. There is code that checks the table length +and sets various fields appropriately. This can affect older machines with +early FADT versions. For example, this can cause inadvertent writes to the +CST_CNT register. Julian Anastasov. + +Fixed a mapping issue related to a physical table override. Use the deferred +mapping mechanism for tables loaded via the physical override OSL interface. +This allows for early mapping before the virtual memory manager is available. +Thomas Renninger, Bob Moore. + +Enhanced the automatic return-object repair code: Repair a common problem with +predefined methods that are defined to return a variable-length Package of +sub-objects. If there is only one sub-object, some BIOS ASL code mistakenly +simply returns the single object instead of a Package with one sub-object. +This new support will repair this error by wrapping a Package object around +the original object, creating the correct and expected Package with one sub- +object. Names that can be repaired in this manner include: _ALR, _CSD, _HPX, +_MLS, _PLD, _PRT, _PSS, _TRT, _TSS, _BCL, _DOD, _FIX, and _Sx. ACPICA BZ 939. + +Changed the exception code returned for invalid ACPI paths passed as +parameters to external interfaces such as AcpiEvaluateObject. Was +AE_BAD_PARAMETER, now is the more sensible AE_BAD_PATHNAME. + +Example Code and Data Size: These are the sizes for the OS-independent +acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The debug +version of the code includes the debug output trace mechanism and has a much +larger code and data size. + + Previous Release: + Non-Debug Version: 93.0K Code, 25.0K Data, 118.0K Total + Debug Version: 172.5K Code, 73.2K Data, 245.7K Total + Current Release: + Non-Debug Version: 92.9K Code, 25.0K Data, 117.9K Total + Debug Version: 172.5K Code, 73.2K Data, 245.7K Total + + +2) iASL Compiler/Disassembler and Tools: + +iASL: Added the infrastructure and initial implementation of a integrated C- +like preprocessor. This will simplify BIOS development process by eliminating +the need for a separate preprocessing step during builds. On Windows, it also +eliminates the need to install a separate C compiler. ACPICA BZ 761. Some +features including full #define() macro support are still under development. +These preprocessor directives are supported: + #define + #elif + #else + #endif + #error + #if + #ifdef + #ifndef + #include + #pragma message + #undef + #warning +In addition, these new command line options are supported: + -D Define symbol for preprocessor use + -li Create preprocessed output file (*.i) + -P Preprocess only and create preprocessor output file (*.i) + +Table Compiler: Fixed a problem where the equals operator within an expression +did not work properly. + +Updated iASL to use the current versions of Bison/Flex. Updated the Windows +project file to invoke these tools from the standard location. ACPICA BZ 904. +Versions supported: + Flex for Windows: V2.5.4 + Bison for Windows: V2.4.1 + ---------------------------------------- 15 February 2012. Summary of changes for version 20120215: diff --git a/generate/unix/iasl/Makefile b/generate/unix/iasl/Makefile index e66606f59616..c61a5d8abdb3 100644 --- a/generate/unix/iasl/Makefile +++ b/generate/unix/iasl/Makefile @@ -32,13 +32,16 @@ vpath %.c \ HEADERS = \ $(wildcard $(ASL_COMPILER)/*.h) \ $(OBJDIR)/aslcompiler.y.h \ - $(OBJDIR)/dtparser.y.h + $(OBJDIR)/dtparser.y.h \ + $(OBJDIR)/prparser.y.h OBJECTS = \ $(OBJDIR)/aslcompilerlex.o \ $(OBJDIR)/aslcompilerparse.o \ $(OBJDIR)/dtparserlex.o \ $(OBJDIR)/dtparserparse.o \ + $(OBJDIR)/prparserlex.o \ + $(OBJDIR)/prparserparse.o \ $(OBJDIR)/adfile.o \ $(OBJDIR)/adisasm.o \ $(OBJDIR)/adwalk.o \ @@ -142,6 +145,10 @@ OBJECTS = \ $(OBJDIR)/nswalk.o \ $(OBJDIR)/nsxfobj.o \ $(OBJDIR)/osunixxf.o \ + $(OBJDIR)/prexpress.o \ + $(OBJDIR)/prmacros.o \ + $(OBJDIR)/prscan.o \ + $(OBJDIR)/prutils.o \ $(OBJDIR)/psargs.o \ $(OBJDIR)/psloop.o \ $(OBJDIR)/psopcode.o \ @@ -177,7 +184,9 @@ INTERMEDIATES = \ $(OBJDIR)/aslcompilerlex.c \ $(OBJDIR)/aslcompilerparse.c \ $(OBJDIR)/dtparserlex.c \ - $(OBJDIR)/dtparserparse.c + $(OBJDIR)/dtparserparse.c \ + $(OBJDIR)/prparserlex.c \ + $(OBJDIR)/prparserparse.c MISC = \ $(OBJDIR)/aslcompilerparse.h \ @@ -185,7 +194,10 @@ MISC = \ $(OBJDIR)/aslcompilerparse.output \ $(OBJDIR)/dtparserparse.h \ $(OBJDIR)/dtparser.y.h \ - $(OBJDIR)/dtparserparse.output + $(OBJDIR)/dtparserparse.output \ + $(OBJDIR)/prparserparse.h \ + $(OBJDIR)/prparser.y.h \ + $(OBJDIR)/prparserparse.output # # Flags specific to iASL compiler @@ -217,15 +229,26 @@ $(OBJDIR)/dtparserlex.c : $(ASL_COMPILER)/dtparser.l $(OBJDIR)/dtparserparse.c $(OBJDIR)/dtparserparse.h : $(ASL_COMPILER)/dtparser.y ${YACC} ${YFLAGS} -pDtParser -o$@ $? +$(OBJDIR)/prparserlex.c : $(ASL_COMPILER)/prparser.l + ${LEX} ${LFLAGS} -PPrParser -o$@ $? + +$(OBJDIR)/prparserparse.c $(OBJDIR)/prparserparse.h : $(ASL_COMPILER)/prparser.y + ${YACC} ${YFLAGS} -pPrParser -o$@ $? + + # Rename headers produced by bison/yacc +$(OBJDIR)/aslcompiler.y.h : $(OBJDIR)/aslcompilerparse.h + @echo Copy intermediate file: + @cp -f -v $(OBJDIR)/aslcompilerparse.h $(OBJDIR)/aslcompiler.y.h + $(OBJDIR)/dtparser.y.h: $(OBJDIR)/dtparserparse.h @echo Copy intermediate file: @cp -f -v $(OBJDIR)/dtparserparse.h $(OBJDIR)/dtparser.y.h -$(OBJDIR)/aslcompiler.y.h : $(OBJDIR)/aslcompilerparse.h +$(OBJDIR)/prparser.y.h: $(OBJDIR)/prparserparse.h @echo Copy intermediate file: - @cp -f -v $(OBJDIR)/aslcompilerparse.h $(OBJDIR)/aslcompiler.y.h + @cp -f -v $(OBJDIR)/prparserparse.h $(OBJDIR)/prparser.y.h # @@ -246,6 +269,12 @@ $(OBJDIR)/dtparserlex.o : $(OBJDIR)/dtparserlex.c $(OBJDIR)/dtparserparse.o : $(OBJDIR)/dtparserparse.c $(CC) -c $(CFLAGS) -Wall -Werror -o$@ $? +$(OBJDIR)/prparserlex.o : $(OBJDIR)/prparserlex.c + $(CC) -c $(CFLAGS) -Wall -Werror -o$@ $? + +$(OBJDIR)/prparserparse.o : $(OBJDIR)/prparserparse.c + $(CC) -c $(CFLAGS) -Wall -Werror -o$@ $? + $(OBJDIR)/%.o : %.c $(HEADERS) $(ACPICA_HEADERS) $(COMPILE) diff --git a/source/common/adisasm.c b/source/common/adisasm.c index 2509ca67e948..cc583767e643 100644 --- a/source/common/adisasm.c +++ b/source/common/adisasm.c @@ -75,6 +75,10 @@ LsSetupNsList ( /* Local prototypes */ +static UINT32 +AdGetFileSize ( + FILE *File); + static void AdCreateTableHeader ( char *Filename, @@ -158,6 +162,38 @@ static ACPI_TABLE_DESC LocalTables[1]; static ACPI_PARSE_OBJECT *AcpiGbl_ParseOpRoot; +/******************************************************************************* + * + * FUNCTION: AdGetFileSize + * + * PARAMETERS: File - Open file handle + * + * RETURN: File Size + * + * DESCRIPTION: Get current file size. Uses seek-to-EOF. File must be open. + * + ******************************************************************************/ + +static UINT32 +AdGetFileSize ( + FILE *File) +{ + UINT32 FileSize; + long Offset; + + + Offset = ftell (File); + + fseek (File, 0, SEEK_END); + FileSize = (UINT32) ftell (File); + + /* Restore file pointer */ + + fseek (File, Offset, SEEK_SET); + return (FileSize); +} + + /******************************************************************************* * * FUNCTION: AdInitialize @@ -380,8 +416,10 @@ AdAmlDisassemble ( "FieldName : FieldValue\n */\n\n"); AcpiDmDumpDataTable (Table); - fprintf (stderr, "Acpi Data Table [%4.4s] decoded, written to \"%s\"\n", - Table->Signature, DisasmFilename); + fprintf (stderr, "Acpi Data Table [%4.4s] decoded\n", + Table->Signature); + fprintf (stderr, "Formatted output: %s - %u bytes\n", + DisasmFilename, AdGetFileSize (File)); } else { @@ -490,9 +528,9 @@ AdAmlDisassemble ( if (AcpiGbl_DbOpt_disasm) { AdDisplayTables (Filename, Table); - fprintf (stderr, - "Disassembly completed, written to \"%s\"\n", - DisasmFilename); + fprintf (stderr, "Disassembly completed\n"); + fprintf (stderr, "ASL Output: %s - %u bytes\n", + DisasmFilename, AdGetFileSize (File)); } } diff --git a/source/common/getopt.c b/source/common/getopt.c index b253e8a01d6a..80d80811746b 100644 --- a/source/common/getopt.c +++ b/source/common/getopt.c @@ -49,7 +49,8 @@ #include "accommon.h" #include "acapps.h" -#define ERR(szz,czz) if(AcpiGbl_Opterr){fprintf(stderr,"%s%s%c\n",argv[0],szz,czz);} +#define ACPI_OPTION_ERROR(msg, badchar) \ + if (AcpiGbl_Opterr) {fprintf (stderr, "%s%c\n", msg, badchar);} int AcpiGbl_Opterr = 1; @@ -87,12 +88,12 @@ AcpiGetopt( argv[AcpiGbl_Optind][0] != '-' || argv[AcpiGbl_Optind][1] == '\0') { - return(EOF); + return (EOF); } else if (strcmp (argv[AcpiGbl_Optind], "--") == 0) { AcpiGbl_Optind++; - return(EOF); + return (EOF); } } @@ -105,7 +106,7 @@ AcpiGetopt( if (CurrentChar == ':' || (OptsPtr = strchr (opts, CurrentChar)) == NULL) { - ERR (": illegal option -- ", CurrentChar); + ACPI_OPTION_ERROR ("Illegal option: -", CurrentChar); if (argv[AcpiGbl_Optind][++CurrentCharPtr] == '\0') { @@ -126,7 +127,7 @@ AcpiGetopt( } else if (++AcpiGbl_Optind >= argc) { - ERR (": option requires an argument -- ", CurrentChar); + ACPI_OPTION_ERROR ("Option requires an argument: -", CurrentChar); CurrentCharPtr = 1; return ('?'); @@ -156,6 +157,26 @@ AcpiGetopt( CurrentCharPtr = 1; } + /* Option has a required single-char argument? */ + + else if (*OptsPtr == '|') + { + if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0') + { + AcpiGbl_Optarg = &argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)]; + } + else + { + ACPI_OPTION_ERROR ("Option requires a single-character suboption: -", CurrentChar); + + CurrentCharPtr = 1; + return ('?'); + } + + AcpiGbl_Optind++; + CurrentCharPtr = 1; + } + /* Option with no arguments */ else diff --git a/source/compiler/Makefile b/source/compiler/Makefile index a63538bd0b5f..b4c6b45108b8 100644 --- a/source/compiler/Makefile +++ b/source/compiler/Makefile @@ -64,13 +64,16 @@ vpath %.c \ HEADERS = \ $(wildcard $(ASL_COMPILER)/*.h) \ aslcompiler.y.h \ - dtparser.y.h + dtparser.y.h \ + prparser.y.h OBJECTS = \ aslcompilerlex.o \ aslcompilerparse.o \ dtparserlex.o \ dtparserparse.o \ + prparserlex.o \ + prparserparse.o \ adfile.o \ adisasm.o \ adwalk.o \ @@ -174,6 +177,10 @@ OBJECTS = \ nswalk.o \ nsxfobj.o \ osunixxf.o \ + prexpress.o \ + prmacros.o \ + prscan.o \ + prutils.o \ psargs.o \ psloop.o \ psopcode.o \ @@ -209,7 +216,9 @@ INTERMEDIATES = \ aslcompilerlex.c \ aslcompilerparse.c \ dtparserlex.c \ - dtparserparse.c + dtparserparse.c \ + prparserlex.c \ + prparserparse.c MISC = \ aslcompilerparse.h \ @@ -217,7 +226,10 @@ MISC = \ aslcompilerparse.output \ dtparserparse.h \ dtparser.y.h \ - dtparserparse.output + dtparserparse.output \ + prparserparse.h \ + prparser.y.h \ + prparserparse.output CFLAGS+= \ -D$(HOST) \ @@ -289,15 +301,26 @@ dtparserlex.c : $(ASL_COMPILER)/dtparser.l dtparserparse.c dtparserparse.h : $(ASL_COMPILER)/dtparser.y ${YACC} ${YFLAGS} -pDtParser -o$@ $? +prparserlex.c : $(ASL_COMPILER)/prparser.l + ${LEX} ${LFLAGS} -PPrParser -o$@ $? + +prparserparse.c prparserparse.h : $(ASL_COMPILER)/prparser.y + ${YACC} ${YFLAGS} -pPrParser -o$@ $? + + # Rename headers produced by bison/yacc +aslcompiler.y.h : aslcompilerparse.h + @echo Copy intermediate file: + @cp -f -v aslcompilerparse.h aslcompiler.y.h + dtparser.y.h: dtparserparse.h @echo Copy intermediate file: @cp -f -v dtparserparse.h dtparser.y.h -aslcompiler.y.h : aslcompilerparse.h +prparser.y.h: prparserparse.h @echo Copy intermediate file: - @cp -f -v aslcompilerparse.h aslcompiler.y.h + @cp -f -v prparserparse.h prparser.y.h # @@ -318,6 +341,12 @@ dtparserlex.o : dtparserlex.c dtparserparse.o : dtparserparse.c $(CC) -c $(CFLAGS) -Wall -Werror -Wstrict-aliasing=0 -o$@ $? +prparserlex.o : prparserlex.c + $(CC) -c $(CFLAGS) -Wall -Werror -Wstrict-aliasing=0 -o$@ $? + +prparserparse.o : prparserparse.c + $(CC) -c $(CFLAGS) -Wall -Werror -Wstrict-aliasing=0 -o$@ $? + %.o : %.c $(HEADERS) $(ACPICA_HEADERS) $(COMPILE) diff --git a/source/compiler/aslcodegen.c b/source/compiler/aslcodegen.c index 825dd194fc07..98869f569a90 100644 --- a/source/compiler/aslcodegen.c +++ b/source/compiler/aslcodegen.c @@ -264,7 +264,7 @@ CgWriteAmlOpcode ( /* These opcodes should not get here */ printf ("Found a node with an unassigned AML opcode\n"); - fprintf (stderr, "Found a node with an unassigned AML opcode\n"); + FlPrintFile (ASL_FILE_STDERR, "Found a node with an unassigned AML opcode\n"); return; case AML_INT_RESERVEDFIELD_OP: diff --git a/source/compiler/aslcompile.c b/source/compiler/aslcompile.c index 8f16bf3547f2..6c368a098980 100644 --- a/source/compiler/aslcompile.c +++ b/source/compiler/aslcompile.c @@ -457,6 +457,17 @@ CmDoCompile ( Event = UtBeginEvent ("Open input and output files"); UtEndEvent (Event); + /* Preprocessor */ + + Event = UtBeginEvent ("Preprocess input file"); + PrDoPreprocess (); + UtEndEvent (Event); + if (Gbl_PreprocessOnly) + { + CmCleanupAndExit (); + return 0; + } + /* Build the parse tree */ Event = UtBeginEvent ("Parse source code and build parse tree"); @@ -474,8 +485,7 @@ CmDoCompile ( { AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, NULL, "- Could not resolve parse tree root node"); - CmCleanupAndExit (); - return -1; + goto ErrorExit; } /* Optional parse tree dump, compiler debug output only */ @@ -508,12 +518,12 @@ CmDoCompile ( */ Event = UtBeginEvent ("Open AML output file"); Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix); + UtEndEvent (Event); if (ACPI_FAILURE (Status)) { AePrintErrorLog (ASL_FILE_STDERR); return -1; } - UtEndEvent (Event); /* Interpret and generate all compile-time constants */ @@ -552,6 +562,7 @@ CmDoCompile ( AePrintErrorLog (ASL_FILE_STDERR); UtDisplaySummary (ASL_FILE_STDERR); } + UtEndEvent (FullCompile); return 0; } @@ -566,7 +577,7 @@ CmDoCompile ( UtEndEvent (Event); if (ACPI_FAILURE (Status)) { - return -1; + goto ErrorExit; } /* Namespace cross-reference */ @@ -575,7 +586,7 @@ CmDoCompile ( Status = LkCrossReferenceNamespace (); if (ACPI_FAILURE (Status)) { - return -1; + goto ErrorExit; } /* Namespace - Check for non-referenced objects */ @@ -646,6 +657,11 @@ CmDoCompile ( UtEndEvent (FullCompile); CmCleanupAndExit (); return 0; + +ErrorExit: + UtEndEvent (FullCompile); + CmCleanupAndExit (); + return (-1); } @@ -799,7 +815,9 @@ CmCleanupAndExit ( /* Close all open files */ - for (i = 2; i < ASL_MAX_FILE_TYPE; i++) + Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; /* the .i file is same as source file */ + + for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++) { FlCloseFile (i); } @@ -817,6 +835,18 @@ CmCleanupAndExit ( } } + /* Delete the preprocessor output file (.i) unless -li flag is set */ + + if (!Gbl_PreprocessorOutputFlag && Gbl_Files[ASL_FILE_PREPROCESSOR].Filename) + { + if (remove (Gbl_Files[ASL_FILE_PREPROCESSOR].Filename)) + { + printf ("%s: ", + Gbl_Files[ASL_FILE_PREPROCESSOR].Filename); + perror ("Could not delete preprocessor .i file"); + } + } + /* * Delete intermediate ("combined") source file (if -ls flag not set) * This file is created during normal ASL/AML compiles. It is not diff --git a/source/compiler/aslcompiler.h b/source/compiler/aslcompiler.h index aa69c702bba4..6cc435141986 100644 --- a/source/compiler/aslcompiler.h +++ b/source/compiler/aslcompiler.h @@ -75,6 +75,7 @@ #include "asltypes.h" #include "aslmessages.h" #include "aslglobal.h" +#include "preprocess.h" /******************************************************************************* @@ -84,7 +85,7 @@ ******************************************************************************/ /* - * parser - generated from flex/bison, lex/yacc, etc. + * Main ASL parser - generated from flex/bison, lex/yacc, etc. */ int AslCompilerparse( @@ -302,6 +303,16 @@ AslCommonError ( char *Filename, char *ExtraMessage); +void +AslCommonError2 ( + UINT8 Level, + UINT8 MessageId, + UINT32 LineNumber, + UINT32 Column, + char *SourceLine, + char *Filename, + char *ExtraMessage); + void AePrintException ( UINT32 FileId, diff --git a/source/compiler/aslcompiler.y b/source/compiler/aslcompiler.y index c2cb0a5dd1ac..a9e58f5cd0d6 100644 --- a/source/compiler/aslcompiler.y +++ b/source/compiler/aslcompiler.y @@ -78,6 +78,11 @@ void * AslLocalAllocate (unsigned int Size); #define YYDEBUG 1 /* Enable debug output */ #define YYERROR_VERBOSE 1 /* Verbose error messages */ +/* Define YYMALLOC/YYFREE to prevent redefinition errors */ + +#define YYMALLOC malloc +#define YYFREE free + /* * The windows version of bison defines this incorrectly as "32768" (Not negative). * We use a custom (edited binary) version of bison that defines YYFLAG as YYFBAD diff --git a/source/compiler/aslerror.c b/source/compiler/aslerror.c index e02e234a151b..4bf47e423446 100644 --- a/source/compiler/aslerror.c +++ b/source/compiler/aslerror.c @@ -55,6 +55,18 @@ AeAddToErrorLog ( ASL_ERROR_MSG *Enode); +/******************************************************************************* + * + * FUNCTION: AeClearErrorLog + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Empty the error list + * + ******************************************************************************/ + void AeClearErrorLog ( void) @@ -168,7 +180,7 @@ AePrintException ( UINT32 SourceColumn; UINT32 ErrorColumn; FILE *OutputFile; - FILE *SourceFile; + FILE *SourceFile = NULL; long FileSize; BOOLEAN PrematureEOF = FALSE; @@ -211,24 +223,28 @@ AePrintException ( OutputFile = Gbl_Files[FileId].Handle; - /* Use the merged header/source file if present, otherwise use input file */ - SourceFile = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle; - if (!SourceFile) + if (!Enode->SourceLine) { - SourceFile = Gbl_Files[ASL_FILE_INPUT].Handle; - } + /* Use the merged header/source file if present, otherwise use input file */ - if (SourceFile) - { - /* Determine if the error occurred at source file EOF */ - - fseek (SourceFile, 0, SEEK_END); - FileSize = ftell (SourceFile); - - if ((long) Enode->LogicalByteOffset >= FileSize) + SourceFile = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle; + if (!SourceFile) { - PrematureEOF = TRUE; + SourceFile = Gbl_Files[ASL_FILE_INPUT].Handle; + } + + if (SourceFile) + { + /* Determine if the error occurred at source file EOF */ + + fseek (SourceFile, 0, SEEK_END); + FileSize = ftell (SourceFile); + + if ((long) Enode->LogicalByteOffset >= FileSize) + { + PrematureEOF = TRUE; + } } } @@ -247,46 +263,59 @@ AePrintException ( if (Enode->LineNumber) { - fprintf (OutputFile, " %6u: ", Enode->LineNumber); - - /* - * If not at EOF, get the corresponding source code line and - * display it. Don't attempt this if we have a premature EOF - * condition. - */ - if (!PrematureEOF) + if (Enode->SourceLine) { - /* - * Seek to the offset in the combined source file, read - * the source line, and write it to the output. - */ - Actual = fseek (SourceFile, (long) Enode->LogicalByteOffset, - (int) SEEK_SET); - if (Actual) - { - fprintf (OutputFile, - "[*** iASL: Seek error on source code temp file %s ***]", - Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename); - } + fprintf (OutputFile, " %6u: %s", + Enode->LineNumber, Enode->SourceLine); + } + else + { + if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_ASL) + fprintf (OutputFile, " %6u: ", + PrGetLineNumber (Enode->LineNumber)); else + fprintf (OutputFile, " %6u: ", + Enode->LineNumber); + + /* + * If not at EOF, get the corresponding source code line and + * display it. Don't attempt this if we have a premature EOF + * condition. + */ + if (!PrematureEOF) { - RActual = fread (&SourceByte, 1, 1, SourceFile); - if (!RActual) + /* + * Seek to the offset in the combined source file, read + * the source line, and write it to the output. + */ + Actual = fseek (SourceFile, (long) Enode->LogicalByteOffset, + (int) SEEK_SET); + if (Actual) { fprintf (OutputFile, - "[*** iASL: Read error on source code temp file %s ***]", + "[*** iASL: Seek error on source code temp file %s ***]", Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename); } - - else while (RActual && SourceByte && (SourceByte != '\n')) + else { - fwrite (&SourceByte, 1, 1, OutputFile); RActual = fread (&SourceByte, 1, 1, SourceFile); + if (!RActual) + { + fprintf (OutputFile, + "[*** iASL: Read error on source code temp file %s ***]", + Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename); + } + + else while (RActual && SourceByte && (SourceByte != '\n')) + { + fwrite (&SourceByte, 1, 1, OutputFile); + RActual = fread (&SourceByte, 1, 1, SourceFile); + } } } - } - fprintf (OutputFile, "\n"); + fprintf (OutputFile, "\n"); + } } } else @@ -295,7 +324,16 @@ AePrintException ( if (Enode->LineNumber) { - fprintf (OutputFile, "(%u) : ", Enode->LineNumber); + if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_ASL) + { + fprintf (OutputFile, "(%u) i:%6u : ", + PrGetLineNumber (Enode->LineNumber), Enode->LineNumber); + } + else + { + fprintf (OutputFile, "(%u) i:%6u : ", + Enode->LineNumber, Enode->LineNumber); + } } } } @@ -419,6 +457,91 @@ AePrintErrorLog ( } +/******************************************************************************* + * + * FUNCTION: AslCommonError2 + * + * PARAMETERS: Level - Seriousness (Warning/error, etc.) + * MessageId - Index into global message buffer + * LineNumber - Actual file line number + * Column - Column in current line + * SourceLine - Actual source code line + * Filename - source filename + * ExtraMessage - additional error message + * + * RETURN: None + * + * DESCRIPTION: Create a new error node and add it to the error log + * + ******************************************************************************/ + +void +AslCommonError2 ( + UINT8 Level, + UINT8 MessageId, + UINT32 LineNumber, + UINT32 Column, + char *SourceLine, + char *Filename, + char *ExtraMessage) +{ + char *MessageBuffer = NULL; + char *LineBuffer; + ASL_ERROR_MSG *Enode; + + + Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG)); + + if (ExtraMessage) + { + /* Allocate a buffer for the message and a new error node */ + + MessageBuffer = UtLocalCalloc (strlen (ExtraMessage) + 1); + + /* Keep a copy of the extra message */ + + ACPI_STRCPY (MessageBuffer, ExtraMessage); + } + + LineBuffer = UtLocalCalloc (strlen (SourceLine) + 1); + ACPI_STRCPY (LineBuffer, SourceLine); + + /* Initialize the error node */ + + if (Filename) + { + Enode->Filename = Filename; + Enode->FilenameLength = strlen (Filename); + if (Enode->FilenameLength < 6) + { + Enode->FilenameLength = 6; + } + } + + Enode->MessageId = MessageId; + Enode->Level = Level; + Enode->LineNumber = LineNumber; + Enode->LogicalLineNumber = LineNumber; + Enode->LogicalByteOffset = 0; + Enode->Column = Column; + Enode->Message = MessageBuffer; + Enode->SourceLine = LineBuffer; + + /* Add the new node to the error node list */ + + AeAddToErrorLog (Enode); + + if (Gbl_DebugFlag) + { + /* stderr is a file, send error to it immediately */ + + AePrintException (ASL_FILE_STDERR, Enode, NULL); + } + + Gbl_ExceptionCount[Level]++; +} + + /******************************************************************************* * * FUNCTION: AslCommonError @@ -487,6 +610,7 @@ AslCommonError ( Enode->LogicalByteOffset = LogicalByteOffset; Enode->Column = Column; Enode->Message = MessageBuffer; + Enode->SourceLine = NULL; /* Add the new node to the error node list */ @@ -553,7 +677,6 @@ AslError ( break; } - if (Op) { AslCommonError (Level, MessageId, Op->Asl.LineNumber, @@ -643,5 +766,3 @@ AslCompilererror ( return 0; } - - diff --git a/source/compiler/aslfiles.c b/source/compiler/aslfiles.c index ada383d91c92..1c2f73f95977 100644 --- a/source/compiler/aslfiles.c +++ b/source/compiler/aslfiles.c @@ -50,7 +50,7 @@ /* Local prototypes */ -static FILE * +FILE * FlOpenIncludeWithPrefix ( char *PrefixDir, char *Filename); @@ -363,14 +363,13 @@ FlCloseFile ( } Error = fclose (Gbl_Files[FileId].Handle); - Gbl_Files[FileId].Handle = NULL; - if (Error) { FlFileError (FileId, ASL_MSG_CLOSE); AslAbort (); } + Gbl_Files[FileId].Handle = NULL; return; } @@ -478,7 +477,7 @@ FlAddIncludeDirectory ( * ******************************************************************************/ -static FILE * +FILE * FlOpenIncludeWithPrefix ( char *PrefixDir, char *Filename) @@ -740,6 +739,13 @@ FlOpenMiscOutputFiles ( Gbl_Files[ASL_FILE_DEBUG_OUTPUT].Handle = freopen (Filename, "w+t", stderr); + if (!Gbl_Files[ASL_FILE_DEBUG_OUTPUT].Handle) + { + AslCommonError (ASL_ERROR, ASL_MSG_DEBUG_FILENAME, + 0, 0, 0, 0, NULL, NULL); + return (AE_ERROR); + } + AslCompilerSignon (ASL_FILE_DEBUG_OUTPUT); AslCompilerFileHeader (ASL_FILE_DEBUG_OUTPUT); } @@ -764,12 +770,26 @@ FlOpenMiscOutputFiles ( AslCompilerFileHeader (ASL_FILE_LISTING_OUTPUT); } + /* Create the preprocessor output file */ + + Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_PREPROCESSOR); + if (!Filename) + { + AslCommonError (ASL_ERROR, ASL_MSG_PREPROCESSOR_FILENAME, + 0, 0, 0, 0, NULL, NULL); + return (AE_ERROR); + } + + FlOpenFile (ASL_FILE_PREPROCESSOR, Filename, "w+b"); + + /* All done for data table compiler */ + if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_DATA) { return (AE_OK); } - /* Create/Open a combined source output file */ + /* Create/Open a combined source output file */ Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_SOURCE); if (!Filename) @@ -786,6 +806,10 @@ FlOpenMiscOutputFiles ( */ FlOpenFile (ASL_FILE_SOURCE_OUTPUT, Filename, "w+b"); +/* +// TBD: TEMP +// AslCompilerin = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle; +*/ /* Create/Open a assembly code source output file if asked */ if (Gbl_AsmOutputFlag) diff --git a/source/compiler/aslglobal.h b/source/compiler/aslglobal.h index 08b4b6988f80..26da48bf673c 100644 --- a/source/compiler/aslglobal.h +++ b/source/compiler/aslglobal.h @@ -70,10 +70,11 @@ extern int yydebug; extern FILE *AslCompilerin; extern int AslCompilerdebug; extern int DtParserdebug; +extern int PrParserdebug; extern const ASL_MAPPING_ENTRY AslKeywordMapping[]; extern char *AslCompilertext; -#define ASL_LINE_BUFFER_SIZE 1024 +#define ASL_LINE_BUFFER_SIZE 4096 #define ASL_MSG_BUFFER_SIZE 4096 #define HEX_TABLE_LINE_SIZE 8 #define HEX_LISTING_LINE_SIZE 8 @@ -88,22 +89,22 @@ ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_LogicalLineNumber, 1); ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_CurrentLineOffset, 0); ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_LineBufPtr, Gbl_CurrentLineBuffer); - /* Exception reporting */ ASL_EXTERN ASL_ERROR_MSG ASL_INIT_GLOBAL (*Gbl_ErrorLog,NULL); ASL_EXTERN ASL_ERROR_MSG ASL_INIT_GLOBAL (*Gbl_NextError,NULL); - /* Option flags */ ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_DoCompile, TRUE); ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_DoSignon, TRUE); +ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_PreprocessOnly, FALSE); ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_DisassembleAll, FALSE); ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_Acpi2, FALSE); ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_UseDefaultAmlFilename, TRUE); ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_NsOutputFlag, FALSE); +ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_PreprocessorOutputFlag, FALSE); ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_DebugFlag, FALSE); ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_AsmOutputFlag, FALSE); ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_C_OutputFlag, FALSE); @@ -203,7 +204,7 @@ extern char AslHexLookup[]; /* Event timing */ -#define ASL_NUM_EVENTS 19 +#define ASL_NUM_EVENTS 20 ASL_EXTERN ASL_EVENT_INFO AslGbl_Events[ASL_NUM_EVENTS]; ASL_EXTERN UINT8 AslGbl_NextEvent; ASL_EXTERN UINT8 AslGbl_NamespaceEvent; diff --git a/source/compiler/aslmain.c b/source/compiler/aslmain.c index 69a0e8b8236f..14a02b4778c4 100644 --- a/source/compiler/aslmain.c +++ b/source/compiler/aslmain.c @@ -96,7 +96,7 @@ AslDoResponseFile ( #define ASL_TOKEN_SEPARATORS " \t\n" -#define ASL_SUPPORTED_OPTIONS "@:2b:c:d^e:fgh^i^I:l^mno:p:r:s:t:T:G^v:w:x:z" +#define ASL_SUPPORTED_OPTIONS "@:2b|c|d^D:e:fgh^i|I:l^mno|p:Pr:s|t|T:G^v|w|x:z" /******************************************************************************* @@ -120,6 +120,11 @@ Options ( ACPI_OPTION ("-@ ", "Specify command file"); ACPI_OPTION ("-I ", "Specify additional include directory"); + printf ("\nPreprocessor:\n"); + ACPI_OPTION ("-D ", "Define symbol for preprocessor use"); + ACPI_OPTION ("-li", "Create preprocessed output file (*.i)"); + ACPI_OPTION ("-P", "Preprocess only and create preprocessor output file (*.i)"); + printf ("\nGeneral Output:\n"); ACPI_OPTION ("-p ", "Specify path/filename prefix for all output files"); ACPI_OPTION ("-va", "Disable all errors and warnings (summary only)"); @@ -127,12 +132,12 @@ Options ( ACPI_OPTION ("-vo", "Enable optimization comments"); ACPI_OPTION ("-vr", "Disable remarks"); ACPI_OPTION ("-vs", "Disable signon"); - ACPI_OPTION ("-w <1|2|3>", "Set warning reporting level"); + ACPI_OPTION ("-w1 -w2 -w3", "Set warning reporting level"); printf ("\nAML Output Files:\n"); - ACPI_OPTION ("-s ", "Create AML in assembler or C source file (*.asm or *.c)"); - ACPI_OPTION ("-i ", "Create assembler or C include file (*.inc or *.h)"); - ACPI_OPTION ("-t ", "Create AML in assembler, C, or ASL hex table (*.hex)"); + ACPI_OPTION ("-sa -sc", "Create AML in assembler or C source file (*.asm or *.c)"); + ACPI_OPTION ("-ia -ic", "Create assembler or C include file (*.inc or *.h)"); + ACPI_OPTION ("-ta -tc -ts", "Create AML in assembler, C, or ASL hex table (*.hex)"); printf ("\nAML Code Generation:\n"); ACPI_OPTION ("-oa", "Disable all optimizations (compatibility mode)"); @@ -199,12 +204,12 @@ HelpMessage ( Options (); printf ("\nCompiler/Disassembler Debug Options:\n"); - ACPI_OPTION ("-b", "Create compiler debug/trace file (*.txt)"); + ACPI_OPTION ("-bb -bp -bt", "Create compiler debug/trace file (*.txt)"); ACPI_OPTION ("", "Types: Parse/Tree/Both"); ACPI_OPTION ("-f", "Ignore errors, force creation of AML output file(s)"); ACPI_OPTION ("-n", "Parse only, no output generation"); ACPI_OPTION ("-ot", "Display compile times"); - ACPI_OPTION ("-x", "Set debug level for trace output"); + ACPI_OPTION ("-x ", "Set debug level for trace output"); ACPI_OPTION ("-z", "Do not insert new compiler ID for DataTables"); } @@ -405,34 +410,34 @@ AslDoOptions ( if (IsResponseFile) { printf ("Nested command files are not supported\n"); - return -1; + return (-1); } if (AslDoResponseFile (AcpiGbl_Optarg)) { - return -1; + return (-1); } break; - case '2': - + case '2': /* ACPI 2.0 compatibility mode */ Gbl_Acpi2 = TRUE; break; - case 'b': - + case 'b': /* Debug output options */ switch (AcpiGbl_Optarg[0]) { case 'b': AslCompilerdebug = 1; /* same as yydebug */ DtParserdebug = 1; + PrParserdebug = 1; break; case 'p': AslCompilerdebug = 1; /* same as yydebug */ DtParserdebug = 1; + PrParserdebug = 1; break; case 't': @@ -463,7 +468,7 @@ AslDoOptions ( break; - case 'd': + case 'd': /* Disassembler */ switch (AcpiGbl_Optarg[0]) { case '^': @@ -487,7 +492,12 @@ AslDoOptions ( break; - case 'e': + case 'D': /* Define a symbol */ + PrAddDefine (AcpiGbl_Optarg, NULL, TRUE); + break; + + + case 'e': /* External files for disassembler */ Status = AcpiDmAddToExternalFileList (AcpiGbl_Optarg); if (ACPI_FAILURE (Status)) { @@ -497,17 +507,17 @@ AslDoOptions ( break; - case 'f': - - /* Ignore errors and force creation of aml file */ - + case 'f': /* Ignore errors and force creation of aml file */ Gbl_IgnoreErrors = TRUE; break; - case 'g': + case 'G': + Gbl_CompileGeneric = TRUE; + break; - /* Get all ACPI tables */ + + case 'g': /* Get all ACPI tables */ Gbl_GetAllTables = TRUE; Gbl_DoCompile = FALSE; @@ -515,7 +525,6 @@ AslDoOptions ( case 'h': - switch (AcpiGbl_Optarg[0]) { case '^': @@ -542,14 +551,12 @@ AslDoOptions ( } - case 'I': /* Add an include file search directory */ - + case 'I': /* Add an include file search directory */ FlAddIncludeDirectory (AcpiGbl_Optarg); break; - case 'i': - + case 'i': /* Output AML as an include file */ switch (AcpiGbl_Optarg[0]) { case 'a': @@ -567,14 +574,13 @@ AslDoOptions ( break; default: - printf ("Unknown option: -s%s\n", AcpiGbl_Optarg); + printf ("Unknown option: -i%s\n", AcpiGbl_Optarg); return (-1); } break; - case 'l': - + case 'l': /* Listing files */ switch (AcpiGbl_Optarg[0]) { case '^': @@ -583,6 +589,12 @@ AslDoOptions ( Gbl_ListingFlag = TRUE; break; + case 'i': + /* Produce preprocessor output file */ + + Gbl_PreprocessorOutputFlag = TRUE; + break; + case 'n': /* Produce namespace file */ @@ -602,22 +614,17 @@ AslDoOptions ( break; - case 'm': - + case 'm': /* Do not convert buffers to resource descriptors */ AcpiGbl_NoResourceDisassembly = TRUE; break; - case 'n': - - /* Parse only */ - + case 'n': /* Parse only */ Gbl_ParseOnlyFlag = TRUE; break; - case 'o': - + case 'o': /* Control compiler AML optimizations */ switch (AcpiGbl_Optarg[0]) { case 'a': @@ -664,22 +671,24 @@ AslDoOptions ( break; - case 'p': + case 'P': /* Preprocess (plus .i file) only */ + Gbl_PreprocessOnly = TRUE; + Gbl_PreprocessorOutputFlag = TRUE; + break; - /* Override default AML output filename */ + case 'p': /* Override default AML output filename */ Gbl_OutputFilenamePrefix = AcpiGbl_Optarg; Gbl_UseDefaultAmlFilename = FALSE; break; - case 'r': + case 'r': /* Override revision found in table header */ Gbl_RevisionOverride = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0); break; - case 's': - + case 's': /* Create AML in a source code file */ switch (AcpiGbl_Optarg[0]) { case 'a': @@ -703,10 +712,7 @@ AslDoOptions ( break; - case 't': - - /* Produce hex table output file */ - + case 't': /* Produce hex table output file */ switch (AcpiGbl_Optarg[0]) { case 'a': @@ -728,19 +734,13 @@ AslDoOptions ( break; - case 'G': - Gbl_CompileGeneric = TRUE; - break; - - - case 'T': + case 'T': /* Create a ACPI table template file */ Gbl_DoTemplates = TRUE; Gbl_TemplateSignature = AcpiGbl_Optarg; break; - case 'v': - + case 'v': /* Verbosity settings */ switch (AcpiGbl_Optarg[0]) { case 'a': @@ -779,7 +779,6 @@ AslDoOptions ( case 'w': /* Set warning levels */ - switch (AcpiGbl_Optarg[0]) { case '1': @@ -801,20 +800,17 @@ AslDoOptions ( break; - case 'x': - + case 'x': /* Set debug print output level */ AcpiDbgLevel = strtoul (AcpiGbl_Optarg, NULL, 16); break; case 'z': - Gbl_UseOriginalCompilerId = TRUE; break; default: - return (-1); } @@ -931,6 +927,7 @@ main ( /* Init and command line */ AslInitialize (); + PrInitializePreprocessor (); Index1 = Index2 = AslCommandLine (argc, argv); /* Options that have no additional parameters or pathnames */ diff --git a/source/compiler/aslmessages.h b/source/compiler/aslmessages.h index f96e6f1ea554..45d50da19172 100644 --- a/source/compiler/aslmessages.h +++ b/source/compiler/aslmessages.h @@ -157,6 +157,7 @@ typedef enum ASL_MSG_OUTPUT_FILE_OPEN, ASL_MSG_OUTPUT_FILENAME, ASL_MSG_PACKAGE_LENGTH, + ASL_MSG_PREPROCESSOR_FILENAME, ASL_MSG_READ, ASL_MSG_RECURSION, ASL_MSG_REGION_BUFFER_ACCESS, @@ -197,7 +198,20 @@ typedef enum ASL_MSG_VENDOR_LIST, ASL_MSG_WRITE, -/* These messages are used by the data table compiler only */ + /* These messages are used by the Preprocessor only */ + + ASL_MSG_DIRECTIVE_SYNTAX, + ASL_MSG_ENDIF_MISMATCH, + ASL_MSG_ERROR_DIRECTIVE, + ASL_MSG_EXISTING_NAME, + ASL_MSG_INVALID_INVOCATION, + ASL_MSG_MACRO_SYNTAX, + ASL_MSG_TOO_MANY_ARGUMENTS, + ASL_MSG_UNKNOWN_DIRECTIVE, + ASL_MSG_UNKNOWN_PRAGMA, + + + /* These messages are used by the data table compiler only */ ASL_MSG_BUFFER_ELEMENT, ASL_MSG_DIVIDE_BY_ZERO, @@ -317,6 +331,7 @@ char *AslMessages [] = { /* ASL_MSG_OUTPUT_FILE_OPEN */ "Could not open output AML file", /* ASL_MSG_OUTPUT_FILENAME */ "Could not create output filename", /* ASL_MSG_PACKAGE_LENGTH */ "Effective AML package length is zero", +/* ASL_MSG_PREPROCESSOR_FILENAME */ "Could not create preprocessor filename", /* ASL_MSG_READ */ "Could not read file", /* ASL_MSG_RECURSION */ "Recursive method call", /* ASL_MSG_REGION_BUFFER_ACCESS */ "Host Operation Region requires BufferAcc access", @@ -357,7 +372,19 @@ char *AslMessages [] = { /* ASL_MSG_VENDOR_LIST */ "Too many vendor data bytes (7 max)", /* ASL_MSG_WRITE */ "Could not write file", -/* These messages are used by the data table compiler only */ +/* Preprocessor */ + +/* ASL_MSG_DIRECTIVE_SYNTAX */ "Invalid directive syntax", +/* ASL_MSG_ENDIF_MISMATCH */ "Mismatched #endif", +/* ASL_MSG_ERROR_DIRECTIVE */ "#error", +/* ASL_MSG_EXISTING_NAME */ "Name is already defined", +/* ASL_MSG_INVALID_INVOCATION */ "Invalid macro invocation", +/* ASL_MSG_MACRO_SYNTAX */ "Invalid macro syntax", +/* ASL_MSG_TOO_MANY_ARGUMENTS */ "Too many macro arguments", +/* ASL_MSG_UNKNOWN_DIRECTIVE */ "Unknown directive", +/* ASL_MSG_UNKNOWN_PRAGMA */ "Unknown pragma", + +/* Table compiler */ /* ASL_MSG_BUFFER_ELEMENT */ "Invalid element in buffer initializer list", /* ASL_MSG_DIVIDE_BY_ZERO */ "Expression contains divide-by-zero", diff --git a/source/compiler/aslstartup.c b/source/compiler/aslstartup.c index cbaf06281379..2bc1ba6c0e4c 100644 --- a/source/compiler/aslstartup.c +++ b/source/compiler/aslstartup.c @@ -95,6 +95,8 @@ AslInitializeGlobals ( Gbl_LogicalLineNumber = 1; Gbl_CurrentLineOffset = 0; Gbl_InputFieldCount = 0; + Gbl_InputByteCount = 0; + Gbl_NsLookupCount = 0; Gbl_LineBufPtr = Gbl_CurrentLineBuffer; Gbl_ErrorLog = NULL; @@ -102,17 +104,26 @@ AslInitializeGlobals ( Gbl_Signature = NULL; Gbl_FileType = 0; + TotalExecutableOpcodes = 0; + TotalNamedObjects = 0; + TotalKeywords = 0; + TotalParseNodes = 0; + TotalMethods = 0; + TotalAllocations = 0; + TotalAllocated = 0; + TotalFolds = 0; + AslGbl_NextEvent = 0; for (i = 0; i < ASL_NUM_REPORT_LEVELS; i++) { Gbl_ExceptionCount[i] = 0; } - Gbl_Files[ASL_FILE_AML_OUTPUT].Filename = NULL; - Gbl_Files[ASL_FILE_AML_OUTPUT].Handle = NULL; - - Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename = NULL; - Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle = NULL; + for (i = ASL_FILE_INPUT; i <= ASL_MAX_FILE_TYPE; i++) + { + Gbl_Files[i].Handle = NULL; + Gbl_Files[i].Filename = NULL; + } } @@ -282,11 +293,12 @@ AslDoOneFile ( ACPI_STATUS Status; - Gbl_Files[ASL_FILE_INPUT].Filename = Filename; - - /* Re-initialize "some" compiler globals */ + /* Re-initialize "some" compiler/preprocessor globals */ AslInitializeGlobals (); + PrInitializeGlobals (); + + Gbl_Files[ASL_FILE_INPUT].Filename = Filename; /* * AML Disassembly (Optional) @@ -399,6 +411,7 @@ AslDoOneFile ( Gbl_Signature = NULL; } AeClearErrorLog (); + PrTerminatePreprocessor (); return (Status); /* @@ -427,6 +440,7 @@ AslDoOneFile ( } AeClearErrorLog (); + PrTerminatePreprocessor (); return (AE_OK); case ASL_INPUT_TYPE_BINARY: diff --git a/source/compiler/asltypes.h b/source/compiler/asltypes.h index 0205181d227c..7e3bd0a5c34d 100644 --- a/source/compiler/asltypes.h +++ b/source/compiler/asltypes.h @@ -152,9 +152,10 @@ typedef enum { ASL_FILE_STDOUT = 0, ASL_FILE_STDERR, - ASL_FILE_INPUT, + ASL_FILE_INPUT, /* Don't move these first 3 file types */ ASL_FILE_AML_OUTPUT, ASL_FILE_SOURCE_OUTPUT, + ASL_FILE_PREPROCESSOR, ASL_FILE_LISTING_OUTPUT, ASL_FILE_HEX_OUTPUT, ASL_FILE_NAMESPACE_OUTPUT, @@ -167,7 +168,7 @@ typedef enum } ASL_FILE_TYPES; -#define ASL_MAX_FILE_TYPE 12 +#define ASL_MAX_FILE_TYPE 13 #define ASL_NUM_FILES (ASL_MAX_FILE_TYPE + 1) @@ -190,6 +191,7 @@ typedef struct asl_error_msg char *Message; struct asl_error_msg *Next; char *Filename; + char *SourceLine; UINT32 FilenameLength; UINT8 MessageId; UINT8 Level; diff --git a/source/compiler/aslutils.c b/source/compiler/aslutils.c index 4edc8c4bb8b8..de8ad247a579 100644 --- a/source/compiler/aslutils.c +++ b/source/compiler/aslutils.c @@ -68,6 +68,7 @@ static const char *AslFileTypeNames [ASL_NUM_FILES] = "Table Input: ", "Binary Output:", "Source Output:", + "Preprocessor: ", "Listing File: ", "Hex Dump: ", "Namespace: ", @@ -536,6 +537,13 @@ UtDisplaySummary ( continue; } + /* .I is a temp file unless specifically requested */ + + if ((i == ASL_FILE_PREPROCESSOR) && (!Gbl_PreprocessorOutputFlag)) + { + continue; + } + FlPrintFile (FileId, "%14s %s - %u bytes\n", AslFileTypeNames [i], Gbl_Files[i].Filename, FlGetFileSize (i)); diff --git a/source/compiler/dtcompile.c b/source/compiler/dtcompile.c index 78a6d3dcb229..8536400bb941 100644 --- a/source/compiler/dtcompile.c +++ b/source/compiler/dtcompile.c @@ -101,6 +101,17 @@ DtDoCompile ( return (Status); } + /* Preprocessor */ + + Event = UtBeginEvent ("Preprocess input file"); + PrDoPreprocess (); + UtEndEvent (Event); + + if (Gbl_PreprocessOnly) + { + return AE_OK; + } + /* * Scan the input file (file is already open) and * build the parse tree diff --git a/source/compiler/dtcompiler.h b/source/compiler/dtcompiler.h index c47254f61e6a..84b916acc4c9 100644 --- a/source/compiler/dtcompiler.h +++ b/source/compiler/dtcompiler.h @@ -155,6 +155,10 @@ DtCompileTable ( /* dtio - binary and text input/output */ +UINT32 +DtGetNextLine ( + FILE *Handle); + DT_FIELD * DtScanFile ( FILE *Handle); diff --git a/source/compiler/dtexpress.c b/source/compiler/dtexpress.c index 9773d886c23a..0bb7c5f26bdb 100644 --- a/source/compiler/dtexpress.c +++ b/source/compiler/dtexpress.c @@ -142,7 +142,7 @@ DtDoOperator ( if (!RightValue) { DtError (ASL_ERROR, ASL_MSG_DIVIDE_BY_ZERO, - Gbl_CurrentField, Gbl_CurrentField->Value); + Gbl_CurrentField, NULL); return (0); } Result = LeftValue / RightValue; @@ -152,7 +152,7 @@ DtDoOperator ( if (!RightValue) { DtError (ASL_ERROR, ASL_MSG_DIVIDE_BY_ZERO, - Gbl_CurrentField, Gbl_CurrentField->Value); + Gbl_CurrentField, NULL); return (0); } Result = LeftValue % RightValue; @@ -191,7 +191,7 @@ DtDoOperator ( break; case EXPOP_EQUAL: - Result = LeftValue = RightValue; + Result = LeftValue == RightValue; break; case EXPOP_NOT_EQUAL: @@ -223,13 +223,12 @@ DtDoOperator ( /* Unknown operator */ DtFatal (ASL_MSG_INVALID_EXPRESSION, - Gbl_CurrentField, Gbl_CurrentField->Value); + Gbl_CurrentField, NULL); return (0); } DbgPrint (ASL_DEBUG_OUTPUT, - "IntegerEval: %s (%8.8X%8.8X %s %8.8X%8.8X) = %8.8X%8.8X\n", - Gbl_CurrentField->Value, + "IntegerEval: (%8.8X%8.8X %s %8.8X%8.8X) = %8.8X%8.8X\n", ACPI_FORMAT_UINT64 (LeftValue), DtGetOpName (Operator), ACPI_FORMAT_UINT64 (RightValue), diff --git a/source/compiler/dtio.c b/source/compiler/dtio.c index 0fe0f38b93d6..14accfe103e7 100644 --- a/source/compiler/dtio.c +++ b/source/compiler/dtio.c @@ -66,10 +66,6 @@ DtParseLine ( UINT32 Line, UINT32 Offset); -UINT32 -DtGetNextLine ( - FILE *Handle); - static void DtWriteBinary ( DT_SUBTABLE *Subtable, diff --git a/source/compiler/dtparser.y b/source/compiler/dtparser.y index b931f0976d5f..b6807b3a3fa0 100644 --- a/source/compiler/dtparser.y +++ b/source/compiler/dtparser.y @@ -63,6 +63,10 @@ UINT64 DtParserResult; /* Expression return value */ #define YYERROR_VERBOSE 1 /* Verbose error messages */ #define YYFLAG -32768 +/* Define YYMALLOC/YYFREE to prevent redefinition errors */ + +#define YYMALLOC malloc +#define YYFREE free %} %union diff --git a/source/compiler/preprocess.h b/source/compiler/preprocess.h new file mode 100644 index 000000000000..09b7b7639376 --- /dev/null +++ b/source/compiler/preprocess.h @@ -0,0 +1,290 @@ +/****************************************************************************** + * + * Module Name: preprocess.h - header for iASL Preprocessor + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#define __PREPROCESS_H__ + +#ifndef _PREPROCESS +#define _PREPROCESS + +#undef PR_EXTERN + +#ifdef _DECLARE_PR_GLOBALS +#define PR_EXTERN +#define PR_INIT_GLOBAL(a,b) (a)=(b) +#else +#define PR_EXTERN extern +#define PR_INIT_GLOBAL(a,b) (a) +#endif + + +/* + * Configuration + */ +#define PR_MAX_MACRO_ARGS 32 /* Max number of macro args */ +#define PR_MAX_ARG_INSTANCES 24 /* Max instances of any one arg */ +#define PR_LINES_PER_BLOCK 4096 /* Max input source lines per block */ + + +/* + * Local defines and macros + */ +#define PR_TOKEN_SEPARATORS " ,(){}\t\n" +#define PR_MACRO_SEPARATORS " ,(){}~!*/%+-<>=&^|\"\t\n" +#define PR_MACRO_ARGUMENTS " ,\t\n" +#define PR_EXPR_SEPARATORS " ,(){}~!*/%+-<>=&^|\"\t\n" + +#define PR_PREFIX_ID "Pr(%.4u) - " /* Used for debug output */ + +#define THIS_TOKEN_OFFSET(t) ((t-Gbl_MainTokenBuffer) + 1) + + +/* + * Preprocessor structures + */ +typedef struct pr_macro_arg +{ + char *Name; + UINT32 Offset[PR_MAX_ARG_INSTANCES]; + UINT16 UseCount; + +} PR_MACRO_ARG; + +typedef struct pr_define_info +{ + struct pr_define_info *Previous; + struct pr_define_info *Next; + char *Identifier; + char *Replacement; + char *Body; /* Macro body */ + PR_MACRO_ARG *Args; /* Macro arg list */ + UINT16 ArgCount; /* Macro arg count */ + BOOLEAN Persist; /* Keep for entire compiler run */ + +} PR_DEFINE_INFO; + +typedef struct pr_directive_info +{ + char *Name; /* Directive name */ + UINT8 ArgCount; /* Required # of args */ + +} PR_DIRECTIVE_INFO; + +typedef struct pr_operator_info +{ + char *Op; + +} PR_OPERATOR_INFO; + +typedef struct pr_file_node +{ + struct pr_file_node *Next; + FILE *File; + char *Filename; + UINT32 CurrentLineNumber; + +} PR_FILE_NODE; + +typedef struct pr_line_mapping +{ + UINT32 *Map; + struct pr_line_mapping *Next; + +} PR_LINE_MAPPING; + + +/* + * Globals + */ +PR_EXTERN char XXXEvalBuffer[ASL_LINE_BUFFER_SIZE]; +PR_EXTERN char Gbl_MainTokenBuffer[ASL_LINE_BUFFER_SIZE]; +PR_EXTERN char Gbl_MacroTokenBuffer[ASL_LINE_BUFFER_SIZE]; +PR_EXTERN char Gbl_ExpressionTokenBuffer[ASL_LINE_BUFFER_SIZE]; + +PR_EXTERN PR_LINE_MAPPING *Gbl_MapBlockHead; +PR_EXTERN PR_FILE_NODE *Gbl_InputFileList; +PR_EXTERN PR_DEFINE_INFO PR_INIT_GLOBAL (*Gbl_DefineList, NULL); +PR_EXTERN UINT32 Gbl_PreprocessorLineNumber; +PR_EXTERN int Gbl_IfDepth; +PR_EXTERN BOOLEAN PR_INIT_GLOBAL (Gbl_PreprocessorError, FALSE); + + +/* + * prscan - Preprocessor entry + */ +void +PrInitializePreprocessor ( + void); + +void +PrInitializeGlobals ( + void); + +void +PrTerminatePreprocessor ( + void); + +BOOLEAN +PrDoPreprocess ( + void); + +UINT32 +PrGetLineNumber ( + UINT32 PreprocessorLineNumber); + +UINT64 +PrIsDefined ( + char *Identifier); + +UINT64 +PrResolveDefine ( + char *Identifier); + +int +PrInitLexer ( + char *String); + +void +PrTerminateLexer ( + void); + + +/* + * prmacros - Support for #defines and macros + */ +void +PrDumpPredefinedNames ( + void); + +PR_DEFINE_INFO * +PrAddDefine ( + char *Token, + char *Token2, + BOOLEAN Persist); + +void +PrRemoveDefine ( + char *DefineName); + +PR_DEFINE_INFO * +PrMatchDefine ( + char *MatchString); + +void +PrAddMacro ( + char *Name, + char **Next); + +void +PrDoMacroInvocation ( + char *TokenBuffer, + char *MacroStart, + PR_DEFINE_INFO *DefineInfo, + char **Next); + + +/* + * prexpress - #if expression support + */ +ACPI_STATUS +PrResolveIntegerExpression ( + char *Line, + UINT64 *ReturnValue); + +char * +PrPrioritizeExpression ( + char *OriginalLine); + +/* + * prparser - lex/yacc expression parser + */ +UINT64 +PrEvaluateExpression ( + char *ExprString); + + +/* + * prutils - Preprocesor utilities + */ +char * +PrGetNextToken ( + char *Buffer, + char *MatchString, + char **Next); + +void +PrSetLineNumber ( + UINT32 OriginalLineNumber, + UINT32 NewLineNumber); + +void +PrError ( + UINT8 Level, + UINT8 MessageId, + UINT32 Column); + +void +PrReplaceData ( + char *Buffer, + UINT32 LengthToRemove, + char *BufferToAdd, + UINT32 LengthToAdd); + +void +PrOpenIncludeFile ( + char *Filename); + +FILE * +PrOpenIncludeWithPrefix ( + char *PrefixDir, + char *Filename); + +void +PrPushInputFileStack ( + FILE *InputFile, + char *Filename); + +BOOLEAN +PrPopInputFileStack ( + void); + +#endif diff --git a/source/compiler/prexpress.c b/source/compiler/prexpress.c new file mode 100644 index 000000000000..3778013e4fa0 --- /dev/null +++ b/source/compiler/prexpress.c @@ -0,0 +1,305 @@ +/****************************************************************************** + * + * Module Name: prexpress - Preprocessor #if expression support + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "aslcompiler.h" +#include "dtcompiler.h" + + +#define _COMPONENT ASL_PREPROCESSOR + ACPI_MODULE_NAME ("prexpress") + +/* Local prototypes */ + +static char * +PrExpandMacros ( + char *Line); + + +#ifdef _UNDER_DEVELOPMENT +/****************************************************************************** + * + * FUNCTION: PrUnTokenize + * + * PARAMETERS: Buffer - Token Buffer + * Next - "Next" buffer from GetNextToken + * + * RETURN: None + * + * DESCRIPTION: Un-tokenized the current token buffer. The implementation is + * to simply set the null inserted by GetNextToken to a blank. + * If Next is NULL, there were no tokens found in the Buffer, + * so there is nothing to do. + * + *****************************************************************************/ + +static void +PrUnTokenize ( + char *Buffer, + char *Next) +{ + UINT32 Length = strlen (Buffer); + + + if (!Next) + { + return; + } + if (Buffer[Length] != '\n') + { + Buffer[strlen(Buffer)] = ' '; + } +} +#endif + + +/****************************************************************************** + * + * FUNCTION: PrExpandMacros + * + * PARAMETERS: Line - Pointer into the current line + * + * RETURN: Updated pointer into the current line + * + * DESCRIPTION: Expand any macros found in the current line buffer. + * + *****************************************************************************/ + +static char * +PrExpandMacros ( + char *Line) +{ + char *Token; + char *ReplaceString; + PR_DEFINE_INFO *DefineInfo; + ACPI_SIZE TokenOffset; + char *Next; + int OffsetAdjust; + + + strcpy (Gbl_ExpressionTokenBuffer, Gbl_CurrentLineBuffer); + Token = PrGetNextToken (Gbl_ExpressionTokenBuffer, PR_EXPR_SEPARATORS, &Next); + OffsetAdjust = 0; + + while (Token) + { + DefineInfo = PrMatchDefine (Token); + if (DefineInfo) + { + if (DefineInfo->Body) + { + /* This is a macro. TBD: Is this allowed? */ + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "Matched Macro: %s->%s\n", + Gbl_CurrentLineNumber, DefineInfo->Identifier, + DefineInfo->Replacement); + + PrDoMacroInvocation (Gbl_ExpressionTokenBuffer, Token, + DefineInfo, &Next); + } + else + { + ReplaceString = DefineInfo->Replacement; + + /* Replace the name in the original line buffer */ + + TokenOffset = Token - Gbl_ExpressionTokenBuffer + OffsetAdjust; + PrReplaceData ( + &Gbl_CurrentLineBuffer[TokenOffset], strlen (Token), + ReplaceString, strlen (ReplaceString)); + + /* Adjust for length difference between old and new name length */ + + OffsetAdjust += strlen (ReplaceString) - strlen (Token); + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "Matched #define within expression: %s->%s\n", + Gbl_CurrentLineNumber, Token, + *ReplaceString ? ReplaceString : "(NULL STRING)"); + } + } + + Token = PrGetNextToken (NULL, PR_EXPR_SEPARATORS, &Next); + } + + return (Line); +} + + +/****************************************************************************** + * + * FUNCTION: PrIsDefined + * + * PARAMETERS: Identifier - Name to be resolved + * + * RETURN: 64-bit boolean integer value + * + * DESCRIPTION: Returns TRUE if the name is defined, FALSE otherwise (0). + * + *****************************************************************************/ + +UINT64 +PrIsDefined ( + char *Identifier) +{ + UINT64 Value; + PR_DEFINE_INFO *DefineInfo; + + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "**** Is defined?: %s\n", Gbl_CurrentLineNumber, Identifier); + + Value = 0; /* Default is "Not defined" -- FALSE */ + + DefineInfo = PrMatchDefine (Identifier); + if (DefineInfo) + { + Value = ACPI_UINT64_MAX; /* TRUE */ + } + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "[#if defined %s] resolved to: %8.8X%8.8X\n", + Gbl_CurrentLineNumber, Identifier, ACPI_FORMAT_UINT64 (Value)); + + return (Value); +} + + +/****************************************************************************** + * + * FUNCTION: PrResolveDefine + * + * PARAMETERS: Identifier - Name to be resolved + * + * RETURN: A 64-bit boolean integer value + * + * DESCRIPTION: Returns TRUE if the name is defined, FALSE otherwise (0). + * + *****************************************************************************/ + +UINT64 +PrResolveDefine ( + char *Identifier) +{ + UINT64 Value; + PR_DEFINE_INFO *DefineInfo; + + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "**** Resolve #define: %s\n", Gbl_CurrentLineNumber, Identifier); + + Value = 0; /* Default is "Not defined" -- FALSE */ + + DefineInfo = PrMatchDefine (Identifier); + if (DefineInfo) + { + Value = ACPI_UINT64_MAX; /* TRUE */ + } + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "[#if defined %s] resolved to: %8.8X%8.8X\n", + Gbl_CurrentLineNumber, Identifier, ACPI_FORMAT_UINT64 (Value)); + + return (Value); +} + + +/****************************************************************************** + * + * FUNCTION: PrResolveIntegerExpression + * + * PARAMETERS: Line - Pointer to integer expression + * ReturnValue - Where the resolved 64-bit integer is + * returned. + * + * RETURN: Status + * + * DESCRIPTION: Resolve an integer expression to a single value. Supports + * both integer constants and labels. + * + *****************************************************************************/ + +ACPI_STATUS +PrResolveIntegerExpression ( + char *Line, + UINT64 *ReturnValue) +{ + UINT64 Result; + char *ExpandedLine; + + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "**** Resolve #if: %s\n", Gbl_CurrentLineNumber, Line); + + /* Expand all macros within the expression first */ + + ExpandedLine = PrExpandMacros (Line); + + /* Now we can evaluate the expression */ + + Result = PrEvaluateExpression (ExpandedLine); + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "**** Expression Resolved to: %8.8X%8.8X\n", + Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Result)); + + *ReturnValue = Result; + return (AE_OK); + +#if 0 +InvalidExpression: + + ACPI_FREE (EvalBuffer); + PrError (ASL_ERROR, ASL_MSG_INVALID_EXPRESSION, 0); + return (AE_ERROR); + + +NormalExit: + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "**** Expression Resolved to: %8.8X%8.8X\n", + Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Value1)); + + *ReturnValue = Value1; + return (AE_OK); +#endif +} diff --git a/source/compiler/prmacros.c b/source/compiler/prmacros.c new file mode 100644 index 000000000000..a5b6e4c261aa --- /dev/null +++ b/source/compiler/prmacros.c @@ -0,0 +1,574 @@ +/****************************************************************************** + * + * Module Name: prmacros - Preprocessor #define macro support + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "aslcompiler.h" +#include "dtcompiler.h" + + +#define _COMPONENT ASL_PREPROCESSOR + ACPI_MODULE_NAME ("prmacros") + + +/******************************************************************************* + * + * FUNCTION: PrDumpPredefinedNames + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Dump the list of #defines. Used as the preprocessor starts, to + * display the names that were defined on the command line. + * Debug information only. + * + ******************************************************************************/ + +void +PrDumpPredefinedNames ( + void) +{ + PR_DEFINE_INFO *DefineInfo; + + + DefineInfo = Gbl_DefineList; + while (DefineInfo) + { + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "Predefined #define: %s->%s\n", + 0, DefineInfo->Identifier, DefineInfo->Replacement); + + DefineInfo = DefineInfo->Next; + } +} + + +/******************************************************************************* + * + * FUNCTION: PrAddDefine + * + * PARAMETERS: Identifier - Name to be replaced + * Replacement - Replacement for Identifier + * Persist - Keep define across multiple compiles? + * + * RETURN: A new define_info struct. NULL on error. + * + * DESCRIPTION: Add a new #define to the global list + * + ******************************************************************************/ + +PR_DEFINE_INFO * +PrAddDefine ( + char *Identifier, + char *Replacement, + BOOLEAN Persist) +{ + char *IdentifierString; + char *ReplacementString; + PR_DEFINE_INFO *DefineInfo; + + + if (!Replacement) + { + Replacement = ""; + } + + /* Check for already-defined first */ + + DefineInfo = PrMatchDefine (Identifier); + if (DefineInfo) + { + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID, + "#define: name already exists: %s\n", + Gbl_CurrentLineNumber, Identifier); + + /* + * Name already exists. This is only an error if the target name + * is different. + */ + if (strcmp (Replacement, DefineInfo->Replacement)) + { + PrError (ASL_ERROR, ASL_MSG_EXISTING_NAME, + THIS_TOKEN_OFFSET (Identifier)); + + return (NULL); + } + + return (DefineInfo); + } + + /* Copy input strings */ + + IdentifierString = UtLocalCalloc (strlen (Identifier) + 1); + strcpy (IdentifierString, Identifier); + + ReplacementString = UtLocalCalloc (strlen (Replacement) + 1); + strcpy (ReplacementString, Replacement); + + /* Init and link new define info struct */ + + DefineInfo = UtLocalCalloc (sizeof (PR_DEFINE_INFO)); + DefineInfo->Replacement = ReplacementString; + DefineInfo->Identifier = IdentifierString; + DefineInfo->Persist = Persist; + + if (Gbl_DefineList) + { + Gbl_DefineList->Previous = DefineInfo; + } + + DefineInfo->Next = Gbl_DefineList; + Gbl_DefineList = DefineInfo; + return (DefineInfo); +} + + +/******************************************************************************* + * + * FUNCTION: PrRemoveDefine + * + * PARAMETERS: DefineName - Name of define to be removed + * + * RETURN: None + * + * DESCRIPTION: Implements #undef. Remove a #define if found in the global + * list. No error if the target of the #undef does not exist, + * as per the C #undef definition. + * + ******************************************************************************/ + +void +PrRemoveDefine ( + char *DefineName) +{ + PR_DEFINE_INFO *DefineInfo; + + + /* Match name and delete the node */ + + DefineInfo = Gbl_DefineList; + while (DefineInfo) + { + if (!strcmp (DefineName, DefineInfo->Identifier)) + { + /* Remove from linked list */ + + if (DefineInfo->Previous) + { + (DefineInfo->Previous)->Next = DefineInfo->Next; + } + else + { + Gbl_DefineList = DefineInfo->Next; + } + + if (DefineInfo->Next) + { + (DefineInfo->Next)->Previous = DefineInfo->Previous; + } + + free (DefineInfo); + return; + } + + DefineInfo = DefineInfo->Next; + } + + /* + * Name was not found. By definition of #undef, this is not + * an error, however. + */ + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "#undef: could not find %s\n", + Gbl_CurrentLineNumber, DefineName); +} + + +/******************************************************************************* + * + * FUNCTION: PrMatchDefine + * + * PARAMETERS: MatchString - Name associated with the #define + * + * RETURN: Matched string if found. NULL otherwise. + * + * DESCRIPTION: Find a name in global #define list + * + ******************************************************************************/ + +PR_DEFINE_INFO * +PrMatchDefine ( + char *MatchString) +{ + PR_DEFINE_INFO *DefineInfo; + + + DefineInfo = Gbl_DefineList; + while (DefineInfo) + { + if (!strcmp (MatchString, DefineInfo->Identifier)) + { + return (DefineInfo); + } + + DefineInfo = DefineInfo->Next; + } + + return (NULL); +} + + +/******************************************************************************* + * + * FUNCTION: PrAddMacro + * + * PARAMETERS: Name - Start of the macro definition + * Next - "Next" buffer from GetNextToken + * + * RETURN: None + * + * DESCRIPTION: Add a new macro to the list of #defines. Handles argument + * processing. + * + ******************************************************************************/ + +void +PrAddMacro ( + char *Name, + char **Next) +{ + char *Token = NULL; + ACPI_SIZE TokenOffset; + ACPI_SIZE MacroBodyOffset; + PR_DEFINE_INFO *DefineInfo; + PR_MACRO_ARG *Args; + char *Body; + char *BodyInSource; + UINT32 i; + UINT16 UseCount = 0; + UINT16 ArgCount = 0; + UINT32 Depth = 1; + UINT32 EndOfArgList; + char BufferChar; + + + /* Find the end of the arguments list */ + + TokenOffset = Name - Gbl_MainTokenBuffer + strlen (Name) + 1; + while (1) + { + BufferChar = Gbl_CurrentLineBuffer[TokenOffset]; + if (BufferChar == '(') + { + Depth++; + } + else if (BufferChar == ')') + { + Depth--; + } + else if (BufferChar == 0) + { + PrError (ASL_ERROR, ASL_MSG_MACRO_SYNTAX, TokenOffset); + return; + } + + if (Depth == 0) + { + /* Found arg list end */ + + EndOfArgList = TokenOffset; + break; + } + + TokenOffset++; + } + + /* At this point, we know that we have a reasonable argument list */ + + Args = UtLocalCalloc (sizeof (PR_MACRO_ARG) * PR_MAX_MACRO_ARGS); + + /* Get the macro argument names */ + + for (i = 0; i < PR_MAX_MACRO_ARGS; i++) + { + Token = PrGetNextToken (NULL, PR_MACRO_SEPARATORS, Next); + if (!Token) + { + /* This is the case for a NULL macro body */ + + BodyInSource = ""; + goto AddMacroToList; + } + + /* Don't go beyond the argument list */ + + TokenOffset = Token - Gbl_MainTokenBuffer + strlen (Token); + if (TokenOffset > EndOfArgList) + { + break; + } + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "Macro arg: %s \n", + Gbl_CurrentLineNumber, Token); + + Args[i].Name = UtLocalCalloc (strlen (Token) + 1); + strcpy (Args[i].Name, Token); + + Args[i].UseCount = 0; + + ArgCount++; + if (ArgCount >= PR_MAX_MACRO_ARGS) + { + PrError (ASL_ERROR, ASL_MSG_TOO_MANY_ARGUMENTS, TokenOffset); + return; + } + } + + /* Get the macro body. Token now points to start of body */ + + MacroBodyOffset = Token - Gbl_MainTokenBuffer; + + /* Match each method arg in the macro body for later use */ + + Token = PrGetNextToken (NULL, PR_MACRO_SEPARATORS, Next); + while (Token) + { + /* Search the macro arg list for matching arg */ + + for (i = 0; Args[i].Name && (i < PR_MAX_MACRO_ARGS); i++) + { + /* + * Save argument offset within macro body. This is the mechanism + * used to expand the macro upon invocation. + * + * Handles multiple instances of the same argument + */ + if (!strcmp (Token, Args[i].Name)) + { + UseCount = Args[i].UseCount; + + Args[i].Offset[UseCount] = (Token - Gbl_MainTokenBuffer) - MacroBodyOffset; + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "Macro Arg #%u: %s UseCount %u Offset %u \n", + Gbl_CurrentLineNumber, i, Token, + UseCount+1, Args[i].Offset[UseCount]); + + Args[i].UseCount++; + if (Args[i].UseCount >= PR_MAX_ARG_INSTANCES) + { + PrError (ASL_ERROR, ASL_MSG_TOO_MANY_ARGUMENTS, + THIS_TOKEN_OFFSET (Token)); + + return; + } + break; + } + } + + Token = PrGetNextToken (NULL, PR_MACRO_SEPARATORS, Next); + } + + BodyInSource = &Gbl_CurrentLineBuffer[MacroBodyOffset]; + + +AddMacroToList: + + /* Check if name is already defined first */ + + DefineInfo = PrMatchDefine (Name); + if (DefineInfo) + { + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "#define: macro name already exists: %s\n", + Gbl_CurrentLineNumber, Name); + + /* Error only if not exactly the same macro */ + + if (strcmp (DefineInfo->Body, BodyInSource) || + (DefineInfo->ArgCount != ArgCount)) + { + PrError (ASL_ERROR, ASL_MSG_EXISTING_NAME, + THIS_TOKEN_OFFSET (Name)); + } + + return; + } + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "Macro body: %s \n", + Gbl_CurrentLineNumber, BodyInSource); + + /* Add macro to the #define list */ + + DefineInfo = PrAddDefine (Name, BodyInSource, FALSE); + if (DefineInfo) + { + Body = UtLocalCalloc (strlen (BodyInSource) + 1); + strcpy (Body, BodyInSource); + + DefineInfo->Body = Body; + DefineInfo->Args = Args; + DefineInfo->ArgCount = ArgCount; + } +} + + +/******************************************************************************* + * + * FUNCTION: PrDoMacroInvocation + * + * PARAMETERS: TokenBuffer - Current line buffer + * MacroStart - Start of the macro invocation within + * the token buffer + * DefineInfo - Info for this macro + * Next - "Next" buffer from GetNextToken + * + * RETURN: None + * + * DESCRIPTION: Expand a macro invocation + * + ******************************************************************************/ + +void +PrDoMacroInvocation ( + char *TokenBuffer, + char *MacroStart, + PR_DEFINE_INFO *DefineInfo, + char **Next) +{ + PR_MACRO_ARG *Args; + char *Token = NULL; + UINT32 TokenOffset; + UINT32 Length; + UINT32 i; + + + /* Take a copy of the macro body for expansion */ + + strcpy (Gbl_MacroTokenBuffer, DefineInfo->Body); + + /* Replace each argument within the prototype body */ + + Args = DefineInfo->Args; + if (!Args->Name) + { + /* This macro has no arguments */ + + Token = PrGetNextToken (NULL, PR_MACRO_ARGUMENTS, Next); + if (!Token) + { + goto BadInvocation; + } + + TokenOffset = (MacroStart - TokenBuffer); + Length = Token - MacroStart + strlen (Token) + 1; + + PrReplaceData ( + &Gbl_CurrentLineBuffer[TokenOffset], Length, + Gbl_MacroTokenBuffer, strlen (Gbl_MacroTokenBuffer)); + return; + } + + while (Args->Name) + { + /* Get the next argument from macro invocation */ + + Token = PrGetNextToken (NULL, PR_MACRO_SEPARATORS, Next); + if (!Token) + { + goto BadInvocation; + } + + /* Replace all instances of this argument */ + + for (i = 0; i < Args->UseCount; i++) + { + /* Offset zero indicates "arg not used" */ + /* TBD: Not really needed now, with UseCount available */ + + if (Args->Offset[i] == 0) + { + break; + } + + PrReplaceData ( + &Gbl_MacroTokenBuffer[Args->Offset[i]], strlen (Args->Name), + Token, strlen (Token)); + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "ExpandArg: %s \n", + Gbl_CurrentLineNumber, Gbl_MacroTokenBuffer); + } + + Args++; + } + + /* TBD: need to make sure macro was not invoked with too many arguments */ + + if (!Token) + { + return; + } + + /* Replace the entire macro invocation with the expanded macro */ + + TokenOffset = (MacroStart - TokenBuffer); + Length = Token - MacroStart + strlen (Token) + 1; + + PrReplaceData ( + &Gbl_CurrentLineBuffer[TokenOffset], Length, + Gbl_MacroTokenBuffer, strlen (Gbl_MacroTokenBuffer)); + + return; + + +BadInvocation: + PrError (ASL_ERROR, ASL_MSG_INVALID_INVOCATION, + THIS_TOKEN_OFFSET (MacroStart)); + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "Bad macro invocation: %s \n", + Gbl_CurrentLineNumber, Gbl_MacroTokenBuffer); + return; +} diff --git a/source/compiler/prparser.l b/source/compiler/prparser.l new file mode 100644 index 000000000000..f0a06e1e2105 --- /dev/null +++ b/source/compiler/prparser.l @@ -0,0 +1,153 @@ +%{ +/****************************************************************************** + * + * Module Name: prparser.l - Flex input file for preprocessor lexer + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "aslcompiler.h" +#include "prparser.y.h" + +/* Buffer to pass strings to the parser */ + +#define STRING_SETUP strcpy (StringBuffer, PrParsertext);\ + PrParserlval.str = StringBuffer + +#define YY_NO_INPUT /* No file input, we use strings only */ + +#define _COMPONENT ACPI_COMPILER + ACPI_MODULE_NAME ("prscanner") +%} + +%option noyywrap +%option nounput + +Number [0-9a-fA-F]+ +HexNumber 0[xX][0-9a-fA-F]+ +WhiteSpace [ \t\v\r]+ +NewLine [\n] +Identifier [a-zA-Z][0-9a-zA-Z]* + +%% + +\( return (EXPOP_PAREN_OPEN); +\) return (EXPOP_PAREN_CLOSE); +\~ return (EXPOP_ONES_COMPLIMENT); +\! return (EXPOP_LOGICAL_NOT); +\* return (EXPOP_MULTIPLY); +\/ return (EXPOP_DIVIDE); +\% return (EXPOP_MODULO); +\+ return (EXPOP_ADD); +\- return (EXPOP_SUBTRACT); +">>" return (EXPOP_SHIFT_RIGHT); +"<<" return (EXPOP_SHIFT_LEFT); +\< return (EXPOP_LESS); +\> return (EXPOP_GREATER); +"<=" return (EXPOP_LESS_EQUAL); +">=" return (EXPOP_GREATER_EQUAL); +"==" return (EXPOP_EQUAL); +"!=" return (EXPOP_NOT_EQUAL); +\& return (EXPOP_AND); +\^ return (EXPOP_XOR); +\| return (EXPOP_OR); +"&&" return (EXPOP_LOGICAL_AND); +"||" return (EXPOP_LOGICAL_OR); + +"defined" return (EXPOP_DEFINE); +{Identifier} {STRING_SETUP; return (EXPOP_IDENTIFIER);} + +<> return (EXPOP_EOF); /* null end-of-string */ + +{Number} return (EXPOP_NUMBER); +{HexNumber} return (EXPOP_HEX_NUMBER); +{NewLine} return (EXPOP_NEW_LINE); +{WhiteSpace} /* Ignore */ + +. return (EXPOP_EOF); +%% + +/* + * Local support functions + */ +YY_BUFFER_STATE LexBuffer; + + +/****************************************************************************** + * + * FUNCTION: PrInitLexer + * + * PARAMETERS: String - Input string to be parsed + * + * RETURN: TRUE if parser returns NULL. FALSE otherwise. + * + * DESCRIPTION: Initialization routine for lexer. The lexer needs + * a buffer to handle strings instead of a file. + * + *****************************************************************************/ + +int +PrInitLexer ( + char *String) +{ + + LexBuffer = yy_scan_string (String); + return (LexBuffer == NULL); +} + + +/****************************************************************************** + * + * FUNCTION: PrTerminateLexer + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Termination routine for thelexer. + * + *****************************************************************************/ + +void +PrTerminateLexer ( + void) +{ + + yy_delete_buffer (LexBuffer); +} diff --git a/source/compiler/prparser.y b/source/compiler/prparser.y new file mode 100644 index 000000000000..e1bbb401f929 --- /dev/null +++ b/source/compiler/prparser.y @@ -0,0 +1,284 @@ +%{ +/****************************************************************************** + * + * Module Name: prparser.y - Bison input file for preprocessor parser + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "aslcompiler.h" +#include "dtcompiler.h" + +#define _COMPONENT ASL_PREPROCESSOR + ACPI_MODULE_NAME ("prparser") + +int PrParserlex (void); +int PrParserparse (void); +void PrParsererror (char const *msg); +extern char *PrParsertext; + +UINT64 PrParserResult; /* Expression return value */ + +/* Bison/yacc configuration */ + +#define yytname PrParsername +#define YYDEBUG 1 /* Enable debug output */ +#define YYERROR_VERBOSE 1 /* Verbose error messages */ +#define YYFLAG -32768 + +/* Define YYMALLOC/YYFREE to prevent redefinition errors */ + +#define YYMALLOC malloc +#define YYFREE free +%} + +%union +{ + UINT64 value; + UINT32 op; + char *str; +} + +/*! [Begin] no source code translation */ + +%type Expression + +%token EXPOP_EOF +%token EXPOP_NEW_LINE +%token EXPOP_NUMBER +%token EXPOP_HEX_NUMBER +%token EXPOP_RESERVED1 +%token EXPOP_RESERVED2 +%token EXPOP_PAREN_OPEN +%token EXPOP_PAREN_CLOSE + +%left EXPOP_LOGICAL_OR +%left EXPOP_LOGICAL_AND +%left EXPOP_OR +%left EXPOP_XOR +%left EXPOP_AND +%left EXPOP_EQUAL EXPOP_NOT_EQUAL +%left EXPOP_GREATER EXPOP_LESS EXPOP_GREATER_EQUAL EXPOP_LESS_EQUAL +%left EXPOP_SHIFT_RIGHT EXPOP_SHIFT_LEFT +%left EXPOP_ADD EXPOP_SUBTRACT +%left EXPOP_MULTIPLY EXPOP_DIVIDE EXPOP_MODULO +%right EXPOP_ONES_COMPLIMENT EXPOP_LOGICAL_NOT + +/* Tokens above must be kept in synch with dtparser.y */ + +%token EXPOP_DEFINE +%token EXPOP_IDENTIFIER + +%% + +/* + * Operator precedence rules (from K&R) + * + * 1) ( ) + * 2) ! ~ (unary operators that are supported here) + * 3) * / % + * 4) + - + * 5) >> << + * 6) < > <= >= + * 7) == != + * 8) & + * 9) ^ + * 10) | + * 11) && + * 12) || + */ + +/*! [End] no source code translation !*/ + +Value + : Expression EXPOP_NEW_LINE { PrParserResult=$1; return 0; } /* End of line (newline) */ + | Expression EXPOP_EOF { PrParserResult=$1; return 0; } /* End of string (0) */ + ; + +Expression + + /* Unary operators */ + + : EXPOP_LOGICAL_NOT Expression { $$ = DtDoOperator ($2, EXPOP_LOGICAL_NOT, $2);} + | EXPOP_ONES_COMPLIMENT Expression { $$ = DtDoOperator ($2, EXPOP_ONES_COMPLIMENT, $2);} + + /* Binary operators */ + + | Expression EXPOP_MULTIPLY Expression { $$ = DtDoOperator ($1, EXPOP_MULTIPLY, $3);} + | Expression EXPOP_DIVIDE Expression { $$ = DtDoOperator ($1, EXPOP_DIVIDE, $3);} + | Expression EXPOP_MODULO Expression { $$ = DtDoOperator ($1, EXPOP_MODULO, $3);} + | Expression EXPOP_ADD Expression { $$ = DtDoOperator ($1, EXPOP_ADD, $3);} + | Expression EXPOP_SUBTRACT Expression { $$ = DtDoOperator ($1, EXPOP_SUBTRACT, $3);} + | Expression EXPOP_SHIFT_RIGHT Expression { $$ = DtDoOperator ($1, EXPOP_SHIFT_RIGHT, $3);} + | Expression EXPOP_SHIFT_LEFT Expression { $$ = DtDoOperator ($1, EXPOP_SHIFT_LEFT, $3);} + | Expression EXPOP_GREATER Expression { $$ = DtDoOperator ($1, EXPOP_GREATER, $3);} + | Expression EXPOP_LESS Expression { $$ = DtDoOperator ($1, EXPOP_LESS, $3);} + | Expression EXPOP_GREATER_EQUAL Expression { $$ = DtDoOperator ($1, EXPOP_GREATER_EQUAL, $3);} + | Expression EXPOP_LESS_EQUAL Expression { $$ = DtDoOperator ($1, EXPOP_LESS_EQUAL, $3);} + | Expression EXPOP_EQUAL Expression { $$ = DtDoOperator ($1, EXPOP_EQUAL, $3);} + | Expression EXPOP_NOT_EQUAL Expression { $$ = DtDoOperator ($1, EXPOP_NOT_EQUAL, $3);} + | Expression EXPOP_AND Expression { $$ = DtDoOperator ($1, EXPOP_AND, $3);} + | Expression EXPOP_XOR Expression { $$ = DtDoOperator ($1, EXPOP_XOR, $3);} + | Expression EXPOP_OR Expression { $$ = DtDoOperator ($1, EXPOP_OR, $3);} + | Expression EXPOP_LOGICAL_AND Expression { $$ = DtDoOperator ($1, EXPOP_LOGICAL_AND, $3);} + | Expression EXPOP_LOGICAL_OR Expression { $$ = DtDoOperator ($1, EXPOP_LOGICAL_OR, $3);} + + /* Parentheses: '(' Expression ')' */ + + | EXPOP_PAREN_OPEN Expression + EXPOP_PAREN_CLOSE { $$ = $2;} + + /* #if defined (ID) or #if defined ID */ + + | EXPOP_DEFINE EXPOP_PAREN_OPEN EXPOP_IDENTIFIER + EXPOP_PAREN_CLOSE { $$ = PrIsDefined (PrParserlval.str);} + + | EXPOP_DEFINE EXPOP_IDENTIFIER { $$ = PrIsDefined (PrParserlval.str);} + + | EXPOP_IDENTIFIER { $$ = PrResolveDefine (PrParserlval.str);} + + /* Default base for a non-prefixed integer is 10 */ + + | EXPOP_NUMBER { UtStrtoul64 (PrParsertext, 10, &$$);} + + /* Standard hex number (0x1234) */ + + | EXPOP_HEX_NUMBER { UtStrtoul64 (PrParsertext, 16, &$$);} + ; +%% + +/* + * Local support functions, including parser entry point + */ +#define PR_FIRST_PARSE_OPCODE EXPOP_EOF +#define PR_YYTNAME_START 3 + + +/****************************************************************************** + * + * FUNCTION: PrParsererror + * + * PARAMETERS: Message - Parser-generated error message + * + * RETURN: None + * + * DESCRIPTION: Handler for parser errors + * + *****************************************************************************/ + +void +PrParsererror ( + char const *Message) +{ + DtError (ASL_ERROR, ASL_MSG_SYNTAX, + NULL, (char *) Message); +} + + +/****************************************************************************** + * + * FUNCTION: PrGetOpName + * + * PARAMETERS: ParseOpcode - Parser token (EXPOP_*) + * + * RETURN: Pointer to the opcode name + * + * DESCRIPTION: Get the ascii name of the parse opcode for debug output + * + *****************************************************************************/ + +char * +PrGetOpName ( + UINT32 ParseOpcode) +{ +#ifdef ASL_YYTNAME_START + /* + * First entries (PR_YYTNAME_START) in yytname are special reserved names. + * Ignore first 6 characters of name (EXPOP_) + */ + return ((char *) yytname + [(ParseOpcode - PR_FIRST_PARSE_OPCODE) + PR_YYTNAME_START] + 6); +#else + return ("[Unknown parser generator]"); +#endif +} + + +/****************************************************************************** + * + * FUNCTION: PrEvaluateExpression + * + * PARAMETERS: ExprString - Expression to be evaluated. Must be + * terminated by either a newline or a NUL + * string terminator + * + * RETURN: 64-bit value for the expression + * + * DESCRIPTION: Main entry point for the DT expression parser + * + *****************************************************************************/ + +UINT64 +PrEvaluateExpression ( + char *ExprString) +{ + + DbgPrint (ASL_DEBUG_OUTPUT, + "**** Input expression: %s\n", ExprString); + + /* Point lexer to the input string */ + + if (PrInitLexer (ExprString)) + { + DtError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, + NULL, "Could not initialize lexer"); + return (0); + } + + /* Parse/Evaluate the input string (value returned in PrParserResult) */ + + PrParserparse (); + PrTerminateLexer (); + + DbgPrint (ASL_DEBUG_OUTPUT, + "**** Parser returned value: %u (%8.8X%8.8X)\n", + (UINT32) PrParserResult, ACPI_FORMAT_UINT64 (PrParserResult)); + + return (PrParserResult); +} diff --git a/source/compiler/prscan.c b/source/compiler/prscan.c new file mode 100644 index 000000000000..3719ca6ec18f --- /dev/null +++ b/source/compiler/prscan.c @@ -0,0 +1,749 @@ +/****************************************************************************** + * + * Module Name: prscan - Preprocessor start-up and file scan module + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#define _DECLARE_PR_GLOBALS + +#include "aslcompiler.h" +#include "dtcompiler.h" + +/* + * TBDs: + * + * No nested macros, maybe never + * Implement ASL "Include" as well as "#include" here? + */ +#define _COMPONENT ASL_PREPROCESSOR + ACPI_MODULE_NAME ("prscan") + + +/* Local prototypes */ + +static void +PrPreprocessInputFile ( + void); + +static void +PrDoDirective ( + char *DirectiveToken, + char **Next, + BOOLEAN *IgnoringThisCodeBlock); + +static int +PrMatchDirective ( + char *Directive); + +/* + * Supported preprocessor directives + */ +static const PR_DIRECTIVE_INFO Gbl_DirectiveInfo[] = +{ + {"define", 1}, + {"elif", 0}, /* Converted to #else..#if internally */ + {"else", 0}, + {"endif", 0}, + {"error", 1}, + {"if", 1}, + {"ifdef", 1}, + {"ifndef", 1}, + {"include", 0}, /* Argument is not standard format, so 0 */ + {"line", 1}, + {"pragma", 1}, + {"undef", 1}, + {"warning", 1}, + {NULL, 0} +}; + +enum Gbl_DirectiveIndexes +{ + PR_DIRECTIVE_DEFINE = 0, + PR_DIRECTIVE_ELIF, + PR_DIRECTIVE_ELSE, + PR_DIRECTIVE_ENDIF, + PR_DIRECTIVE_ERROR, + PR_DIRECTIVE_IF, + PR_DIRECTIVE_IFDEF, + PR_DIRECTIVE_IFNDEF, + PR_DIRECTIVE_INCLUDE, + PR_DIRECTIVE_LINE, + PR_DIRECTIVE_PRAGMA, + PR_DIRECTIVE_UNDEF, + PR_DIRECTIVE_WARNING, +}; + +#define ASL_DIRECTIVE_NOT_FOUND -1 + + +/******************************************************************************* + * + * FUNCTION: PrInitializePreprocessor + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Startup initialization for the Preprocessor. + * + ******************************************************************************/ + +void +PrInitializePreprocessor ( + void) +{ + /* Init globals and the list of #defines */ + + PrInitializeGlobals (); + Gbl_DefineList = NULL; +} + + +/******************************************************************************* + * + * FUNCTION: PrInitializeGlobals + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Initialize globals for the Preprocessor. Used for startuup + * initialization and re-initialization between compiles during + * a multiple source file compile. + * + ******************************************************************************/ + +void +PrInitializeGlobals ( + void) +{ + /* Init globals */ + + Gbl_IfDepth = 0; + Gbl_InputFileList = NULL; + Gbl_CurrentLineNumber = 0; + Gbl_PreprocessorLineNumber = 1; + Gbl_PreprocessorError = FALSE; + + Gbl_MapBlockHead = UtLocalCalloc (sizeof (PR_LINE_MAPPING)); + Gbl_MapBlockHead->Map = UtLocalCalloc (PR_LINES_PER_BLOCK * sizeof (UINT32)); +} + + +/******************************************************************************* + * + * FUNCTION: PrTerminatePreprocessor + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Termination of the preprocessor. Delete lists. Keep any + * defines that were specified on the command line, in order to + * support multiple compiles with a single compiler invocation. + * + ******************************************************************************/ + +void +PrTerminatePreprocessor ( + void) +{ + PR_DEFINE_INFO *DefineInfo; + PR_LINE_MAPPING *MapInfo; + + + /* + * The persistent defines (created on the command line) are always at the + * end of the list. We save them. + */ + while ((Gbl_DefineList) && (!Gbl_DefineList->Persist)) + { + DefineInfo = Gbl_DefineList; + Gbl_DefineList = DefineInfo->Next; + + ACPI_FREE (DefineInfo->Replacement); + ACPI_FREE (DefineInfo->Identifier); + ACPI_FREE (DefineInfo); + } + + /* Clear the line number mappings */ + + while (Gbl_MapBlockHead) + { + MapInfo = Gbl_MapBlockHead; + Gbl_MapBlockHead = MapInfo->Next; + + ACPI_FREE (MapInfo->Map); + ACPI_FREE (MapInfo); + } +} + + +/******************************************************************************* + * + * FUNCTION: PrDoPreprocess + * + * PARAMETERS: None + * + * RETURN: Error Status. TRUE if error, FALSE if OK. + * + * DESCRIPTION: Main entry point for the iASL Preprocessor. Input file must + * be already open. Handles multiple input files via the + * #include directive. + * + ******************************************************************************/ + +BOOLEAN +PrDoPreprocess ( + void) +{ + BOOLEAN MoreInputFiles; + + + DbgPrint (ASL_DEBUG_OUTPUT, "Starting preprocessing phase\n\n"); + + + FlSeekFile (ASL_FILE_INPUT, 0); + PrDumpPredefinedNames (); + + /* Main preprocessor loop, handles include files */ + + do + { + PrPreprocessInputFile (); + MoreInputFiles = PrPopInputFileStack (); + + } while (MoreInputFiles); + + + /* + * TBD: is this necessary? (Do we abort on any preprocessing errors?) + */ + if (Gbl_PreprocessorError) + { + /* TBD: can't use source_output file for preprocessor error reporting */ + + Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle = NULL; + PrTerminatePreprocessor (); + return (TRUE); + } + + /* Point compiler input to the new preprocessor file (.i) */ + + FlCloseFile (ASL_FILE_INPUT); + Gbl_Files[ASL_FILE_INPUT].Handle = Gbl_Files[ASL_FILE_PREPROCESSOR].Handle; + AslCompilerin = Gbl_Files[ASL_FILE_INPUT].Handle; + + /* Reset globals to allow compiler to run */ + + FlSeekFile (ASL_FILE_INPUT, 0); + Gbl_CurrentLineNumber = 1; + + DbgPrint (ASL_DEBUG_OUTPUT, "Preprocessing phase complete \n\n"); + return (FALSE); +} + + +/******************************************************************************* + * + * FUNCTION: PrPreprocessInputFile + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Preprocess one entire file, line-by-line. + * + * Input: Raw user ASL from ASL_FILE_INPUT + * Output: Preprocessed file written to ASL_FILE_PREPROCESSOR + * + ******************************************************************************/ + +static void +PrPreprocessInputFile ( + void) +{ + UINT32 Offset; + char *Token; + char *ReplaceString; + PR_DEFINE_INFO *DefineInfo; + ACPI_SIZE TokenOffset; + BOOLEAN IgnoringThisCodeBlock = FALSE; + char *Next; + int OffsetAdjust; + + + /* Scan line-by-line. Comments and blank lines are skipped by this function */ + + while ((Offset = DtGetNextLine (Gbl_Files[ASL_FILE_INPUT].Handle)) != ASL_EOF) + { + /* Need a copy of the input line for strok() */ + + strcpy (Gbl_MainTokenBuffer, Gbl_CurrentLineBuffer); + Token = PrGetNextToken (Gbl_MainTokenBuffer, PR_TOKEN_SEPARATORS, &Next); + OffsetAdjust = 0; + + /* All preprocessor directives must begin with '#' */ + + if (Token && (*Token == '#')) + { + if (strlen (Token) == 1) + { + Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next); + } + else + { + Token++; /* Skip leading # */ + } + + /* Execute the directive, do not write line to output file */ + + PrDoDirective (Token, &Next, &IgnoringThisCodeBlock); + continue; + } + + /* + * If we are currently within the part of an IF/ELSE block that is + * FALSE, ignore the line and do not write it to the output file. + * This continues until an #else or #endif is encountered. + */ + if (IgnoringThisCodeBlock == TRUE) + { + continue; + } + + /* Match and replace all #defined names within this source line */ + + while (Token) + { + DefineInfo = PrMatchDefine (Token); + if (DefineInfo) + { + if (DefineInfo->Body) + { + /* This is a macro */ + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "Matched Macro: %s->%s\n", + Gbl_CurrentLineNumber, DefineInfo->Identifier, + DefineInfo->Replacement); + + PrDoMacroInvocation (Gbl_MainTokenBuffer, Token, + DefineInfo, &Next); + } + else + { + ReplaceString = DefineInfo->Replacement; + + /* Replace the name in the original line buffer */ + + TokenOffset = Token - Gbl_MainTokenBuffer + OffsetAdjust; + PrReplaceData ( + &Gbl_CurrentLineBuffer[TokenOffset], strlen (Token), + ReplaceString, strlen (ReplaceString)); + + /* Adjust for length difference between old and new name length */ + + OffsetAdjust += strlen (ReplaceString) - strlen (Token); + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "Matched #define: %s->%s\n", + Gbl_CurrentLineNumber, Token, + *ReplaceString ? ReplaceString : "(NULL STRING)"); + } + } + + Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next); + } + + /* Write the possibly modified line to the .i file*/ + +#if 0 +/* Line prefix */ + FlPrintFile (ASL_FILE_PREPROCESSOR, "/* %14s %.5u i:%.5u */ ", + Gbl_Files[ASL_FILE_INPUT].Filename, + Gbl_CurrentLineNumber, Gbl_PreprocessorLineNumber); +#endif + + FlWriteFile (ASL_FILE_PREPROCESSOR, Gbl_CurrentLineBuffer, + strlen (Gbl_CurrentLineBuffer)); + + PrSetLineNumber (Gbl_CurrentLineNumber, Gbl_PreprocessorLineNumber); + Gbl_PreprocessorLineNumber++; + } +} + + +/******************************************************************************* + * + * FUNCTION: PrDoDirective + * + * PARAMETERS: Directive - Pointer to directive name token + * Next - "Next" buffer from GetNextToken + * IgnoringThisCodeBlock - Where the "ignore code" flag is + * returned. + * + * RETURN: IgnoringThisCodeBlock: Set to TRUE if we are skipping the FALSE + * part of an #if or #else block. Set to FALSE when the + * corresponding #else or #endif is encountered. + * + * DESCRIPTION: Main processing for all preprocessor directives + * + ******************************************************************************/ + +static void +PrDoDirective ( + char *DirectiveToken, + char **Next, + BOOLEAN *IgnoringThisCodeBlock) +{ + char *Token = Gbl_MainTokenBuffer; + char *Token2; + char *End; + UINT64 Value; + ACPI_SIZE TokenOffset; + int Directive; + ACPI_STATUS Status; + + + if (!DirectiveToken) + { + goto SyntaxError; + } + + Directive = PrMatchDirective (DirectiveToken); + if (Directive == ASL_DIRECTIVE_NOT_FOUND) + { + PrError (ASL_ERROR, ASL_MSG_UNKNOWN_DIRECTIVE, + THIS_TOKEN_OFFSET (DirectiveToken)); + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "#%s: Unknown directive\n", + Gbl_CurrentLineNumber, DirectiveToken); + return; + } + + /* TBD: Need a faster way to do this: */ + + if ((Directive == PR_DIRECTIVE_ELIF) || + (Directive == PR_DIRECTIVE_ELSE) || + (Directive == PR_DIRECTIVE_ENDIF)) + { + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Begin #%s\n", + Gbl_CurrentLineNumber, Gbl_DirectiveInfo[Directive].Name); + } + + /* + * Need to always check for #else, #elif, #endif regardless of + * whether we are ignoring the current code block, since these + * are conditional code block terminators. + */ + switch (Directive) + { + case PR_DIRECTIVE_ELIF: + *IgnoringThisCodeBlock = !(*IgnoringThisCodeBlock); + if (*IgnoringThisCodeBlock == TRUE) + { + /* Not executing the ELSE part -- all done here */ + return; + } + + /* Will execute the ELSE..IF part */ + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "#elif - Executing else block\n", + Gbl_CurrentLineNumber); + Directive = PR_DIRECTIVE_IF; + break; + + case PR_DIRECTIVE_ELSE: + *IgnoringThisCodeBlock = !(*IgnoringThisCodeBlock); + return; + + case PR_DIRECTIVE_ENDIF: + *IgnoringThisCodeBlock = FALSE; + Gbl_IfDepth--; + if (Gbl_IfDepth < 0) + { + PrError (ASL_ERROR, ASL_MSG_ENDIF_MISMATCH, + THIS_TOKEN_OFFSET (DirectiveToken)); + Gbl_IfDepth = 0; + } + return; + + default: + break; + } + + /* + * At this point, if we are ignoring the current code block, + * do not process any more directives (i.e., ignore them also.) + */ + if (*IgnoringThisCodeBlock == TRUE) + { + return; + } + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Begin #%s\n", + Gbl_CurrentLineNumber, Gbl_DirectiveInfo[Directive].Name); + + /* Most directives have at least one argument */ + + if (Gbl_DirectiveInfo[Directive].ArgCount == 1) + { + Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); + if (!Token) + { + goto SyntaxError; + } + } + + switch (Directive) + { + case PR_DIRECTIVE_DEFINE: + /* + * By definition, if first char after the name is a paren, + * this is a function macro. + */ + TokenOffset = Token - Gbl_MainTokenBuffer + strlen (Token); + if (*(&Gbl_CurrentLineBuffer[TokenOffset]) == '(') + { +#ifndef MACROS_SUPPORTED + AcpiOsPrintf ("#define macros not supported\n"); + goto SyntaxError; +#else + PrAddMacro (Token, Next); +#endif + } + else + { + /* Use the remainder of the line for the #define */ + + Token2 = *Next; + if (Token2) + { + while ((*Token2 == ' ') || (*Token2 == '\t')) + { + Token2++; + } + End = Token2; + while (*End != '\n') + { + End++; + } + *End = 0; + } + else + { + Token2 = ""; + } +#if 0 + Token2 = PrGetNextToken (NULL, "\n", /*PR_TOKEN_SEPARATORS,*/ Next); + if (!Token2) + { + Token2 = ""; + } +#endif + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "New #define: %s->%s\n", + Gbl_CurrentLineNumber, Token, Token2); + + PrAddDefine (Token, Token2, FALSE); + } + break; + + case PR_DIRECTIVE_ERROR: + /* TBD compiler should abort */ + /* Note: No macro expansion */ + + PrError (ASL_ERROR, ASL_MSG_ERROR_DIRECTIVE, + THIS_TOKEN_OFFSET (Token)); + break; + + case PR_DIRECTIVE_IF: + TokenOffset = Token - Gbl_MainTokenBuffer; + + /* Need to expand #define macros in the expression string first */ + + Status = PrResolveIntegerExpression ( + &Gbl_CurrentLineBuffer[TokenOffset-1], &Value); + if (ACPI_FAILURE (Status)) + { + return; + } + + if (!Value) + { + *IgnoringThisCodeBlock = TRUE; + } + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "Resolved #if: %8.8X%8.8X %s\n", + Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Value), + *IgnoringThisCodeBlock ? "" : ""); + + Gbl_IfDepth++; + break; + + case PR_DIRECTIVE_IFDEF: + if (!PrMatchDefine (Token)) + { + *IgnoringThisCodeBlock = TRUE; + } + + Gbl_IfDepth++; + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "Start #ifdef %s\n", Gbl_CurrentLineNumber, + *IgnoringThisCodeBlock ? "" : ""); + break; + + case PR_DIRECTIVE_IFNDEF: + if (PrMatchDefine (Token)) + { + *IgnoringThisCodeBlock = TRUE; + } + + Gbl_IfDepth++; + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "Start #ifndef %2.2X\n", Gbl_CurrentLineNumber, + *IgnoringThisCodeBlock, Gbl_CurrentLineNumber); + break; + + case PR_DIRECTIVE_INCLUDE: + Token = PrGetNextToken (NULL, " \"<>", Next); + if (!Token) + { + goto SyntaxError; + } + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "Start #include file %s\n", Gbl_CurrentLineNumber, + Token, Gbl_CurrentLineNumber); + + PrOpenIncludeFile (Token); + break; + + case PR_DIRECTIVE_PRAGMA: + /* Only "#pragma message" supported at this time */ + + if (strcmp (Token, "message")) + { + PrError (ASL_ERROR, ASL_MSG_UNKNOWN_PRAGMA, + THIS_TOKEN_OFFSET (Token)); + return; + } + + Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); + if (!Token) + { + goto SyntaxError; + } + + TokenOffset = Token - Gbl_MainTokenBuffer; + AcpiOsPrintf ("%s\n", &Gbl_CurrentLineBuffer[TokenOffset]); + break; + + case PR_DIRECTIVE_UNDEF: + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "#undef: %s\n", Gbl_CurrentLineNumber, Token); + + PrRemoveDefine (Token); + break; + + case PR_DIRECTIVE_WARNING: + PrError (ASL_WARNING, ASL_MSG_ERROR_DIRECTIVE, + THIS_TOKEN_OFFSET (Token)); + break; + + case PR_DIRECTIVE_LINE: + /* TBD: set line number -- or, do this in main compiler */ + default: + /* Should never get here */ + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "Unrecognized directive: %u\n", + Gbl_CurrentLineNumber, Directive); + break; + } + + return; + + +SyntaxError: + + PrError (ASL_ERROR, ASL_MSG_DIRECTIVE_SYNTAX, + THIS_TOKEN_OFFSET (DirectiveToken)); + return; +} + + +/******************************************************************************* + * + * FUNCTION: PrMatchDirective + * + * PARAMETERS: Directive - Pointer to directive name token + * + * RETURN: Index into command array, -1 if not found + * + * DESCRIPTION: Lookup the incoming directive in the known directives table. + * + ******************************************************************************/ + +static int +PrMatchDirective ( + char *Directive) +{ + int i; + + + if (!Directive || Directive[0] == 0) + { + return (ASL_DIRECTIVE_NOT_FOUND); + } + + for (i = 0; Gbl_DirectiveInfo[i].Name; i++) + { + if (!strcmp (Gbl_DirectiveInfo[i].Name, Directive)) + { + return (i); + } + } + + return (ASL_DIRECTIVE_NOT_FOUND); /* Command not recognized */ +} diff --git a/source/compiler/prutils.c b/source/compiler/prutils.c new file mode 100644 index 000000000000..70a2edc605cc --- /dev/null +++ b/source/compiler/prutils.c @@ -0,0 +1,550 @@ +/****************************************************************************** + * + * Module Name: prutils - Preprocessor utilities + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "aslcompiler.h" +#include "dtcompiler.h" + + +#define _COMPONENT ASL_PREPROCESSOR + ACPI_MODULE_NAME ("prutils") + + +/******************************************************************************* + * + * FUNCTION: PrSetLineNumber + * + * PARAMETERS: OriginalLineNumber - Line number in original source file, + * or include file + * PreprocessorLineNumber - Line number in the preprocessed file + * + * RETURN: None + * + * DESCRIPTION: Insert this mapping into the mapping data structure, for use + * in possible error/warning messages. + * + * Line number mapping functions. + * For error messages, we need to keep track of the line number in the + * original file, versus the preprocessed (.i) file. + * + ******************************************************************************/ + +void +PrSetLineNumber ( + UINT32 OriginalLineNumber, + UINT32 PreprocessorLineNumber) +{ + UINT32 Entry; + PR_LINE_MAPPING *Block; + UINT32 Index; + UINT32 i; + + + Entry = PreprocessorLineNumber / PR_LINES_PER_BLOCK; + Index = PreprocessorLineNumber % PR_LINES_PER_BLOCK; + Block = Gbl_MapBlockHead; + + for (i = 0; i < Entry; i++) + { + /* Allocate new mapping blocks as necessary */ + + if (!Block->Next) + { + Block->Next = UtLocalCalloc (sizeof (PR_LINE_MAPPING)); + Block->Next->Map = UtLocalCalloc (PR_LINES_PER_BLOCK * sizeof (UINT32)); + } + + Block = Block->Next; + } + + Block->Map[Index] = OriginalLineNumber; +} + + +/******************************************************************************* + * + * FUNCTION: PrGetLineNumber + * + * PARAMETERS: PreprocessorLineNumber - Line number in the preprocessed file + * (or, the "logical line number) + * + * RETURN: The line number in the original source file or include file. + * + * DESCRIPTION: Return the mapped value of a line number in the preprocessed + * source file to the actual line number in the original source + * file. + * + ******************************************************************************/ + +UINT32 +PrGetLineNumber ( + UINT32 PreprocessorLineNumber) +{ + UINT32 Entry; + PR_LINE_MAPPING *Block; + UINT32 Index; + UINT32 i; + + + Entry = PreprocessorLineNumber / PR_LINES_PER_BLOCK; + Index = PreprocessorLineNumber % PR_LINES_PER_BLOCK; + Block = Gbl_MapBlockHead; + + for (i = 0; i < Entry; i++) + { + Block = Block->Next; + if (!Block) + { + /* Bad error, should not happen */ + return (0); + } + } + + return (Block->Map[Index]); +} + + +/****************************************************************************** + * + * FUNCTION: PrGetNextToken + * + * PARAMETERS: Buffer - Current line buffer + * MatchString - String with valid token delimiters + * Next - Set to next possible token in buffer + * + * RETURN: Next token (null-terminated). Modifies the input line. + * Remainder of line is stored in *Next. + * + * DESCRIPTION: Local implementation of strtok() with local storage for the + * next pointer. Not only thread-safe, but allows multiple + * parsing of substrings such as expressions. + * + *****************************************************************************/ + +char * +PrGetNextToken ( + char *Buffer, + char *MatchString, + char **Next) +{ + char *TokenStart; + + + if (!Buffer) + { + /* Use Next if it is valid */ + + Buffer = *Next; + if (!(*Next)) + { + return (NULL); + } + } + + /* Skip any leading delimiters */ + + while (*Buffer) + { + if (strchr (MatchString, *Buffer)) + { + Buffer++; + } + else + { + break; + } + } + + /* Anything left on the line? */ + + if (!(*Buffer)) + { + *Next = NULL; + return (NULL); + } + + TokenStart = Buffer; + + /* Find the end of this token */ + + while (*Buffer) + { + if (strchr (MatchString, *Buffer)) + { + *Buffer = 0; + *Next = Buffer+1; + if (!**Next) + { + *Next = NULL; + } + return (TokenStart); + } + Buffer++; + } + + *Next = NULL; + return (TokenStart); +} + + +/******************************************************************************* + * + * FUNCTION: PrError + * + * PARAMETERS: Level - Seriousness (Warning/error, etc.) + * MessageId - Index into global message buffer + * Column - Column in current line + * + * RETURN: None + * + * DESCRIPTION: Preprocessor error reporting. Front end to AslCommonError2 + * + ******************************************************************************/ + +void +PrError ( + UINT8 Level, + UINT8 MessageId, + UINT32 Column) +{ +#if 0 + AcpiOsPrintf ("%s (%u) : %s", Gbl_Files[ASL_FILE_INPUT].Filename, + Gbl_CurrentLineNumber, Gbl_CurrentLineBuffer); +#endif + + + if (Column > 120) + { + Column = 0; + } + + /* TBD: Need Logical line number? */ + + AslCommonError2 (Level, MessageId, + Gbl_CurrentLineNumber, Column, + Gbl_CurrentLineBuffer, + Gbl_Files[ASL_FILE_INPUT].Filename, "Preprocessor"); + + Gbl_PreprocessorError = TRUE; +} + + +/******************************************************************************* + * + * FUNCTION: PrReplaceData + * + * PARAMETERS: Buffer - Original(target) buffer pointer + * LengthToRemove - Length to be removed from target buffer + * BufferToAdd - Data to be inserted into target buffer + * LengthToAdd - Length of BufferToAdd + * + * RETURN: None + * + * DESCRIPTION: Generic buffer data replacement. + * + ******************************************************************************/ + +void +PrReplaceData ( + char *Buffer, + UINT32 LengthToRemove, + char *BufferToAdd, + UINT32 LengthToAdd) +{ + UINT32 BufferLength; + + + /* Buffer is a string, so the length must include the terminating zero */ + + BufferLength = strlen (Buffer) + 1; + + if (LengthToRemove != LengthToAdd) + { + /* + * Move some of the existing data + * 1) If adding more bytes than removing, make room for the new data + * 2) if removing more bytes than adding, delete the extra space + */ + if (LengthToRemove > 0) + { + memmove ((Buffer + LengthToAdd), (Buffer + LengthToRemove), + (BufferLength - LengthToRemove)); + } + } + + /* Now we can move in the new data */ + + if (LengthToAdd > 0) + { + memmove (Buffer, BufferToAdd, LengthToAdd); + } +} + + +/******************************************************************************* + * + * FUNCTION: PrOpenIncludeFile + * + * PARAMETERS: Filename - Filename or pathname for include file + * + * RETURN: None. + * + * DESCRIPTION: Open an include file and push it on the input file stack. + * + ******************************************************************************/ + +void +PrOpenIncludeFile ( + char *Filename) +{ + FILE *IncludeFile; + ASL_INCLUDE_DIR *NextDir; + + + /* + * start the actual include file on the next line + */ + Gbl_CurrentLineOffset++; + + /* Attempt to open the include file */ + + /* If the file specifies an absolute path, just open it */ + + if ((Filename[0] == '/') || + (Filename[0] == '\\') || + (Filename[1] == ':')) + { + IncludeFile = PrOpenIncludeWithPrefix ("", Filename); + if (!IncludeFile) + { + goto ErrorExit; + } + return; + } + + /* + * The include filename is not an absolute path. + * + * First, search for the file within the "local" directory -- meaning + * the same directory that contains the source file. + * + * Construct the file pathname from the global directory name. + */ + IncludeFile = PrOpenIncludeWithPrefix (Gbl_DirectoryPath, Filename); + if (IncludeFile) + { + return; + } + + /* + * Second, search for the file within the (possibly multiple) + * directories specified by the -I option on the command line. + */ + NextDir = Gbl_IncludeDirList; + while (NextDir) + { + IncludeFile = PrOpenIncludeWithPrefix (NextDir->Dir, Filename); + if (IncludeFile) + { + return; + } + + NextDir = NextDir->Next; + } + + /* We could not open the include file after trying very hard */ + +ErrorExit: + sprintf (Gbl_MainTokenBuffer, "%s, %s", Filename, strerror (errno)); + PrError (ASL_ERROR, ASL_MSG_INCLUDE_FILE_OPEN, 0); +} + + +/******************************************************************************* + * + * FUNCTION: FlOpenIncludeWithPrefix + * + * PARAMETERS: PrefixDir - Prefix directory pathname. Can be a zero + * length string. + * Filename - The include filename from the source ASL. + * + * RETURN: Valid file descriptor if successful. Null otherwise. + * + * DESCRIPTION: Open an include file and push it on the input file stack. + * + ******************************************************************************/ + +FILE * +PrOpenIncludeWithPrefix ( + char *PrefixDir, + char *Filename) +{ + FILE *IncludeFile; + char *Pathname; + + + /* Build the full pathname to the file */ + + Pathname = ACPI_ALLOCATE (strlen (PrefixDir) + strlen (Filename) + 1); + + strcpy (Pathname, PrefixDir); + strcat (Pathname, Filename); + + DbgPrint (ASL_PARSE_OUTPUT, "\n" PR_PREFIX_ID + "Opening include file: path %s\n", + Gbl_CurrentLineNumber, Pathname); + + /* Attempt to open the file, push if successful */ + + IncludeFile = fopen (Pathname, "r"); + if (IncludeFile) + { + /* Push the include file on the open input file stack */ + + PrPushInputFileStack (IncludeFile, Pathname); + return (IncludeFile); + } + + ACPI_FREE (Pathname); + return (NULL); +} + + +/******************************************************************************* + * + * FUNCTION: AslPushInputFileStack + * + * PARAMETERS: InputFile - Open file pointer + * Filename - Name of the file + * + * RETURN: None + * + * DESCRIPTION: Push the InputFile onto the file stack, and point the parser + * to this file. Called when an include file is successfully + * opened. + * + ******************************************************************************/ + +void +PrPushInputFileStack ( + FILE *InputFile, + char *Filename) +{ + PR_FILE_NODE *Fnode; + + + /* Save the current state in an Fnode */ + + Fnode = UtLocalCalloc (sizeof (PR_FILE_NODE)); + + Fnode->File = Gbl_Files[ASL_FILE_INPUT].Handle; + Fnode->Next = Gbl_InputFileList; + Fnode->Filename = Gbl_Files[ASL_FILE_INPUT].Filename; + Fnode->CurrentLineNumber = Gbl_CurrentLineNumber; + + /* Push it on the stack */ + + Gbl_InputFileList = Fnode; + + DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID + "Push InputFile Stack, returning %p\n\n", + Gbl_CurrentLineNumber, InputFile); + + /* Reset the global line count and filename */ + + Gbl_Files[ASL_FILE_INPUT].Filename = Filename; + Gbl_Files[ASL_FILE_INPUT].Handle = InputFile; + Gbl_CurrentLineNumber = 1; +} + + +/******************************************************************************* + * + * FUNCTION: AslPopInputFileStack + * + * PARAMETERS: None + * + * RETURN: 0 if a node was popped, -1 otherwise + * + * DESCRIPTION: Pop the top of the input file stack and point the parser to + * the saved parse buffer contained in the fnode. Also, set the + * global line counters to the saved values. This function is + * called when an include file reaches EOF. + * + ******************************************************************************/ + +BOOLEAN +PrPopInputFileStack ( + void) +{ + PR_FILE_NODE *Fnode; + + + Fnode = Gbl_InputFileList; + DbgPrint (ASL_PARSE_OUTPUT, "\n" PR_PREFIX_ID + "Pop InputFile Stack, Fnode %p\n\n", + Gbl_CurrentLineNumber, Fnode); + + if (!Fnode) + { + return (FALSE); + } + + /* Close the current include file */ + + fclose (Gbl_Files[ASL_FILE_INPUT].Handle); + + /* Update the top-of-stack */ + + Gbl_InputFileList = Fnode->Next; + + /* Reset global line counter and filename */ + + Gbl_Files[ASL_FILE_INPUT].Filename = Fnode->Filename; + Gbl_Files[ASL_FILE_INPUT].Handle = Fnode->File; + Gbl_CurrentLineNumber = Fnode->CurrentLineNumber; + + /* All done with this node */ + + ACPI_FREE (Fnode); + return (TRUE); +} diff --git a/source/compiler/readme.txt b/source/compiler/readme.txt index fceea472e57d..882993b6bc9e 100644 --- a/source/compiler/readme.txt +++ b/source/compiler/readme.txt @@ -1,7 +1,8 @@ -Instructions for integrating iASL compiler into MS VC++ 6.0 environment. +Instructions for integrating iASL compiler into MS VC++ environment. -Part 1. Integration as a custom tool +1a) Integration as a custom tool +------------------------------- This procedure adds the iASL compiler as a custom tool that can be used to compile ASL source files. The output is sent to the VC output @@ -38,7 +39,8 @@ automatically displayed by VC. Also, you can use F4 to step through the messages and the corresponding source line(s). -Part 2. Integration into a project build +1b) Integration into a project build +------------------------------------ This procedure creates a project that compiles ASL files to AML. @@ -55,24 +57,49 @@ $(InputDir)\$(InputPath).aml -Compiler Generation From Source +2) Compiler Generation From Source +------------------------------- Generation of the ASL compiler from source code requires these items: -Required Tools +2a) Required Tools +-------------- + 1) The Flex (or Lex) lexical analyzer generator. 2) The Bison (or Yacc) parser generator. 3) An ANSI C compiler. -Required Source Code. +Windows GNU Flex and GNU Bison Notes: + +GNU Flex/Bison must be installed in a directory that has no embedded +spaces in the name. They cannot be installed in the default +c:\"Program Files" directory. This is a bug in Bison. The default +Windows project file for iASL assumes that these tools are +installed at c:\GnuWin32. + +When installed, ensure that c:\GnuWin32\bin is added to the default +system $PATH environment variable. + +iASL has been generated with these versions on Windows: + + Flex for Windows: V2.5.4 + Bison for Windows: V2.4.1 + + +Flex is available at: http://gnuwin32.sourceforge.net/packages/flex.htm +Bison is available at: http://gnuwin32.sourceforge.net/packages/bison.htm + + +2b) Required Source Code +-------------------- There are three major source code components that are required to generate the compiler: 1) The ASL compiler source. -2) The ACPI CA Core Subsystem source. In particular, the Namespace Manager +2) The ACPICA Core Subsystem source. In particular, the Namespace Manager component is used to create an internal ACPI namespace and symbol table, and the AML Interpreter is used to evaluate constant expressions. 3) The Common source for all ACPI components. diff --git a/source/components/debugger/dbcmds.c b/source/components/debugger/dbcmds.c index cf214a161c07..ba6181bb39a0 100644 --- a/source/components/debugger/dbcmds.c +++ b/source/components/debugger/dbcmds.c @@ -174,14 +174,14 @@ AcpiDbSleep ( } AcpiOsPrintf ("**** Going to sleep ****\n"); - Status = AcpiEnterSleepState (SleepState); + Status = AcpiEnterSleepState (SleepState, ACPI_NO_OPTIONAL_METHODS); if (ACPI_FAILURE (Status)) { goto ErrorExit; } AcpiOsPrintf ("**** Prepare to return from sleep ****\n"); - Status = AcpiLeaveSleepStatePrep (SleepState); + Status = AcpiLeaveSleepStatePrep (SleepState, ACPI_NO_OPTIONAL_METHODS); if (ACPI_FAILURE (Status)) { goto ErrorExit; diff --git a/source/components/hardware/hwesleep.c b/source/components/hardware/hwesleep.c index e95647e5cd19..ce7b792dbb6d 100644 --- a/source/components/hardware/hwesleep.c +++ b/source/components/hardware/hwesleep.c @@ -53,7 +53,7 @@ * * FUNCTION: AcpiHwExecuteSleepMethod * - * PARAMETERS: MethodName - Pathname of method to execute + * PARAMETERS: MethodPathname - Pathname of method to execute * IntegerArgument - Argument to pass to the method * * RETURN: None @@ -65,7 +65,7 @@ void AcpiHwExecuteSleepMethod ( - char *MethodName, + char *MethodPathname, UINT32 IntegerArgument) { ACPI_OBJECT_LIST ArgList; @@ -83,11 +83,11 @@ AcpiHwExecuteSleepMethod ( Arg.Type = ACPI_TYPE_INTEGER; Arg.Integer.Value = (UINT64) IntegerArgument; - Status = AcpiEvaluateObject (NULL, MethodName, &ArgList, NULL); + Status = AcpiEvaluateObject (NULL, MethodPathname, &ArgList, NULL); if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) { ACPI_EXCEPTION ((AE_INFO, Status, "While executing method %s", - MethodName)); + MethodPathname)); } return_VOID; @@ -99,6 +99,7 @@ AcpiHwExecuteSleepMethod ( * FUNCTION: AcpiHwExtendedSleep * * PARAMETERS: SleepState - Which sleep state to enter + * Flags - ACPI_EXECUTE_GTS to run optional method * * RETURN: Status * @@ -110,7 +111,8 @@ AcpiHwExecuteSleepMethod ( ACPI_STATUS AcpiHwExtendedSleep ( - UINT8 SleepState) + UINT8 SleepState, + UINT8 Flags) { ACPI_STATUS Status; UINT8 SleepTypeValue; @@ -138,9 +140,12 @@ AcpiHwExtendedSleep ( AcpiGbl_SystemAwakeAndRunning = FALSE; - /* Execute the _GTS method (Going To Sleep) */ + /* Optionally execute _GTS (Going To Sleep) */ - AcpiHwExecuteSleepMethod (METHOD_NAME__GTS, SleepState); + if (Flags & ACPI_EXECUTE_GTS) + { + AcpiHwExecuteSleepMethod (METHOD_PATHNAME__GTS, SleepState); + } /* Flush caches, as per ACPI specification */ @@ -186,6 +191,7 @@ AcpiHwExtendedSleep ( * FUNCTION: AcpiHwExtendedWakePrep * * PARAMETERS: SleepState - Which sleep state we just exited + * Flags - ACPI_EXECUTE_BFS to run optional method * * RETURN: Status * @@ -196,7 +202,8 @@ AcpiHwExtendedSleep ( ACPI_STATUS AcpiHwExtendedWakePrep ( - UINT8 SleepState) + UINT8 SleepState, + UINT8 Flags) { ACPI_STATUS Status; UINT8 SleepTypeValue; @@ -216,7 +223,12 @@ AcpiHwExtendedWakePrep ( &AcpiGbl_FADT.SleepControl); } - AcpiHwExecuteSleepMethod (METHOD_NAME__BFS, SleepState); + /* Optionally execute _BFS (Back From Sleep) */ + + if (Flags & ACPI_EXECUTE_BFS) + { + AcpiHwExecuteSleepMethod (METHOD_PATHNAME__BFS, SleepState); + } return_ACPI_STATUS (AE_OK); } @@ -226,6 +238,7 @@ AcpiHwExtendedWakePrep ( * FUNCTION: AcpiHwExtendedWake * * PARAMETERS: SleepState - Which sleep state we just exited + * Flags - Reserved, set to zero * * RETURN: Status * @@ -236,7 +249,8 @@ AcpiHwExtendedWakePrep ( ACPI_STATUS AcpiHwExtendedWake ( - UINT8 SleepState) + UINT8 SleepState, + UINT8 Flags) { ACPI_FUNCTION_TRACE (HwExtendedWake); @@ -247,8 +261,8 @@ AcpiHwExtendedWake ( /* Execute the wake methods */ - AcpiHwExecuteSleepMethod (METHOD_NAME__SST, ACPI_SST_WAKING); - AcpiHwExecuteSleepMethod (METHOD_NAME__WAK, SleepState); + AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, ACPI_SST_WAKING); + AcpiHwExecuteSleepMethod (METHOD_PATHNAME__WAK, SleepState); /* * Some BIOS code assumes that WAK_STS will be cleared on resume @@ -258,6 +272,6 @@ AcpiHwExtendedWake ( (void) AcpiWrite (ACPI_X_WAKE_STATUS, &AcpiGbl_FADT.SleepStatus); AcpiGbl_SystemAwakeAndRunning = TRUE; - AcpiHwExecuteSleepMethod (METHOD_NAME__SST, ACPI_SST_WORKING); + AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, ACPI_SST_WORKING); return_ACPI_STATUS (AE_OK); } diff --git a/source/components/hardware/hwsleep.c b/source/components/hardware/hwsleep.c index 0d311435555a..1953ff846e80 100644 --- a/source/components/hardware/hwsleep.c +++ b/source/components/hardware/hwsleep.c @@ -55,6 +55,7 @@ * FUNCTION: AcpiHwLegacySleep * * PARAMETERS: SleepState - Which sleep state to enter + * Flags - ACPI_EXECUTE_GTS to run optional method * * RETURN: Status * @@ -65,7 +66,8 @@ ACPI_STATUS AcpiHwLegacySleep ( - UINT8 SleepState) + UINT8 SleepState, + UINT8 Flags) { ACPI_BIT_REGISTER_INFO *SleepTypeRegInfo; ACPI_BIT_REGISTER_INFO *SleepEnableRegInfo; @@ -128,9 +130,12 @@ AcpiHwLegacySleep ( return_ACPI_STATUS (Status); } - /* Execute the _GTS method (Going To Sleep) */ + /* Optionally execute _GTS (Going To Sleep) */ - AcpiHwExecuteSleepMethod (METHOD_NAME__GTS, SleepState); + if (Flags & ACPI_EXECUTE_GTS) + { + AcpiHwExecuteSleepMethod (METHOD_PATHNAME__GTS, SleepState); + } /* Get current value of PM1A control */ @@ -228,6 +233,7 @@ AcpiHwLegacySleep ( * FUNCTION: AcpiHwLegacyWakePrep * * PARAMETERS: SleepState - Which sleep state we just exited + * Flags - ACPI_EXECUTE_BFS to run optional method * * RETURN: Status * @@ -239,7 +245,8 @@ AcpiHwLegacySleep ( ACPI_STATUS AcpiHwLegacyWakePrep ( - UINT8 SleepState) + UINT8 SleepState, + UINT8 Flags) { ACPI_STATUS Status; ACPI_BIT_REGISTER_INFO *SleepTypeRegInfo; @@ -289,7 +296,12 @@ AcpiHwLegacyWakePrep ( } } - AcpiHwExecuteSleepMethod (METHOD_NAME__BFS, SleepState); + /* Optionally execute _BFS (Back From Sleep) */ + + if (Flags & ACPI_EXECUTE_BFS) + { + AcpiHwExecuteSleepMethod (METHOD_PATHNAME__BFS, SleepState); + } return_ACPI_STATUS (Status); } @@ -299,6 +311,7 @@ AcpiHwLegacyWakePrep ( * FUNCTION: AcpiHwLegacyWake * * PARAMETERS: SleepState - Which sleep state we just exited + * Flags - Reserved, set to zero * * RETURN: Status * @@ -309,7 +322,8 @@ AcpiHwLegacyWakePrep ( ACPI_STATUS AcpiHwLegacyWake ( - UINT8 SleepState) + UINT8 SleepState, + UINT8 Flags) { ACPI_STATUS Status; @@ -320,7 +334,7 @@ AcpiHwLegacyWake ( /* Ensure EnterSleepStatePrep -> EnterSleepState ordering */ AcpiGbl_SleepTypeA = ACPI_SLEEP_TYPE_INVALID; - AcpiHwExecuteSleepMethod (METHOD_NAME__SST, ACPI_SST_WAKING); + AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, ACPI_SST_WAKING); /* * GPEs must be enabled before _WAK is called as GPEs @@ -346,7 +360,7 @@ AcpiHwLegacyWake ( * Now we can execute _WAK, etc. Some machines require that the GPEs * are enabled before the wake methods are executed. */ - AcpiHwExecuteSleepMethod (METHOD_NAME__WAK, SleepState); + AcpiHwExecuteSleepMethod (METHOD_PATHNAME__WAK, SleepState); /* * Some BIOS code assumes that WAK_STS will be cleared on resume @@ -377,7 +391,7 @@ AcpiHwLegacyWake ( return_ACPI_STATUS (Status); } - AcpiHwExecuteSleepMethod (METHOD_NAME__SST, ACPI_SST_WORKING); + AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, ACPI_SST_WORKING); return_ACPI_STATUS (Status); } diff --git a/source/components/hardware/hwxfsleep.c b/source/components/hardware/hwxfsleep.c index 39bf122a072e..b7cbbc813e65 100644 --- a/source/components/hardware/hwxfsleep.c +++ b/source/components/hardware/hwxfsleep.c @@ -52,6 +52,7 @@ static ACPI_STATUS AcpiHwSleepDispatch ( UINT8 SleepState, + UINT8 Flags, UINT32 FunctionId); /* @@ -252,6 +253,7 @@ ACPI_EXPORT_SYMBOL (AcpiEnterSleepStateS4bios) static ACPI_STATUS AcpiHwSleepDispatch ( UINT8 SleepState, + UINT8 Flags, UINT32 FunctionId) { ACPI_STATUS Status; @@ -267,13 +269,13 @@ AcpiHwSleepDispatch ( if (AcpiGbl_ReducedHardware || AcpiGbl_FADT.SleepControl.Address) { - Status = SleepFunctions->ExtendedFunction (SleepState); + Status = SleepFunctions->ExtendedFunction (SleepState, Flags); } else { /* Legacy sleep */ - Status = SleepFunctions->LegacyFunction (SleepState); + Status = SleepFunctions->LegacyFunction (SleepState, Flags); } return (Status); @@ -283,7 +285,7 @@ AcpiHwSleepDispatch ( * For the case where reduced-hardware-only code is being generated, * we know that only the extended sleep registers are available */ - Status = SleepFunctions->ExtendedFunction (SleepState); + Status = SleepFunctions->ExtendedFunction (SleepState, Flags); return (Status); #endif /* !ACPI_REDUCED_HARDWARE */ @@ -318,8 +320,6 @@ AcpiEnterSleepStatePrep ( ACPI_FUNCTION_TRACE (AcpiEnterSleepStatePrep); - /* _PSW methods could be run here to enable wake-on keyboard, LAN, etc. */ - Status = AcpiGetSleepTypeData (SleepState, &AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB); if (ACPI_FAILURE (Status)) @@ -334,7 +334,7 @@ AcpiEnterSleepStatePrep ( Arg.Type = ACPI_TYPE_INTEGER; Arg.Integer.Value = SleepState; - Status = AcpiEvaluateObject (NULL, METHOD_NAME__PTS, &ArgList, NULL); + Status = AcpiEvaluateObject (NULL, METHOD_PATHNAME__PTS, &ArgList, NULL); if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) { return_ACPI_STATUS (Status); @@ -367,7 +367,7 @@ AcpiEnterSleepStatePrep ( * Set the system indicators to show the desired sleep state. * _SST is an optional method (return no error if not found) */ - AcpiHwExecuteSleepMethod (METHOD_NAME__SST, SstValue); + AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, SstValue); return_ACPI_STATUS (AE_OK); } @@ -379,6 +379,7 @@ ACPI_EXPORT_SYMBOL (AcpiEnterSleepStatePrep) * FUNCTION: AcpiEnterSleepState * * PARAMETERS: SleepState - Which sleep state to enter + * Flags - ACPI_EXECUTE_GTS to run optional method * * RETURN: Status * @@ -389,7 +390,8 @@ ACPI_EXPORT_SYMBOL (AcpiEnterSleepStatePrep) ACPI_STATUS AcpiEnterSleepState ( - UINT8 SleepState) + UINT8 SleepState, + UINT8 Flags) { ACPI_STATUS Status; @@ -405,7 +407,7 @@ AcpiEnterSleepState ( return_ACPI_STATUS (AE_AML_OPERAND_VALUE); } - Status = AcpiHwSleepDispatch (SleepState, ACPI_SLEEP_FUNCTION_ID); + Status = AcpiHwSleepDispatch (SleepState, Flags, ACPI_SLEEP_FUNCTION_ID); return_ACPI_STATUS (Status); } @@ -417,6 +419,7 @@ ACPI_EXPORT_SYMBOL (AcpiEnterSleepState) * FUNCTION: AcpiLeaveSleepStatePrep * * PARAMETERS: SleepState - Which sleep state we are exiting + * Flags - ACPI_EXECUTE_BFS to run optional method * * RETURN: Status * @@ -429,7 +432,8 @@ ACPI_EXPORT_SYMBOL (AcpiEnterSleepState) ACPI_STATUS AcpiLeaveSleepStatePrep ( - UINT8 SleepState) + UINT8 SleepState, + UINT8 Flags) { ACPI_STATUS Status; @@ -437,7 +441,7 @@ AcpiLeaveSleepStatePrep ( ACPI_FUNCTION_TRACE (AcpiLeaveSleepStatePrep); - Status = AcpiHwSleepDispatch (SleepState, ACPI_WAKE_PREP_FUNCTION_ID); + Status = AcpiHwSleepDispatch (SleepState, Flags, ACPI_WAKE_PREP_FUNCTION_ID); return_ACPI_STATUS (Status); } @@ -467,7 +471,7 @@ AcpiLeaveSleepState ( ACPI_FUNCTION_TRACE (AcpiLeaveSleepState); - Status = AcpiHwSleepDispatch (SleepState, ACPI_WAKE_FUNCTION_ID); + Status = AcpiHwSleepDispatch (SleepState, 0, ACPI_WAKE_FUNCTION_ID); return_ACPI_STATUS (Status); } diff --git a/source/components/namespace/nsdump.c b/source/components/namespace/nsdump.c index edc16257d4dd..6b7c50577918 100644 --- a/source/components/namespace/nsdump.c +++ b/source/components/namespace/nsdump.c @@ -270,7 +270,21 @@ AcpiNsDumpOneObject ( if (!ObjDesc) { - /* No attached object, we are done */ + /* No attached object. Some types should always have an object */ + + switch (Type) + { + case ACPI_TYPE_INTEGER: + case ACPI_TYPE_PACKAGE: + case ACPI_TYPE_BUFFER: + case ACPI_TYPE_STRING: + case ACPI_TYPE_METHOD: + AcpiOsPrintf (""); + break; + + default: + break; + } AcpiOsPrintf ("\n"); return (AE_OK); diff --git a/source/components/namespace/nsdumpdv.c b/source/components/namespace/nsdumpdv.c index dde0a8d09abc..9d30886608a3 100644 --- a/source/components/namespace/nsdumpdv.c +++ b/source/components/namespace/nsdumpdv.c @@ -141,7 +141,7 @@ AcpiNsDumpRootDevices ( return; } - Status = AcpiGetHandle (NULL, ACPI_NS_SYSTEM_BUS, &SysBusHandle); + Status = AcpiGetHandle (NULL, METHOD_NAME__SB_, &SysBusHandle); if (ACPI_FAILURE (Status)) { return; diff --git a/source/components/namespace/nspredef.c b/source/components/namespace/nspredef.c index 19662680125c..3a61aa3666e8 100644 --- a/source/components/namespace/nspredef.c +++ b/source/components/namespace/nspredef.c @@ -681,7 +681,7 @@ AcpiNsCheckPackage ( { /* Create the new outer package and populate it */ - Status = AcpiNsRepairPackageList (Data, ReturnObjectPtr); + Status = AcpiNsWrapWithPackage (Data, *Elements, ReturnObjectPtr); if (ACPI_FAILURE (Status)) { return (Status); diff --git a/source/components/namespace/nsrepair.c b/source/components/namespace/nsrepair.c index d820834e881e..06898a31e41c 100644 --- a/source/components/namespace/nsrepair.c +++ b/source/components/namespace/nsrepair.c @@ -74,11 +74,10 @@ * Buffer -> String * Buffer -> Package of Integers * Package -> Package of one Package + * An incorrect standalone object is wrapped with required outer package * * Additional possible repairs: - * * Required package elements that are NULL replaced by Integer/String/Buffer - * Incorrect standalone package wrapped with required outer package * ******************************************************************************/ @@ -100,11 +99,6 @@ AcpiNsConvertToBuffer ( ACPI_OPERAND_OBJECT *OriginalObject, ACPI_OPERAND_OBJECT **ReturnObject); -static ACPI_STATUS -AcpiNsConvertToPackage ( - ACPI_OPERAND_OBJECT *OriginalObject, - ACPI_OPERAND_OBJECT **ReturnObject); - /******************************************************************************* * @@ -172,10 +166,24 @@ AcpiNsRepairObject ( } if (ExpectedBtypes & ACPI_RTYPE_PACKAGE) { - Status = AcpiNsConvertToPackage (ReturnObject, &NewObject); + /* + * A package is expected. We will wrap the existing object with a + * new package object. It is often the case that if a variable-length + * package is required, but there is only a single object needed, the + * BIOS will return that object instead of wrapping it with a Package + * object. Note: after the wrapping, the package will be validated + * for correct contents (expected object type or types). + */ + Status = AcpiNsWrapWithPackage (Data, ReturnObject, &NewObject); if (ACPI_SUCCESS (Status)) { - goto ObjectRepaired; + /* + * The original object just had its reference count + * incremented for being inserted into the new package. + */ + *ReturnObjectPtr = NewObject; /* New Package object */ + Data->Flags |= ACPI_OBJECT_REPAIRED; + return (AE_OK); } } @@ -188,24 +196,27 @@ AcpiNsRepairObject ( /* Object was successfully repaired */ - /* - * If the original object is a package element, we need to: - * 1. Set the reference count of the new object to match the - * reference count of the old object. - * 2. Decrement the reference count of the original object. - */ if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT) { - NewObject->Common.ReferenceCount = - ReturnObject->Common.ReferenceCount; - - if (ReturnObject->Common.ReferenceCount > 1) + /* + * The original object is a package element. We need to + * decrement the reference count of the original object, + * for removing it from the package. + * + * However, if the original object was just wrapped with a + * package object as part of the repair, we don't need to + * change the reference count. + */ + if (!(Data->Flags & ACPI_OBJECT_WRAPPED)) { - ReturnObject->Common.ReferenceCount--; + if (ReturnObject->Common.ReferenceCount > 1) + { + ReturnObject->Common.ReferenceCount--; + } } ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, - "%s: Converted %s to expected %s at index %u\n", + "%s: Converted %s to expected %s at Package index %u\n", Data->Pathname, AcpiUtGetObjectTypeName (ReturnObject), AcpiUtGetObjectTypeName (NewObject), PackageIndex)); } @@ -496,71 +507,6 @@ AcpiNsConvertToBuffer ( } -/******************************************************************************* - * - * FUNCTION: AcpiNsConvertToPackage - * - * PARAMETERS: OriginalObject - Object to be converted - * ReturnObject - Where the new converted object is returned - * - * RETURN: Status. AE_OK if conversion was successful. - * - * DESCRIPTION: Attempt to convert a Buffer object to a Package. Each byte of - * the buffer is converted to a single integer package element. - * - ******************************************************************************/ - -static ACPI_STATUS -AcpiNsConvertToPackage ( - ACPI_OPERAND_OBJECT *OriginalObject, - ACPI_OPERAND_OBJECT **ReturnObject) -{ - ACPI_OPERAND_OBJECT *NewObject; - ACPI_OPERAND_OBJECT **Elements; - UINT32 Length; - UINT8 *Buffer; - - - switch (OriginalObject->Common.Type) - { - case ACPI_TYPE_BUFFER: - - /* Buffer-to-Package conversion */ - - Length = OriginalObject->Buffer.Length; - NewObject = AcpiUtCreatePackageObject (Length); - if (!NewObject) - { - return (AE_NO_MEMORY); - } - - /* Convert each buffer byte to an integer package element */ - - Elements = NewObject->Package.Elements; - Buffer = OriginalObject->Buffer.Pointer; - - while (Length--) - { - *Elements = AcpiUtCreateIntegerObject ((UINT64) *Buffer); - if (!*Elements) - { - AcpiUtRemoveReference (NewObject); - return (AE_NO_MEMORY); - } - Elements++; - Buffer++; - } - break; - - default: - return (AE_AML_OPERAND_TYPE); - } - - *ReturnObject = NewObject; - return (AE_OK); -} - - /******************************************************************************* * * FUNCTION: AcpiNsRepairNullElement @@ -745,42 +691,43 @@ AcpiNsRemoveNullElements ( /******************************************************************************* * - * FUNCTION: AcpiNsRepairPackageList + * FUNCTION: AcpiNsWrapWithPackage * * PARAMETERS: Data - Pointer to validation data structure - * ObjDescPtr - Pointer to the object to repair. The new - * package object is returned here, - * overwriting the old object. + * OriginalObject - Pointer to the object to repair. + * ObjDescPtr - The new package object is returned here * * RETURN: Status, new object in *ObjDescPtr * - * DESCRIPTION: Repair a common problem with objects that are defined to return - * a variable-length Package of Packages. If the variable-length - * is one, some BIOS code mistakenly simply declares a single - * Package instead of a Package with one sub-Package. This - * function attempts to repair this error by wrapping a Package - * object around the original Package, creating the correct - * Package with one sub-Package. + * DESCRIPTION: Repair a common problem with objects that are defined to + * return a variable-length Package of sub-objects. If there is + * only one sub-object, some BIOS code mistakenly simply declares + * the single object instead of a Package with one sub-object. + * This function attempts to repair this error by wrapping a + * Package object around the original object, creating the + * correct and expected Package with one sub-object. * * Names that can be repaired in this manner include: - * _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS + * _ALR, _CSD, _HPX, _MLS, _PLD, _PRT, _PSS, _TRT, _TSS, + * _BCL, _DOD, _FIX, _Sx * ******************************************************************************/ ACPI_STATUS -AcpiNsRepairPackageList ( +AcpiNsWrapWithPackage ( ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT *OriginalObject, ACPI_OPERAND_OBJECT **ObjDescPtr) { ACPI_OPERAND_OBJECT *PkgObjDesc; - ACPI_FUNCTION_NAME (NsRepairPackageList); + ACPI_FUNCTION_NAME (NsWrapWithPackage); /* * Create the new outer package and populate it. The new package will - * have a single element, the lone subpackage. + * have a single element, the lone sub-object. */ PkgObjDesc = AcpiUtCreatePackageObject (1); if (!PkgObjDesc) @@ -788,15 +735,15 @@ AcpiNsRepairPackageList ( return (AE_NO_MEMORY); } - PkgObjDesc->Package.Elements[0] = *ObjDescPtr; + PkgObjDesc->Package.Elements[0] = OriginalObject; + + ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, + "%s: Wrapped %s with expected Package object\n", + Data->Pathname, AcpiUtGetObjectTypeName (OriginalObject))); /* Return the new object in the object pointer */ *ObjDescPtr = PkgObjDesc; - Data->Flags |= ACPI_OBJECT_REPAIRED; - - ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, - "%s: Repaired incorrectly formed Package\n", Data->Pathname)); - + Data->Flags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED; return (AE_OK); } diff --git a/source/components/namespace/nsutils.c b/source/components/namespace/nsutils.c index 3b07f83a9e33..43f734e81902 100644 --- a/source/components/namespace/nsutils.c +++ b/source/components/namespace/nsutils.c @@ -405,7 +405,7 @@ AcpiNsBuildInternalName ( if (!AcpiNsValidPathSeparator (*ExternalName) && (*ExternalName != 0)) { - return_ACPI_STATUS (AE_BAD_PARAMETER); + return_ACPI_STATUS (AE_BAD_PATHNAME); } /* Move on the next segment */ diff --git a/source/components/tables/tbfadt.c b/source/components/tables/tbfadt.c index ae4052099fe5..e8773204478c 100644 --- a/source/components/tables/tbfadt.c +++ b/source/components/tables/tbfadt.c @@ -400,10 +400,6 @@ AcpiTbConvertFadt ( UINT32 i; - /* Update the local FADT table header length */ - - AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT); - /* * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary. * Later code will always use the X 64-bit field. @@ -436,6 +432,13 @@ AcpiTbConvertFadt ( AcpiGbl_FADT.BootFlags = 0; } + /* + * Now we can update the local FADT length to the length of the + * current FADT version as defined by the ACPI specification. + * Thus, we will have a common FADT internally. + */ + AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT); + /* * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" * generic address structures as necessary. Later code will always use diff --git a/source/components/tables/tbinstal.c b/source/components/tables/tbinstal.c index 5c6bd876f819..f100ab43f721 100644 --- a/source/components/tables/tbinstal.c +++ b/source/components/tables/tbinstal.c @@ -510,8 +510,10 @@ AcpiTbDeleteTable ( ACPI_FREE (TableDesc->Pointer); break; + /* Not mapped or allocated, there is nothing we can do */ + default: - break; + return; } TableDesc->Pointer = NULL; diff --git a/source/components/tables/tbutils.c b/source/components/tables/tbutils.c index bfdcf0c29832..e8b5705e96e7 100644 --- a/source/components/tables/tbutils.c +++ b/source/components/tables/tbutils.c @@ -492,8 +492,9 @@ AcpiTbInstallTable ( * * NOTE: If the table is overridden, then FinalTable will contain a * mapped pointer to the full new table. If the table is not overridden, - * then the table will be fully mapped elsewhere (in verify table). - * In any case, we must unmap the header that was mapped above. + * or if there has been a physical override, then the table will be + * fully mapped later (in verify table). In any case, we must + * unmap the header that was mapped above. */ FinalTable = AcpiTbTableOverride (Table, TableDesc); if (!FinalTable) @@ -510,6 +511,20 @@ AcpiTbInstallTable ( AcpiUtSetIntegerWidth (FinalTable->Revision); } + /* + * If we have a physical override during this early loading of the ACPI + * tables, unmap the table for now. It will be mapped again later when + * it is actually used. This supports very early loading of ACPI tables, + * before virtual memory is fully initialized and running within the + * host OS. Note: A logical override has the ACPI_TABLE_ORIGIN_OVERRIDE + * flag set and will not be deleted below. + */ + if (FinalTable != Table) + { + AcpiTbDeleteTable (TableDesc); + } + + UnmapAndExit: /* Always unmap the table header that we mapped above */ diff --git a/source/include/achware.h b/source/include/achware.h index 004795dbfa12..f607d1702ac3 100644 --- a/source/include/achware.h +++ b/source/include/achware.h @@ -114,15 +114,18 @@ AcpiHwClearAcpiStatus ( */ ACPI_STATUS AcpiHwLegacySleep ( - UINT8 SleepState); + UINT8 SleepState, + UINT8 Flags); ACPI_STATUS AcpiHwLegacyWakePrep ( - UINT8 SleepState); + UINT8 SleepState, + UINT8 Flags); ACPI_STATUS AcpiHwLegacyWake ( - UINT8 SleepState); + UINT8 SleepState, + UINT8 Flags); /* @@ -135,15 +138,18 @@ AcpiHwExecuteSleepMethod ( ACPI_STATUS AcpiHwExtendedSleep ( - UINT8 SleepState); + UINT8 SleepState, + UINT8 Flags); ACPI_STATUS AcpiHwExtendedWakePrep ( - UINT8 SleepState); + UINT8 SleepState, + UINT8 Flags); ACPI_STATUS AcpiHwExtendedWake ( - UINT8 SleepState); + UINT8 SleepState, + UINT8 Flags); /* diff --git a/source/include/aclocal.h b/source/include/aclocal.h index d29a72157639..30c648dcdbab 100644 --- a/source/include/aclocal.h +++ b/source/include/aclocal.h @@ -424,6 +424,7 @@ typedef struct acpi_predefined_data /* Defines for Flags field above */ #define ACPI_OBJECT_REPAIRED 1 +#define ACPI_OBJECT_WRAPPED 2 /* diff --git a/source/include/acnames.h b/source/include/acnames.h index f0bbde8541c1..4c5fab696f15 100644 --- a/source/include/acnames.h +++ b/source/include/acnames.h @@ -46,6 +46,7 @@ /* Method names - these methods can appear anywhere in the namespace */ +#define METHOD_NAME__SB_ "_SB_" #define METHOD_NAME__HID "_HID" #define METHOD_NAME__CID "_CID" #define METHOD_NAME__UID "_UID" @@ -64,11 +65,11 @@ /* Method names - these methods must appear at the namespace root */ -#define METHOD_NAME__BFS "\\_BFS" -#define METHOD_NAME__GTS "\\_GTS" -#define METHOD_NAME__PTS "\\_PTS" -#define METHOD_NAME__SST "\\_SI._SST" -#define METHOD_NAME__WAK "\\_WAK" +#define METHOD_PATHNAME__BFS "\\_BFS" +#define METHOD_PATHNAME__GTS "\\_GTS" +#define METHOD_PATHNAME__PTS "\\_PTS" +#define METHOD_PATHNAME__SST "\\_SI._SST" +#define METHOD_PATHNAME__WAK "\\_WAK" /* Definitions of the predefined namespace names */ @@ -79,7 +80,6 @@ #define ACPI_PREFIX_LOWER (UINT32) 0x69706361 /* "acpi" */ #define ACPI_NS_ROOT_PATH "\\" -#define ACPI_NS_SYSTEM_BUS "_SB_" #endif /* __ACNAMES_H__ */ diff --git a/source/include/acnamesp.h b/source/include/acnamesp.h index 5e22cb538895..4a91108eae42 100644 --- a/source/include/acnamesp.h +++ b/source/include/acnamesp.h @@ -368,8 +368,9 @@ AcpiNsRepairObject ( ACPI_OPERAND_OBJECT **ReturnObjectPtr); ACPI_STATUS -AcpiNsRepairPackageList ( +AcpiNsWrapWithPackage ( ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT *OriginalObject, ACPI_OPERAND_OBJECT **ObjDescPtr); ACPI_STATUS diff --git a/source/include/acoutput.h b/source/include/acoutput.h index 88c1cab71221..a1d89d408cc3 100644 --- a/source/include/acoutput.h +++ b/source/include/acoutput.h @@ -72,6 +72,7 @@ #define ACPI_EXAMPLE 0x00004000 #define ACPI_DRIVER 0x00008000 #define DT_COMPILER 0x00010000 +#define ASL_PREPROCESSOR 0x00020000 #define ACPI_ALL_COMPONENTS 0x0001FFFF #define ACPI_COMPONENT_DEFAULT (ACPI_ALL_COMPONENTS) diff --git a/source/include/acpixf.h b/source/include/acpixf.h index fafa51f8ebf4..e84d395824af 100644 --- a/source/include/acpixf.h +++ b/source/include/acpixf.h @@ -48,7 +48,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20120215 +#define ACPI_CA_VERSION 0x20120320 #include "acconfig.h" #include "actypes.h" @@ -674,7 +674,8 @@ AcpiEnterSleepStatePrep ( ACPI_STATUS AcpiEnterSleepState ( - UINT8 SleepState); + UINT8 SleepState, + UINT8 Flags); ACPI_HW_DEPENDENT_RETURN_STATUS ( ACPI_STATUS @@ -683,7 +684,8 @@ AcpiEnterSleepStateS4bios ( ACPI_STATUS AcpiLeaveSleepStatePrep ( - UINT8 SleepState); + UINT8 SleepState, + UINT8 Flags); ACPI_STATUS AcpiLeaveSleepState ( diff --git a/source/include/actypes.h b/source/include/actypes.h index 30d9088b8eb4..0125347070c7 100644 --- a/source/include/actypes.h +++ b/source/include/actypes.h @@ -519,6 +519,13 @@ typedef UINT64 ACPI_INTEGER; #define ACPI_SLEEP_TYPE_MAX 0x7 #define ACPI_SLEEP_TYPE_INVALID 0xFF +/* + * Sleep/Wake flags + */ +#define ACPI_NO_OPTIONAL_METHODS 0x00 /* Do not execute any optional methods */ +#define ACPI_EXECUTE_GTS 0x01 /* For enter sleep interface */ +#define ACPI_EXECUTE_BFS 0x02 /* For leave sleep prep interface */ + /* * Standard notify values */ @@ -797,7 +804,8 @@ typedef UINT8 ACPI_ADR_SPACE_TYPE; /* Sleep function dispatch */ typedef ACPI_STATUS (*ACPI_SLEEP_FUNCTION) ( - UINT8 SleepState); + UINT8 SleepState, + UINT8 Flags); typedef struct acpi_sleep_functions { diff --git a/source/tools/acpisrc/astable.c b/source/tools/acpisrc/astable.c index a1d96d32a83a..52218be1864e 100644 --- a/source/tools/acpisrc/astable.c +++ b/source/tools/acpisrc/astable.c @@ -600,6 +600,15 @@ ACPI_TYPED_IDENTIFIER_TABLE AcpiIdentifiers[] = { {"DT_SUBTABLE", SRC_TYPE_STRUCT}, {"DT_WALK_CALLBACK", SRC_TYPE_SIMPLE}, + /* iASL preprocessor */ + + {"PR_DEFINE_INFO", SRC_TYPE_STRUCT}, + {"PR_DIRECTIVE_INFO", SRC_TYPE_STRUCT}, + {"PR_FILE_NODE", SRC_TYPE_STRUCT}, + {"PR_LINE_MAPPING", SRC_TYPE_STRUCT}, + {"PR_MACRO_ARG", SRC_TYPE_STRUCT}, + {"PR_OPERATOR_INFO", SRC_TYPE_STRUCT}, + /* AcpiHelp utility */ {"AH_AML_OPCODE", SRC_TYPE_STRUCT},