From 857ea3a120d65e0680accfdce91c7e37bea443ac Mon Sep 17 00:00:00 2001 From: Al Stone Date: Jul 24 2013 22:25:11 +0000 Subject: Imported Upstream version 20130626 --- diff --git a/changes.txt b/changes.txt index a16fc69..0eb04f9 100755 --- a/changes.txt +++ b/changes.txt @@ -1,4 +1,60 @@ ---------------------------------------- +26 June 2013. Summary of changes for version 20130626: + +1) ACPICA kernel-resident subsystem: + +Fixed an issue with runtime repair of the _CST object. Null or invalid +elements were not always removed properly. Lv Zheng. + +Removed an arbitrary restriction of 256 GPEs per GPE block (such as the +FADT-defined GPE0 and GPE1). For GPE0, GPE1, and each GPE Block Device, +the maximum number of GPEs is 1016. Use of multiple GPE block devices +makes the system-wide number of GPEs essentially unlimited. + +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. + + Current Release: + Non-Debug Version: 95.9K Code, 26.9K Data, 122.8K Total + Debug Version: 184.1K Code, 76.7K Data, 260.8K Total + Previous Release: + Non-Debug Version: 96.0K Code, 27.0K Data, 123.0K Total + Debug Version: 184.1K Code, 76.8K Data, 260.9K Total + + +2) iASL Compiler/Disassembler and Tools: + +Portable AcpiDump: Implemented full support for the Linux and FreeBSD +hosts. Now supports Linux, FreeBSD, and Windows. + +Disassembler: Added some missing types for the HEST and EINJ tables: "Set +Error Type With Address", "CMCI", "MCE", and "Flush Cacheline". + +iASL/Preprocessor: Implemented full support for nested +#if/#else/#elif/#endif blocks. Allows arbitrary depth of nested blocks. + +Disassembler: Expanded maximum output string length to 64K. Was 256 bytes +max. The original purpose of this constraint was to limit the amount of +debug output. However, the string function in question (UtPrintString) is +now used for the disassembler also, where 256 bytes is insufficient. +Reported by RehabMan@GitHub. + +iASL/DataTables: Fixed some problems and issues with compilation of DMAR +tables. ACPICA BZ 999. Lv Zheng. + +iASL: Fixed a couple of error exit issues that could result in a "Could +not delete " message during ASL compilation. + +AcpiDump: Allow "FADT" and "MADT" as valid table signatures, even though +the actual signatures for these tables are "FACP" and "APIC", +respectively. + +AcpiDump: Added support for multiple UEFI tables. Only SSDT and UEFI +tables are allowed to have multiple instances. + +---------------------------------------- 17 May 2013. Summary of changes for version 20130517: 1) ACPICA kernel-resident subsystem: diff --git a/generate/unix/Makefile.common b/generate/unix/Makefile.common index a0e26ba..21f8786 100644 --- a/generate/unix/Makefile.common +++ b/generate/unix/Makefile.common @@ -12,11 +12,11 @@ HARDWARE_NAME := $(shell uname -m) # Main rule will only generate versions that are appropriate for the running # OS, either 64-bit or 32-bit. # -all: ${PROGS} -${PROGS}: FORCE +all: $(PROGS) +$(PROGS): FORCE @cd $(BUILD_DIRECTORY_PATH)/$@; \ mkdir -p obj; \ - make || exit "$$?"; \ + $(MAKE) || exit "$$?"; \ if [ $(findstring 64,$(HARDWARE_NAME)) ]; then \ echo "64-bit version of $@:"; \ else \ @@ -30,12 +30,12 @@ ${PROGS}: FORCE # in the local bin directory # clean: FORCE - @for toolname in ${PROGS}; do \ + @for toolname in $(PROGS); do \ (cd $(BUILD_DIRECTORY_PATH)/$$toolname; \ if [ -d "obj" ] ; then \ echo "Removing $$toolname:"; \ pwd; \ - make clean; \ + $(MAKE) clean; \ rmdir obj; \ echo ""; \ fi; \ @@ -46,12 +46,12 @@ clean: FORCE # Very clean removes all executables and the local bin directory # veryclean: FORCE - @for toolname in ${PROGS}; do \ + @for toolname in $(PROGS); do \ (cd $(BUILD_DIRECTORY_PATH)/$$toolname; \ if [ -d "obj" ] ; then \ echo "Removing $$toolname:"; \ pwd; \ - make clean; \ + $(MAKE) clean; \ rmdir obj; \ echo ""; \ fi; \ @@ -68,10 +68,10 @@ veryclean: FORCE # Install all tools, either 32-bit or 64-bit as appropriate for the host OS # install: FORCE - @for toolname in ${PROGS}; do \ + @for toolname in $(PROGS); do \ (cd $(BUILD_DIRECTORY_PATH)/$$toolname; \ pwd; \ - make PROG=$$toolname install; \ + $(MAKE) PROG=$$toolname install; \ if [ $(findstring 64,$(HARDWARE_NAME)) ]; then \ echo "Installed 64-bit version of $$toolname"; \ else \ diff --git a/generate/unix/Makefile.config b/generate/unix/Makefile.config index 390a464..3e4ecd2 100644 --- a/generate/unix/Makefile.config +++ b/generate/unix/Makefile.config @@ -26,7 +26,7 @@ # Notes: # gcc should be version 4 or greater, otherwise some of the options # used will not be recognized. -# Optional: Change HOST to an appropriate value (_LINUX, __FreeBSD__, etc.) +# Optional: Set HOST to an appropriate value (_LINUX, _FreeBSD, _APPLE, _CYGWIN, etc.) # See include/platform/acenv.h for supported values. # Note: HOST is not nearly as important for applications as it # is for the kernel-resident version of ACPICA, and it may @@ -155,22 +155,27 @@ CWARNINGFLAGS += \ -Waddress\ -Waggregate-return\ -Wchar-subscripts\ - -Wempty-body\ -Wmissing-declarations\ -Wmissing-field-initializers\ -Wnested-externs\ -Wold-style-definition\ + -Wno-format-nonliteral\ -Wredundant-decls # -# Additional gcc 4+ flags +# Per-host flags and exclusions # -ifneq ($(HOST), _APPLE) -CWARNINGFLAGS += \ - -Wlogical-op\ - -Wmissing-parameter-type\ - -Wold-style-declaration\ - -Wtype-limits +ifneq ($(HOST), _FreeBSD) + CWARNINGFLAGS += \ + -Wempty-body + + ifneq ($(HOST), _APPLE) + CWARNINGFLAGS += \ + -Wlogical-op\ + -Wmissing-parameter-type\ + -Wold-style-declaration\ + -Wtype-limits + endif endif # diff --git a/generate/unix/acpidump/Makefile b/generate/unix/acpidump/Makefile index 637ef33..9865b2c 100644 --- a/generate/unix/acpidump/Makefile +++ b/generate/unix/acpidump/Makefile @@ -32,15 +32,26 @@ OBJECTS = \ $(OBJDIR)/apfiles.o\ $(OBJDIR)/apmain.o\ $(OBJDIR)/tbprint.o\ + $(OBJDIR)/tbxfroot.o\ $(OBJDIR)/utbuffer.o\ $(OBJDIR)/utexcep.o\ $(OBJDIR)/utmath.o\ $(OBJDIR)/utstring.o\ $(OBJDIR)/utxferror.o\ - $(OBJDIR)/oslinuxtbl.o\ $(OBJDIR)/getopt.o # +# Per-host interfaces +# +ifeq ($(HOST), _FreeBSD) +OBJECTS += \ + $(OBJDIR)/osfreebsdtbl.o +else +OBJECTS += \ + $(OBJDIR)/oslinuxtbl.o +endif + +# # Flags specific to acpidump # CFLAGS += \ diff --git a/generate/unix/iasl/Makefile b/generate/unix/iasl/Makefile index 931620a..e9520ed 100644 --- a/generate/unix/iasl/Makefile +++ b/generate/unix/iasl/Makefile @@ -238,22 +238,22 @@ include ../Makefile.rules # Parser and Lexer - intermediate C files # $(OBJDIR)/aslcompilerlex.c : $(ASL_COMPILER)/aslcompiler.l $(ASL_COMPILER)/aslsupport.l - ${LEX} ${LFLAGS} -PAslCompiler -o$@ $(ASL_COMPILER)/aslcompiler.l + $(LEX) $(LFLAGS) -PAslCompiler -o$@ $(ASL_COMPILER)/aslcompiler.l $(OBJDIR)/aslcompilerparse.c $(OBJDIR)/aslcompilerparse.h : $(ASL_COMPILER)/aslcompiler.y - ${YACC} ${YFLAGS} -pAslCompiler -o$@ $? + $(YACC) $(YFLAGS) -pAslCompiler -o$@ $? $(OBJDIR)/dtparserlex.c : $(ASL_COMPILER)/dtparser.l - ${LEX} ${LFLAGS} -PDtParser -o$@ $? + $(LEX) $(LFLAGS) -PDtParser -o$@ $? $(OBJDIR)/dtparserparse.c $(OBJDIR)/dtparserparse.h : $(ASL_COMPILER)/dtparser.y - ${YACC} ${YFLAGS} -pDtParser -o$@ $? + $(YACC) $(YFLAGS) -pDtParser -o$@ $? $(OBJDIR)/prparserlex.c : $(ASL_COMPILER)/prparser.l - ${LEX} ${LFLAGS} -PPrParser -o$@ $? + $(LEX) $(LFLAGS) -PPrParser -o$@ $? $(OBJDIR)/prparserparse.c $(OBJDIR)/prparserparse.h : $(ASL_COMPILER)/prparser.y - ${YACC} ${YFLAGS} -pPrParser -o$@ $? + $(YACC) $(YFLAGS) -pPrParser -o$@ $? # diff --git a/source/common/dmrestag.c b/source/common/dmrestag.c index d72ecad..d4960ef 100644 --- a/source/common/dmrestag.c +++ b/source/common/dmrestag.c @@ -666,6 +666,7 @@ AcpiGetTagPathname ( Status = AcpiNsBuildExternalPath (BufferNode, RequiredSize, Pathname); if (ACPI_FAILURE (Status)) { + ACPI_FREE (Pathname); return (NULL); } diff --git a/source/common/dmtable.c b/source/common/dmtable.c index 46d7b67..e57b8cc 100644 --- a/source/common/dmtable.c +++ b/source/common/dmtable.c @@ -100,6 +100,7 @@ static const char *AcpiDmEinjActions[] = "Execute Operation", "Check Busy Status", "Get Command Status", + "Set Error Type With Address", "Unknown Action" }; @@ -110,6 +111,7 @@ static const char *AcpiDmEinjInstructions[] = "Write Register", "Write Register Value", "Noop", + "Flush Cacheline", "Unknown Instruction" }; @@ -180,6 +182,8 @@ static const char *AcpiDmHestNotifySubnames[] = "Local Interrupt", "SCI", "NMI", + "CMCI", /* ACPI 5.0 */ + "MCE", /* ACPI 5.0 */ "Unknown Notify Type" /* Reserved */ }; @@ -744,6 +748,11 @@ AcpiDmDumpTable ( ByteLength = 8; break; + case ACPI_DMT_BUF10: + + ByteLength = 10; + break; + case ACPI_DMT_BUF16: case ACPI_DMT_UUID: @@ -862,6 +871,7 @@ AcpiDmDumpTable ( break; case ACPI_DMT_BUF7: + case ACPI_DMT_BUF10: case ACPI_DMT_BUF16: case ACPI_DMT_BUF128: /* diff --git a/source/common/dmtbdump.c b/source/common/dmtbdump.c index 57c160d..5b98191 100644 --- a/source/common/dmtbdump.c +++ b/source/common/dmtbdump.c @@ -872,6 +872,7 @@ AcpiDmDumpDmar ( { return; } + AcpiOsPrintf ("\n"); switch (SubTable->Type) { @@ -924,6 +925,7 @@ AcpiDmDumpDmar ( { return; } + AcpiOsPrintf ("\n"); /* Dump the PCI Path entries for this device scope */ @@ -941,6 +943,7 @@ AcpiDmDumpDmar ( PathOffset += 2; PciPath += 2; + AcpiOsPrintf ("\n"); } /* Point to next device scope entry */ diff --git a/source/common/dmtbinfo.c b/source/common/dmtbinfo.c index 033f7ef..ed675c1 100644 --- a/source/common/dmtbinfo.c +++ b/source/common/dmtbinfo.c @@ -780,6 +780,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoDmar[] = { {ACPI_DMT_UINT8, ACPI_DMAR_OFFSET (Width), "Host Address Width", 0}, {ACPI_DMT_UINT8, ACPI_DMAR_OFFSET (Flags), "Flags", 0}, + {ACPI_DMT_BUF10, ACPI_DMAR_OFFSET (Reserved[0]), "Reserved", 0}, ACPI_DMT_TERMINATOR }; diff --git a/source/compiler/aslcompile.c b/source/compiler/aslcompile.c index bbd8ab9..87f97ef 100644 --- a/source/compiler/aslcompile.c +++ b/source/compiler/aslcompile.c @@ -966,7 +966,19 @@ CmCleanupAndExit ( /* Close all open files */ - Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; /* the .i file is same as source file */ + /* + * Take care with the preprocessor file (.i), it might be the same + * as the "input" file, depending on where the compiler has terminated + * or aborted. Prevent attempt to close the same file twice in + * loop below. + */ + if (Gbl_Files[ASL_FILE_PREPROCESSOR].Handle == + Gbl_Files[ASL_FILE_INPUT].Handle) + { + Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; + } + + /* Close the standard I/O files */ for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++) { diff --git a/source/compiler/aslmessages.h b/source/compiler/aslmessages.h index a104a44..9fb7229 100644 --- a/source/compiler/aslmessages.h +++ b/source/compiler/aslmessages.h @@ -248,7 +248,7 @@ typedef enum ASL_MSG_TOO_MANY_ARGUMENTS, ASL_MSG_UNKNOWN_DIRECTIVE, ASL_MSG_UNKNOWN_PRAGMA, - + ASL_MSG_WARNING_DIRECTIVE, /* These messages are used by the data table compiler only */ @@ -433,6 +433,7 @@ char *AslMessages [] = /* ASL_MSG_TOO_MANY_ARGUMENTS */ "Too many macro arguments", /* ASL_MSG_UNKNOWN_DIRECTIVE */ "Unknown directive", /* ASL_MSG_UNKNOWN_PRAGMA */ "Unknown pragma", +/* ASL_MSG_WARNING_DIRECTIVE */ "#warning", /* Table compiler */ diff --git a/source/compiler/asltree.c b/source/compiler/asltree.c index ca88071..c8d05e4 100644 --- a/source/compiler/asltree.c +++ b/source/compiler/asltree.c @@ -823,6 +823,7 @@ TrLinkChildren ( { AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Child, "Child node list invalid"); + va_end(ap); return (Op); } @@ -869,8 +870,8 @@ TrLinkChildren ( } PrevChild = Child; } - va_end(ap); + va_end(ap); DbgPrint (ASL_PARSE_OUTPUT, "\n\n"); return (Op); } diff --git a/source/compiler/aslutils.c b/source/compiler/aslutils.c index 8174eeb..6537c2e 100644 --- a/source/compiler/aslutils.c +++ b/source/compiler/aslutils.c @@ -353,8 +353,6 @@ DbgPrint ( va_list Args; - va_start (Args, Fmt); - if (!Gbl_DebugFlag) { return; @@ -366,6 +364,7 @@ DbgPrint ( return; } + va_start (Args, Fmt); (void) vfprintf (stderr, Fmt, Args); va_end (Args); return; diff --git a/source/compiler/dtfield.c b/source/compiler/dtfield.c index 697b277..a5642a1 100644 --- a/source/compiler/dtfield.c +++ b/source/compiler/dtfield.c @@ -467,12 +467,13 @@ DtCompileBuffer ( if (ACPI_FAILURE (Status)) { DtError (ASL_ERROR, ASL_MSG_BUFFER_ELEMENT, Field, MsgBuffer); - return (ByteLength - Count); + goto Exit; } Buffer[i] = (UINT8) Value; } +Exit: ACPI_FREE (StringValue); return (ByteLength - Count); } diff --git a/source/compiler/dtio.c b/source/compiler/dtio.c index c26b2b8..8b03234 100644 --- a/source/compiler/dtio.c +++ b/source/compiler/dtio.c @@ -287,31 +287,21 @@ DtParseLine ( while (Start < Colon) { - if (*Start == ' ') - { - Start++; - continue; - } - - /* Found left bracket, go to the right bracket */ - if (*Start == '[') { + /* Found left bracket, go to the right bracket */ + while (Start < Colon && *Start != ']') { Start++; } - - if (Start == Colon) - { - break; - } - - Start++; - continue; + } + else if (*Start != ' ') + { + break; } - break; + Start++; } /* @@ -1138,4 +1128,5 @@ DtWriteTableToListing ( AcpiUtDumpBuffer (Buffer, Gbl_TableLength, DB_BYTE_DISPLAY, 0); AcpiOsRedirectOutput (stdout); + ACPI_FREE (Buffer); } diff --git a/source/compiler/dttable.c b/source/compiler/dttable.c index 4236c6c..3b84956 100644 --- a/source/compiler/dttable.c +++ b/source/compiler/dttable.c @@ -541,8 +541,9 @@ DtCompileDmar ( DT_FIELD *SubtableStart; ACPI_DMTABLE_INFO *InfoTable; ACPI_DMAR_HEADER *DmarHeader; - UINT8 *ReservedBuffer; - UINT32 ReservedSize; + ACPI_DMAR_DEVICE_SCOPE *DmarDeviceScope; + UINT32 DeviceScopeLength; + UINT32 PciPathLength; Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE); @@ -553,17 +554,7 @@ DtCompileDmar ( ParentTable = DtPeekSubtable (); DtInsertSubtable (ParentTable, Subtable); - - /* DMAR Reserved area */ - - ReservedSize = (UINT32) sizeof (((ACPI_TABLE_DMAR *) NULL)->Reserved); - ReservedBuffer = UtLocalCalloc (ReservedSize); - - DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable); - - ACPI_FREE (ReservedBuffer); - ParentTable = DtPeekSubtable (); - DtInsertSubtable (ParentTable, Subtable); + DtPushSubtable (Subtable); while (*PFieldList) { @@ -621,10 +612,13 @@ DtCompileDmar ( ParentTable = DtPeekSubtable (); DtInsertSubtable (ParentTable, Subtable); + DtPushSubtable (Subtable); /* Optional Device Scope subtables */ - while (*PFieldList) + DeviceScopeLength = DmarHeader->Length - Subtable->Length - + ParentTable->Length; + while (DeviceScopeLength) { Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope, &Subtable, FALSE); @@ -637,9 +631,12 @@ DtCompileDmar ( DtInsertSubtable (ParentTable, Subtable); DtPushSubtable (Subtable); + DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer); + /* Optional PCI Paths */ - while (*PFieldList) + PciPathLength = DmarDeviceScope->Length - Subtable->Length; + while (PciPathLength) { Status = DtCompileTable (PFieldList, TableInfoDmarPciPath, &Subtable, FALSE); @@ -651,10 +648,15 @@ DtCompileDmar ( ParentTable = DtPeekSubtable (); DtInsertSubtable (ParentTable, Subtable); + PciPathLength -= Subtable->Length; } + + DtPopSubtable (); + DeviceScopeLength -= DmarDeviceScope->Length; } DtPopSubtable (); + DtPopSubtable (); } return (AE_OK); diff --git a/source/compiler/dttemplate.h b/source/compiler/dttemplate.h index d3fadf5..f620abd 100644 --- a/source/compiler/dttemplate.h +++ b/source/compiler/dttemplate.h @@ -188,22 +188,22 @@ const unsigned char TemplateDbgp[] = const unsigned char TemplateDmar[] = { 0x44,0x4D,0x41,0x52,0x8C,0x00,0x00,0x00, /* 00000000 "DMAR...." */ - 0x01,0x15,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */ + 0x01,0x03,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */ 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */ - 0x28,0x05,0x10,0x20,0x2F,0x01,0x00,0x00, /* 00000020 "(.. /..." */ + 0x17,0x05,0x13,0x20,0x2F,0x01,0x00,0x00, /* 00000020 "... /..." */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */ 0x00,0x00,0x18,0x00,0x01,0x00,0x00,0x00, /* 00000030 "........" */ - 0x00,0x00,0x02,0xFD,0x00,0x00,0x00,0x00, /* 00000038 "........" */ - 0x03,0x08,0x00,0x00,0x08,0xF0,0x1F,0x07, /* 00000040 "........" */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */ + 0x03,0x08,0x00,0x00,0x08,0x00,0x00,0x01, /* 00000040 "........" */ 0x01,0x00,0x20,0x00,0x00,0x00,0x00,0x00, /* 00000048 ".. ....." */ - 0x00,0x10,0xC2,0x78,0x00,0x00,0x00,0x00, /* 00000050 "...x...." */ - 0xFF,0x3F,0xC2,0x78,0x00,0x00,0x00,0x00, /* 00000058 ".?.x...." */ - 0x01,0x08,0x00,0x00,0x00,0x00,0x1D,0x00, /* 00000060 "........" */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000050 "........" */ + 0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000058 "........" */ + 0x01,0x08,0x00,0x00,0x00,0x00,0x00,0x02, /* 00000060 "........" */ 0x02,0x00,0x10,0x00,0x00,0x00,0x00,0x00, /* 00000068 "........" */ - 0x02,0x08,0x00,0x00,0x00,0x00,0x01,0x00, /* 00000070 "........" */ + 0x02,0x08,0x00,0x00,0x00,0x00,0x00,0x03, /* 00000070 "........" */ 0x03,0x00,0x14,0x00,0x00,0x00,0x00,0x00, /* 00000078 "........" */ - 0x00,0x00,0x02,0xFD,0x00,0x00,0x00,0x00, /* 00000080 "........" */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000080 "........" */ 0x00,0x00,0x00,0x00 /* 00000088 "...." */ }; diff --git a/source/compiler/dtutils.c b/source/compiler/dtutils.c index 1f4207a..e7376f4 100644 --- a/source/compiler/dtutils.c +++ b/source/compiler/dtutils.c @@ -397,6 +397,7 @@ DtGetFieldType ( case ACPI_DMT_BUFFER: case ACPI_DMT_BUF7: + case ACPI_DMT_BUF10: case ACPI_DMT_BUF16: case ACPI_DMT_BUF128: case ACPI_DMT_PCI_PATH: @@ -630,6 +631,11 @@ DtGetFieldLength ( } break; + case ACPI_DMT_BUF10: + + ByteLength = 10; + break; + case ACPI_DMT_BUF16: case ACPI_DMT_UUID: diff --git a/source/compiler/preprocess.h b/source/compiler/preprocess.h index 6decc00..ae32a8c 100644 --- a/source/compiler/preprocess.h +++ b/source/compiler/preprocess.h @@ -124,6 +124,17 @@ typedef struct pr_file_node } PR_FILE_NODE; +#define MAX_ARGUMENT_LENGTH 24 + +typedef struct directive_info +{ + struct directive_info *Next; + char Argument[MAX_ARGUMENT_LENGTH]; + int Directive; + BOOLEAN IgnoringThisCodeBlock; + +} DIRECTIVE_INFO; + /* * Globals @@ -136,12 +147,13 @@ PR_EXTERN char PR_INIT_GLOBAL (*Gbl_MainTokenBuffer, NULL); /* PR_EXTERN char PR_INIT_GLOBAL (*Gbl_MacroTokenBuffer, NULL); /* [ASL_LINE_BUFFER_SIZE]; */ PR_EXTERN char PR_INIT_GLOBAL (*Gbl_ExpressionTokenBuffer, NULL); /* [ASL_LINE_BUFFER_SIZE]; */ -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 PR_FILE_NODE *Gbl_InputFileList; +PR_EXTERN PR_DEFINE_INFO PR_INIT_GLOBAL (*Gbl_DefineList, NULL); PR_EXTERN BOOLEAN PR_INIT_GLOBAL (Gbl_PreprocessorError, FALSE); - +PR_EXTERN BOOLEAN PR_INIT_GLOBAL (Gbl_IgnoringThisCodeBlock, FALSE); +PR_EXTERN DIRECTIVE_INFO PR_INIT_GLOBAL (*Gbl_DirectiveStack, NULL); /* * prscan - Preprocessor entry @@ -158,7 +170,7 @@ void PrTerminatePreprocessor ( void); -BOOLEAN +void PrDoPreprocess ( void); diff --git a/source/compiler/prscan.c b/source/compiler/prscan.c index cc9b3ce..3b5416a 100644 --- a/source/compiler/prscan.c +++ b/source/compiler/prscan.c @@ -65,13 +65,27 @@ PrPreprocessInputFile ( static void PrDoDirective ( char *DirectiveToken, - char **Next, - BOOLEAN *IgnoringThisCodeBlock); + char **Next); static int PrMatchDirective ( char *Directive); +static void +PrPushDirective ( + int Directive, + char *Argument); + +static ACPI_STATUS +PrPopDirective ( + void); + +static void +PrDbgPrint ( + char *Action, + char *DirectiveName); + + /* * Supported preprocessor directives */ @@ -156,11 +170,16 @@ PrInitializeGlobals ( { /* Init globals */ - Gbl_IfDepth = 0; Gbl_InputFileList = NULL; Gbl_CurrentLineNumber = 0; Gbl_PreprocessorLineNumber = 1; Gbl_PreprocessorError = FALSE; + + /* These are used to track #if/#else blocks (possibly nested) */ + + Gbl_IfDepth = 0; + Gbl_IgnoringThisCodeBlock = FALSE; + Gbl_DirectiveStack = NULL; } @@ -207,7 +226,7 @@ PrTerminatePreprocessor ( * * PARAMETERS: None * - * RETURN: Error Status. TRUE if error, FALSE if OK. + * RETURN: None * * DESCRIPTION: Main entry point for the iASL Preprocessor. Input file must * be already open. Handles multiple input files via the @@ -215,7 +234,7 @@ PrTerminatePreprocessor ( * ******************************************************************************/ -BOOLEAN +void PrDoPreprocess ( void) { @@ -237,20 +256,7 @@ PrDoPreprocess ( } 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) */ + /* Point compiler input to the new preprocessor output file (.i) */ FlCloseFile (ASL_FILE_INPUT); Gbl_Files[ASL_FILE_INPUT].Handle = Gbl_Files[ASL_FILE_PREPROCESSOR].Handle; @@ -262,7 +268,6 @@ PrDoPreprocess ( Gbl_CurrentLineNumber = 1; DbgPrint (ASL_DEBUG_OUTPUT, "Preprocessing phase complete \n\n"); - return (FALSE); } @@ -290,7 +295,6 @@ PrPreprocessInputFile ( char *ReplaceString; PR_DEFINE_INFO *DefineInfo; ACPI_SIZE TokenOffset; - BOOLEAN IgnoringThisCodeBlock = FALSE; char *Next; int OffsetAdjust; @@ -320,7 +324,7 @@ PrPreprocessInputFile ( /* Execute the directive, do not write line to output file */ - PrDoDirective (Token, &Next, &IgnoringThisCodeBlock); + PrDoDirective (Token, &Next); continue; } @@ -329,7 +333,7 @@ PrPreprocessInputFile ( * 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) + if (Gbl_IgnoringThisCodeBlock) { continue; } @@ -416,12 +420,8 @@ PrPreprocessInputFile ( * * 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. + * RETURN: None. * * DESCRIPTION: Main processing for all preprocessor directives * @@ -430,8 +430,7 @@ PrPreprocessInputFile ( static void PrDoDirective ( char *DirectiveToken, - char **Next, - BOOLEAN *IgnoringThisCodeBlock) + char **Next) { char *Token = Gbl_MainTokenBuffer; char *Token2; @@ -459,14 +458,28 @@ PrDoDirective ( return; } - /* TBD: Need a faster way to do this: */ - - if ((Directive == PR_DIRECTIVE_ELIF) || - (Directive == PR_DIRECTIVE_ELSE) || - (Directive == PR_DIRECTIVE_ENDIF)) + /* + * If we are currently ignoring this block and we encounter a #else or + * #elif, we must ignore their blocks also if the parent block is also + * being ignored. + */ + if (Gbl_IgnoringThisCodeBlock) { - DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Begin #%s\n", - Gbl_CurrentLineNumber, Gbl_DirectiveInfo[Directive].Name); + switch (Directive) + { + case PR_DIRECTIVE_ELSE: + case PR_DIRECTIVE_ELIF: + + if (Gbl_DirectiveStack && Gbl_DirectiveStack->IgnoringThisCodeBlock) + { + PrDbgPrint ("Ignoring", Gbl_DirectiveInfo[Directive].Name); + return; + } + break; + + default: + break; + } } /* @@ -476,57 +489,54 @@ PrDoDirective ( */ switch (Directive) { + case PR_DIRECTIVE_ELSE: + + Gbl_IgnoringThisCodeBlock = !(Gbl_IgnoringThisCodeBlock); + PrDbgPrint ("Executing", "else block"); + return; + case PR_DIRECTIVE_ELIF: - *IgnoringThisCodeBlock = !(*IgnoringThisCodeBlock); - if (*IgnoringThisCodeBlock == TRUE) + Gbl_IgnoringThisCodeBlock = !(Gbl_IgnoringThisCodeBlock); + Directive = PR_DIRECTIVE_IF; + + if (Gbl_IgnoringThisCodeBlock == TRUE) { /* Not executing the ELSE part -- all done here */ + PrDbgPrint ("Ignoring", "elif block"); return; } - /* Will execute the ELSE..IF part */ + /* + * After this, we will execute the IF part further below. + * First, however, pop off the original #if directive. + */ + if (ACPI_FAILURE (PrPopDirective ())) + { + PrError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, + THIS_TOKEN_OFFSET (DirectiveToken)); + } - DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID - "#elif - Executing else block\n", - Gbl_CurrentLineNumber); - Directive = PR_DIRECTIVE_IF; + PrDbgPrint ("Executing", "elif block"); break; - case PR_DIRECTIVE_ELSE: + case PR_DIRECTIVE_ENDIF: - *IgnoringThisCodeBlock = !(*IgnoringThisCodeBlock); - return; + PrDbgPrint ("Executing", "endif"); - case PR_DIRECTIVE_ENDIF: + /* Pop the owning #if/#ifdef/#ifndef */ - *IgnoringThisCodeBlock = FALSE; - Gbl_IfDepth--; - if (Gbl_IfDepth < 0) + if (ACPI_FAILURE (PrPopDirective ())) { 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) @@ -538,8 +548,85 @@ PrDoDirective ( } } + /* + * At this point, if we are ignoring the current code block, + * do not process any more directives (i.e., ignore them also.) + * For "if" style directives, open/push a new block anyway. We + * must do this to keep track of #endif directives + */ + if (Gbl_IgnoringThisCodeBlock) + { + switch (Directive) + { + case PR_DIRECTIVE_IF: + case PR_DIRECTIVE_IFDEF: + case PR_DIRECTIVE_IFNDEF: + + PrPushDirective (Directive, Token); + PrDbgPrint ("Ignoring", Gbl_DirectiveInfo[Directive].Name); + break; + + default: + break; + } + + return; + } + + /* + * Execute the directive + */ + PrDbgPrint ("Begin execution", Gbl_DirectiveInfo[Directive].Name); + switch (Directive) { + 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; + } + + PrPushDirective (Directive, Token); + if (!Value) + { + Gbl_IgnoringThisCodeBlock = TRUE; + } + + DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID + "Resolved #if: %8.8X%8.8X %s\n", + Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Value), + Gbl_IgnoringThisCodeBlock ? "" : ""); + break; + + case PR_DIRECTIVE_IFDEF: + + PrPushDirective (Directive, Token); + if (!PrMatchDefine (Token)) + { + Gbl_IgnoringThisCodeBlock = TRUE; + } + + PrDbgPrint ("Evaluated", "ifdef"); + break; + + case PR_DIRECTIVE_IFNDEF: + + PrPushDirective (Directive, Token); + if (PrMatchDefine (Token)) + { + Gbl_IgnoringThisCodeBlock = TRUE; + } + + PrDbgPrint ("Evaluated", "ifndef"); + break; + case PR_DIRECTIVE_DEFINE: /* * By definition, if first char after the name is a paren, @@ -595,64 +682,15 @@ PrDoDirective ( 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; + Gbl_SourceLine = 0; + Gbl_NextError = Gbl_ErrorLog; + CmCleanupAndExit (); + exit(1); case PR_DIRECTIVE_INCLUDE: @@ -738,7 +776,7 @@ PrDoDirective ( case PR_DIRECTIVE_WARNING: - PrError (ASL_WARNING, ASL_MSG_ERROR_DIRECTIVE, + PrError (ASL_WARNING, ASL_MSG_WARNING_DIRECTIVE, THIS_TOKEN_OFFSET (Token)); break; @@ -753,7 +791,6 @@ PrDoDirective ( return; - SyntaxError: PrError (ASL_ERROR, ASL_MSG_DIRECTIVE_SYNTAX, @@ -796,3 +833,130 @@ PrMatchDirective ( return (ASL_DIRECTIVE_NOT_FOUND); /* Command not recognized */ } + + +/******************************************************************************* + * + * FUNCTION: PrPushDirective + * + * PARAMETERS: Directive - Encoded directive ID + * Argument - String containing argument to the + * directive + * + * RETURN: None + * + * DESCRIPTION: Push an item onto the directive stack. Used for processing + * nested #if/#else type conditional compilation directives. + * Specifically: Used on detection of #if/#ifdef/#ifndef to open + * a block. + * + ******************************************************************************/ + +static void +PrPushDirective ( + int Directive, + char *Argument) +{ + DIRECTIVE_INFO *Info; + + + /* Allocate and populate a stack info item */ + + Info = ACPI_ALLOCATE (sizeof (DIRECTIVE_INFO)); + + Info->Next = Gbl_DirectiveStack; + Info->Directive = Directive; + Info->IgnoringThisCodeBlock = Gbl_IgnoringThisCodeBlock; + strncpy (Info->Argument, Argument, MAX_ARGUMENT_LENGTH); + + DbgPrint (ASL_DEBUG_OUTPUT, + "Pr(%.4u) - [%u %s] %*s Pushed [#%s %s]: IgnoreFlag = %s\n", + Gbl_CurrentLineNumber, Gbl_IfDepth, + Gbl_IgnoringThisCodeBlock ? "I" : "E", + Gbl_IfDepth * 4, " ", + Gbl_DirectiveInfo[Directive].Name, + Argument, Gbl_IgnoringThisCodeBlock ? "TRUE" : "FALSE"); + + /* Push new item */ + + Gbl_DirectiveStack = Info; + Gbl_IfDepth++; +} + + +/******************************************************************************* + * + * FUNCTION: PrPopDirective + * + * PARAMETERS: None + * + * RETURN: Status. Error if the stack is empty. + * + * DESCRIPTION: Pop an item off the directive stack. Used for processing + * nested #if/#else type conditional compilation directives. + * Specifically: Used on detection of #elif and #endif to remove + * the original #if/#ifdef/#ifndef from the stack and close + * the block. + * + ******************************************************************************/ + +static ACPI_STATUS +PrPopDirective ( + void) +{ + DIRECTIVE_INFO *Info; + + + /* Check for empty stack */ + + Info = Gbl_DirectiveStack; + if (!Info) + { + return (AE_ERROR); + } + + /* Pop one item, keep globals up-to-date */ + + Gbl_IfDepth--; + Gbl_IgnoringThisCodeBlock = Info->IgnoringThisCodeBlock; + Gbl_DirectiveStack = Info->Next; + + DbgPrint (ASL_DEBUG_OUTPUT, + "Pr(%.4u) - [%u %s] %*s Popped [#%s %s]: IgnoreFlag now = %s\n", + Gbl_CurrentLineNumber, Gbl_IfDepth, + Gbl_IgnoringThisCodeBlock ? "I" : "E", + Gbl_IfDepth * 4, " ", + Gbl_DirectiveInfo[Info->Directive].Name, + Info->Argument, Gbl_IgnoringThisCodeBlock ? "TRUE" : "FALSE"); + + ACPI_FREE (Info); + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: PrDbgPrint + * + * PARAMETERS: Action - Action being performed + * DirectiveName - Directive being processed + * + * RETURN: None + * + * DESCRIPTION: Special debug print for directive processing. + * + ******************************************************************************/ + +static void +PrDbgPrint ( + char *Action, + char *DirectiveName) +{ + + DbgPrint (ASL_DEBUG_OUTPUT, "Pr(%.4u) - [%u %s] " + "%*s %s #%s, Depth %u\n", + Gbl_CurrentLineNumber, Gbl_IfDepth, + Gbl_IgnoringThisCodeBlock ? "I" : "E", + Gbl_IfDepth * 4, " ", + Action, DirectiveName, Gbl_IfDepth); +} diff --git a/source/components/debugger/dbcmds.c b/source/components/debugger/dbcmds.c index 5700441..307644b 100644 --- a/source/components/debugger/dbcmds.c +++ b/source/components/debugger/dbcmds.c @@ -105,13 +105,15 @@ AcpiDbConvertToNode ( char *InString) { ACPI_NAMESPACE_NODE *Node; + ACPI_SIZE Address; if ((*InString >= 0x30) && (*InString <= 0x39)) { /* Numeric argument, convert */ - Node = ACPI_TO_POINTER (ACPI_STRTOUL (InString, NULL, 16)); + Address = ACPI_STRTOUL (InString, NULL, 16); + Node = ACPI_TO_POINTER (Address); if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE))) { AcpiOsPrintf ("Address %p is invalid in this address space\n", diff --git a/source/components/debugger/dbdisply.c b/source/components/debugger/dbdisply.c index c453d57..046bbc3 100644 --- a/source/components/debugger/dbdisply.c +++ b/source/components/debugger/dbdisply.c @@ -139,9 +139,11 @@ AcpiDbGetPointer ( void *Target) { void *ObjPtr; + ACPI_SIZE Address; - ObjPtr = ACPI_TO_POINTER (ACPI_STRTOUL (Target, NULL, 16)); + Address = ACPI_STRTOUL (Target, NULL, 16); + ObjPtr = ACPI_TO_POINTER (Address); return (ObjPtr); } diff --git a/source/components/debugger/dbinput.c b/source/components/debugger/dbinput.c index 1e3ebff..e7d88bc 100644 --- a/source/components/debugger/dbinput.c +++ b/source/components/debugger/dbinput.c @@ -829,7 +829,7 @@ AcpiDbCommandDispatch ( break; case CMD_EVENT: - + AcpiOsPrintf ("Event command not implemented\n"); break; @@ -888,7 +888,7 @@ AcpiDbCommandDispatch ( return (Status); case CMD_HISTORY_LAST: /* !! command */ - + CommandLine = AcpiDbGetFromHistory (NULL); if (!CommandLine) { @@ -899,12 +899,12 @@ AcpiDbCommandDispatch ( return (Status); case CMD_INFORMATION: - + AcpiDbDisplayMethodInfo (Op); break; case CMD_INTEGRITY: - + AcpiDbCheckIntegrity (); break; @@ -998,7 +998,7 @@ AcpiDbCommandDispatch ( break; case CMD_OWNER: - + AcpiDbDumpNamespaceByOwner (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]); break; diff --git a/source/components/debugger/dbnames.c b/source/components/debugger/dbnames.c index b414a40..1e1543c 100644 --- a/source/components/debugger/dbnames.c +++ b/source/components/debugger/dbnames.c @@ -783,11 +783,13 @@ AcpiDbFindReferences ( char *ObjectArg) { ACPI_OPERAND_OBJECT *ObjDesc; + ACPI_SIZE Address; /* Convert string to object pointer */ - ObjDesc = ACPI_TO_POINTER (ACPI_STRTOUL (ObjectArg, NULL, 16)); + Address = ACPI_STRTOUL (ObjectArg, NULL, 16); + ObjDesc = ACPI_TO_POINTER (Address); /* Search all nodes in namespace */ diff --git a/source/components/disassembler/dmbuffer.c b/source/components/disassembler/dmbuffer.c index d0f57ce..a9496a9 100644 --- a/source/components/disassembler/dmbuffer.c +++ b/source/components/disassembler/dmbuffer.c @@ -177,7 +177,7 @@ AcpiDmByteList ( case ACPI_DASM_STRING: AcpiDmIndent (Info->Level); - AcpiUtPrintString ((char *) ByteData, ACPI_UINT8_MAX); + AcpiUtPrintString ((char *) ByteData, ACPI_UINT16_MAX); AcpiOsPrintf ("\n"); break; @@ -523,11 +523,9 @@ AcpiDmUnicode ( WordData = ACPI_CAST_PTR (UINT16, Op->Named.Data); WordCount = ACPI_DIV_2 (((UINT32) Op->Common.Value.Integer)); - - AcpiOsPrintf ("\""); - /* Write every other byte as an ASCII character */ + AcpiOsPrintf ("\""); for (i = 0; i < (WordCount - 1); i++) { AcpiOsPrintf ("%c", (int) WordData[i]); diff --git a/source/components/disassembler/dmopcode.c b/source/components/disassembler/dmopcode.c index 490fa8c..bbe5af3 100644 --- a/source/components/disassembler/dmopcode.c +++ b/source/components/disassembler/dmopcode.c @@ -633,7 +633,7 @@ AcpiDmDisassembleOneOp ( case AML_STRING_OP: - AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT8_MAX); + AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT16_MAX); break; case AML_BUFFER_OP: diff --git a/source/components/disassembler/dmresrcl.c b/source/components/disassembler/dmresrcl.c index e35b1b4..0e53672 100644 --- a/source/components/disassembler/dmresrcl.c +++ b/source/components/disassembler/dmresrcl.c @@ -565,7 +565,7 @@ AcpiDmResourceSource ( if (TotalLength > (MinimumTotalLength + 1)) { AcpiOsPrintf (" "); - AcpiUtPrintString ((char *) &AmlResourceSource[1], ACPI_UINT8_MAX); + AcpiUtPrintString ((char *) &AmlResourceSource[1], ACPI_UINT16_MAX); } AcpiOsPrintf (", "); diff --git a/source/components/disassembler/dmresrcl2.c b/source/components/disassembler/dmresrcl2.c index 1e26f61..a81f9f8 100644 --- a/source/components/disassembler/dmresrcl2.c +++ b/source/components/disassembler/dmresrcl2.c @@ -195,7 +195,7 @@ AcpiDmGpioCommon ( { AcpiUtPrintString ( ACPI_ADD_PTR (char, Resource, Resource->Gpio.ResSourceOffset), - ACPI_UINT8_MAX); + ACPI_UINT16_MAX); } AcpiOsPrintf (", "); @@ -498,7 +498,7 @@ AcpiDmI2cSerialBusDescriptor ( AcpiUtPrintString ( ACPI_ADD_PTR (char, Resource, ResourceSourceOffset), - ACPI_UINT8_MAX); + ACPI_UINT16_MAX); /* ResourceSourceIndex, ResourceUsage */ @@ -573,7 +573,7 @@ AcpiDmSpiSerialBusDescriptor ( AcpiUtPrintString ( ACPI_ADD_PTR (char, Resource, ResourceSourceOffset), - ACPI_UINT8_MAX); + ACPI_UINT16_MAX); /* ResourceSourceIndex, ResourceUsage */ @@ -651,7 +651,7 @@ AcpiDmUartSerialBusDescriptor ( AcpiUtPrintString ( ACPI_ADD_PTR (char, Resource, ResourceSourceOffset), - ACPI_UINT8_MAX); + ACPI_UINT16_MAX); /* ResourceSourceIndex, ResourceUsage */ diff --git a/source/components/events/evgpeinit.c b/source/components/events/evgpeinit.c index 44a1378..dae7dc1 100644 --- a/source/components/events/evgpeinit.c +++ b/source/components/events/evgpeinit.c @@ -134,7 +134,6 @@ AcpiEvGpeInitialize ( /* GPE block 0 exists (has both length and address > 0) */ RegisterCount0 = (UINT16) (AcpiGbl_FADT.Gpe0BlockLength / 2); - GpeNumberMax = (RegisterCount0 * ACPI_GPE_REGISTER_WIDTH) - 1; /* Install GPE Block 0 */ @@ -209,16 +208,6 @@ AcpiEvGpeInitialize ( goto Cleanup; } - /* Check for Max GPE number out-of-range */ - - if (GpeNumberMax > ACPI_GPE_MAX) - { - ACPI_ERROR ((AE_INFO, - "Maximum GPE number from FADT is too large: 0x%X", - GpeNumberMax)); - Status = AE_BAD_VALUE; - goto Cleanup; - } Cleanup: (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); diff --git a/source/components/executer/exdump.c b/source/components/executer/exdump.c index 333168e..197eda8 100644 --- a/source/components/executer/exdump.c +++ b/source/components/executer/exdump.c @@ -357,6 +357,7 @@ AcpiExDumpObject ( { UINT8 *Target; char *Name; + const char *ReferenceName; UINT8 Count; @@ -441,8 +442,8 @@ AcpiExDumpObject ( case ACPI_EXD_REFERENCE: - AcpiExOutString ("Class Name", - ACPI_CAST_PTR (char, AcpiUtGetReferenceName (ObjDesc))); + ReferenceName = AcpiUtGetReferenceName (ObjDesc); + AcpiExOutString ("Class Name", ACPI_CAST_PTR (char, ReferenceName)); AcpiExDumpReferenceObj (ObjDesc); break; diff --git a/source/components/namespace/nsdump.c b/source/components/namespace/nsdump.c index be780f2..82e6602 100644 --- a/source/components/namespace/nsdump.c +++ b/source/components/namespace/nsdump.c @@ -618,7 +618,7 @@ AcpiNsDumpOneObject ( break; case ACPI_TYPE_LOCAL_INDEX_FIELD: - + ObjDesc = (void *) ObjDesc->IndexField.IndexObj; break; diff --git a/source/components/namespace/nsrepair2.c b/source/components/namespace/nsrepair2.c index 0dcfaad..0cf604b 100644 --- a/source/components/namespace/nsrepair2.c +++ b/source/components/namespace/nsrepair2.c @@ -501,19 +501,7 @@ AcpiNsRepair_CST ( /* - * Entries (subpackages) in the _CST Package must be sorted by the - * C-state type, in ascending order. - */ - Status = AcpiNsCheckSortedList (Info, ReturnObject, 1, 4, 1, - ACPI_SORT_ASCENDING, "C-State Type"); - if (ACPI_FAILURE (Status)) - { - return (Status); - } - - /* - * We now know the list is correctly sorted by C-state type. Check if - * the C-state type values are proportional. + * Check if the C-state type values are proportional. */ OuterElementCount = ReturnObject->Package.Count - 1; i = 0; @@ -527,6 +515,7 @@ AcpiNsRepair_CST ( ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, "SubPackage[%u] - removing entry due to zero count", i)); Removing = TRUE; + goto RemoveElement; } ObjDesc = (*OuterElements)->Package.Elements[1]; /* Index1 = Type */ @@ -537,6 +526,7 @@ AcpiNsRepair_CST ( Removing = TRUE; } +RemoveElement: if (Removing) { AcpiNsRemoveElement (ReturnObject, i + 1); @@ -552,6 +542,18 @@ AcpiNsRepair_CST ( ObjDesc = ReturnObject->Package.Elements[0]; ObjDesc->Integer.Value = OuterElementCount; + + /* + * Entries (subpackages) in the _CST Package must be sorted by the + * C-state type, in ascending order. + */ + Status = AcpiNsCheckSortedList (Info, ReturnObject, 1, 4, 1, + ACPI_SORT_ASCENDING, "C-State Type"); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + return (AE_OK); } diff --git a/source/components/namespace/nsxfname.c b/source/components/namespace/nsxfname.c index 619cec3..289ecd8 100644 --- a/source/components/namespace/nsxfname.c +++ b/source/components/namespace/nsxfname.c @@ -177,6 +177,7 @@ AcpiGetName ( { ACPI_STATUS Status; ACPI_NAMESPACE_NODE *Node; + char *NodeName; /* Parameter validation */ @@ -227,7 +228,8 @@ AcpiGetName ( /* Just copy the ACPI name from the Node and zero terminate it */ - ACPI_MOVE_NAME (Buffer->Pointer, AcpiUtGetNodeName (Node)); + NodeName = AcpiUtGetNodeName (Node); + ACPI_MOVE_NAME (Buffer->Pointer, NodeName); ((char *) Buffer->Pointer) [ACPI_NAME_SIZE] = 0; Status = AE_OK; @@ -423,9 +425,14 @@ AcpiGetObjectInfo ( * Get extra info for ACPI Device/Processor objects only: * Run the _STA, _ADR and, SxW, and _SxD methods. * - * Note: none of these methods are required, so they may or may + * Notes: none of these methods are required, so they may or may * not be present for this device. The Info->Valid bitfield is used * to indicate which methods were found and run successfully. + * + * For _STA, if the method does not exist, then (as per the ACPI + * specification), the returned CurrentStatus flags will indicate + * that the device is present/functional/enabled. Otherwise, the + * CurrentStatus flags reflect the value returned from _STA. */ /* Execute the Device._STA method */ diff --git a/source/components/resources/rsdump.c b/source/components/resources/rsdump.c index 4f72cdf..35d9a4a 100644 --- a/source/components/resources/rsdump.c +++ b/source/components/resources/rsdump.c @@ -203,7 +203,7 @@ AcpiRsDumpDescriptor ( break; case ACPI_RSD_UINT64: - + AcpiRsOutInteger64 (Name, ACPI_GET64 (Target)); break; diff --git a/source/components/resources/rsutils.c b/source/components/resources/rsutils.c index a453efe..04591d9 100644 --- a/source/components/resources/rsutils.c +++ b/source/components/resources/rsutils.c @@ -193,7 +193,7 @@ AcpiRsMoveData ( break; case ACPI_RSC_MOVE32: - + ACPI_MOVE_32_TO_32 (&ACPI_CAST_PTR (UINT32, Destination)[i], &ACPI_CAST_PTR (UINT32, Source)[i]); break; diff --git a/source/components/tables/tbxfroot.c b/source/components/tables/tbxfroot.c index 7e4d545..20cc0fa 100644 --- a/source/components/tables/tbxfroot.c +++ b/source/components/tables/tbxfroot.c @@ -53,11 +53,6 @@ /* Local prototypes */ -static UINT8 * -AcpiTbScanMemoryForRsdp ( - UINT8 *StartAddress, - UINT32 Length); - static ACPI_STATUS AcpiTbValidateRsdp ( ACPI_TABLE_RSDP *Rsdp); @@ -252,7 +247,7 @@ ACPI_EXPORT_SYMBOL (AcpiFindRootPointer) * ******************************************************************************/ -static UINT8 * +UINT8 * AcpiTbScanMemoryForRsdp ( UINT8 *StartAddress, UINT32 Length) diff --git a/source/components/utilities/uteval.c b/source/components/utilities/uteval.c index e24f2a2..472bd30 100644 --- a/source/components/utilities/uteval.c +++ b/source/components/utilities/uteval.c @@ -260,7 +260,8 @@ AcpiUtEvaluateNumericObject ( * RETURN: Status * * DESCRIPTION: Executes _STA for selected device and stores results in - * *Flags. + * *Flags. If _STA does not exist, then the device is assumed + * to be present/functional/enabled (as per the ACPI spec). * * NOTE: Internal function, no parameter validation * @@ -284,6 +285,11 @@ AcpiUtExecute_STA ( { if (AE_NOT_FOUND == Status) { + /* + * if _STA does not exist, then (as per the ACPI specification), + * the returned flags will indicate that the device is present, + * functional, and enabled. + */ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "_STA on %4.4s was not found, assuming device is present\n", AcpiUtGetNodeName (DeviceNode))); diff --git a/source/components/utilities/utstring.c b/source/components/utilities/utstring.c index 9e58908..9798700 100644 --- a/source/components/utilities/utstring.c +++ b/source/components/utilities/utstring.c @@ -395,7 +395,8 @@ ErrorExit: * FUNCTION: AcpiUtPrintString * * PARAMETERS: String - Null terminated ASCII string - * MaxLength - Maximum output length + * MaxLength - Maximum output length. Used to constrain the + * length of strings during debug output only. * * RETURN: None * @@ -407,7 +408,7 @@ ErrorExit: void AcpiUtPrintString ( char *String, - UINT8 MaxLength) + UINT16 MaxLength) { UINT32 i; diff --git a/source/include/acdisasm.h b/source/include/acdisasm.h index 5abf24e..84af4a6 100644 --- a/source/include/acdisasm.h +++ b/source/include/acdisasm.h @@ -108,6 +108,7 @@ typedef enum ACPI_DMT_UINT56, ACPI_DMT_UINT64, ACPI_DMT_BUF7, + ACPI_DMT_BUF10, ACPI_DMT_BUF16, ACPI_DMT_BUF128, ACPI_DMT_SIG, diff --git a/source/include/acpixf.h b/source/include/acpixf.h index 9f94e52..a334b2d 100644 --- a/source/include/acpixf.h +++ b/source/include/acpixf.h @@ -47,7 +47,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20130517 +#define ACPI_CA_VERSION 0x20130626 #include "acconfig.h" #include "actypes.h" diff --git a/source/include/actables.h b/source/include/actables.h index b16c6e3..3452a7b 100644 --- a/source/include/actables.h +++ b/source/include/actables.h @@ -50,6 +50,15 @@ AcpiAllocateRootTable ( UINT32 InitialTableCount); /* + * tbxfroot - Root pointer utilities + */ +UINT8 * +AcpiTbScanMemoryForRsdp ( + UINT8 *StartAddress, + UINT32 Length); + + +/* * tbfadt - FADT parse/convert/validate */ void diff --git a/source/include/actypes.h b/source/include/actypes.h index 840c146..09ccfdf 100644 --- a/source/include/actypes.h +++ b/source/include/actypes.h @@ -680,13 +680,6 @@ typedef UINT32 ACPI_EVENT_STATUS; #define ACPI_EVENT_FLAG_WAKE_ENABLED (ACPI_EVENT_STATUS) 0x02 #define ACPI_EVENT_FLAG_SET (ACPI_EVENT_STATUS) 0x04 -/* - * General Purpose Events (GPE) - */ -#define ACPI_GPE_INVALID 0xFF -#define ACPI_GPE_MAX 0xFF -#define ACPI_NUM_GPE 256 - /* Actions for AcpiSetGpe, AcpiGpeWakeup, AcpiHwLowSetGpe */ #define ACPI_GPE_ENABLE 0 diff --git a/source/include/acutils.h b/source/include/acutils.h index c79240c..c0ea533 100644 --- a/source/include/acutils.h +++ b/source/include/acutils.h @@ -903,7 +903,7 @@ AcpiUtStrtoul64 ( void AcpiUtPrintString ( char *String, - UINT8 MaxLength); + UINT16 MaxLength); void UtConvertBackslashes ( diff --git a/source/os_specific/service_layers/osfreebsdtbl.c b/source/os_specific/service_layers/osfreebsdtbl.c new file mode 100644 index 0000000..3df4845 --- /dev/null +++ b/source/os_specific/service_layers/osfreebsdtbl.c @@ -0,0 +1,992 @@ +/****************************************************************************** + * + * Module Name: osfreebsdtbl - FreeBSD OSL for obtaining ACPI tables + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2013, 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 "acpidump.h" + +#include +#include +#include +#include +#include + + +#define _COMPONENT ACPI_OS_SERVICES + ACPI_MODULE_NAME ("osfreebsdtbl") + + +/* Local prototypes */ + +static ACPI_STATUS +OslTableInitialize ( + void); + +static ACPI_STATUS +OslMapTable ( + ACPI_SIZE Address, + char *Signature, + ACPI_TABLE_HEADER **Table); + +static ACPI_STATUS +OslAddTablesToList ( + void); + +static ACPI_STATUS +OslGetTableViaRoot ( + char *Signature, + UINT32 Instance, + ACPI_TABLE_HEADER **Table, + ACPI_PHYSICAL_ADDRESS *Address); + + +/* File locations */ + +#define SYSTEM_MEMORY "/dev/mem" + +/* Hints for RSDP */ + +#define SYSTEM_KENV "hint.acpi.0.rsdp" +#define SYSTEM_SYSCTL "machdep.acpi_root" + +/* Initialization flags */ + +UINT8 Gbl_TableListInitialized = FALSE; +UINT8 Gbl_MainTableObtained = FALSE; + +/* Local copies of main ACPI tables */ + +ACPI_TABLE_RSDP Gbl_Rsdp; +ACPI_TABLE_FADT *Gbl_Fadt; +ACPI_TABLE_RSDT *Gbl_Rsdt; +ACPI_TABLE_XSDT *Gbl_Xsdt; + +/* Fadt address */ + +ACPI_PHYSICAL_ADDRESS Gbl_FadtAddress; + +/* Revision of RSD PTR */ + +UINT8 Gbl_Revision; + +/* List of information about obtained ACPI tables */ + +typedef struct table_info +{ + struct table_info *Next; + char Signature[4]; + UINT32 Instance; + ACPI_PHYSICAL_ADDRESS Address; + +} OSL_TABLE_INFO; + +OSL_TABLE_INFO *Gbl_TableListHead = NULL; + + +/****************************************************************************** + * + * FUNCTION: AcpiOsGetTableByAddress + * + * PARAMETERS: Address - Physical address of the ACPI table + * Table - Where a pointer to the table is returned + * + * RETURN: Status; Table buffer is returned if AE_OK. + * AE_NOT_FOUND: A valid table was not found at the address + * + * DESCRIPTION: Get an ACPI table via a physical memory address. + * + *****************************************************************************/ + +ACPI_STATUS +AcpiOsGetTableByAddress ( + ACPI_PHYSICAL_ADDRESS Address, + ACPI_TABLE_HEADER **Table) +{ + ACPI_TABLE_HEADER *MappedTable; + ACPI_TABLE_HEADER *LocalTable; + ACPI_STATUS Status; + + + /* Validate the input physical address to avoid program crash */ + + if (Address < ACPI_HI_RSDP_WINDOW_BASE) + { + fprintf (stderr, "Invalid table address: 0x%8.8X%8.8X\n", + ACPI_FORMAT_UINT64 (Address)); + return (AE_BAD_ADDRESS); + } + + /* Map the table and validate it */ + + Status = OslMapTable (Address, NULL, &MappedTable); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* Copy table to local buffer and return it */ + + LocalTable = calloc (1, MappedTable->Length); + if (!LocalTable) + { + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + return (AE_NO_MEMORY); + } + + ACPI_MEMCPY (LocalTable, MappedTable, MappedTable->Length); + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + + *Table = LocalTable; + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiOsGetTableByName + * + * PARAMETERS: Signature - ACPI Signature for desired table. Must be + * a null terminated 4-character string. + * Instance - Multiple table support for SSDT/UEFI (0...n) + * Must be 0 for other tables. + * Table - Where a pointer to the table is returned + * Address - Where the table physical address is returned + * + * RETURN: Status; Table buffer and physical address returned if AE_OK. + * AE_LIMIT: Instance is beyond valid limit + * AE_NOT_FOUND: A table with the signature was not found + * + * NOTE: Assumes the input signature is uppercase. + * + *****************************************************************************/ + +ACPI_STATUS +AcpiOsGetTableByName ( + char *Signature, + UINT32 Instance, + ACPI_TABLE_HEADER **Table, + ACPI_PHYSICAL_ADDRESS *Address) +{ + ACPI_STATUS Status; + + + /* Instance is only valid for SSDT/UEFI tables */ + + if (Instance && + !ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT) && + !ACPI_COMPARE_NAME (Signature, ACPI_SIG_UEFI)) + { + return (AE_LIMIT); + } + + /* Initialize main tables */ + + Status = OslTableInitialize (); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* + * If one of the main ACPI tables was requested (RSDT/XSDT/FADT), + * simply return it immediately. + */ + if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_XSDT)) + { + if (!Gbl_Revision) + { + return (AE_NOT_FOUND); + } + + *Address = Gbl_Rsdp.XsdtPhysicalAddress; + *Table = (ACPI_TABLE_HEADER *) Gbl_Xsdt; + return (AE_OK); + } + + if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_RSDT)) + { + if (!Gbl_Rsdp.RsdtPhysicalAddress) + { + return (AE_NOT_FOUND); + } + + *Address = Gbl_Rsdp.RsdtPhysicalAddress; + *Table = (ACPI_TABLE_HEADER *) Gbl_Rsdt; + return (AE_OK); + } + + if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FADT)) + { + *Address = Gbl_FadtAddress; + *Table = (ACPI_TABLE_HEADER *) Gbl_Fadt; + return (AE_OK); + } + + /* Not a main ACPI table, attempt to extract it from the RSDT/XSDT */ + + Status = OslGetTableViaRoot (Signature, Instance, Table, Address); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiOsGetTableByIndex + * + * PARAMETERS: Index - Which table to get + * Table - Where a pointer to the table is returned + * Address - Where the table physical address is returned + * + * RETURN: Status; Table buffer and physical address returned if AE_OK. + * AE_LIMIT: Index is beyond valid limit + * + * DESCRIPTION: Get an ACPI table via an index value (0 through n). Returns + * AE_LIMIT when an invalid index is reached. Index is not + * necessarily an index into the RSDT/XSDT. + * + *****************************************************************************/ + +ACPI_STATUS +AcpiOsGetTableByIndex ( + UINT32 Index, + ACPI_TABLE_HEADER **Table, + ACPI_PHYSICAL_ADDRESS *Address) +{ + OSL_TABLE_INFO *Info; + ACPI_STATUS Status; + UINT32 i; + + + /* Initialize main tables */ + + Status = OslTableInitialize (); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* Add all tables to list */ + + Status = OslAddTablesToList (); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* Validate Index */ + + if (Index >= Gbl_TableListHead->Instance) + { + return (AE_LIMIT); + } + + /* Point to the table list entry specified by the Index argument */ + + Info = Gbl_TableListHead; + for (i = 0; i <= Index; i++) + { + Info = Info->Next; + } + + /* Now we can just get the table via the address or name */ + + if (Info->Address) + { + Status = AcpiOsGetTableByAddress (Info->Address, Table); + if (ACPI_SUCCESS (Status)) + { + *Address = Info->Address; + } + } + else + { + Status = AcpiOsGetTableByName (Info->Signature, Info->Instance, + Table, Address); + } + return (Status); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiOsMapMemory + * + * PARAMETERS: Where - Physical address of memory to be mapped + * Length - How much memory to map + * + * RETURN: Pointer to mapped memory. Null on error. + * + * DESCRIPTION: Map physical memory into local address space. + * + *****************************************************************************/ + +void * +AcpiOsMapMemory ( + ACPI_PHYSICAL_ADDRESS Where, + ACPI_SIZE Length) +{ + UINT8 *MappedMemory; + ACPI_PHYSICAL_ADDRESS Offset; + int fd; + + + fd = open (SYSTEM_MEMORY, O_RDONLY); + if (fd < 0) + { + fprintf (stderr, "Cannot open %s\n", SYSTEM_MEMORY); + return (NULL); + } + + /* Align the offset to use mmap */ + + Offset = Where % PAGE_SIZE; + + /* Map the table header to get the length of the full table */ + + MappedMemory = mmap (NULL, (Length + Offset), PROT_READ, MAP_SHARED, + fd, (Where - Offset)); + close (fd); + + if (MappedMemory == MAP_FAILED) + { + fprintf (stderr, + "Could not map memory at 0x%8.8X%8.8X length 0x%8.8X%8.8X\n", + ACPI_FORMAT_UINT64 (Where), ACPI_FORMAT_NATIVE_UINT (Length)); + return (NULL); + } + + return (ACPI_CAST8 (MappedMemory + Offset)); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiOsUnmapMemory + * + * PARAMETERS: Where - Logical address of memory to be unmapped + * Length - How much memory to unmap + * + * RETURN: None. + * + * DESCRIPTION: Delete a previously created mapping. Where and Length must + * correspond to a previous mapping exactly. + * + *****************************************************************************/ + +void +AcpiOsUnmapMemory ( + void *Where, + ACPI_SIZE Length) +{ + ACPI_PHYSICAL_ADDRESS Offset; + + + Offset = (ACPI_PHYSICAL_ADDRESS) Where % PAGE_SIZE; + munmap ((UINT8 *) Where - Offset, (Length + Offset)); +} + + +/****************************************************************************** + * + * FUNCTION: OslTableInitialize + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Initialize ACPI table data. Get and store main ACPI tables to + * local variables. Main ACPI tables include RSDP, FADT, RSDT, + * and/or XSDT. + * + *****************************************************************************/ + +static ACPI_STATUS +OslTableInitialize ( + void) +{ + char Buffer[32]; + ACPI_TABLE_HEADER *MappedTable; + UINT8 *TableAddress; + UINT8 *RsdpAddress; + ACPI_PHYSICAL_ADDRESS RsdpBase; + ACPI_SIZE RsdpSize; + ACPI_STATUS Status; + u_long Address = 0; + size_t Length = sizeof (Address); + + + /* Get main ACPI tables from memory on first invocation of this function */ + + if (Gbl_MainTableObtained) + { + return (AE_OK); + } + + /* Attempt to use kenv or sysctl to find RSD PTR record. */ + + if (kenv (KENV_GET, SYSTEM_KENV, Buffer, sizeof (Buffer)) > 0) + { + Address = ACPI_STRTOUL (Buffer, NULL, 0); + } + if (!Address) + { + if (sysctlbyname (SYSTEM_SYSCTL, &Address, &Length, NULL, 0) != 0) + { + Address = 0; + } + } + if (Address) + { + RsdpBase = Address; + RsdpSize = sizeof (Gbl_Rsdp); + } + else + { + RsdpBase = ACPI_HI_RSDP_WINDOW_BASE; + RsdpSize = ACPI_HI_RSDP_WINDOW_SIZE; + } + + /* Get RSDP from memory */ + + RsdpAddress = AcpiOsMapMemory (RsdpBase, RsdpSize); + if (!RsdpAddress) + { + return (AE_BAD_ADDRESS); + } + + /* Search low memory for the RSDP */ + + TableAddress = AcpiTbScanMemoryForRsdp (RsdpAddress, RsdpSize); + if (!TableAddress) + { + AcpiOsUnmapMemory (RsdpAddress, RsdpSize); + return (AE_ERROR); + } + + ACPI_MEMCPY (&Gbl_Rsdp, TableAddress, sizeof (Gbl_Rsdp)); + AcpiOsUnmapMemory (RsdpAddress, RsdpSize); + + /* Get XSDT from memory */ + + if (Gbl_Rsdp.Revision) + { + Status = OslMapTable (Gbl_Rsdp.XsdtPhysicalAddress, + ACPI_SIG_XSDT, &MappedTable); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + Gbl_Revision = 2; + Gbl_Xsdt = calloc (1, MappedTable->Length); + if (!Gbl_Xsdt) + { + fprintf (stderr, + "XSDT: Could not allocate buffer for table of length %X\n", + MappedTable->Length); + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + return (AE_NO_MEMORY); + } + + ACPI_MEMCPY (Gbl_Xsdt, MappedTable, MappedTable->Length); + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + } + + /* Get RSDT from memory */ + + if (Gbl_Rsdp.RsdtPhysicalAddress) + { + Status = OslMapTable (Gbl_Rsdp.RsdtPhysicalAddress, + ACPI_SIG_RSDT, &MappedTable); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + Gbl_Rsdt = calloc (1, MappedTable->Length); + if (!Gbl_Rsdt) + { + fprintf (stderr, + "RSDT: Could not allocate buffer for table of length %X\n", + MappedTable->Length); + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + return (AE_NO_MEMORY); + } + + ACPI_MEMCPY (Gbl_Rsdt, MappedTable, MappedTable->Length); + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + } + + /* Get FADT from memory */ + + if (Gbl_Revision) + { + Gbl_FadtAddress = Gbl_Xsdt->TableOffsetEntry[0]; + } + else + { + Gbl_FadtAddress = Gbl_Rsdt->TableOffsetEntry[0]; + } + + if (!Gbl_FadtAddress) + { + fprintf(stderr, "FADT: Table could not be found\n"); + return (AE_ERROR); + } + + Status = OslMapTable (Gbl_FadtAddress, ACPI_SIG_FADT, &MappedTable); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + Gbl_Fadt = calloc (1, MappedTable->Length); + if (!Gbl_Fadt) + { + fprintf (stderr, + "FADT: Could not allocate buffer for table of length %X\n", + MappedTable->Length); + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + return (AE_NO_MEMORY); + } + + ACPI_MEMCPY (Gbl_Fadt, MappedTable, MappedTable->Length); + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + Gbl_MainTableObtained = TRUE; + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: OslGetTableViaRoot + * + * PARAMETERS: Signature - ACPI Signature for common table. Must be + * a null terminated 4-character string. + * Instance - Multiple table support for SSDT/UEFI (0...n) + * Must be 0 for other tables. + * Table - Where a pointer to the table is returned + * Address - Where the table physical address is returned + * + * RETURN: Status; Table buffer and physical address returned if AE_OK. + * AE_LIMIT: Instance is beyond valid limit + * AE_NOT_FOUND: A table with the signature was not found + * + * DESCRIPTION: Get an ACPI table via the root table (RSDT/XSDT) + * + * NOTE: Assumes the input signature is uppercase. + * + *****************************************************************************/ + +static ACPI_STATUS +OslGetTableViaRoot ( + char *Signature, + UINT32 Instance, + ACPI_TABLE_HEADER **Table, + ACPI_PHYSICAL_ADDRESS *Address) +{ + ACPI_TABLE_HEADER *LocalTable = NULL; + ACPI_TABLE_HEADER *MappedTable = NULL; + UINT8 NumberOfTables; + UINT32 CurrentInstance = 0; + ACPI_PHYSICAL_ADDRESS TableAddress = 0; + ACPI_STATUS Status; + UINT32 i; + + + /* DSDT and FACS address must be extracted from the FADT */ + + if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT) || + ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS)) + { + /* + * Get the appropriate address, either 32-bit or 64-bit. Be very + * careful about the FADT length and validate table addresses. + * Note: The 64-bit addresses have priority. + */ + if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT)) + { + if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XDSDT) && + Gbl_Fadt->XDsdt) + { + TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XDsdt; + } + else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_DSDT) && + Gbl_Fadt->Dsdt) + { + TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Dsdt; + } + } + else /* FACS */ + { + if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XFACS) && + Gbl_Fadt->XFacs) + { + TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XFacs; + } + else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_FACS) && + Gbl_Fadt->Facs) + { + TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Facs; + } + } + } + else /* Case for a normal ACPI table */ + { + if (Gbl_Revision) + { + NumberOfTables = + (Gbl_Xsdt->Header.Length - sizeof (Gbl_Xsdt->Header)) + / sizeof (Gbl_Xsdt->TableOffsetEntry[0]); + } + else /* Use RSDT if XSDT is not available */ + { + NumberOfTables = + (Gbl_Rsdt->Header.Length - sizeof (Gbl_Rsdt->Header)) + / sizeof (Gbl_Rsdt->TableOffsetEntry[0]); + } + + /* Search RSDT/XSDT for the requested table */ + + for (i = 0; i < NumberOfTables; i++) + { + if (Gbl_Revision) + { + TableAddress = Gbl_Xsdt->TableOffsetEntry[i]; + } + else + { + TableAddress = Gbl_Rsdt->TableOffsetEntry[i]; + } + + MappedTable = AcpiOsMapMemory (TableAddress, sizeof (*MappedTable)); + if (!MappedTable) + { + return (AE_BAD_ADDRESS); + } + + /* Does this table match the requested signature? */ + + if (ACPI_COMPARE_NAME (MappedTable->Signature, Signature)) + { + + /* Match table instance (for SSDT/UEFI tables) */ + + if (CurrentInstance == Instance) + { + AcpiOsUnmapMemory (MappedTable, sizeof (*MappedTable)); + break; + } + + CurrentInstance++; + } + + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + TableAddress = 0; + } + } + + if (!TableAddress) + { + if (CurrentInstance) + { + return (AE_LIMIT); + } + return (AE_NOT_FOUND); + } + + /* Now we can get the requested table */ + + Status = OslMapTable (TableAddress, Signature, &MappedTable); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* Copy table to local buffer and return it */ + + LocalTable = calloc (1, MappedTable->Length); + if (!LocalTable) + { + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + return (AE_NO_MEMORY); + } + + ACPI_MEMCPY (LocalTable, MappedTable, MappedTable->Length); + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + *Table = LocalTable; + *Address = TableAddress; + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: OslAddTablesToList + * + * PARAMETERS: None + * + * RETURN: Status; Table list is initialized if AE_OK. + * + * DESCRIPTION: Add ACPI tables to the table list. + * + *****************************************************************************/ + +static ACPI_STATUS +OslAddTablesToList( + void) +{ + ACPI_PHYSICAL_ADDRESS TableAddress; + OSL_TABLE_INFO *Info = NULL; + OSL_TABLE_INFO *NewInfo; + ACPI_TABLE_HEADER *Table; + UINT8 Instance; + UINT8 NumberOfTables; + int i; + + + /* Initialize the table list on first invocation */ + + if (Gbl_TableListInitialized) + { + return (AE_OK); + } + + /* Add mandatory tables to global table list first */ + + for (i = 0; i < 4; i++) + { + NewInfo = calloc (1, sizeof (*NewInfo)); + if (!NewInfo) + { + return (AE_NO_MEMORY); + } + + switch (i) { + case 0: + + Gbl_TableListHead = Info = NewInfo; + continue; + + case 1: + + ACPI_MOVE_NAME (NewInfo->Signature, + Gbl_Revision ? ACPI_SIG_XSDT : ACPI_SIG_RSDT); + break; + + case 2: + + ACPI_MOVE_NAME (NewInfo->Signature, ACPI_SIG_FACS); + break; + + default: + + ACPI_MOVE_NAME (NewInfo->Signature, ACPI_SIG_DSDT); + + } + + Info->Next = NewInfo; + Info = NewInfo; + Gbl_TableListHead->Instance++; + } + + /* Add normal tables from RSDT/XSDT to global list */ + + if (Gbl_Revision) + { + NumberOfTables = + (Gbl_Xsdt->Header.Length - sizeof (Gbl_Xsdt->Header)) + / sizeof (Gbl_Xsdt->TableOffsetEntry[0]); + } + else + { + NumberOfTables = + (Gbl_Rsdt->Header.Length - sizeof (Gbl_Rsdt->Header)) + / sizeof (Gbl_Rsdt->TableOffsetEntry[0]); + } + + for (i = 0; i < NumberOfTables; i++) + { + if (Gbl_Revision) + { + TableAddress = Gbl_Xsdt->TableOffsetEntry[i]; + } + else + { + TableAddress = Gbl_Rsdt->TableOffsetEntry[i]; + } + + Table = AcpiOsMapMemory (TableAddress, sizeof (*Table)); + if (!Table) + { + return (AE_BAD_ADDRESS); + } + + Instance = 0; + NewInfo = Gbl_TableListHead; + while (NewInfo->Next != NULL) + { + NewInfo = NewInfo->Next; + if (ACPI_COMPARE_NAME (Table->Signature, NewInfo->Signature)) + { + Instance++; + } + } + + NewInfo = calloc (1, sizeof (*NewInfo)); + if (!NewInfo) + { + AcpiOsUnmapMemory (Table, sizeof (*Table)); + return (AE_NO_MEMORY); + } + + ACPI_MOVE_NAME (NewInfo->Signature, Table->Signature); + + AcpiOsUnmapMemory (Table, sizeof (*Table)); + + NewInfo->Instance = Instance; + NewInfo->Address = TableAddress; + Info->Next = NewInfo; + Info = NewInfo; + Gbl_TableListHead->Instance++; + } + + Gbl_TableListInitialized = TRUE; + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: OslMapTable + * + * PARAMETERS: Address - Address of the table in memory + * Signature - Optional ACPI Signature for desired table. + * Null terminated 4-character string. + * Table - Where a pointer to the mapped table is + * returned + * + * RETURN: Status; Mapped table is returned if AE_OK. + * + * DESCRIPTION: Map entire ACPI table into caller's address space. Also + * validates the table and checksum. + * + *****************************************************************************/ + +static ACPI_STATUS +OslMapTable ( + ACPI_SIZE Address, + char *Signature, + ACPI_TABLE_HEADER **Table) +{ + ACPI_TABLE_HEADER *MappedTable; + UINT32 Length; + + + /* Map the header so we can get the table length */ + + MappedTable = AcpiOsMapMemory (Address, sizeof (*MappedTable)); + if (!MappedTable) + { + return (AE_BAD_ADDRESS); + } + + /* Check if table is valid */ + + if (!ApIsValidHeader (MappedTable)) + { + AcpiOsUnmapMemory (MappedTable, sizeof (*MappedTable)); + return (AE_BAD_HEADER); + } + + /* If specified, signature must match */ + + if (Signature && + !ACPI_COMPARE_NAME (Signature, MappedTable->Signature)) + { + AcpiOsUnmapMemory (MappedTable, sizeof (*MappedTable)); + return (AE_NOT_EXIST); + } + + /* Map the entire table */ + + Length = MappedTable->Length; + AcpiOsUnmapMemory (MappedTable, sizeof (*MappedTable)); + + MappedTable = AcpiOsMapMemory (Address, Length); + if (!MappedTable) + { + return (AE_BAD_ADDRESS); + } + + *Table = MappedTable; + + /* Checksum for RSDP */ + + if (!ACPI_STRNCMP (MappedTable->Signature, ACPI_SIG_RSDP, + sizeof (ACPI_SIG_RSDP) - 1)) + { + /* Check the standard checksum */ + + if (AcpiTbChecksum ((UINT8 *) MappedTable, ACPI_RSDP_CHECKSUM_LENGTH)) + { + fprintf (stderr, "Warning: wrong checksum for RSDP\n"); + } + + /* Check extended checksum if table version >= 2 */ + + if (MappedTable->Revision) + { + if (AcpiTbChecksum ((UINT8 *) MappedTable, + ACPI_RSDP_XCHECKSUM_LENGTH)) + { + fprintf (stderr, "Warning: wrong checksum for RSDP\n"); + } + } + } + + return (AE_OK); +} diff --git a/source/os_specific/service_layers/oslinuxtbl.c b/source/os_specific/service_layers/oslinuxtbl.c index 2d1be3f..67a5e02 100644 --- a/source/os_specific/service_layers/oslinuxtbl.c +++ b/source/os_specific/service_layers/oslinuxtbl.c @@ -41,15 +41,112 @@ * POSSIBILITY OF SUCH DAMAGES. */ -#include "acpi.h" +#include "acpidump.h" + +#include +#include -#include -#include #define _COMPONENT ACPI_OS_SERVICES ACPI_MODULE_NAME ("oslinuxtbl") +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#ifndef PATH_MAX +#define PATH_MAX 256 +#endif + + +/* Local prototypes */ + +static ACPI_STATUS +OslTableInitialize ( + void); + +static ACPI_STATUS +OslReadTableFromFile ( + FILE *TableFile, + ACPI_SIZE FileOffset, + char *Signature, + ACPI_TABLE_HEADER **Table); + +static ACPI_STATUS +OslMapTable ( + ACPI_SIZE Address, + char *Signature, + ACPI_TABLE_HEADER **Table); + +static ACPI_STATUS +OslGetOverrideTable ( + char *Signature, + UINT32 Instance, + ACPI_TABLE_HEADER **Table, + ACPI_PHYSICAL_ADDRESS *Address); + +static ACPI_STATUS +OslGetDynamicSsdt ( + UINT32 Instance, + ACPI_TABLE_HEADER **Table, + ACPI_PHYSICAL_ADDRESS *Address); + +static ACPI_STATUS +OslAddTablesToList ( + char *Directory); + +static ACPI_STATUS +OslGetTableViaRoot ( + char *Signature, + UINT32 Instance, + ACPI_TABLE_HEADER **Table, + ACPI_PHYSICAL_ADDRESS *Address); + + +/* File locations */ + +#define DYNAMIC_SSDT_DIR "/sys/firmware/acpi/tables/dynamic" +#define OVERRIDE_TABLE_DIR "/sys/firmware/acpi/tables" +#define SYSTEM_MEMORY "/dev/mem" + +/* Should we get dynamically loaded SSDTs from DYNAMIC_SSDT_DIR? */ + +UINT8 Gbl_DumpDynamicSsdts = TRUE; + +/* Initialization flags */ + +UINT8 Gbl_TableListInitialized = FALSE; +UINT8 Gbl_MainTableObtained = FALSE; + +/* Local copies of main ACPI tables */ + +ACPI_TABLE_RSDP Gbl_Rsdp; +ACPI_TABLE_FADT *Gbl_Fadt; +ACPI_TABLE_RSDT *Gbl_Rsdt; +ACPI_TABLE_XSDT *Gbl_Xsdt; + +/* Fadt address */ + +ACPI_PHYSICAL_ADDRESS Gbl_FadtAddress; + +/* Revision of RSD PTR */ + +UINT8 Gbl_Revision; + +/* List of information about obtained ACPI tables */ + +typedef struct table_info +{ + struct table_info *Next; + UINT32 Instance; + char Signature[4]; + +} OSL_TABLE_INFO; + +OSL_TABLE_INFO *Gbl_TableListHead = NULL; + + /****************************************************************************** * * FUNCTION: AcpiOsGetTableByAddress @@ -69,9 +166,150 @@ AcpiOsGetTableByAddress ( ACPI_PHYSICAL_ADDRESS Address, ACPI_TABLE_HEADER **Table) { + ACPI_TABLE_HEADER *MappedTable; + ACPI_TABLE_HEADER *LocalTable; + ACPI_STATUS Status; + + + /* Validate the input physical address to avoid program crash */ + + if (Address < ACPI_HI_RSDP_WINDOW_BASE) + { + fprintf (stderr, "Invalid table address: 0x%8.8X%8.8X\n", + ACPI_FORMAT_UINT64 (Address)); + return (AE_BAD_ADDRESS); + } + + /* Map the table and validate it */ + + Status = OslMapTable (Address, NULL, &MappedTable); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* Copy table to local buffer and return it */ + + LocalTable = calloc (1, MappedTable->Length); + if (!LocalTable) + { + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + return (AE_NO_MEMORY); + } + + ACPI_MEMCPY (LocalTable, MappedTable, MappedTable->Length); + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + + *Table = LocalTable; + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiOsGetTableByName + * + * PARAMETERS: Signature - ACPI Signature for desired table. Must be + * a null terminated 4-character string. + * Instance - Multiple table support for SSDT/UEFI (0...n) + * Must be 0 for other tables. + * Table - Where a pointer to the table is returned + * Address - Where the table physical address is returned + * + * RETURN: Status; Table buffer and physical address returned if AE_OK. + * AE_LIMIT: Instance is beyond valid limit + * AE_NOT_FOUND: A table with the signature was not found + * + * NOTE: Assumes the input signature is uppercase. + * + *****************************************************************************/ + +ACPI_STATUS +AcpiOsGetTableByName ( + char *Signature, + UINT32 Instance, + ACPI_TABLE_HEADER **Table, + ACPI_PHYSICAL_ADDRESS *Address) +{ + ACPI_STATUS Status; + + + /* Instance is only valid for SSDTs */ + + if (Instance && + !ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT) && + !ACPI_COMPARE_NAME (Signature, ACPI_SIG_UEFI)) + { + return (AE_LIMIT); + } + + /* Get main ACPI tables from memory on first invocation of this function */ + + if (!Gbl_MainTableObtained) + { + Status = OslTableInitialize (); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + Gbl_MainTableObtained = TRUE; + } - fprintf (stderr, "Linux version not implemented yet\n"); - return (AE_SUPPORT); + /* + * If one of the main ACPI tables was requested (RSDT/XSDT/FADT), + * simply return it immediately. + */ + if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_XSDT)) + { + if (!Gbl_Revision) + { + return (AE_NOT_FOUND); + } + + *Address = Gbl_Rsdp.XsdtPhysicalAddress; + *Table = (ACPI_TABLE_HEADER *) Gbl_Xsdt; + return (AE_OK); + } + + if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_RSDT)) + { + if (!Gbl_Rsdp.RsdtPhysicalAddress) + { + return (AE_NOT_FOUND); + } + + *Address = Gbl_Rsdp.RsdtPhysicalAddress; + *Table = (ACPI_TABLE_HEADER *) Gbl_Rsdt; + return (AE_OK); + } + + if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FADT)) + { + *Address = Gbl_FadtAddress; + *Table = (ACPI_TABLE_HEADER *) Gbl_Fadt; + return (AE_OK); + } + + /* Not a main ACPI table, attempt to extract it from the RSDT/XSDT */ + + Status = OslGetTableViaRoot (Signature, Instance, Table, Address); + if (ACPI_FAILURE (Status)) + { + /* Attempt to get the table from the override directory */ + + Status = OslGetOverrideTable (Signature, Instance, Table, Address); + if ((Status == AE_LIMIT) && Gbl_DumpDynamicSsdts) + { + /* Attempt to get a dynamic SSDT */ + + Status = OslGetDynamicSsdt (Instance, Table, Address); + } + + return (Status); + } + + return (AE_OK); } @@ -98,40 +336,991 @@ AcpiOsGetTableByIndex ( ACPI_TABLE_HEADER **Table, ACPI_PHYSICAL_ADDRESS *Address) { + OSL_TABLE_INFO *Info; + ACPI_STATUS Status; + UINT32 i; + - fprintf (stderr, "Linux version not implemented yet\n"); - return (AE_SUPPORT); + /* Initialize the table list on first invocation */ + + if (!Gbl_TableListInitialized) + { + Gbl_TableListHead = calloc (1, sizeof (OSL_TABLE_INFO)); + + /* List head records the length of the list */ + + Gbl_TableListHead->Instance = 0; + + /* Add all tables found in the override directory */ + + Status = OslAddTablesToList (OVERRIDE_TABLE_DIR); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* Add all dynamically loaded SSDTs in the dynamic directory */ + + OslAddTablesToList (DYNAMIC_SSDT_DIR); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + Gbl_TableListInitialized = TRUE; + } + + /* Validate Index */ + + if (Index >= Gbl_TableListHead->Instance) + { + return (AE_LIMIT); + } + + /* Point to the table list entry specified by the Index argument */ + + Info = Gbl_TableListHead; + for (i = 0; i <= Index; i++) + { + Info = Info->Next; + } + + /* Now we can just get the table via the signature */ + + Status = AcpiOsGetTableByName (Info->Signature, Info->Instance, + Table, Address); + return (Status); } /****************************************************************************** * - * FUNCTION: AcpiOsGetTableByName + * FUNCTION: AcpiOsMapMemory * - * PARAMETERS: Signature - ACPI Signature for desired table. Must be + * PARAMETERS: Where - Physical address of memory to be mapped + * Length - How much memory to map + * + * RETURN: Pointer to mapped memory. Null on error. + * + * DESCRIPTION: Map physical memory into local address space. + * + *****************************************************************************/ + +void * +AcpiOsMapMemory ( + ACPI_PHYSICAL_ADDRESS Where, + ACPI_SIZE Length) +{ + UINT8 *MappedMemory; + ACPI_PHYSICAL_ADDRESS Offset; + ACPI_SIZE PageSize; + int fd; + + + fd = open (SYSTEM_MEMORY, O_RDONLY | O_BINARY); + if (fd < 0) + { + fprintf (stderr, "Cannot open %s\n", SYSTEM_MEMORY); + return (NULL); + } + + /* Align the offset to use mmap */ + + PageSize = sysconf (_SC_PAGESIZE); + Offset = Where % PageSize; + + /* Map the table header to get the length of the full table */ + + MappedMemory = mmap (NULL, (Length + Offset), PROT_READ, MAP_PRIVATE, + fd, (Where - Offset)); + close (fd); + + if (MappedMemory == MAP_FAILED) + { + return (NULL); + } + + return (ACPI_CAST8 (MappedMemory + Offset)); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiOsUnmapMemory + * + * PARAMETERS: Where - Logical address of memory to be unmapped + * Length - How much memory to unmap + * + * RETURN: None. + * + * DESCRIPTION: Delete a previously created mapping. Where and Length must + * correspond to a previous mapping exactly. + * + *****************************************************************************/ + +void +AcpiOsUnmapMemory ( + void *Where, + ACPI_SIZE Length) +{ + ACPI_PHYSICAL_ADDRESS Offset; + ACPI_SIZE PageSize; + + + PageSize = sysconf (_SC_PAGESIZE); + Offset = (ACPI_PHYSICAL_ADDRESS) Where % PageSize; + munmap ((UINT8 *) Where - Offset, (Length + Offset)); +} + + +/****************************************************************************** + * + * FUNCTION: OslTableInitialize + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Initialize ACPI table data. Get and store main ACPI tables to + * local variables. Main ACPI tables include RSDT, FADT, RSDT, + * and/or XSDT. + * + *****************************************************************************/ + +static ACPI_STATUS +OslTableInitialize ( + void) +{ + ACPI_TABLE_HEADER *MappedTable; + UINT8 *TableData; + UINT8 *RsdpAddress; + ACPI_PHYSICAL_ADDRESS RsdpBase; + ACPI_SIZE RsdpSize; + ACPI_STATUS Status; + + + /* Get RSDP from memory */ + + RsdpBase = ACPI_HI_RSDP_WINDOW_BASE; + RsdpSize = ACPI_HI_RSDP_WINDOW_SIZE; + + RsdpAddress = AcpiOsMapMemory (RsdpBase, RsdpSize); + if (!RsdpAddress) + { + return (AE_BAD_ADDRESS); + } + + /* Search low memory for the RSDP */ + + MappedTable = ACPI_CAST_PTR (ACPI_TABLE_HEADER, + AcpiTbScanMemoryForRsdp (RsdpAddress, RsdpSize)); + if (!MappedTable) + { + AcpiOsUnmapMemory (RsdpAddress, RsdpSize); + return (AE_ERROR); + } + + ACPI_MEMCPY (&Gbl_Rsdp, MappedTable, sizeof (ACPI_TABLE_RSDP)); + AcpiOsUnmapMemory (RsdpAddress, RsdpSize); + + /* Get XSDT from memory */ + + if (Gbl_Rsdp.Revision) + { + Status = OslMapTable (Gbl_Rsdp.XsdtPhysicalAddress, + ACPI_SIG_XSDT, &MappedTable); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + Gbl_Revision = 2; + Gbl_Xsdt = calloc (1, MappedTable->Length); + if (!Gbl_Xsdt) + { + fprintf (stderr, + "XSDT: Could not allocate buffer for table of length %X\n", + MappedTable->Length); + return (AE_NO_MEMORY); + } + + ACPI_MEMCPY (Gbl_Xsdt, MappedTable, MappedTable->Length); + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + } + + /* Get RSDT from memory */ + + if (Gbl_Rsdp.RsdtPhysicalAddress) + { + Status = OslMapTable (Gbl_Rsdp.RsdtPhysicalAddress, + ACPI_SIG_RSDT, &MappedTable); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + Gbl_Rsdt = calloc (1, MappedTable->Length); + if (!Gbl_Rsdt) + { + fprintf (stderr, + "RSDT: Could not allocate buffer for table of length %X\n", + MappedTable->Length); + return (AE_NO_MEMORY); + } + + ACPI_MEMCPY (Gbl_Rsdt, MappedTable, MappedTable->Length); + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + } + + /* Get FADT from memory */ + + if (Gbl_Revision) + { + TableData = ACPI_CAST8 (Gbl_Xsdt) + sizeof (ACPI_TABLE_HEADER); + Gbl_FadtAddress = (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST64 (TableData)); + } + else + { + TableData = ACPI_CAST8 (Gbl_Rsdt) + sizeof (ACPI_TABLE_HEADER); + Gbl_FadtAddress = (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST32 (TableData)); + } + + if (!Gbl_FadtAddress) + { + fprintf(stderr, "FADT: Table could not be found\n"); + return (AE_ERROR); + } + + Status = OslMapTable (Gbl_FadtAddress, ACPI_SIG_FADT, &MappedTable); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + Gbl_Fadt = calloc (1, MappedTable->Length); + if (!Gbl_Fadt) + { + fprintf (stderr, + "FADT: Could not allocate buffer for table of length %X\n", + MappedTable->Length); + return (AE_NO_MEMORY); + } + + ACPI_MEMCPY (Gbl_Fadt, MappedTable, MappedTable->Length); + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: OslGetTableViaRoot + * + * PARAMETERS: Signature - ACPI Signature for common table. Must be * a null terminated 4-character string. - * Instance - For SSDTs (0...n) + * Instance - Multiple table support for SSDT/UEFI (0...n) + * Must be 0 for other tables. * Table - Where a pointer to the table is returned * Address - Where the table physical address is returned * * RETURN: Status; Table buffer and physical address returned if AE_OK. - * - * RETURN: Status; Table buffer and physical address returned if AE_OK. * AE_LIMIT: Instance is beyond valid limit * AE_NOT_FOUND: A table with the signature was not found * + * DESCRIPTION: Get an ACPI table via the root table (RSDT/XSDT) + * * NOTE: Assumes the input signature is uppercase. * *****************************************************************************/ -ACPI_STATUS -AcpiOsGetTableByName ( +static ACPI_STATUS +OslGetTableViaRoot ( + char *Signature, + UINT32 Instance, + ACPI_TABLE_HEADER **Table, + ACPI_PHYSICAL_ADDRESS *Address) +{ + ACPI_TABLE_HEADER *LocalTable = NULL; + ACPI_TABLE_HEADER *MappedTable = NULL; + UINT8 *TableData; + UINT8 NumberOfTables; + UINT8 ItemSize; + UINT32 CurrentInstance = 0; + ACPI_PHYSICAL_ADDRESS TableAddress = 0; + ACPI_STATUS Status; + UINT32 i; + + + /* DSDT and FACS address must be extracted from the FADT */ + + if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT) || + ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS)) + { + /* + * Get the appropriate address, either 32-bit or 64-bit. Be very + * careful about the FADT length and validate table addresses. + * Note: The 64-bit addresses have priority. + */ + if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT)) + { + if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XDSDT) && + Gbl_Fadt->XDsdt) + { + TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XDsdt; + } + else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_DSDT) && + Gbl_Fadt->Dsdt) + { + TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Dsdt; + } + } + else /* FACS */ + { + if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XFACS) && + Gbl_Fadt->XFacs) + { + TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XFacs; + } + else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_FACS) && + Gbl_Fadt->Facs) + { + TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Facs; + } + } + + if (!TableAddress) + { + fprintf (stderr, + "Could not find a valid address for %4.4s in the FADT\n", + Signature); + + return (AE_NOT_FOUND); + } + + /* Now we can get the requested table (DSDT or FACS) */ + + Status = OslMapTable (TableAddress, Signature, &MappedTable); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + } + else /* Case for a normal ACPI table */ + { + if (Gbl_Revision) + { + ItemSize = sizeof (UINT64); + TableData = ACPI_CAST8 (Gbl_Xsdt) + sizeof (ACPI_TABLE_HEADER); + NumberOfTables = + (Gbl_Xsdt->Header.Length - sizeof (ACPI_TABLE_HEADER)) + / ItemSize; + } + else /* Use RSDT if XSDT is not available */ + { + ItemSize = sizeof (UINT32); + TableData = ACPI_CAST8 (Gbl_Rsdt) + sizeof (ACPI_TABLE_HEADER); + NumberOfTables = + (Gbl_Rsdt->Header.Length - sizeof (ACPI_TABLE_HEADER)) + / ItemSize; + } + + /* Search RSDT/XSDT for the requested table */ + + for (i = 0; i < NumberOfTables; ++i, TableData += ItemSize) + { + if (Gbl_Revision) + { + TableAddress = + (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST64 (TableData)); + } + else + { + TableAddress = + (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST32 (TableData)); + } + + Status = OslMapTable (TableAddress, NULL, &MappedTable); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* Does this table match the requested signature? */ + + if (!ACPI_COMPARE_NAME (MappedTable->Signature, Signature)) + { + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + MappedTable = NULL; + continue; + } + + /* Match table instance (for SSDT/UEFI tables) */ + + if (CurrentInstance != Instance) + { + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + MappedTable = NULL; + CurrentInstance++; + continue; + } + + break; + } + } + + if (CurrentInstance != Instance) + { + return (AE_LIMIT); + } + + if (!MappedTable) + { + return (AE_NOT_FOUND); + } + + /* Copy table to local buffer and return it */ + + LocalTable = calloc (1, MappedTable->Length); + if (!LocalTable) + { + return (AE_NO_MEMORY); + } + + ACPI_MEMCPY (LocalTable, MappedTable, MappedTable->Length); + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + *Address = TableAddress; + + *Table = LocalTable; + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: OslAddTablesToList + * + * PARAMETERS: Directory - Directory that contains the tables + * + * RETURN: Status; Table list is initialized if AE_OK. + * + * DESCRIPTION: Add ACPI tables to the table list from a directory. + * + *****************************************************************************/ + +static ACPI_STATUS +OslAddTablesToList( + char *Directory) +{ + struct stat FileInfo; + OSL_TABLE_INFO *NewInfo; + OSL_TABLE_INFO *Info; + struct dirent *DirInfo; + DIR *TableDir; + char TempName[4]; + char Filename[PATH_MAX]; + UINT32 i; + + + /* Open the requested directory */ + + if (stat (Directory, &FileInfo) == -1) + { + return (AE_NOT_FOUND); + } + + if (!(TableDir = opendir (Directory))) + { + return (AE_ERROR); + } + + /* Move pointer to the end of the list */ + + if (!Gbl_TableListHead) + { + return (AE_ERROR); + } + + Info = Gbl_TableListHead; + for (i = 0; i < Gbl_TableListHead->Instance; i++) + { + Info = Info->Next; + } + + /* Examine all entries in this directory */ + + while ((DirInfo = readdir (TableDir)) != 0) + { + /* Ignore meaningless files */ + + if (DirInfo->d_name[0] == '.') + { + continue; + } + + /* Skip any subdirectories and create a new info node */ + + sprintf (Filename, "%s/%s", Directory, DirInfo->d_name); + + if (stat (Filename, &FileInfo) == -1) + { + return (AE_ERROR); + } + + if (!S_ISDIR (FileInfo.st_mode)) + { + NewInfo = calloc (1, sizeof (OSL_TABLE_INFO)); + if (strlen (DirInfo->d_name) > ACPI_NAME_SIZE) + { + sscanf (DirInfo->d_name, "%[^1-9]%d", + TempName, &NewInfo->Instance); + } + + /* Add new info node to global table list */ + + sscanf (DirInfo->d_name, "%4s", NewInfo->Signature); + Info->Next = NewInfo; + Info = NewInfo; + Gbl_TableListHead->Instance++; + } + } + + closedir (TableDir); + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: OslMapTable + * + * PARAMETERS: Address - Address of the table in memory + * Signature - Optional ACPI Signature for desired table. + * Null terminated 4-character string. + * Table - Where a pointer to the mapped table is + * returned + * + * RETURN: Status; Mapped table is returned if AE_OK. + * + * DESCRIPTION: Map entire ACPI table into caller's address space. Also + * validates the table and checksum. + * + *****************************************************************************/ + +static ACPI_STATUS +OslMapTable ( + ACPI_SIZE Address, + char *Signature, + ACPI_TABLE_HEADER **Table) +{ + ACPI_TABLE_HEADER *MappedTable; + UINT32 Length; + + + /* Map the header so we can get the table length */ + + MappedTable = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); + if (!MappedTable) + { + fprintf (stderr, "Could not map table header at 0x%8.8X%8.8X\n", + ACPI_FORMAT_UINT64 (Address)); + return (AE_BAD_ADDRESS); + } + + /* Check if table is valid */ + + if (!ApIsValidHeader (MappedTable)) + { + return (AE_BAD_HEADER); + } + + /* If specified, signature must match */ + + if (Signature && + !ACPI_COMPARE_NAME (Signature, MappedTable->Signature)) + { + return (AE_NOT_EXIST); + } + + /* Map the entire table */ + + Length = MappedTable->Length; + AcpiOsUnmapMemory (MappedTable, sizeof (ACPI_TABLE_HEADER)); + + MappedTable = AcpiOsMapMemory (Address, Length); + if (!MappedTable) + { + fprintf (stderr, "Could not map table at 0x%8.8X%8.8X length %8.8X\n", + ACPI_FORMAT_UINT64 (Address), Length); + return (AE_NO_MEMORY); + } + + *Table = MappedTable; + + /* + * Checksum for RSDP. + * Note: Other checksums are computed during the table dump. + */ + if (!ACPI_STRNCMP (MappedTable->Signature, ACPI_SIG_RSDP, + sizeof (ACPI_SIG_RSDP) - 1)) + { + /* Check the standard checksum */ + + if (AcpiTbChecksum ((UINT8 *) MappedTable, ACPI_RSDP_CHECKSUM_LENGTH)) + { + fprintf (stderr, "Warning: wrong checksum for RSDP\n"); + } + + /* Check extended checksum if table version >= 2 */ + + if (MappedTable->Revision) + { + if (AcpiTbChecksum ((UINT8 *) MappedTable, + ACPI_RSDP_XCHECKSUM_LENGTH)) + { + fprintf (stderr, "Warning: wrong checksum for RSDP\n"); + } + } + } + + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: OslReadTableFromFile + * + * PARAMETERS: TableFile - File that contains the desired table + * FileOffset - Offset of the table in file + * Signature - Optional ACPI Signature for desired table. + * A null terminated 4-character string. + * Table - Where a pointer to the table is returned + * + * RETURN: Status; Table buffer is returned if AE_OK. + * + * DESCRIPTION: Read a ACPI table from a file. + * + *****************************************************************************/ + +static ACPI_STATUS +OslReadTableFromFile ( + FILE *TableFile, + ACPI_SIZE FileOffset, + char *Signature, + ACPI_TABLE_HEADER **Table) +{ + ACPI_TABLE_HEADER Header; + ACPI_TABLE_RSDP Rsdp; + ACPI_TABLE_HEADER *LocalTable; + UINT32 TableLength; + UINT32 Count; + + + /* Read the table header */ + + fseek (TableFile, FileOffset, SEEK_SET); + + Count = fread (&Header, 1, sizeof (ACPI_TABLE_HEADER), TableFile); + if (Count != sizeof (ACPI_TABLE_HEADER)) + { + fprintf (stderr, "Could not read ACPI table header from file\n"); + return (AE_BAD_HEADER); + } + + /* Check if table is valid */ + + if (!ApIsValidHeader (&Header)) + { + return (AE_BAD_HEADER); + } + + /* If signature is specified, it must match the table */ + + if (Signature && + !ACPI_COMPARE_NAME (Signature, Header.Signature)) + { + fprintf (stderr, "Incorrect signature: Expecting %4.4s, found %4.4s\n", + Signature, Header.Signature); + return (AE_NOT_FOUND); + } + + /* + * For RSDP, we must read the entire table, because the length field + * is in a non-standard place, beyond the normal ACPI header. + */ + if (ACPI_COMPARE_NAME (Header.Signature, ACPI_SIG_RSDP)) + { + fseek (TableFile, FileOffset, SEEK_SET); + + Count = fread (&Rsdp, 1, sizeof (ACPI_TABLE_RSDP), TableFile); + if (Count != sizeof (ACPI_TABLE_RSDP)) + { + fprintf (stderr, "Error while reading RSDP\n"); + return (AE_NOT_FOUND); + } + + TableLength = Rsdp.Length; + } + else + { + TableLength = Header.Length; + } + + /* Read the entire table into a local buffer */ + + LocalTable = calloc (1, TableLength); + if (!LocalTable) + { + fprintf (stderr, + "%4.4s: Could not allocate buffer for table of length %X\n", + Header.Signature, TableLength); + return (AE_NO_MEMORY); + } + + fseek (TableFile, FileOffset, SEEK_SET); + + Count = fread (LocalTable, 1, TableLength, TableFile); + if (Count != TableLength) + { + fprintf (stderr, "%4.4s: Error while reading table content\n", + Header.Signature); + return (AE_NOT_FOUND); + } + + /* Validate checksum, except for special tables */ + + if (!ACPI_COMPARE_NAME (Header.Signature, ACPI_SIG_S3PT) && + !ACPI_COMPARE_NAME (Header.Signature, ACPI_SIG_FACS)) + { + if (AcpiTbChecksum ((UINT8 *) LocalTable, TableLength)) + { + fprintf (stderr, "%4.4s: Warning: wrong checksum\n", + Header.Signature); + } + } + + *Table = LocalTable; + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: OslGetOverrideTable + * + * PARAMETERS: Signature - ACPI Signature for desired table. Must be + * a null terminated 4-character string. + * Instance - Multiple table support for SSDT/UEFI (0...n) + * Must be 0 for other tables. + * Table - Where a pointer to the table is returned + * Address - Where the table physical address is returned + * + * RETURN: Status; Table buffer is returned if AE_OK. + * AE_NOT_FOUND: A valid table was not found at the address + * + * DESCRIPTION: Get a table that was overridden and appears under the + * directory OVERRIDE_TABLE_DIR. + * + *****************************************************************************/ + +static ACPI_STATUS +OslGetOverrideTable ( char *Signature, UINT32 Instance, ACPI_TABLE_HEADER **Table, ACPI_PHYSICAL_ADDRESS *Address) { + ACPI_TABLE_HEADER Header; + struct stat FileInfo; + struct dirent *DirInfo; + DIR *TableDir; + FILE *TableFile = NULL; + UINT32 CurrentInstance = 0; + UINT32 Count; + char TempName[4]; + char TableFilename[PATH_MAX]; + ACPI_STATUS Status; + + + /* Open the directory for override tables */ + + if (stat (OVERRIDE_TABLE_DIR, &FileInfo) == -1) + { + return (AE_NOT_FOUND); + } + + if (!(TableDir = opendir (OVERRIDE_TABLE_DIR))) + { + return (AE_ERROR); + } + + /* Attempt to find the table in the directory */ + + while ((DirInfo = readdir (TableDir)) != 0) + { + /* Ignore meaningless files */ + + if (DirInfo->d_name[0] == '.') + { + continue; + } + + if (!ACPI_COMPARE_NAME (DirInfo->d_name, Signature)) + { + continue; + } + + if (strlen (DirInfo->d_name) > 4) + { + sscanf (DirInfo->d_name, "%[^1-9]%d", TempName, &CurrentInstance); + if (CurrentInstance != Instance) + { + continue; + } + } + + /* Create the table pathname and open the file */ + + sprintf (TableFilename, "%s/%s", OVERRIDE_TABLE_DIR, DirInfo->d_name); + + TableFile = fopen (TableFilename, "rb"); + if (TableFile == NULL) + { + perror (TableFilename); + return (AE_ERROR); + } + + /* Read the Table header to get the table length */ + + Count = fread (&Header, 1, sizeof (ACPI_TABLE_HEADER), TableFile); + if (Count != sizeof (ACPI_TABLE_HEADER)) + { + fclose (TableFile); + return (AE_ERROR); + } + + break; + } + + closedir (TableDir); + if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT) && !TableFile) + { + return (AE_LIMIT); + } + + if (!TableFile) + { + return (AE_NOT_FOUND); + } + + /* There is no physical address saved for override tables, use zero */ + + *Address = 0; + Status = OslReadTableFromFile (TableFile, 0, NULL, Table); + + fclose (TableFile); + return (Status); +} + + +/****************************************************************************** + * + * FUNCTION: OslGetDynamicSsdt + * + * PARAMETERS: Instance - For SSDTs (0...n) + * Table - Where a pointer to the table is returned + * Address - Where the table physical address is returned + * + * RETURN: Status; Table buffer is returned if AE_OK. + * AE_NOT_FOUND: A valid table was not found at the address + * + * DESCRIPTION: Get an SSDT table under directory DYNAMIC_SSDT_DIR. + * + *****************************************************************************/ + +static ACPI_STATUS +OslGetDynamicSsdt ( + UINT32 Instance, + ACPI_TABLE_HEADER **Table, + ACPI_PHYSICAL_ADDRESS *Address) +{ + ACPI_TABLE_HEADER Header; + struct stat FileInfo; + struct dirent *DirInfo; + DIR *TableDir; + FILE *TableFile = NULL; + UINT32 Count; + UINT32 CurrentInstance = 0; + char TempName[4]; + char TableFilename[PATH_MAX]; + ACPI_STATUS Status; + + + /* Open the directory for dynamically loaded SSDTs */ + + if (stat (DYNAMIC_SSDT_DIR, &FileInfo) == -1) + { + return (AE_NOT_FOUND); + } + + if (!(TableDir = opendir (DYNAMIC_SSDT_DIR))) + { + return (AE_ERROR); + } + + /* Search directory for correct SSDT instance */ + + while ((DirInfo = readdir (TableDir)) != 0) + { + /* Ignore meaningless files */ + + if (DirInfo->d_name[0] == '.') + { + continue; + } + + /* Check if this table is what we need */ + + sscanf (DirInfo->d_name, "%[^1-9]%d", TempName, &CurrentInstance); + if (CurrentInstance != Instance) + { + continue; + } + + /* Get the SSDT filename and open the file */ + + sprintf (TableFilename, "%s/%s", DYNAMIC_SSDT_DIR, DirInfo->d_name); + + TableFile = fopen (TableFilename, "rb"); + if (TableFile == NULL) + { + perror (TableFilename); + return (AE_ERROR); + } + + /* Read the Table header to get the table length */ + + Count = fread (&Header, 1, sizeof (ACPI_TABLE_HEADER), TableFile); + if (Count != sizeof (ACPI_TABLE_HEADER)) + { + fclose (TableFile); + return (AE_ERROR); + } + + break; + } + + closedir (TableDir); + if (CurrentInstance != Instance) + { + return (AE_LIMIT); + } + + /* There is no physical address saved for dynamic SSDTs, use zero */ + + *Address = 0; + Status = OslReadTableFromFile (TableFile, Header.Length, NULL, Table); - fprintf (stderr, "Linux version not implemented yet\n"); - return (AE_SUPPORT); + fclose (TableFile); + return (Status); } diff --git a/source/tools/acpidump/acpidump.h b/source/tools/acpidump/acpidump.h index c76ec87..44fd7d3 100644 --- a/source/tools/acpidump/acpidump.h +++ b/source/tools/acpidump/acpidump.h @@ -98,6 +98,14 @@ typedef struct ap_dump_action #define AP_MAX_ACPI_FILES 256 /* Prevent infinite loops */ +/* Minimum FADT sizes for various table addresses */ + +#define MIN_FADT_FOR_DSDT (ACPI_FADT_OFFSET (Dsdt) + sizeof (UINT32)) +#define MIN_FADT_FOR_FACS (ACPI_FADT_OFFSET (Facs) + sizeof (UINT32)) +#define MIN_FADT_FOR_XDSDT (ACPI_FADT_OFFSET (XDsdt) + sizeof (UINT64)) +#define MIN_FADT_FOR_XFACS (ACPI_FADT_OFFSET (XFacs) + sizeof (UINT64)) + + /* * apdump - Table get/dump routines */ @@ -117,6 +125,10 @@ int ApDumpAllTables ( void); +BOOLEAN +ApIsValidHeader ( + ACPI_TABLE_HEADER *Table); + /* * apfiles - File I/O utilities diff --git a/source/tools/acpidump/apdump.c b/source/tools/acpidump/apdump.c index c229ba5..5000e4d 100644 --- a/source/tools/acpidump/apdump.c +++ b/source/tools/acpidump/apdump.c @@ -46,10 +46,6 @@ /* Local prototypes */ -static BOOLEAN -ApIsValidHeader ( - ACPI_TABLE_HEADER *Table); - static int ApDumpTableBuffer ( ACPI_TABLE_HEADER *Table, @@ -68,7 +64,7 @@ ApDumpTableBuffer ( * ******************************************************************************/ -static BOOLEAN +BOOLEAN ApIsValidHeader ( ACPI_TABLE_HEADER *Table) { @@ -77,7 +73,7 @@ ApIsValidHeader ( if (!AcpiUtValidAcpiName (Table->Signature)) { - fprintf (stderr, "Table signature (0x%X) is invalid\n", + fprintf (stderr, "Table signature (0x%8.8X) is invalid\n", *(UINT32 *) Table->Signature); return (FALSE); } @@ -86,7 +82,7 @@ ApIsValidHeader ( if (Table->Length <= sizeof (ACPI_TABLE_HEADER)) { - fprintf (stderr, "Table length (0x%X) is invalid\n", + fprintf (stderr, "Table length (0x%8.8X) is invalid\n", Table->Length); return (FALSE); } @@ -295,10 +291,10 @@ ApDumpTableByName ( ACPI_STATUS Status; - if (strlen (Signature) > ACPI_NAME_SIZE) + if (strlen (Signature) != ACPI_NAME_SIZE) { fprintf (stderr, - "Invalid table signature [%s]: too long (4 chars max)\n", + "Invalid table signature [%s]: must be exactly 4 characters\n", Signature); return (-1); } @@ -308,6 +304,17 @@ ApDumpTableByName ( strcpy (LocalSignature, Signature); AcpiUtStrupr (LocalSignature); + /* To be friendly, handle tables whose signatures do not match the name */ + + if (ACPI_COMPARE_NAME (LocalSignature, "FADT")) + { + strcpy (LocalSignature, ACPI_SIG_FADT); + } + else if (ACPI_COMPARE_NAME (LocalSignature, "MADT")) + { + strcpy (LocalSignature, ACPI_SIG_MADT); + } + /* Dump all instances of this signature (to handle multiple SSDTs) */ for (Instance = 0; Instance < AP_MAX_ACPI_FILES; Instance++) diff --git a/source/tools/acpidump/apmain.c b/source/tools/acpidump/apmain.c index 9ee4f46..4c90cb7 100644 --- a/source/tools/acpidump/apmain.c +++ b/source/tools/acpidump/apmain.c @@ -92,7 +92,7 @@ UINT32 CurrentAction = 0; #define AP_UTILITY_NAME "ACPI Binary Table Dump Utility" -#define AP_SUPPORTED_OPTIONS "?a:bf:hn:o:rsv" +#define AP_SUPPORTED_OPTIONS "?a:bf:hn:o:svz" /****************************************************************************** @@ -113,15 +113,15 @@ ApDisplayUsage ( ACPI_OPTION ("-b", "Dump tables to binary files"); ACPI_OPTION ("-h -?", "This help message"); ACPI_OPTION ("-o ", "Redirect output to file"); - ACPI_OPTION ("-r", "Revision (version)"); ACPI_OPTION ("-s", "Print table summaries only"); - ACPI_OPTION ("-v", "Verbose mode"); + ACPI_OPTION ("-v", "Version of this utility"); + ACPI_OPTION ("-z", "Verbose mode"); printf ("\nTable Options:\n"); - ACPI_OPTION ("-a
", "Get table via physical address"); - ACPI_OPTION ("-f ", "Get table via binary file"); - ACPI_OPTION ("-n ", "Get table via name/signature"); + ACPI_OPTION ("-a
", "Get table via a physical address"); + ACPI_OPTION ("-f ", "Get table via a binary file"); + ACPI_OPTION ("-n ", "Get table via a name/signature"); printf ( "\n" @@ -210,17 +210,17 @@ ApDoOptions ( } continue; - case 'r': /* Revision/version */ - - printf (ACPI_COMMON_SIGNON (AP_UTILITY_NAME)); - exit (0); - case 's': /* Print table summaries only */ Gbl_SummaryMode = TRUE; continue; - case 'v': /* Verbose mode */ + case 'v': /* Revision/version */ + + printf (ACPI_COMMON_SIGNON (AP_UTILITY_NAME)); + exit (0); + + case 'z': /* Verbose mode */ Gbl_VerboseMode = TRUE; fprintf (stderr, ACPI_COMMON_SIGNON (AP_UTILITY_NAME)); diff --git a/source/tools/acpiexec/aeexec.c b/source/tools/acpiexec/aeexec.c index 4c7cb4e..be4d8d6 100644 --- a/source/tools/acpiexec/aeexec.c +++ b/source/tools/acpiexec/aeexec.c @@ -588,7 +588,6 @@ AeMiscellaneousTests ( AE_CHECK_OK (AcpiLoadTable, Status); } - AeHardwareInterfaces (); AeGenericRegisters (); AeSetupConfiguration (Ssdt3Code); @@ -597,6 +596,8 @@ AeMiscellaneousTests ( AeTestPackageArgument (); AeMutexInterfaces (); + /* Test _OSI install/remove */ + Status = AcpiInstallInterface (""); AE_CHECK_STATUS (AcpiInstallInterface, Status, AE_BAD_PARAMETER); @@ -618,6 +619,10 @@ AeMiscellaneousTests ( Status = AcpiInstallInterface ("AnotherTestString"); AE_CHECK_OK (AcpiInstallInterface, Status); + /* Test _OSI execution */ + + Status = ExecuteOSI ("Extended Address Space Descriptor", 0xFFFFFFFF); + AE_CHECK_OK (ExecuteOSI, Status); Status = ExecuteOSI ("Windows 2001", 0xFFFFFFFF); AE_CHECK_OK (ExecuteOSI, Status); diff --git a/source/tools/acpiexec/aehandlers.c b/source/tools/acpiexec/aehandlers.c index 7f704ef..44ce31f 100644 --- a/source/tools/acpiexec/aehandlers.c +++ b/source/tools/acpiexec/aehandlers.c @@ -1192,7 +1192,7 @@ AeRegionHandler ( case AML_FIELD_ATTRIB_QUICK: case AML_FIELD_ATTRIB_SEND_RCV: case AML_FIELD_ATTRIB_BYTE: - + Length = 1; break; diff --git a/source/tools/acpiexec/aemain.c b/source/tools/acpiexec/aemain.c index 2764b58..aa0612c 100644 --- a/source/tools/acpiexec/aemain.c +++ b/source/tools/acpiexec/aemain.c @@ -194,19 +194,19 @@ AeDoOptions ( break; case 'r': - + AcpiGbl_DisableAutoRepair = TRUE; break; case 't': - + #ifdef ACPI_DBG_TRACK_ALLOCATIONS AcpiGbl_DisableMemTracking = TRUE; #endif break; default: - + printf ("Unknown option: -d%s\n", AcpiGbl_Optarg); return (-1); } @@ -327,7 +327,7 @@ AeDoOptions ( break; default: - + usage(); return (-1); } diff --git a/source/tools/acpihelp/ahmain.c b/source/tools/acpihelp/ahmain.c index 31748b2..07e162c 100644 --- a/source/tools/acpihelp/ahmain.c +++ b/source/tools/acpihelp/ahmain.c @@ -148,7 +148,7 @@ main ( break; case 's': - + DecodeType = AH_DECODE_ASL; break; @@ -171,7 +171,7 @@ main ( break; case AH_DECODE_AML_OPCODE: - + AhDecodeAmlOpcode (Name); break; diff --git a/source/tools/acpisrc/asfile.c b/source/tools/acpisrc/asfile.c index 9b8ec2f..d691582 100644 --- a/source/tools/acpisrc/asfile.c +++ b/source/tools/acpisrc/asfile.c @@ -312,7 +312,7 @@ AsConvertFile ( switch (FileType) { case FILE_TYPE_SOURCE: - + Functions = ConversionTable->SourceFunctions; StringTable = ConversionTable->SourceStringTable; LineTable = ConversionTable->SourceLineTable; diff --git a/source/tools/acpisrc/asmain.c b/source/tools/acpisrc/asmain.c index ee2f3a9..dc69189 100644 --- a/source/tools/acpisrc/asmain.c +++ b/source/tools/acpisrc/asmain.c @@ -334,7 +334,7 @@ main ( while ((j = AcpiGetopt (argc, argv, "cdhlqsuvy")) != EOF) switch(j) { case 'l': - + /* Linux code generation */ printf ("Creating Linux source code\n"); @@ -344,7 +344,7 @@ main ( break; case 'c': - + /* Cleanup code */ printf ("Code cleanup\n"); @@ -375,7 +375,7 @@ main ( break; case 'v': - + /* Verbose mode */ Gbl_VerboseMode = TRUE; @@ -403,7 +403,7 @@ main ( break; default: - + AsDisplayUsage (); return (-1); } diff --git a/tests/aslts/src/runtime/collections/Identity2MS/abbu/misc/ms1.asl b/tests/aslts/src/runtime/collections/Identity2MS/abbu/misc/ms1.asl index 0e0b6f1..e5dadf1 100644 --- a/tests/aslts/src/runtime/collections/Identity2MS/abbu/misc/ms1.asl +++ b/tests/aslts/src/runtime/collections/Identity2MS/abbu/misc/ms1.asl @@ -5826,7 +5826,7 @@ Method(ms2c, 1, Serialized) Name(WHIN, Ones) while (Local0) { - if (Local1) { + if (LGreater(Local1, 2)) { CH04(ts, 0, 0xff, z179, 0x2bf, 0, 0) } else { CH03(ts, z179, 0x2c0, 0, 0) diff --git a/tests/aslts/src/runtime/collections/Identity2MS/abbu/recursion/rec_aslts.asl b/tests/aslts/src/runtime/collections/Identity2MS/abbu/recursion/rec_aslts.asl index 6c5f20a..9458b99 100644 --- a/tests/aslts/src/runtime/collections/Identity2MS/abbu/recursion/rec_aslts.asl +++ b/tests/aslts/src/runtime/collections/Identity2MS/abbu/recursion/rec_aslts.asl @@ -43,6 +43,8 @@ Name(IG03, 0) // Do anything once only Name(RC00, 5) Name(RCFF, 1) +Name(ts, "mr00") + Processor(pr00, 0, 0x000, 0x008) { Name(i000, 0xabcd0000) @@ -71,12 +73,10 @@ Method(mrfe, 1) */ Method(mr00) { - Name(ts, "mr00") - Name(i000, 0xabcd0000) - + Store("mr00", ts) mrfe(ts) - Store(IG00, i000) + Store(IG00, Local0) Increment(IG00) Increment(IG02) if (LLess(IG00, RC00)) { @@ -84,8 +84,8 @@ Method(mr00) } Decrement(IG00) - if (LNotEqual(i000, IG00)) { - err(ts, z172, 0x000, 0, 0, i000, IG00) + if (LNotEqual(Local0, IG00)) { + err(ts, z172, 0x000, 0, 0, Local0, IG00) } if (LNotEqual(IG02, RC00)) { @@ -103,14 +103,12 @@ Method(mr00) */ Method(mr01, 1) { - Name(ts, "mr01") - Name(i000, 0xabcd0000) - Name(i001, 0xabcd0001) + Store("mr01", ts) mrfe(ts) - Store(IG00, i000) - Store(arg0, i001) + Store(IG00, Local1) + Store(arg0, Local2) Increment(IG00) Increment(IG02) if (LLess(IG00, RC00)) { @@ -118,11 +116,11 @@ Method(mr01, 1) } Decrement(IG00) - if (LNotEqual(i000, IG00)) { - err(ts, z172, 0x000, 0, 0, i000, IG00) + if (LNotEqual(Local1, IG00)) { + err(ts, z172, 0x000, 0, 0, Local1, IG00) } - if (LNotEqual(i001, arg0)) { - err(ts, z172, 0x000, 0, 0, i001, arg0) + if (LNotEqual(Local2, arg0)) { + err(ts, z172, 0x000, 0, 0, Local2, arg0) } Multiply(RC00, 2, Local0) @@ -137,14 +135,12 @@ Method(mr01, 1) Method(mr02, 1) { - Name(ts, "mr02") - Name(i000, 0xabcd0000) - Name(i001, 0xabcd0001) + Store("mr02", ts) mrfe(ts) - Store(IG01, i000) - Store(arg0, i001) + Store(IG01, Local1) + Store(arg0, Local2) Increment(IG01) Increment(IG02) if (LLess(IG01, RC00)) { @@ -152,11 +148,11 @@ Method(mr02, 1) } Decrement(IG01) - if (LNotEqual(i000, IG01)) { - err(ts, z172, 0x000, 0, 0, i000, IG01) + if (LNotEqual(Local1, IG01)) { + err(ts, z172, 0x000, 0, 0, Local1, IG01) } - if (LNotEqual(i001, arg0)) { - err(ts, z172, 0x000, 0, 0, i001, arg0) + if (LNotEqual(Local2, arg0)) { + err(ts, z172, 0x000, 0, 0, Local2, arg0) } Multiply(RC00, 2, Local0) @@ -175,7 +171,7 @@ Method(mr02, 1) */ Method(mr03) { - Name(ts, "mr03") + Store("mr03", ts) Device(d100) { @@ -188,12 +184,9 @@ Method(mr03) Name(i202, 0xabcd0202) Method(m203) { - Name(i300, 0xabcd0300) - Name(i301, 0xabcd0301) - mrfe("m203") - Store(IG00, i300) + Store(IG00, Local0) Increment(IG00) Increment(IG02) if (LLess(IG00, RC00)) { @@ -201,8 +194,8 @@ Method(mr03) } Decrement(IG00) - if (LNotEqual(i300, IG00)) { - err(ts, z172, 0x000, 0, 0, i300, IG00) + if (LNotEqual(Local0, IG00)) { + err(ts, z172, 0x000, 0, 0, Local0, IG00) } } @@ -235,7 +228,7 @@ Method(mr03) */ Method(mr04) { - Name(ts, "mr04") + Store("mr04", ts) Device(d100) { @@ -248,12 +241,9 @@ Method(mr04) Name(i202, 0xabcd0202) Method(m203, 1) { - Name(i300, 0xabcd0300) - Name(i301, 0xabcd0301) - mrfe("m203") - Store(IG00, i300) + Store(IG00, Local0) Increment(IG00) Increment(IG02) if (LLess(IG00, RC00)) { @@ -261,8 +251,8 @@ Method(mr04) } Decrement(IG00) - if (LNotEqual(i300, IG00)) { - err(ts, z172, 0x000, 0, 0, i300, IG00) + if (LNotEqual(Local0, IG00)) { + err(ts, z172, 0x000, 0, 0, Local0, IG00) } } @@ -276,24 +266,24 @@ Method(mr04) d101.m203(0) - if (LNotEqual(IG02, RC00)) { + Multiply(RC00, 2, Local0) + Decrement(Local0) + if (LNotEqual(IG02, Local0)) { if (LNot(IG03)) { Store(1, IG03) - err(ts, z172, 0x000, 0, 0, IG02, RC00) + err(ts, z172, 0x000, 0, 0, IG02, Local0) } } } Method(mr05, 1) { - Name(ts, "mr05") - Name(i000, 0xabcd0000) - Name(i001, 0xabcd0001) + Store("mr05", ts) mrfe(ts) - Store(IG01, i000) - Store(arg0, i001) + Store(IG01, Local1) + Store(arg0, Local2) Increment(IG01) Increment(IG02) if (LLess(IG01, RC00)) { @@ -301,11 +291,11 @@ Method(mr05, 1) } Decrement(IG01) - if (LNotEqual(i000, IG01)) { - err(ts, z172, 0x000, 0, 0, i000, IG01) + if (LNotEqual(Local1, IG01)) { + err(ts, z172, 0x000, 0, 0, Local1, IG01) } - if (LNotEqual(i001, arg0)) { - err(ts, z172, 0x000, 0, 0, i001, arg0) + if (LNotEqual(Local2, arg0)) { + err(ts, z172, 0x000, 0, 0, Local2, arg0) } Multiply(RC00, 2, Local0)