From 7c6f304a2eb855cf2d71ca0638d4f3c72f436fcd Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Thu, 27 Mar 2014 23:50:54 +0000 Subject: Import ACPICA 20140325. --- source/components/debugger/dbcmds.c | 27 +- source/components/debugger/dbfileio.c | 37 +- source/components/debugger/dbmethod.c | 5 + source/components/disassembler/dmbuffer.c | 114 ++-- source/components/disassembler/dmopcode.c | 195 ++++++- source/components/disassembler/dmwalk.c | 11 +- source/components/dispatcher/dsmethod.c | 19 +- source/components/events/evmisc.c | 2 +- source/components/events/evsci.c | 2 +- source/components/events/evxface.c | 62 ++- source/components/executer/exconfig.c | 79 +-- source/components/executer/exdump.c | 3 +- source/components/tables/tbdata.c | 816 +++++++++++++++++++++++++++ source/components/tables/tbfadt.c | 4 +- source/components/tables/tbfind.c | 2 +- source/components/tables/tbinstal.c | 889 +++++++++++------------------- source/components/tables/tbutils.c | 175 +----- source/components/tables/tbxface.c | 6 +- source/components/tables/tbxfload.c | 92 +++- source/components/utilities/utdecode.c | 77 ++- source/components/utilities/utstring.c | 2 +- 21 files changed, 1682 insertions(+), 937 deletions(-) create mode 100644 source/components/tables/tbdata.c (limited to 'source/components') diff --git a/source/components/debugger/dbcmds.c b/source/components/debugger/dbcmds.c index 8fde330bc9ec..e9774cdebe67 100644 --- a/source/components/debugger/dbcmds.c +++ b/source/components/debugger/dbcmds.c @@ -116,7 +116,7 @@ AcpiDbConvertToNode ( Node = ACPI_TO_POINTER (Address); if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE))) { - AcpiOsPrintf ("Address %p is invalid in this address space\n", + AcpiOsPrintf ("Address %p is invalid", Node); return (NULL); } @@ -125,7 +125,7 @@ AcpiDbConvertToNode ( if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED) { - AcpiOsPrintf ("Address %p is not a valid NS node [%s]\n", + AcpiOsPrintf ("Address %p is not a valid namespace node [%s]\n", Node, AcpiUtGetDescriptorName (Node)); return (NULL); } @@ -139,6 +139,8 @@ AcpiDbConvertToNode ( Node = AcpiDbLocalNsLookup (InString); if (!Node) { + AcpiOsPrintf ("Could not find [%s] in namespace, defaulting to root node\n", + InString); Node = AcpiGbl_RootNode; } } @@ -362,24 +364,19 @@ AcpiDbDisplayTableInfo ( switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) { - case ACPI_TABLE_ORIGIN_UNKNOWN: + case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: - AcpiOsPrintf ("Unknown "); + AcpiOsPrintf ("External virtual "); break; - case ACPI_TABLE_ORIGIN_MAPPED: + case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: - AcpiOsPrintf ("Mapped "); + AcpiOsPrintf ("Internal physical "); break; - case ACPI_TABLE_ORIGIN_ALLOCATED: + case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: - AcpiOsPrintf ("Allocated "); - break; - - case ACPI_TABLE_ORIGIN_OVERRIDE: - - AcpiOsPrintf ("Override "); + AcpiOsPrintf ("Internal virtual "); break; default: @@ -390,7 +387,7 @@ AcpiDbDisplayTableInfo ( /* Make sure that the table is mapped */ - Status = AcpiTbVerifyTable (TableDesc); + Status = AcpiTbValidateTable (TableDesc); if (ACPI_FAILURE (Status)) { return; @@ -440,8 +437,6 @@ AcpiDbUnloadAcpiTable ( Node = AcpiDbConvertToNode (ObjectName); if (!Node) { - AcpiOsPrintf ("Could not find [%s] in namespace\n", - ObjectName); return; } diff --git a/source/components/debugger/dbfileio.c b/source/components/debugger/dbfileio.c index 63ecfd87447c..a09c1de8cbd7 100644 --- a/source/components/debugger/dbfileio.c +++ b/source/components/debugger/dbfileio.c @@ -142,6 +142,8 @@ AcpiDbOpenDebugFile ( #ifdef ACPI_APPLICATION +#include "acapps.h" + /******************************************************************************* * * FUNCTION: AcpiDbCheckTextModeCorruption @@ -246,9 +248,11 @@ AcpiDbReadTable ( /* Get the file size */ - fseek (fp, 0, SEEK_END); - FileSize = (UINT32) ftell (fp); - fseek (fp, 0, SEEK_SET); + FileSize = CmGetFileSize (fp); + if (FileSize == ACPI_UINT32_MAX) + { + return (AE_ERROR); + } if (FileSize < 4) { @@ -421,7 +425,7 @@ AeLocalLoadTable ( /* Install the new table into the local data structures */ - Status = AcpiTbInstallTable (&TableInfo); + Status = AcpiTbInitTableDescriptor (&TableInfo); if (ACPI_FAILURE (Status)) { if (Status == AE_ALREADY_EXISTS) @@ -475,23 +479,23 @@ AcpiDbReadTableFromFile ( FILE *File; UINT32 FileSize; UINT32 TableLength; - ACPI_STATUS Status; + ACPI_STATUS Status = AE_ERROR; - /* Open the file */ + /* Open the file, get current size */ File = fopen (Filename, "rb"); if (!File) { perror ("Could not open input file"); - return (AE_ERROR); + return (Status); } - /* Get the file size */ - - fseek (File, 0, SEEK_END); - FileSize = (UINT32) ftell (File); - fseek (File, 0, SEEK_SET); + FileSize = CmGetFileSize (File); + if (FileSize == ACPI_UINT32_MAX) + { + goto Exit; + } /* Get the entire file */ @@ -499,15 +503,14 @@ AcpiDbReadTableFromFile ( Filename, FileSize, FileSize); Status = AcpiDbReadTable (File, Table, &TableLength); - fclose(File); - if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not get table from the file\n"); - return (Status); } - return (AE_OK); +Exit: + fclose(File); + return (Status); } #endif @@ -567,6 +570,8 @@ AcpiDbGetTableFromFile ( return (Status); } + AcpiTbPrintTableHeader (0, Table); + fprintf (stderr, "Acpi table [%4.4s] successfully installed and loaded\n", Table->Signature); diff --git a/source/components/debugger/dbmethod.c b/source/components/debugger/dbmethod.c index 6e44eafeed2e..90d131408c36 100644 --- a/source/components/debugger/dbmethod.c +++ b/source/components/debugger/dbmethod.c @@ -180,6 +180,11 @@ AcpiDbSetMethodData ( if (Type == 'N') { Node = AcpiDbConvertToNode (IndexArg); + if (!Node) + { + return; + } + if (Node->Type != ACPI_TYPE_INTEGER) { AcpiOsPrintf ("Can only set Integer nodes\n"); diff --git a/source/components/disassembler/dmbuffer.c b/source/components/disassembler/dmbuffer.c index ce694590b171..85f0618bbdf1 100644 --- a/source/components/disassembler/dmbuffer.c +++ b/source/components/disassembler/dmbuffer.c @@ -47,6 +47,7 @@ #include "acdisasm.h" #include "acparser.h" #include "amlcode.h" +#include "acinterp.h" #ifdef ACPI_DISASSEMBLER @@ -61,7 +62,7 @@ AcpiDmUnicode ( ACPI_PARSE_OBJECT *Op); static void -AcpiDmIsEisaIdElement ( +AcpiDmGetHardwareIdType ( ACPI_PARSE_OBJECT *Op); static void @@ -537,19 +538,20 @@ AcpiDmUnicode ( /******************************************************************************* * - * FUNCTION: AcpiDmIsEisaIdElement + * FUNCTION: AcpiDmGetHardwareIdType * * PARAMETERS: Op - Op to be examined * * RETURN: None * - * DESCRIPTION: Determine if an Op (argument to _HID or _CID) can be converted - * to an EISA ID. + * DESCRIPTION: Determine the type of the argument to a _HID or _CID + * 1) Strings are allowed + * 2) If Integer, determine if it is a valid EISAID * ******************************************************************************/ static void -AcpiDmIsEisaIdElement ( +AcpiDmGetHardwareIdType ( ACPI_PARSE_OBJECT *Op) { UINT32 BigEndianId; @@ -557,55 +559,66 @@ AcpiDmIsEisaIdElement ( UINT32 i; - /* The parameter must be either a word or a dword */ - - if ((Op->Common.AmlOpcode != AML_DWORD_OP) && - (Op->Common.AmlOpcode != AML_WORD_OP)) + switch (Op->Common.AmlOpcode) { - return; - } + case AML_STRING_OP: - /* Swap from little-endian to big-endian to simplify conversion */ + /* Mark this string as an _HID/_CID string */ - BigEndianId = AcpiUtDwordByteSwap ((UINT32) Op->Common.Value.Integer); + Op->Common.DisasmOpcode = ACPI_DASM_HID_STRING; + break; - /* Create the 3 leading ASCII letters */ + case AML_WORD_OP: + case AML_DWORD_OP: - Prefix[0] = ((BigEndianId >> 26) & 0x1F) + 0x40; - Prefix[1] = ((BigEndianId >> 21) & 0x1F) + 0x40; - Prefix[2] = ((BigEndianId >> 16) & 0x1F) + 0x40; + /* Determine if a Word/Dword is a valid encoded EISAID */ - /* Verify that all 3 are ascii and alpha */ + /* Swap from little-endian to big-endian to simplify conversion */ - for (i = 0; i < 3; i++) - { - if (!ACPI_IS_ASCII (Prefix[i]) || - !ACPI_IS_ALPHA (Prefix[i])) + BigEndianId = AcpiUtDwordByteSwap ((UINT32) Op->Common.Value.Integer); + + /* Create the 3 leading ASCII letters */ + + Prefix[0] = ((BigEndianId >> 26) & 0x1F) + 0x40; + Prefix[1] = ((BigEndianId >> 21) & 0x1F) + 0x40; + Prefix[2] = ((BigEndianId >> 16) & 0x1F) + 0x40; + + /* Verify that all 3 are ascii and alpha */ + + for (i = 0; i < 3; i++) { - return; + if (!ACPI_IS_ASCII (Prefix[i]) || + !ACPI_IS_ALPHA (Prefix[i])) + { + return; + } } - } - /* OK - mark this node as convertable to an EISA ID */ + /* Mark this node as convertable to an EISA ID string */ - Op->Common.DisasmOpcode = ACPI_DASM_EISAID; + Op->Common.DisasmOpcode = ACPI_DASM_EISAID; + break; + + default: + break; + } } /******************************************************************************* * - * FUNCTION: AcpiDmIsEisaId + * FUNCTION: AcpiDmCheckForHardwareId * * PARAMETERS: Op - Op to be examined * * RETURN: None * - * DESCRIPTION: Determine if a Name() Op can be converted to an EisaId. + * DESCRIPTION: Determine if a Name() Op is a _HID/_CID. * ******************************************************************************/ void -AcpiDmIsEisaId ( +AcpiDmCheckForHardwareId ( ACPI_PARSE_OBJECT *Op) { UINT32 Name; @@ -630,7 +643,7 @@ AcpiDmIsEisaId ( if (ACPI_COMPARE_NAME (&Name, METHOD_NAME__HID)) { - AcpiDmIsEisaIdElement (NextOp); + AcpiDmGetHardwareIdType (NextOp); return; } @@ -645,11 +658,11 @@ AcpiDmIsEisaId ( if (NextOp->Common.AmlOpcode != AML_PACKAGE_OP) { - AcpiDmIsEisaIdElement (NextOp); + AcpiDmGetHardwareIdType (NextOp); return; } - /* _CID with Package: get the package length */ + /* _CID with Package: get the package length, check all elements */ NextOp = AcpiPsGetDepthNext (NULL, NextOp); @@ -658,7 +671,7 @@ AcpiDmIsEisaId ( NextOp = NextOp->Common.Next; while (NextOp) { - AcpiDmIsEisaIdElement (NextOp); + AcpiDmGetHardwareIdType (NextOp); NextOp = NextOp->Common.Next; } } @@ -666,41 +679,38 @@ AcpiDmIsEisaId ( /******************************************************************************* * - * FUNCTION: AcpiDmEisaId + * FUNCTION: AcpiDmDecompressEisaId * * PARAMETERS: EncodedId - Raw encoded EISA ID. * * RETURN: None * - * DESCRIPTION: Convert an encoded EISAID back to the original ASCII String. + * DESCRIPTION: Convert an encoded EISAID back to the original ASCII String + * and emit the correct ASL statement. If the ID is known, emit + * a description of the ID as a comment. * ******************************************************************************/ void -AcpiDmEisaId ( +AcpiDmDecompressEisaId ( UINT32 EncodedId) { - UINT32 BigEndianId; - + char IdBuffer[ACPI_EISAID_STRING_SIZE]; + const AH_DEVICE_ID *Info; - /* Swap from little-endian to big-endian to simplify conversion */ - BigEndianId = AcpiUtDwordByteSwap (EncodedId); + /* Convert EISAID to a string an emit the statement */ + AcpiExEisaIdToString (IdBuffer, EncodedId); + AcpiOsPrintf ("EisaId (\"%s\")", IdBuffer); - /* Split to form "AAANNNN" string */ + /* If we know about the ID, emit the description */ - AcpiOsPrintf ("EisaId (\"%c%c%c%4.4X\")", - - /* Three Alpha characters (AAA), 5 bits each */ - - (int) ((BigEndianId >> 26) & 0x1F) + 0x40, - (int) ((BigEndianId >> 21) & 0x1F) + 0x40, - (int) ((BigEndianId >> 16) & 0x1F) + 0x40, - - /* Numeric part (NNNN) is simply the lower 16 bits */ - - (UINT32) (BigEndianId & 0xFFFF)); + Info = AcpiAhMatchHardwareId (IdBuffer); + if (Info) + { + AcpiOsPrintf (" /* %s */", Info->Description); + } } #endif diff --git a/source/components/disassembler/dmopcode.c b/source/components/disassembler/dmopcode.c index 10c66b2d894c..30f985c524c1 100644 --- a/source/components/disassembler/dmopcode.c +++ b/source/components/disassembler/dmopcode.c @@ -46,6 +46,8 @@ #include "acparser.h" #include "amlcode.h" #include "acdisasm.h" +#include "acinterp.h" +#include "acnamesp.h" #ifdef ACPI_DISASSEMBLER @@ -59,6 +61,159 @@ AcpiDmMatchKeyword ( ACPI_PARSE_OBJECT *Op); +/******************************************************************************* + * + * FUNCTION: AcpiDmDisplayTargetPathname + * + * PARAMETERS: Op - Parse object + * + * RETURN: None + * + * DESCRIPTION: For AML opcodes that have a target operand, display the full + * pathname for the target, in a comment field. Handles Return() + * statements also. + * + ******************************************************************************/ + +void +AcpiDmDisplayTargetPathname ( + ACPI_PARSE_OBJECT *Op) +{ + ACPI_PARSE_OBJECT *NextOp; + ACPI_PARSE_OBJECT *PrevOp = NULL; + char *Pathname; + const ACPI_OPCODE_INFO *OpInfo; + + + if (Op->Common.AmlOpcode == AML_RETURN_OP) + { + PrevOp = Op->Asl.Value.Arg; + } + else + { + OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); + if (!(OpInfo->Flags & AML_HAS_TARGET)) + { + return; + } + + /* Target is the last Op in the arg list */ + + NextOp = Op->Asl.Value.Arg; + while (NextOp) + { + PrevOp = NextOp; + NextOp = PrevOp->Asl.Next; + } + } + + if (!PrevOp) + { + return; + } + + /* We must have a namepath AML opcode */ + + if (PrevOp->Asl.AmlOpcode != AML_INT_NAMEPATH_OP) + { + return; + } + + /* A null string is the "no target specified" case */ + + if (!PrevOp->Asl.Value.String) + { + return; + } + + /* No node means "unresolved external reference" */ + + if (!PrevOp->Asl.Node) + { + AcpiOsPrintf (" /* External reference */"); + return; + } + + /* Ignore if path is already from the root */ + + if (*PrevOp->Asl.Value.String == '\\') + { + return; + } + + /* Now: we can get the full pathname */ + + Pathname = AcpiNsGetExternalPathname (PrevOp->Asl.Node); + if (!Pathname) + { + return; + } + + AcpiOsPrintf (" /* %s */", Pathname); + ACPI_FREE (Pathname); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmNotifyDescription + * + * PARAMETERS: Op - Name() parse object + * + * RETURN: None + * + * DESCRIPTION: Emit a description comment for the value associated with a + * Notify() operator. + * + ******************************************************************************/ + +void +AcpiDmNotifyDescription ( + ACPI_PARSE_OBJECT *Op) +{ + ACPI_PARSE_OBJECT *NextOp; + ACPI_NAMESPACE_NODE *Node; + UINT8 NotifyValue; + UINT8 Type = ACPI_TYPE_ANY; + + + /* The notify value is the second argument */ + + NextOp = Op->Asl.Value.Arg; + NextOp = NextOp->Asl.Next; + + switch (NextOp->Common.AmlOpcode) + { + case AML_ZERO_OP: + case AML_ONE_OP: + + NotifyValue = (UINT8) NextOp->Common.AmlOpcode; + break; + + case AML_BYTE_OP: + + NotifyValue = (UINT8) NextOp->Asl.Value.Integer; + break; + + default: + return; + } + + /* + * Attempt to get the namespace node so we can determine the object type. + * Some notify values are dependent on the object type (Device, Thermal, + * or Processor). + */ + Node = Op->Asl.Node; + if (Node) + { + Type = Node->Type; + } + + AcpiOsPrintf (" // %s", AcpiUtGetNotifyName (NotifyValue, Type)); +} + + /******************************************************************************* * * FUNCTION: AcpiDmPredefinedDescription @@ -183,14 +338,11 @@ AcpiDmPredefinedDescription ( /* Match the name in the info table */ - for (Info = AslPredefinedInfo; Info->Name; Info++) + Info = AcpiAhMatchPredefinedName (NameString); + if (Info) { - if (ACPI_COMPARE_NAME (NameString, Info->Name)) - { - AcpiOsPrintf (" // %4.4s: %s", - NameString, ACPI_CAST_PTR (char, Info->Description)); - return; - } + AcpiOsPrintf (" // %4.4s: %s", + NameString, ACPI_CAST_PTR (char, Info->Description)); } #endif @@ -267,14 +419,11 @@ AcpiDmFieldPredefinedDescription ( /* Match the name in the info table */ - for (Info = AslPredefinedInfo; Info->Name; Info++) + Info = AcpiAhMatchPredefinedName (Tag); + if (Info) { - if (ACPI_COMPARE_NAME (Tag, Info->Name)) - { - AcpiOsPrintf (" // %4.4s: %s", Tag, - ACPI_CAST_PTR (char, Info->Description)); - return; - } + AcpiOsPrintf (" // %4.4s: %s", Tag, + ACPI_CAST_PTR (char, Info->Description)); } #endif @@ -527,6 +676,7 @@ AcpiDmDisassembleOneOp ( ACPI_PARSE_OBJECT *Child; ACPI_STATUS Status; UINT8 *Aml; + const AH_DEVICE_ID *IdInfo; if (!Op) @@ -605,7 +755,7 @@ AcpiDmDisassembleOneOp ( if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID) { - AcpiDmEisaId ((UINT32) Op->Common.Value.Integer); + AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer); } else { @@ -617,7 +767,7 @@ AcpiDmDisassembleOneOp ( if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID) { - AcpiDmEisaId ((UINT32) Op->Common.Value.Integer); + AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer); } else { @@ -634,6 +784,19 @@ AcpiDmDisassembleOneOp ( case AML_STRING_OP: AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT16_MAX); + + /* For _HID/_CID strings, attempt to output a descriptive comment */ + + if (Op->Common.DisasmOpcode == ACPI_DASM_HID_STRING) + { + /* If we know about the ID, emit the description */ + + IdInfo = AcpiAhMatchHardwareId (Op->Common.Value.String); + if (IdInfo) + { + AcpiOsPrintf (" /* %s */", IdInfo->Description); + } + } break; case AML_BUFFER_OP: diff --git a/source/components/disassembler/dmwalk.c b/source/components/disassembler/dmwalk.c index 79242f5780cc..3cf74b38c467 100644 --- a/source/components/disassembler/dmwalk.c +++ b/source/components/disassembler/dmwalk.c @@ -568,7 +568,7 @@ AcpiDmDescendingOp ( /* Check for _HID and related EISAID() */ - AcpiDmIsEisaId (Op); + AcpiDmCheckForHardwareId (Op); AcpiOsPrintf (", "); break; @@ -842,6 +842,15 @@ AcpiDmAscendingOp ( AcpiDmFieldPredefinedDescription (Op); } + /* Decode Notify() values */ + + if (Op->Common.AmlOpcode == AML_NOTIFY_OP) + { + AcpiDmNotifyDescription (Op); + } + + AcpiDmDisplayTargetPathname (Op); + /* Could be a nested operator, check if comma required */ if (!AcpiDmCommaIfListMember (Op)) diff --git a/source/components/dispatcher/dsmethod.c b/source/components/dispatcher/dsmethod.c index 5cefb4fbb627..8d1845b61aef 100644 --- a/source/components/dispatcher/dsmethod.c +++ b/source/components/dispatcher/dsmethod.c @@ -186,8 +186,15 @@ AcpiDsDetectNamedOpcodes ( * At this point, we know we have a Named object opcode. * Mark the method as serialized. Later code will create a mutex for * this method to enforce serialization. + * + * Note, ACPI_METHOD_IGNORE_SYNC_LEVEL flag means that we will ignore the + * Sync Level mechanism for this method, even though it is now serialized. + * Otherwise, there can be conflicts with existing ASL code that actually + * uses sync levels. */ - WalkState->MethodDesc->Method.InfoFlags |= ACPI_METHOD_SERIALIZED; + WalkState->MethodDesc->Method.SyncLevel = 0; + WalkState->MethodDesc->Method.InfoFlags |= + (ACPI_METHOD_SERIALIZED | ACPI_METHOD_IGNORE_SYNC_LEVEL); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Method serialized [%4.4s] %p - [%s] (%4.4X)\n", @@ -377,11 +384,16 @@ AcpiDsBeginMethodExecution ( /* * The CurrentSyncLevel (per-thread) must be less than or equal to * the sync level of the method. This mechanism provides some - * deadlock prevention + * deadlock prevention. + * + * If the method was auto-serialized, we just ignore the sync level + * mechanism, because auto-serialization of methods can interfere + * with ASL code that actually uses sync levels. * * Top-level method invocation has no walk state at this point */ if (WalkState && + (!(ObjDesc->Method.InfoFlags & ACPI_METHOD_IGNORE_SYNC_LEVEL)) && (WalkState->Thread->CurrentSyncLevel > ObjDesc->Method.Mutex->Mutex.SyncLevel)) { ACPI_ERROR ((AE_INFO, @@ -849,7 +861,8 @@ AcpiDsTerminateControlMethod ( * thread exits here. */ MethodDesc->Method.InfoFlags &= ~ACPI_METHOD_SERIALIZED_PENDING; - MethodDesc->Method.InfoFlags |= ACPI_METHOD_SERIALIZED; + MethodDesc->Method.InfoFlags |= + (ACPI_METHOD_SERIALIZED | ACPI_METHOD_IGNORE_SYNC_LEVEL); MethodDesc->Method.SyncLevel = 0; } diff --git a/source/components/events/evmisc.c b/source/components/events/evmisc.c index 3bfa81c7d6ca..72f671845e00 100644 --- a/source/components/events/evmisc.c +++ b/source/components/events/evmisc.c @@ -181,7 +181,7 @@ AcpiEvQueueNotifyRequest ( ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n", AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type), - NotifyValue, AcpiUtGetNotifyName (NotifyValue), Node)); + NotifyValue, AcpiUtGetNotifyName (NotifyValue, ACPI_TYPE_ANY), Node)); Status = AcpiOsExecute (OSL_NOTIFY_HANDLER, AcpiEvNotifyDispatch, Info); diff --git a/source/components/events/evsci.c b/source/components/events/evsci.c index 07c86d869c85..664b40858ea4 100644 --- a/source/components/events/evsci.c +++ b/source/components/events/evsci.c @@ -135,7 +135,7 @@ AcpiEvSciXruptHandler ( /* - * We are guaranteed by the ACPI CA initialization/shutdown code that + * We are guaranteed by the ACPICA initialization/shutdown code that * if this interrupt handler is installed, ACPI is enabled. */ diff --git a/source/components/events/evxface.c b/source/components/events/evxface.c index 3755b09aae90..51437a915b39 100644 --- a/source/components/events/evxface.c +++ b/source/components/events/evxface.c @@ -266,7 +266,7 @@ AcpiRemoveNotifyHandler ( ACPI_OPERAND_OBJECT *ObjDesc; ACPI_OPERAND_OBJECT *HandlerObj; ACPI_OPERAND_OBJECT *PreviousHandlerObj; - ACPI_STATUS Status; + ACPI_STATUS Status = AE_OK; UINT32 i; @@ -281,16 +281,6 @@ AcpiRemoveNotifyHandler ( return_ACPI_STATUS (AE_BAD_PARAMETER); } - /* Make sure all deferred notify tasks are completed */ - - AcpiOsWaitEventsComplete (); - - Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } - /* Root Object. Global handlers are removed here */ if (Device == ACPI_ROOT_OBJECT) @@ -299,6 +289,12 @@ AcpiRemoveNotifyHandler ( { if (HandlerType & (i+1)) { + Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + if (!AcpiGbl_GlobalNotify[i].Handler || (AcpiGbl_GlobalNotify[i].Handler != Handler)) { @@ -311,18 +307,23 @@ AcpiRemoveNotifyHandler ( AcpiGbl_GlobalNotify[i].Handler = NULL; AcpiGbl_GlobalNotify[i].Context = NULL; + + (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); + + /* Make sure all deferred notify tasks are completed */ + + AcpiOsWaitEventsComplete (); } } - goto UnlockAndExit; + return_ACPI_STATUS (AE_OK); } /* All other objects: Are Notifies allowed on this object? */ if (!AcpiEvIsNotifyObject (Node)) { - Status = AE_TYPE; - goto UnlockAndExit; + return_ACPI_STATUS (AE_TYPE); } /* Must have an existing internal object */ @@ -330,8 +331,7 @@ AcpiRemoveNotifyHandler ( ObjDesc = AcpiNsGetAttachedObject (Node); if (!ObjDesc) { - Status = AE_NOT_EXIST; - goto UnlockAndExit; + return_ACPI_STATUS (AE_NOT_EXIST); } /* Internal object exists. Find the handler and remove it */ @@ -340,6 +340,12 @@ AcpiRemoveNotifyHandler ( { if (HandlerType & (i+1)) { + Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + HandlerObj = ObjDesc->CommonNotify.NotifyList[i]; PreviousHandlerObj = NULL; @@ -371,10 +377,17 @@ AcpiRemoveNotifyHandler ( HandlerObj->Notify.Next[i]; } + (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); + + /* Make sure all deferred notify tasks are completed */ + + AcpiOsWaitEventsComplete (); AcpiUtRemoveReference (HandlerObj); } } + return_ACPI_STATUS (Status); + UnlockAndExit: (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); @@ -520,6 +533,8 @@ Exit: return_ACPI_STATUS (Status); } +ACPI_EXPORT_SYMBOL (AcpiInstallSciHandler) + /******************************************************************************* * @@ -596,6 +611,8 @@ UnlockAndExit: return_ACPI_STATUS (Status); } +ACPI_EXPORT_SYMBOL (AcpiRemoveSciHandler) + /******************************************************************************* * @@ -970,10 +987,6 @@ AcpiRemoveGpeHandler ( return_ACPI_STATUS (AE_BAD_PARAMETER); } - /* Make sure all deferred GPE tasks are completed */ - - AcpiOsWaitEventsComplete (); - Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); if (ACPI_FAILURE (Status)) { @@ -1030,10 +1043,17 @@ AcpiRemoveGpeHandler ( (void) AcpiEvAddGpeReference (GpeEventInfo); } + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); + (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); + + /* Make sure all deferred GPE tasks are completed */ + + AcpiOsWaitEventsComplete (); + /* Now we can free the handler object */ ACPI_FREE (Handler); - + return_ACPI_STATUS (Status); UnlockAndExit: AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); diff --git a/source/components/executer/exconfig.c b/source/components/executer/exconfig.c index 3ed056e507cc..b5adb96700e1 100644 --- a/source/components/executer/exconfig.c +++ b/source/components/executer/exconfig.c @@ -380,8 +380,8 @@ AcpiExLoadOp ( ACPI_WALK_STATE *WalkState) { ACPI_OPERAND_OBJECT *DdbHandle; + ACPI_TABLE_HEADER *TableHeader; ACPI_TABLE_HEADER *Table; - ACPI_TABLE_DESC TableDesc; UINT32 TableIndex; ACPI_STATUS Status; UINT32 Length; @@ -390,8 +390,6 @@ AcpiExLoadOp ( ACPI_FUNCTION_TRACE (ExLoadOp); - ACPI_MEMSET (&TableDesc, 0, sizeof (ACPI_TABLE_DESC)); - /* Source Object can be either an OpRegion or a Buffer/Field */ switch (ObjDesc->Common.Type) @@ -423,16 +421,16 @@ AcpiExLoadOp ( /* Get the table header first so we can get the table length */ - Table = ACPI_ALLOCATE (sizeof (ACPI_TABLE_HEADER)); - if (!Table) + TableHeader = ACPI_ALLOCATE (sizeof (ACPI_TABLE_HEADER)); + if (!TableHeader) { return_ACPI_STATUS (AE_NO_MEMORY); } Status = AcpiExRegionRead (ObjDesc, sizeof (ACPI_TABLE_HEADER), - ACPI_CAST_PTR (UINT8, Table)); - Length = Table->Length; - ACPI_FREE (Table); + ACPI_CAST_PTR (UINT8, TableHeader)); + Length = TableHeader->Length; + ACPI_FREE (TableHeader); if (ACPI_FAILURE (Status)) { @@ -464,8 +462,8 @@ AcpiExLoadOp ( /* Allocate a buffer for the table */ - TableDesc.Pointer = ACPI_ALLOCATE (Length); - if (!TableDesc.Pointer) + Table = ACPI_ALLOCATE (Length); + if (!Table) { return_ACPI_STATUS (AE_NO_MEMORY); } @@ -473,14 +471,12 @@ AcpiExLoadOp ( /* Read the entire table */ Status = AcpiExRegionRead (ObjDesc, Length, - ACPI_CAST_PTR (UINT8, TableDesc.Pointer)); + ACPI_CAST_PTR (UINT8, Table)); if (ACPI_FAILURE (Status)) { - ACPI_FREE (TableDesc.Pointer); + ACPI_FREE (Table); return_ACPI_STATUS (Status); } - - TableDesc.Address = ObjDesc->Region.Address; break; case ACPI_TYPE_BUFFER: /* Buffer or resolved RegionField */ @@ -497,8 +493,8 @@ AcpiExLoadOp ( /* Get the actual table length from the table header */ - Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ObjDesc->Buffer.Pointer); - Length = Table->Length; + TableHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ObjDesc->Buffer.Pointer); + Length = TableHeader->Length; /* Table cannot extend beyond the buffer */ @@ -515,14 +511,13 @@ AcpiExLoadOp ( * Copy the table from the buffer because the buffer could be modified * or even deleted in the future */ - TableDesc.Pointer = ACPI_ALLOCATE (Length); - if (!TableDesc.Pointer) + Table = ACPI_ALLOCATE (Length); + if (!Table) { return_ACPI_STATUS (AE_NO_MEMORY); } - ACPI_MEMCPY (TableDesc.Pointer, Table, Length); - TableDesc.Address = ACPI_TO_INTEGER (TableDesc.Pointer); + ACPI_MEMCPY (Table, TableHeader, Length); break; default: @@ -530,28 +525,31 @@ AcpiExLoadOp ( return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } - /* Validate table checksum (will not get validated in TbAddTable) */ + /* Install the new table into the local data structures */ + + ACPI_INFO ((AE_INFO, "Dynamic OEM Table Load:")); + (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); + + Status = AcpiTbInstallStandardTable (ACPI_PTR_TO_PHYSADDR (Table), + ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, TRUE, TRUE, + &TableIndex); - Status = AcpiTbVerifyChecksum (TableDesc.Pointer, Length); + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); if (ACPI_FAILURE (Status)) { - ACPI_FREE (TableDesc.Pointer); + /* Delete allocated table buffer */ + + ACPI_FREE (Table); return_ACPI_STATUS (Status); } - /* Complete the table descriptor */ - - TableDesc.Length = Length; - TableDesc.Flags = ACPI_TABLE_ORIGIN_ALLOCATED; - - /* Install the new table into the local data structures */ - - Status = AcpiTbAddTable (&TableDesc, &TableIndex); + /* + * Note: Now table is "INSTALLED", it must be validated before + * loading. + */ + Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[TableIndex]); if (ACPI_FAILURE (Status)) { - /* Delete allocated table buffer */ - - AcpiTbDeleteTable (&TableDesc); return_ACPI_STATUS (Status); } @@ -583,9 +581,6 @@ AcpiExLoadOp ( return_ACPI_STATUS (Status); } - ACPI_INFO ((AE_INFO, "Dynamic OEM Table Load:")); - AcpiTbPrintTableHeader (0, TableDesc.Pointer); - /* Remove the reference by added by AcpiExStore above */ AcpiUtRemoveReference (DdbHandle); @@ -594,7 +589,7 @@ AcpiExLoadOp ( if (AcpiGbl_TableHandler) { - (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, TableDesc.Pointer, + (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table, AcpiGbl_TableHandlerContext); } @@ -627,6 +622,14 @@ AcpiExUnloadTable ( ACPI_FUNCTION_TRACE (ExUnloadTable); + /* + * Temporarily emit a warning so that the ASL for the machine can be + * hopefully obtained. This is to say that the Unload() operator is + * extremely rare if not completely unused. + */ + ACPI_WARNING ((AE_INFO, + "Received request to unload an ACPI table")); + /* * Validate the handle * Although the handle is partially validated in AcpiExReconfiguration() diff --git a/source/components/executer/exdump.c b/source/components/executer/exdump.c index ac92f90c4767..815e337be5b2 100644 --- a/source/components/executer/exdump.c +++ b/source/components/executer/exdump.c @@ -155,10 +155,11 @@ static ACPI_EXDUMP_INFO AcpiExDumpMethod[9] = {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Method.AmlStart), "Aml Start"} }; -static ACPI_EXDUMP_INFO AcpiExDumpMutex[5] = +static ACPI_EXDUMP_INFO AcpiExDumpMutex[6] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpMutex), NULL}, {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (Mutex.SyncLevel), "Sync Level"}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET (Mutex.OriginalSyncLevel), "Original Sync Level"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Mutex.OwnerThread), "Owner Thread"}, {ACPI_EXD_UINT16, ACPI_EXD_OFFSET (Mutex.AcquisitionDepth), "Acquire Depth"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET (Mutex.OsMutex), "OsMutex"} diff --git a/source/components/tables/tbdata.c b/source/components/tables/tbdata.c new file mode 100644 index 000000000000..549c5551bcb1 --- /dev/null +++ b/source/components/tables/tbdata.c @@ -0,0 +1,816 @@ +/****************************************************************************** + * + * Module Name: tbdata - Table manager data structure functions + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2014, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#define __TBDATA_C__ + +#include "acpi.h" +#include "accommon.h" +#include "acnamesp.h" +#include "actables.h" + +#define _COMPONENT ACPI_TABLES + ACPI_MODULE_NAME ("tbdata") + + +/******************************************************************************* + * + * FUNCTION: AcpiTbInitTableDescriptor + * + * PARAMETERS: TableDesc - Table descriptor + * Address - Physical address of the table + * Flags - Allocation flags of the table + * Table - Pointer to the table + * + * RETURN: None + * + * DESCRIPTION: Initialize a new table descriptor + * + ******************************************************************************/ + +void +AcpiTbInitTableDescriptor ( + ACPI_TABLE_DESC *TableDesc, + ACPI_PHYSICAL_ADDRESS Address, + UINT8 Flags, + ACPI_TABLE_HEADER *Table) +{ + + /* + * Initialize the table descriptor. Set the pointer to NULL, since the + * table is not fully mapped at this time. + */ + ACPI_MEMSET (TableDesc, 0, sizeof (ACPI_TABLE_DESC)); + TableDesc->Address = Address; + TableDesc->Length = Table->Length; + TableDesc->Flags = Flags; + ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbAcquireTable + * + * PARAMETERS: TableDesc - Table descriptor + * TablePtr - Where table is returned + * TableLength - Where table length is returned + * TableFlags - Where table allocation flags are returned + * + * RETURN: Status + * + * DESCRIPTION: Acquire an ACPI table. It can be used for tables not + * maintained in the AcpiGbl_RootTableList. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiTbAcquireTable ( + ACPI_TABLE_DESC *TableDesc, + ACPI_TABLE_HEADER **TablePtr, + UINT32 *TableLength, + UINT8 *TableFlags) +{ + ACPI_TABLE_HEADER *Table = NULL; + + + switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) + { + case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: + + Table = AcpiOsMapMemory (TableDesc->Address, TableDesc->Length); + break; + + case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: + case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: + + Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, TableDesc->Address); + break; + + default: + + break; + } + + /* Table is not valid yet */ + + if (!Table) + { + return (AE_NO_MEMORY); + } + + /* Fill the return values */ + + *TablePtr = Table; + *TableLength = TableDesc->Length; + *TableFlags = TableDesc->Flags; + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbReleaseTable + * + * PARAMETERS: Table - Pointer for the table + * TableLength - Length for the table + * TableFlags - Allocation flags for the table + * + * RETURN: None + * + * DESCRIPTION: Release a table. The inverse of AcpiTbAcquireTable(). + * + ******************************************************************************/ + +void +AcpiTbReleaseTable ( + ACPI_TABLE_HEADER *Table, + UINT32 TableLength, + UINT8 TableFlags) +{ + + switch (TableFlags & ACPI_TABLE_ORIGIN_MASK) + { + case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: + + AcpiOsUnmapMemory (Table, TableLength); + break; + + case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: + case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: + default: + + break; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbAcquireTempTable + * + * PARAMETERS: TableDesc - Table descriptor to be acquired + * Address - Address of the table + * Flags - Allocation flags of the table + * + * RETURN: Status + * + * DESCRIPTION: This function validates the table header to obtain the length + * of a table and fills the table descriptor to make its state as + * "INSTALLED". Such a table descriptor is only used for verified + * installation. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiTbAcquireTempTable ( + ACPI_TABLE_DESC *TableDesc, + ACPI_PHYSICAL_ADDRESS Address, + UINT8 Flags) +{ + ACPI_TABLE_HEADER *TableHeader; + + + switch (Flags & ACPI_TABLE_ORIGIN_MASK) + { + case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: + + /* Get the length of the full table from the header */ + + TableHeader = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); + if (!TableHeader) + { + return (AE_NO_MEMORY); + } + + AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader); + AcpiOsUnmapMemory (TableHeader, sizeof (ACPI_TABLE_HEADER)); + return (AE_OK); + + case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: + case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: + + TableHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, Address); + if (!TableHeader) + { + return (AE_NO_MEMORY); + } + + AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader); + return (AE_OK); + + default: + + break; + } + + /* Table is not valid yet */ + + return (AE_NO_MEMORY); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbReleaseTempTable + * + * PARAMETERS: TableDesc - Table descriptor to be released + * + * RETURN: Status + * + * DESCRIPTION: The inverse of AcpiTbAcquireTempTable(). + * + *****************************************************************************/ + +void +AcpiTbReleaseTempTable ( + ACPI_TABLE_DESC *TableDesc) +{ + + /* + * Note that the .Address is maintained by the callers of + * AcpiTbAcquireTempTable(), thus do not invoke AcpiTbUninstallTable() + * where .Address will be freed. + */ + AcpiTbInvalidateTable (TableDesc); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiTbValidateTable + * + * PARAMETERS: TableDesc - Table descriptor + * + * RETURN: Status + * + * DESCRIPTION: This function is called to validate the table, the returned + * table descriptor is in "VALIDATED" state. + * + *****************************************************************************/ + +ACPI_STATUS +AcpiTbValidateTable ( + ACPI_TABLE_DESC *TableDesc) +{ + ACPI_STATUS Status = AE_OK; + + + ACPI_FUNCTION_TRACE (TbValidateTable); + + + /* Validate the table if necessary */ + + if (!TableDesc->Pointer) + { + Status = AcpiTbAcquireTable (TableDesc, &TableDesc->Pointer, + &TableDesc->Length, &TableDesc->Flags); + if (!TableDesc->Pointer) + { + Status = AE_NO_MEMORY; + } + } + + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbInvalidateTable + * + * PARAMETERS: TableDesc - Table descriptor + * + * RETURN: None + * + * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of + * AcpiTbValidateTable(). + * + ******************************************************************************/ + +void +AcpiTbInvalidateTable ( + ACPI_TABLE_DESC *TableDesc) +{ + + ACPI_FUNCTION_TRACE (TbInvalidateTable); + + + /* Table must be validated */ + + if (!TableDesc->Pointer) + { + return_VOID; + } + + AcpiTbReleaseTable (TableDesc->Pointer, TableDesc->Length, + TableDesc->Flags); + TableDesc->Pointer = NULL; + + return_VOID; +} + + +/****************************************************************************** + * + * FUNCTION: AcpiTbVerifyTable + * + * PARAMETERS: TableDesc - Table descriptor + * Signature - Table signature to verify + * + * RETURN: Status + * + * DESCRIPTION: This function is called to validate and verify the table, the + * returned table descriptor is in "VALIDATED" state. + * + *****************************************************************************/ + +ACPI_STATUS +AcpiTbVerifyTable ( + ACPI_TABLE_DESC *TableDesc, + char *Signature) +{ + ACPI_STATUS Status = AE_OK; + + + ACPI_FUNCTION_TRACE (TbVerifyTable); + + + /* Validate the table */ + + Status = AcpiTbValidateTable (TableDesc); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + /* If a particular signature is expected (DSDT/FACS), it must match */ + + if (Signature && + !ACPI_COMPARE_NAME (&TableDesc->Signature, Signature)) + { + ACPI_BIOS_ERROR ((AE_INFO, + "Invalid signature 0x%X for ACPI table, expected [%s]", + TableDesc->Signature.Integer, Signature)); + Status = AE_BAD_SIGNATURE; + goto InvalidateAndExit; + } + + /* Verify the checksum */ + + Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length); + if (ACPI_FAILURE (Status)) + { + ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY, + "%4.4s " ACPI_PRINTF_UINT + " Attempted table install failed", + AcpiUtValidAcpiName (TableDesc->Signature.Ascii) ? + TableDesc->Signature.Ascii : "????", + ACPI_FORMAT_TO_UINT (TableDesc->Address))); + goto InvalidateAndExit; + } + + return_ACPI_STATUS (AE_OK); + +InvalidateAndExit: + AcpiTbInvalidateTable (TableDesc); + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbResizeRootTableList + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Expand the size of global table array + * + ******************************************************************************/ + +ACPI_STATUS +AcpiTbResizeRootTableList ( + void) +{ + ACPI_TABLE_DESC *Tables; + UINT32 TableCount; + + + ACPI_FUNCTION_TRACE (TbResizeRootTableList); + + + /* AllowResize flag is a parameter to AcpiInitializeTables */ + + if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE)) + { + ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed")); + return_ACPI_STATUS (AE_SUPPORT); + } + + /* Increase the Table Array size */ + + if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) + { + TableCount = AcpiGbl_RootTableList.MaxTableCount; + } + else + { + TableCount = AcpiGbl_RootTableList.CurrentTableCount; + } + + Tables = ACPI_ALLOCATE_ZEROED ( + ((ACPI_SIZE) TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT) * + sizeof (ACPI_TABLE_DESC)); + if (!Tables) + { + ACPI_ERROR ((AE_INFO, "Could not allocate new root table array")); + return_ACPI_STATUS (AE_NO_MEMORY); + } + + /* Copy and free the previous table array */ + + if (AcpiGbl_RootTableList.Tables) + { + ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, + (ACPI_SIZE) TableCount * sizeof (ACPI_TABLE_DESC)); + + if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) + { + ACPI_FREE (AcpiGbl_RootTableList.Tables); + } + } + + AcpiGbl_RootTableList.Tables = Tables; + AcpiGbl_RootTableList.MaxTableCount = + TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT; + AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED; + + return_ACPI_STATUS (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbGetNextRootIndex + * + * PARAMETERS: TableIndex - Where table index is returned + * + * RETURN: Status and table index. + * + * DESCRIPTION: Allocate a new ACPI table entry to the global table list + * + ******************************************************************************/ + +ACPI_STATUS +AcpiTbGetNextRootIndex ( + UINT32 *TableIndex) +{ + ACPI_STATUS Status; + + + /* Ensure that there is room for the table in the Root Table List */ + + if (AcpiGbl_RootTableList.CurrentTableCount >= + AcpiGbl_RootTableList.MaxTableCount) + { + Status = AcpiTbResizeRootTableList(); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + } + + *TableIndex = AcpiGbl_RootTableList.CurrentTableCount; + AcpiGbl_RootTableList.CurrentTableCount++; + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbTerminate + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Delete all internal ACPI tables + * + ******************************************************************************/ + +void +AcpiTbTerminate ( + void) +{ + UINT32 i; + + + ACPI_FUNCTION_TRACE (TbTerminate); + + + (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); + + /* Delete the individual tables */ + + for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) + { + AcpiTbUninstallTable (&AcpiGbl_RootTableList.Tables[i]); + } + + /* + * Delete the root table array if allocated locally. Array cannot be + * mapped, so we don't need to check for that flag. + */ + if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) + { + ACPI_FREE (AcpiGbl_RootTableList.Tables); + } + + AcpiGbl_RootTableList.Tables = NULL; + AcpiGbl_RootTableList.Flags = 0; + AcpiGbl_RootTableList.CurrentTableCount = 0; + + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n")); + + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + return_VOID; +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbDeleteNamespaceByOwner + * + * PARAMETERS: TableIndex - Table index + * + * RETURN: Status + * + * DESCRIPTION: Delete all namespace objects created when this table was loaded. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiTbDeleteNamespaceByOwner ( + UINT32 TableIndex) +{ + ACPI_OWNER_ID OwnerId; + ACPI_STATUS Status; + + + ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner); + + + Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + + if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) + { + /* The table index does not exist */ + + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + return_ACPI_STATUS (AE_NOT_EXIST); + } + + /* Get the owner ID for this table, used to delete namespace nodes */ + + OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + + /* + * Need to acquire the namespace writer lock to prevent interference + * with any concurrent namespace walks. The interpreter must be + * released during the deletion since the acquisition of the deletion + * lock may block, and also since the execution of a namespace walk + * must be allowed to use the interpreter. + */ + (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER); + Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock); + + AcpiNsDeleteNamespaceByOwner (OwnerId); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + + AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock); + + Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER); + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbAllocateOwnerId + * + * PARAMETERS: TableIndex - Table index + * + * RETURN: Status + * + * DESCRIPTION: Allocates OwnerId in TableDesc + * + ******************************************************************************/ + +ACPI_STATUS +AcpiTbAllocateOwnerId ( + UINT32 TableIndex) +{ + ACPI_STATUS Status = AE_BAD_PARAMETER; + + + ACPI_FUNCTION_TRACE (TbAllocateOwnerId); + + + (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); + if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) + { + Status = AcpiUtAllocateOwnerId ( + &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); + } + + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbReleaseOwnerId + * + * PARAMETERS: TableIndex - Table index + * + * RETURN: Status + * + * DESCRIPTION: Releases OwnerId in TableDesc + * + ******************************************************************************/ + +ACPI_STATUS +AcpiTbReleaseOwnerId ( + UINT32 TableIndex) +{ + ACPI_STATUS Status = AE_BAD_PARAMETER; + + + ACPI_FUNCTION_TRACE (TbReleaseOwnerId); + + + (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); + if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) + { + AcpiUtReleaseOwnerId ( + &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); + Status = AE_OK; + } + + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbGetOwnerId + * + * PARAMETERS: TableIndex - Table index + * OwnerId - Where the table OwnerId is returned + * + * RETURN: Status + * + * DESCRIPTION: returns OwnerId for the ACPI table + * + ******************************************************************************/ + +ACPI_STATUS +AcpiTbGetOwnerId ( + UINT32 TableIndex, + ACPI_OWNER_ID *OwnerId) +{ + ACPI_STATUS Status = AE_BAD_PARAMETER; + + + ACPI_FUNCTION_TRACE (TbGetOwnerId); + + + (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); + if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) + { + *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; + Status = AE_OK; + } + + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbIsTableLoaded + * + * PARAMETERS: TableIndex - Index into the root table + * + * RETURN: Table Loaded Flag + * + ******************************************************************************/ + +BOOLEAN +AcpiTbIsTableLoaded ( + UINT32 TableIndex) +{ + BOOLEAN IsLoaded = FALSE; + + + (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); + if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) + { + IsLoaded = (BOOLEAN) + (AcpiGbl_RootTableList.Tables[TableIndex].Flags & + ACPI_TABLE_IS_LOADED); + } + + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + return (IsLoaded); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbSetTableLoadedFlag + * + * PARAMETERS: TableIndex - Table index + * IsLoaded - TRUE if table is loaded, FALSE otherwise + * + * RETURN: None + * + * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. + * + ******************************************************************************/ + +void +AcpiTbSetTableLoadedFlag ( + UINT32 TableIndex, + BOOLEAN IsLoaded) +{ + + (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); + if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) + { + if (IsLoaded) + { + AcpiGbl_RootTableList.Tables[TableIndex].Flags |= + ACPI_TABLE_IS_LOADED; + } + else + { + AcpiGbl_RootTableList.Tables[TableIndex].Flags &= + ~ACPI_TABLE_IS_LOADED; + } + } + + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); +} diff --git a/source/components/tables/tbfadt.c b/source/components/tables/tbfadt.c index 9010825883fe..789161dfc765 100644 --- a/source/components/tables/tbfadt.c +++ b/source/components/tables/tbfadt.c @@ -365,14 +365,14 @@ AcpiTbParseFadt ( /* Obtain the DSDT and FACS tables via their addresses within the FADT */ - AcpiTbInstallTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XDsdt, + AcpiTbInstallFixedTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XDsdt, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); /* If Hardware Reduced flag is set, there is no FACS */ if (!AcpiGbl_ReducedHardware) { - AcpiTbInstallTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XFacs, + AcpiTbInstallFixedTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XFacs, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS); } } diff --git a/source/components/tables/tbfind.c b/source/components/tables/tbfind.c index 8940437046bf..bbd8523e4059 100644 --- a/source/components/tables/tbfind.c +++ b/source/components/tables/tbfind.c @@ -108,7 +108,7 @@ AcpiTbFindTable ( { /* Table is not currently mapped, map it */ - Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]); + Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); diff --git a/source/components/tables/tbinstal.c b/source/components/tables/tbinstal.c index ce4a93d87adf..9dcaa9115c3c 100644 --- a/source/components/tables/tbinstal.c +++ b/source/components/tables/tbinstal.c @@ -41,779 +41,528 @@ * POSSIBILITY OF SUCH DAMAGES. */ - #define __TBINSTAL_C__ #include "acpi.h" #include "accommon.h" -#include "acnamesp.h" #include "actables.h" - #define _COMPONENT ACPI_TABLES ACPI_MODULE_NAME ("tbinstal") +/* Local prototypes */ -/****************************************************************************** +static BOOLEAN +AcpiTbCompareTables ( + ACPI_TABLE_DESC *TableDesc, + UINT32 TableIndex); + + +/******************************************************************************* * - * FUNCTION: AcpiTbVerifyTable + * FUNCTION: AcpiTbCompareTables * - * PARAMETERS: TableDesc - table + * PARAMETERS: TableDesc - Table 1 descriptor to be compared + * TableIndex - Index of table 2 to be compared * - * RETURN: Status + * RETURN: TRUE if both tables are identical. * - * DESCRIPTION: this function is called to verify and map table + * DESCRIPTION: This function compares a table with another table that has + * already been installed in the root table list. * - *****************************************************************************/ + ******************************************************************************/ -ACPI_STATUS -AcpiTbVerifyTable ( - ACPI_TABLE_DESC *TableDesc) +static BOOLEAN +AcpiTbCompareTables ( + ACPI_TABLE_DESC *TableDesc, + UINT32 TableIndex) { ACPI_STATUS Status = AE_OK; + BOOLEAN IsIdentical; + ACPI_TABLE_HEADER *Table; + UINT32 TableLength; + UINT8 TableFlags; - ACPI_FUNCTION_TRACE (TbVerifyTable); - - - /* Map the table if necessary */ - - if (!TableDesc->Pointer) + Status = AcpiTbAcquireTable (&AcpiGbl_RootTableList.Tables[TableIndex], + &Table, &TableLength, &TableFlags); + if (ACPI_FAILURE (Status)) { - if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) == - ACPI_TABLE_ORIGIN_MAPPED) - { - TableDesc->Pointer = AcpiOsMapMemory ( - TableDesc->Address, TableDesc->Length); - } - - if (!TableDesc->Pointer) - { - return_ACPI_STATUS (AE_NO_MEMORY); - } + return (FALSE); } - /* Always calculate checksum, ignore bad checksum if requested */ + /* + * Check for a table match on the entire table length, + * not just the header. + */ + IsIdentical = (BOOLEAN)((TableDesc->Length != TableLength || + ACPI_MEMCMP (TableDesc->Pointer, Table, TableLength)) ? + FALSE : TRUE); - Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length); + /* Release the acquired table */ - return_ACPI_STATUS (Status); + AcpiTbReleaseTable (Table, TableLength, TableFlags); + return (IsIdentical); } /******************************************************************************* * - * FUNCTION: AcpiTbAddTable + * FUNCTION: AcpiTbInstallTableWithOverride * - * PARAMETERS: TableDesc - Table descriptor - * TableIndex - Where the table index is returned + * PARAMETERS: TableIndex - Index into root table array + * NewTableDesc - New table descriptor to install + * Override - Whether override should be performed * - * RETURN: Status + * RETURN: None * - * DESCRIPTION: This function is called to add an ACPI table. It is used to - * dynamically load tables via the Load and LoadTable AML - * operators. + * DESCRIPTION: Install an ACPI table into the global data structure. The + * table override mechanism is called to allow the host + * OS to replace any table before it is installed in the root + * table array. * ******************************************************************************/ -ACPI_STATUS -AcpiTbAddTable ( - ACPI_TABLE_DESC *TableDesc, - UINT32 *TableIndex) +void +AcpiTbInstallTableWithOverride ( + UINT32 TableIndex, + ACPI_TABLE_DESC *NewTableDesc, + BOOLEAN Override) { - UINT32 i; - ACPI_STATUS Status = AE_OK; - - - ACPI_FUNCTION_TRACE (TbAddTable); - - if (!TableDesc->Pointer) + if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) { - Status = AcpiTbVerifyTable (TableDesc); - if (ACPI_FAILURE (Status) || !TableDesc->Pointer) - { - return_ACPI_STATUS (Status); - } + return; } /* - * Validate the incoming table signature. + * ACPI Table Override: * - * 1) Originally, we checked the table signature for "SSDT" or "PSDT". - * 2) We added support for OEMx tables, signature "OEM". - * 3) Valid tables were encountered with a null signature, so we just - * gave up on validating the signature, (05/2008). - * 4) We encountered non-AML tables such as the MADT, which caused - * interpreter errors and kernel faults. So now, we once again allow - * only "SSDT", "OEMx", and now, also a null signature. (05/2011). + * Before we install the table, let the host OS override it with a new + * one if desired. Any table within the RSDT/XSDT can be replaced, + * including the DSDT which is pointed to by the FADT. */ - if ((TableDesc->Pointer->Signature[0] != 0x00) && - (!ACPI_COMPARE_NAME (TableDesc->Pointer->Signature, ACPI_SIG_SSDT)) && - (ACPI_STRNCMP (TableDesc->Pointer->Signature, "OEM", 3))) + if (Override) { - ACPI_BIOS_ERROR ((AE_INFO, - "Table has invalid signature [%4.4s] (0x%8.8X), " - "must be SSDT or OEMx", - AcpiUtValidAcpiName (TableDesc->Pointer->Signature) ? - TableDesc->Pointer->Signature : "????", - *(UINT32 *) TableDesc->Pointer->Signature)); - - return_ACPI_STATUS (AE_BAD_SIGNATURE); + AcpiTbOverrideTable (NewTableDesc); } - (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); - - /* Check if table is already registered */ - - for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) - { - if (!AcpiGbl_RootTableList.Tables[i].Pointer) - { - Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]); - if (ACPI_FAILURE (Status) || - !AcpiGbl_RootTableList.Tables[i].Pointer) - { - continue; - } - } - - /* - * Check for a table match on the entire table length, - * not just the header. - */ - if (TableDesc->Length != AcpiGbl_RootTableList.Tables[i].Length) - { - continue; - } - - if (ACPI_MEMCMP (TableDesc->Pointer, - AcpiGbl_RootTableList.Tables[i].Pointer, - AcpiGbl_RootTableList.Tables[i].Length)) - { - continue; - } - - /* - * Note: the current mechanism does not unregister a table if it is - * dynamically unloaded. The related namespace entries are deleted, - * but the table remains in the root table list. - * - * The assumption here is that the number of different tables that - * will be loaded is actually small, and there is minimal overhead - * in just keeping the table in case it is needed again. - * - * If this assumption changes in the future (perhaps on large - * machines with many table load/unload operations), tables will - * need to be unregistered when they are unloaded, and slots in the - * root table list should be reused when empty. - */ - - /* - * Table is already registered. - * We can delete the table that was passed as a parameter. - */ - AcpiTbDeleteTable (TableDesc); - *TableIndex = i; - - if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED) - { - /* Table is still loaded, this is an error */ - - Status = AE_ALREADY_EXISTS; - goto Release; - } - else - { - /* Table was unloaded, allow it to be reloaded */ - - TableDesc->Pointer = AcpiGbl_RootTableList.Tables[i].Pointer; - TableDesc->Address = AcpiGbl_RootTableList.Tables[i].Address; - Status = AE_OK; - goto PrintHeader; - } - } + AcpiTbInitTableDescriptor (&AcpiGbl_RootTableList.Tables[TableIndex], + NewTableDesc->Address, NewTableDesc->Flags, NewTableDesc->Pointer); - /* - * ACPI Table Override: - * Allow the host to override dynamically loaded tables. - * NOTE: the table is fully mapped at this point, and the mapping will - * be deleted by TbTableOverride if the table is actually overridden. - */ - (void) AcpiTbTableOverride (TableDesc->Pointer, TableDesc); + AcpiTbPrintTableHeader (NewTableDesc->Address, NewTableDesc->Pointer); - /* Add the table to the global root table list */ + /* Set the global integer width (based upon revision of the DSDT) */ - Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer, - TableDesc->Length, TableDesc->Flags, TableIndex); - if (ACPI_FAILURE (Status)) + if (TableIndex == ACPI_TABLE_INDEX_DSDT) { - goto Release; + AcpiUtSetIntegerWidth (NewTableDesc->Pointer->Revision); } - -PrintHeader: - AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer); - -Release: - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - return_ACPI_STATUS (Status); } /******************************************************************************* * - * FUNCTION: AcpiTbTableOverride + * FUNCTION: AcpiTbInstallFixedTable * - * PARAMETERS: TableHeader - Header for the original table - * TableDesc - Table descriptor initialized for the - * original table. May or may not be mapped. + * PARAMETERS: Address - Physical address of DSDT or FACS + * Signature - Table signature, NULL if no need to + * match + * TableIndex - Index into root table array * - * RETURN: Pointer to the entire new table. NULL if table not overridden. - * If overridden, installs the new table within the input table - * descriptor. + * RETURN: Status * - * DESCRIPTION: Attempt table override by calling the OSL override functions. - * Note: If the table is overridden, then the entire new table - * is mapped and returned by this function. + * DESCRIPTION: Install a fixed ACPI table (DSDT/FACS) into the global data + * structure. * ******************************************************************************/ -ACPI_TABLE_HEADER * -AcpiTbTableOverride ( - ACPI_TABLE_HEADER *TableHeader, - ACPI_TABLE_DESC *TableDesc) +ACPI_STATUS +AcpiTbInstallFixedTable ( + ACPI_PHYSICAL_ADDRESS Address, + char *Signature, + UINT32 TableIndex) { + ACPI_TABLE_DESC NewTableDesc; ACPI_STATUS Status; - ACPI_TABLE_HEADER *NewTable = NULL; - ACPI_PHYSICAL_ADDRESS NewAddress = 0; - UINT32 NewTableLength = 0; - UINT8 NewFlags; - char *OverrideType; - /* (1) Attempt logical override (returns a logical address) */ + ACPI_FUNCTION_TRACE (TbInstallFixedTable); - Status = AcpiOsTableOverride (TableHeader, &NewTable); - if (ACPI_SUCCESS (Status) && NewTable) + + if (!Address) { - NewAddress = ACPI_PTR_TO_PHYSADDR (NewTable); - NewTableLength = NewTable->Length; - NewFlags = ACPI_TABLE_ORIGIN_OVERRIDE; - OverrideType = "Logical"; - goto FinishOverride; + ACPI_ERROR ((AE_INFO, "Null physical address for ACPI table [%s]", + Signature)); + return (AE_NO_MEMORY); } - /* (2) Attempt physical override (returns a physical address) */ + /* Fill a table descriptor for validation */ - Status = AcpiOsPhysicalTableOverride (TableHeader, - &NewAddress, &NewTableLength); - if (ACPI_SUCCESS (Status) && NewAddress && NewTableLength) + Status = AcpiTbAcquireTempTable (&NewTableDesc, Address, + ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL); + if (ACPI_FAILURE (Status)) { - /* Map the entire new table */ - - NewTable = AcpiOsMapMemory (NewAddress, NewTableLength); - if (!NewTable) - { - ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY, - "%4.4s " ACPI_PRINTF_UINT - " Attempted physical table override failed", - TableHeader->Signature, - ACPI_FORMAT_TO_UINT (TableDesc->Address))); - return (NULL); - } - - OverrideType = "Physical"; - NewFlags = ACPI_TABLE_ORIGIN_MAPPED; - goto FinishOverride; + ACPI_ERROR ((AE_INFO, "Could not acquire table length at %p", + ACPI_CAST_PTR (void, Address))); + return_ACPI_STATUS (Status); } - return (NULL); /* There was no override */ - - -FinishOverride: - - ACPI_INFO ((AE_INFO, "%4.4s " ACPI_PRINTF_UINT - " %s table override, new table: " ACPI_PRINTF_UINT, - TableHeader->Signature, - ACPI_FORMAT_TO_UINT (TableDesc->Address), - OverrideType, ACPI_FORMAT_TO_UINT (NewTable))); + /* Validate and verify a table before installation */ - /* We can now unmap/delete the original table (if fully mapped) */ + Status = AcpiTbVerifyTable (&NewTableDesc, Signature); + if (ACPI_FAILURE (Status)) + { + goto ReleaseAndExit; + } - AcpiTbDeleteTable (TableDesc); + AcpiTbInstallTableWithOverride (TableIndex, &NewTableDesc, TRUE); - /* Setup descriptor for the new table */ +ReleaseAndExit: - TableDesc->Address = NewAddress; - TableDesc->Pointer = NewTable; - TableDesc->Length = NewTableLength; - TableDesc->Flags = NewFlags; + /* Release the temporary table descriptor */ - return (NewTable); + AcpiTbReleaseTempTable (&NewTableDesc); + return_ACPI_STATUS (Status); } /******************************************************************************* * - * FUNCTION: AcpiTbResizeRootTableList + * FUNCTION: AcpiTbInstallStandardTable * - * PARAMETERS: None + * PARAMETERS: Address - Address of the table (might be a virtual + * address depending on the TableFlags) + * Flags - Flags for the table + * Reload - Whether reload should be performed + * Override - Whether override should be performed + * TableIndex - Where the table index is returned * * RETURN: Status * - * DESCRIPTION: Expand the size of global table array + * DESCRIPTION: This function is called to install an ACPI table that is + * neither DSDT nor FACS (a "standard" table.) + * When this function is called by "Load" or "LoadTable" opcodes, + * or by AcpiLoadTable() API, the "Reload" parameter is set. + * After sucessfully returning from this function, table is + * "INSTALLED" but not "VALIDATED". * ******************************************************************************/ ACPI_STATUS -AcpiTbResizeRootTableList ( - void) +AcpiTbInstallStandardTable ( + ACPI_PHYSICAL_ADDRESS Address, + UINT8 Flags, + BOOLEAN Reload, + BOOLEAN Override, + UINT32 *TableIndex) { - ACPI_TABLE_DESC *Tables; - UINT32 TableCount; + UINT32 i; + ACPI_STATUS Status = AE_OK; + ACPI_TABLE_DESC NewTableDesc; - ACPI_FUNCTION_TRACE (TbResizeRootTableList); + ACPI_FUNCTION_TRACE (TbInstallStandardTable); - /* AllowResize flag is a parameter to AcpiInitializeTables */ + /* Acquire a temporary table descriptor for validation */ - if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE)) + Status = AcpiTbAcquireTempTable (&NewTableDesc, Address, Flags); + if (ACPI_FAILURE (Status)) { - ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed")); - return_ACPI_STATUS (AE_SUPPORT); + ACPI_ERROR ((AE_INFO, "Could not acquire table length at %p", + ACPI_CAST_PTR (void, Address))); + return_ACPI_STATUS (Status); } - /* Increase the Table Array size */ - - if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) - { - TableCount = AcpiGbl_RootTableList.MaxTableCount; - } - else + /* + * Optionally do not load any SSDTs from the RSDT/XSDT. This can + * be useful for debugging ACPI problems on some machines. + */ + if (!Reload && + AcpiGbl_DisableSsdtTableInstall && + ACPI_COMPARE_NAME (&NewTableDesc.Signature, ACPI_SIG_SSDT)) { - TableCount = AcpiGbl_RootTableList.CurrentTableCount; + ACPI_INFO ((AE_INFO, "Ignoring installation of %4.4s at %p", + NewTableDesc.Signature.Ascii, ACPI_CAST_PTR (void, Address))); + goto ReleaseAndExit; } - Tables = ACPI_ALLOCATE_ZEROED ( - ((ACPI_SIZE) TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT) * - sizeof (ACPI_TABLE_DESC)); - if (!Tables) + /* Validate and verify a table before installation */ + + Status = AcpiTbVerifyTable (&NewTableDesc, NULL); + if (ACPI_FAILURE (Status)) { - ACPI_ERROR ((AE_INFO, "Could not allocate new root table array")); - return_ACPI_STATUS (AE_NO_MEMORY); + goto ReleaseAndExit; } - /* Copy and free the previous table array */ - - if (AcpiGbl_RootTableList.Tables) + if (Reload) { - ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, - (ACPI_SIZE) TableCount * sizeof (ACPI_TABLE_DESC)); - - if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) + /* + * Validate the incoming table signature. + * + * 1) Originally, we checked the table signature for "SSDT" or "PSDT". + * 2) We added support for OEMx tables, signature "OEM". + * 3) Valid tables were encountered with a null signature, so we just + * gave up on validating the signature, (05/2008). + * 4) We encountered non-AML tables such as the MADT, which caused + * interpreter errors and kernel faults. So now, we once again allow + * only "SSDT", "OEMx", and now, also a null signature. (05/2011). + */ + if ((NewTableDesc.Signature.Ascii[0] != 0x00) && + (!ACPI_COMPARE_NAME (&NewTableDesc.Signature, ACPI_SIG_SSDT)) && + (ACPI_STRNCMP (NewTableDesc.Signature.Ascii, "OEM", 3))) { - ACPI_FREE (AcpiGbl_RootTableList.Tables); + ACPI_BIOS_ERROR ((AE_INFO, + "Table has invalid signature [%4.4s] (0x%8.8X), " + "must be SSDT or OEMx", + AcpiUtValidAcpiName (NewTableDesc.Signature.Ascii) ? + NewTableDesc.Signature.Ascii : "????", + NewTableDesc.Signature.Integer)); + + Status = AE_BAD_SIGNATURE; + goto ReleaseAndExit; } - } - - AcpiGbl_RootTableList.Tables = Tables; - AcpiGbl_RootTableList.MaxTableCount = - TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT; - AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED; - return_ACPI_STATUS (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: AcpiTbStoreTable - * - * PARAMETERS: Address - Table address - * Table - Table header - * Length - Table length - * Flags - flags - * - * RETURN: Status and table index. - * - * DESCRIPTION: Add an ACPI table to the global table list - * - ******************************************************************************/ - -ACPI_STATUS -AcpiTbStoreTable ( - ACPI_PHYSICAL_ADDRESS Address, - ACPI_TABLE_HEADER *Table, - UINT32 Length, - UINT8 Flags, - UINT32 *TableIndex) -{ - ACPI_STATUS Status; - ACPI_TABLE_DESC *NewTable; + /* Check if table is already registered */ + for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) + { + /* + * Check for a table match on the entire table length, + * not just the header. + */ + if (!AcpiTbCompareTables (&NewTableDesc, i)) + { + continue; + } - /* Ensure that there is room for the table in the Root Table List */ + /* + * Note: the current mechanism does not unregister a table if it is + * dynamically unloaded. The related namespace entries are deleted, + * but the table remains in the root table list. + * + * The assumption here is that the number of different tables that + * will be loaded is actually small, and there is minimal overhead + * in just keeping the table in case it is needed again. + * + * If this assumption changes in the future (perhaps on large + * machines with many table load/unload operations), tables will + * need to be unregistered when they are unloaded, and slots in the + * root table list should be reused when empty. + */ + if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED) + { + /* Table is still loaded, this is an error */ - if (AcpiGbl_RootTableList.CurrentTableCount >= - AcpiGbl_RootTableList.MaxTableCount) - { - Status = AcpiTbResizeRootTableList(); - if (ACPI_FAILURE (Status)) - { - return (Status); + Status = AE_ALREADY_EXISTS; + goto ReleaseAndExit; + } + else + { + /* + * Table was unloaded, allow it to be reloaded. + * As we are going to return AE_OK to the caller, we should + * take the responsibility of freeing the input descriptor. + * Refill the input descriptor to ensure + * AcpiTbInstallTableWithOverride() can be called again to + * indicate the re-installation. + */ + AcpiTbUninstallTable (&NewTableDesc); + *TableIndex = i; + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + return_ACPI_STATUS (AE_OK); + } } } - NewTable = &AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount]; - - /* Initialize added table */ - - NewTable->Address = Address; - NewTable->Pointer = Table; - NewTable->Length = Length; - NewTable->OwnerId = 0; - NewTable->Flags = Flags; - - ACPI_MOVE_32_TO_32 (&NewTable->Signature, Table->Signature); - - *TableIndex = AcpiGbl_RootTableList.CurrentTableCount; - AcpiGbl_RootTableList.CurrentTableCount++; - return (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: AcpiTbDeleteTable - * - * PARAMETERS: TableIndex - Table index - * - * RETURN: None - * - * DESCRIPTION: Delete one internal ACPI table - * - ******************************************************************************/ - -void -AcpiTbDeleteTable ( - ACPI_TABLE_DESC *TableDesc) -{ - - /* Table must be mapped or allocated */ + /* Add the table to the global root table list */ - if (!TableDesc->Pointer) + Status = AcpiTbGetNextRootIndex (&i); + if (ACPI_FAILURE (Status)) { - return; + goto ReleaseAndExit; } - switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) - { - case ACPI_TABLE_ORIGIN_MAPPED: - - AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length); - break; - - case ACPI_TABLE_ORIGIN_ALLOCATED: + *TableIndex = i; + AcpiTbInstallTableWithOverride (i, &NewTableDesc, Override); - ACPI_FREE (TableDesc->Pointer); - break; +ReleaseAndExit: - /* Not mapped or allocated, there is nothing we can do */ + /* Release the temporary table descriptor */ - default: - - return; - } - - TableDesc->Pointer = NULL; + AcpiTbReleaseTempTable (&NewTableDesc); + return_ACPI_STATUS (Status); } /******************************************************************************* * - * FUNCTION: AcpiTbTerminate + * FUNCTION: AcpiTbOverrideTable * - * PARAMETERS: None + * PARAMETERS: OldTableDesc - Validated table descriptor to be + * overridden * * RETURN: None * - * DESCRIPTION: Delete all internal ACPI tables + * DESCRIPTION: Attempt table override by calling the OSL override functions. + * Note: If the table is overridden, then the entire new table + * is acquired and returned by this function. + * Before/after invocation, the table descriptor is in a state + * that is "VALIDATED". * ******************************************************************************/ void -AcpiTbTerminate ( - void) +AcpiTbOverrideTable ( + ACPI_TABLE_DESC *OldTableDesc) { - UINT32 i; - - - ACPI_FUNCTION_TRACE (TbTerminate); - + ACPI_STATUS Status; + char *OverrideType; + ACPI_TABLE_DESC NewTableDesc; + ACPI_TABLE_HEADER *Table; + ACPI_PHYSICAL_ADDRESS Address; + UINT32 Length; - (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); - /* Delete the individual tables */ + /* (1) Attempt logical override (returns a logical address) */ - for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) + Status = AcpiOsTableOverride (OldTableDesc->Pointer, &Table); + if (ACPI_SUCCESS (Status) && Table) { - AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]); + AcpiTbAcquireTempTable (&NewTableDesc, ACPI_PTR_TO_PHYSADDR (Table), + ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL); + OverrideType = "Logical"; + goto FinishOverride; } - /* - * Delete the root table array if allocated locally. Array cannot be - * mapped, so we don't need to check for that flag. - */ - if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) + /* (2) Attempt physical override (returns a physical address) */ + + Status = AcpiOsPhysicalTableOverride (OldTableDesc->Pointer, + &Address, &Length); + if (ACPI_SUCCESS (Status) && Address && Length) { - ACPI_FREE (AcpiGbl_RootTableList.Tables); + AcpiTbAcquireTempTable (&NewTableDesc, Address, + ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL); + OverrideType = "Physical"; + goto FinishOverride; } - AcpiGbl_RootTableList.Tables = NULL; - AcpiGbl_RootTableList.Flags = 0; - AcpiGbl_RootTableList.CurrentTableCount = 0; - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n")); - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - - return_VOID; -} - + return; /* There was no override */ -/******************************************************************************* - * - * FUNCTION: AcpiTbDeleteNamespaceByOwner - * - * PARAMETERS: TableIndex - Table index - * - * RETURN: Status - * - * DESCRIPTION: Delete all namespace objects created when this table was loaded. - * - ******************************************************************************/ -ACPI_STATUS -AcpiTbDeleteNamespaceByOwner ( - UINT32 TableIndex) -{ - ACPI_OWNER_ID OwnerId; - ACPI_STATUS Status; - - - ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner); +FinishOverride: + /* Validate and verify a table before overriding */ - Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES); + Status = AcpiTbVerifyTable (&NewTableDesc, NULL); if (ACPI_FAILURE (Status)) { - return_ACPI_STATUS (Status); + return; } - if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) - { - /* The table index does not exist */ - - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - return_ACPI_STATUS (AE_NOT_EXIST); - } + ACPI_INFO ((AE_INFO, "%4.4s " ACPI_PRINTF_UINT + " %s table override, new table: " ACPI_PRINTF_UINT, + OldTableDesc->Signature.Ascii, + ACPI_FORMAT_TO_UINT (OldTableDesc->Address), + OverrideType, ACPI_FORMAT_TO_UINT (NewTableDesc.Address))); - /* Get the owner ID for this table, used to delete namespace nodes */ + /* We can now uninstall the original table */ - OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + AcpiTbUninstallTable (OldTableDesc); /* - * Need to acquire the namespace writer lock to prevent interference - * with any concurrent namespace walks. The interpreter must be - * released during the deletion since the acquisition of the deletion - * lock may block, and also since the execution of a namespace walk - * must be allowed to use the interpreter. + * Replace the original table descriptor and keep its state as + * "VALIDATED". */ - (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER); - Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock); - - AcpiNsDeleteNamespaceByOwner (OwnerId); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } + AcpiTbInitTableDescriptor (OldTableDesc, NewTableDesc.Address, + NewTableDesc.Flags, NewTableDesc.Pointer); + AcpiTbValidateTable (OldTableDesc); - AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock); + /* Release the temporary table descriptor */ - Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER); - return_ACPI_STATUS (Status); + AcpiTbReleaseTempTable (&NewTableDesc); } /******************************************************************************* * - * FUNCTION: AcpiTbAllocateOwnerId + * FUNCTION: AcpiTbStoreTable * - * PARAMETERS: TableIndex - Table index + * PARAMETERS: Address - Table address + * Table - Table header + * Length - Table length + * Flags - Install flags + * TableIndex - Where the table index is returned * - * RETURN: Status + * RETURN: Status and table index. * - * DESCRIPTION: Allocates OwnerId in TableDesc + * DESCRIPTION: Add an ACPI table to the global table list * ******************************************************************************/ ACPI_STATUS -AcpiTbAllocateOwnerId ( - UINT32 TableIndex) +AcpiTbStoreTable ( + ACPI_PHYSICAL_ADDRESS Address, + ACPI_TABLE_HEADER *Table, + UINT32 Length, + UINT8 Flags, + UINT32 *TableIndex) { - ACPI_STATUS Status = AE_BAD_PARAMETER; - - - ACPI_FUNCTION_TRACE (TbAllocateOwnerId); + ACPI_STATUS Status; + ACPI_TABLE_DESC *TableDesc; - (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); - if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) + Status = AcpiTbGetNextRootIndex (TableIndex); + if (ACPI_FAILURE (Status)) { - Status = AcpiUtAllocateOwnerId - (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); + return (Status); } - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - return_ACPI_STATUS (Status); -} - - -/******************************************************************************* - * - * FUNCTION: AcpiTbReleaseOwnerId - * - * PARAMETERS: TableIndex - Table index - * - * RETURN: Status - * - * DESCRIPTION: Releases OwnerId in TableDesc - * - ******************************************************************************/ - -ACPI_STATUS -AcpiTbReleaseOwnerId ( - UINT32 TableIndex) -{ - ACPI_STATUS Status = AE_BAD_PARAMETER; - - - ACPI_FUNCTION_TRACE (TbReleaseOwnerId); - - - (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); - if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) - { - AcpiUtReleaseOwnerId ( - &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); - Status = AE_OK; - } + /* Initialize added table */ - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - return_ACPI_STATUS (Status); + TableDesc = &AcpiGbl_RootTableList.Tables[*TableIndex]; + AcpiTbInitTableDescriptor (TableDesc, Address, Flags, Table); + TableDesc->Pointer = Table; + return (AE_OK); } /******************************************************************************* * - * FUNCTION: AcpiTbGetOwnerId + * FUNCTION: AcpiTbUninstallTable * - * PARAMETERS: TableIndex - Table index - * OwnerId - Where the table OwnerId is returned + * PARAMETERS: TableDesc - Table descriptor * - * RETURN: Status + * RETURN: None * - * DESCRIPTION: returns OwnerId for the ACPI table + * DESCRIPTION: Delete one internal ACPI table * ******************************************************************************/ -ACPI_STATUS -AcpiTbGetOwnerId ( - UINT32 TableIndex, - ACPI_OWNER_ID *OwnerId) +void +AcpiTbUninstallTable ( + ACPI_TABLE_DESC *TableDesc) { - ACPI_STATUS Status = AE_BAD_PARAMETER; + ACPI_FUNCTION_TRACE (TbUninstallTable); - ACPI_FUNCTION_TRACE (TbGetOwnerId); + /* Table must be installed */ - (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); - if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) + if (!TableDesc->Address) { - *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; - Status = AE_OK; + return_VOID; } - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - return_ACPI_STATUS (Status); -} - - -/******************************************************************************* - * - * FUNCTION: AcpiTbIsTableLoaded - * - * PARAMETERS: TableIndex - Table index - * - * RETURN: Table Loaded Flag - * - ******************************************************************************/ - -BOOLEAN -AcpiTbIsTableLoaded ( - UINT32 TableIndex) -{ - BOOLEAN IsLoaded = FALSE; - + AcpiTbInvalidateTable (TableDesc); - (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); - if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) + if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) == + ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL) { - IsLoaded = (BOOLEAN) - (AcpiGbl_RootTableList.Tables[TableIndex].Flags & - ACPI_TABLE_IS_LOADED); + ACPI_FREE (ACPI_CAST_PTR (void, TableDesc->Address)); } - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - return (IsLoaded); -} - - -/******************************************************************************* - * - * FUNCTION: AcpiTbSetTableLoadedFlag - * - * PARAMETERS: TableIndex - Table index - * IsLoaded - TRUE if table is loaded, FALSE otherwise - * - * RETURN: None - * - * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. - * - ******************************************************************************/ - -void -AcpiTbSetTableLoadedFlag ( - UINT32 TableIndex, - BOOLEAN IsLoaded) -{ - - (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); - if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) - { - if (IsLoaded) - { - AcpiGbl_RootTableList.Tables[TableIndex].Flags |= - ACPI_TABLE_IS_LOADED; - } - else - { - AcpiGbl_RootTableList.Tables[TableIndex].Flags &= - ~ACPI_TABLE_IS_LOADED; - } - } - - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + TableDesc->Address = ACPI_PTR_TO_PHYSADDR (NULL); + return_VOID; } diff --git a/source/components/tables/tbutils.c b/source/components/tables/tbutils.c index a9c2d138cd6a..fc580f6b0e1f 100644 --- a/source/components/tables/tbutils.c +++ b/source/components/tables/tbutils.c @@ -197,9 +197,12 @@ AcpiTbCopyDsdt ( } ACPI_MEMCPY (NewTable, TableDesc->Pointer, TableDesc->Length); - AcpiTbDeleteTable (TableDesc); - TableDesc->Pointer = NewTable; - TableDesc->Flags = ACPI_TABLE_ORIGIN_ALLOCATED; + AcpiTbUninstallTable (TableDesc); + + AcpiTbInitTableDescriptor ( + &AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT], + ACPI_PTR_TO_PHYSADDR (NewTable), ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, + NewTable); ACPI_INFO ((AE_INFO, "Forced DSDT copy: length 0x%05X copied locally, original unmapped", @@ -209,125 +212,6 @@ AcpiTbCopyDsdt ( } -/******************************************************************************* - * - * FUNCTION: AcpiTbInstallTable - * - * PARAMETERS: Address - Physical address of DSDT or FACS - * Signature - Table signature, NULL if no need to - * match - * TableIndex - Index into root table array - * - * RETURN: None - * - * DESCRIPTION: Install an ACPI table into the global data structure. The - * table override mechanism is called to allow the host - * OS to replace any table before it is installed in the root - * table array. - * - ******************************************************************************/ - -void -AcpiTbInstallTable ( - ACPI_PHYSICAL_ADDRESS Address, - char *Signature, - UINT32 TableIndex) -{ - ACPI_TABLE_HEADER *Table; - ACPI_TABLE_HEADER *FinalTable; - ACPI_TABLE_DESC *TableDesc; - - - if (!Address) - { - ACPI_ERROR ((AE_INFO, "Null physical address for ACPI table [%s]", - Signature)); - return; - } - - /* Map just the table header */ - - Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); - if (!Table) - { - ACPI_ERROR ((AE_INFO, "Could not map memory for table [%s] at %p", - Signature, ACPI_CAST_PTR (void, Address))); - return; - } - - /* If a particular signature is expected (DSDT/FACS), it must match */ - - if (Signature && - !ACPI_COMPARE_NAME (Table->Signature, Signature)) - { - ACPI_BIOS_ERROR ((AE_INFO, - "Invalid signature 0x%X for ACPI table, expected [%s]", - *ACPI_CAST_PTR (UINT32, Table->Signature), Signature)); - goto UnmapAndExit; - } - - /* - * Initialize the table entry. Set the pointer to NULL, since the - * table is not fully mapped at this time. - */ - TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex]; - - TableDesc->Address = Address; - TableDesc->Pointer = NULL; - TableDesc->Length = Table->Length; - TableDesc->Flags = ACPI_TABLE_ORIGIN_MAPPED; - ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature); - - /* - * ACPI Table Override: - * - * Before we install the table, let the host OS override it with a new - * one if desired. Any table within the RSDT/XSDT can be replaced, - * including the DSDT which is pointed to by the FADT. - * - * NOTE: If the table is overridden, then FinalTable will contain a - * mapped pointer to the full new table. If the table is not overridden, - * or if there has been a physical override, then the table will be - * fully mapped later (in verify table). In any case, we must - * unmap the header that was mapped above. - */ - FinalTable = AcpiTbTableOverride (Table, TableDesc); - if (!FinalTable) - { - FinalTable = Table; /* There was no override */ - } - - AcpiTbPrintTableHeader (TableDesc->Address, FinalTable); - - /* Set the global integer width (based upon revision of the DSDT) */ - - if (TableIndex == ACPI_TABLE_INDEX_DSDT) - { - AcpiUtSetIntegerWidth (FinalTable->Revision); - } - - /* - * If we have a physical override during this early loading of the ACPI - * tables, unmap the table for now. It will be mapped again later when - * it is actually used. This supports very early loading of ACPI tables, - * before virtual memory is fully initialized and running within the - * host OS. Note: A logical override has the ACPI_TABLE_ORIGIN_OVERRIDE - * flag set and will not be deleted below. - */ - if (FinalTable != Table) - { - AcpiTbDeleteTable (TableDesc); - } - - -UnmapAndExit: - - /* Always unmap the table header that we mapped above */ - - AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER)); -} - - /******************************************************************************* * * FUNCTION: AcpiTbGetRootTableEntry @@ -506,6 +390,7 @@ AcpiTbParseRootTable ( UINT32 Length; UINT8 *TableEntry; ACPI_STATUS Status; + UINT32 TableIndex; ACPI_FUNCTION_TRACE (TbParseRootTable); @@ -625,28 +510,20 @@ AcpiTbParseRootTable ( for (i = 0; i < TableCount; i++) { - if (AcpiGbl_RootTableList.CurrentTableCount >= - AcpiGbl_RootTableList.MaxTableCount) - { - /* There is no more room in the root table array, attempt resize */ - - Status = AcpiTbResizeRootTableList (); - if (ACPI_FAILURE (Status)) - { - ACPI_WARNING ((AE_INFO, "Truncating %u table entries!", - (unsigned) (TableCount - - (AcpiGbl_RootTableList.CurrentTableCount - 2)))); - break; - } - } - /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ - AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount].Address = - AcpiTbGetRootTableEntry (TableEntry, TableEntrySize); + Status = AcpiTbInstallStandardTable ( + AcpiTbGetRootTableEntry (TableEntry, TableEntrySize), + ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, FALSE, TRUE, &TableIndex); + + if (ACPI_SUCCESS (Status) && + ACPI_COMPARE_NAME (&AcpiGbl_RootTableList.Tables[TableIndex].Signature, + ACPI_SIG_FADT)) + { + AcpiTbParseFadt (TableIndex); + } TableEntry += TableEntrySize; - AcpiGbl_RootTableList.CurrentTableCount++; } /* @@ -655,23 +532,5 @@ AcpiTbParseRootTable ( */ AcpiOsUnmapMemory (Table, Length); - /* - * Complete the initialization of the root table array by examining - * the header of each table - */ - for (i = 2; i < AcpiGbl_RootTableList.CurrentTableCount; i++) - { - AcpiTbInstallTable (AcpiGbl_RootTableList.Tables[i].Address, - NULL, i); - - /* Special case for FADT - validate it then get the DSDT and FACS */ - - if (ACPI_COMPARE_NAME ( - &AcpiGbl_RootTableList.Tables[i].Signature, ACPI_SIG_FADT)) - { - AcpiTbParseFadt (i); - } - } - return_ACPI_STATUS (AE_OK); } diff --git a/source/components/tables/tbxface.c b/source/components/tables/tbxface.c index dc6374bb091e..26ee44bd9ed4 100644 --- a/source/components/tables/tbxface.c +++ b/source/components/tables/tbxface.c @@ -262,7 +262,7 @@ AcpiGetTableHeader ( { if ((AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_ORIGIN_MASK) == - ACPI_TABLE_ORIGIN_MAPPED) + ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL) { Header = AcpiOsMapMemory ( AcpiGbl_RootTableList.Tables[i].Address, @@ -345,7 +345,7 @@ AcpiGetTable ( continue; } - Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]); + Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]); if (ACPI_SUCCESS (Status)) { *OutTable = AcpiGbl_RootTableList.Tables[i].Pointer; @@ -406,7 +406,7 @@ AcpiGetTableByIndex ( { /* Table is not mapped, map it */ - Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[TableIndex]); + Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[TableIndex]); if (ACPI_FAILURE (Status)) { (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); diff --git a/source/components/tables/tbxfload.c b/source/components/tables/tbxfload.c index f39c2c679796..f28aa091bfc0 100644 --- a/source/components/tables/tbxfload.c +++ b/source/components/tables/tbxfload.c @@ -131,7 +131,7 @@ AcpiTbLoadNamespace ( !ACPI_COMPARE_NAME ( &(AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Signature), ACPI_SIG_DSDT) || - ACPI_FAILURE (AcpiTbVerifyTable ( + ACPI_FAILURE (AcpiTbValidateTable ( &AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT]))) { Status = AE_NO_ACPI_TABLES; @@ -142,7 +142,7 @@ AcpiTbLoadNamespace ( * Save the DSDT pointer for simple access. This is the mapped memory * address. We must take care here because the address of the .Tables * array can change dynamically as tables are loaded at run-time. Note: - * .Pointer field is not validated until after call to AcpiTbVerifyTable. + * .Pointer field is not validated until after call to AcpiTbValidateTable. */ AcpiGbl_DSDT = AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer; @@ -187,24 +187,12 @@ AcpiTbLoadNamespace ( ACPI_SIG_SSDT) && !ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature), ACPI_SIG_PSDT)) || - ACPI_FAILURE (AcpiTbVerifyTable ( + ACPI_FAILURE (AcpiTbValidateTable ( &AcpiGbl_RootTableList.Tables[i]))) { continue; } - /* - * Optionally do not load any SSDTs from the RSDT/XSDT. This can - * be useful for debugging ACPI problems on some machines. - */ - if (AcpiGbl_DisableSsdtTableLoad) - { - ACPI_INFO ((AE_INFO, "Ignoring %4.4s at %p", - AcpiGbl_RootTableList.Tables[i].Signature.Ascii, - ACPI_CAST_PTR (void, AcpiGbl_RootTableList.Tables[i].Address))); - continue; - } - /* Ignore errors while loading tables, get as many as possible */ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); @@ -220,6 +208,53 @@ UnlockAndExit: } +/******************************************************************************* + * + * FUNCTION: AcpiInstallTable + * + * PARAMETERS: Address - Address of the ACPI table to be installed. + * Physical - Whether the address is a physical table + * address or not + * + * RETURN: Status + * + * DESCRIPTION: Dynamically install an ACPI table. + * Note: This function should only be invoked after + * AcpiInitializeTables() and before AcpiLoadTables(). + * + ******************************************************************************/ + +ACPI_STATUS +AcpiInstallTable ( + ACPI_PHYSICAL_ADDRESS Address, + BOOLEAN Physical) +{ + ACPI_STATUS Status; + UINT8 Flags; + UINT32 TableIndex; + + + ACPI_FUNCTION_TRACE (AcpiInstallTable); + + + if (Physical) + { + Flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL; + } + else + { + Flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL; + } + + Status = AcpiTbInstallStandardTable (Address, Flags, + FALSE, FALSE, &TableIndex); + + return_ACPI_STATUS (Status); +} + +ACPI_EXPORT_SYMBOL_INIT (AcpiInstallTable) + + /******************************************************************************* * * FUNCTION: AcpiLoadTable @@ -242,7 +277,6 @@ AcpiLoadTable ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status; - ACPI_TABLE_DESC TableDesc; UINT32 TableIndex; @@ -256,14 +290,6 @@ AcpiLoadTable ( return_ACPI_STATUS (AE_BAD_PARAMETER); } - /* Init local table descriptor */ - - ACPI_MEMSET (&TableDesc, 0, sizeof (ACPI_TABLE_DESC)); - TableDesc.Address = ACPI_PTR_TO_PHYSADDR (Table); - TableDesc.Pointer = Table; - TableDesc.Length = Table->Length; - TableDesc.Flags = ACPI_TABLE_ORIGIN_UNKNOWN; - /* Must acquire the interpreter lock during this operation */ Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER); @@ -275,7 +301,23 @@ AcpiLoadTable ( /* Install the table and load it into the namespace */ ACPI_INFO ((AE_INFO, "Host-directed Dynamic ACPI Table Load:")); - Status = AcpiTbAddTable (&TableDesc, &TableIndex); + (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); + + Status = AcpiTbInstallStandardTable (ACPI_PTR_TO_PHYSADDR (Table), + ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, TRUE, FALSE, + &TableIndex); + + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + if (ACPI_FAILURE (Status)) + { + goto UnlockAndExit; + } + + /* + * Note: Now table is "INSTALLED", it must be validated before + * using. + */ + Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[TableIndex]); if (ACPI_FAILURE (Status)) { goto UnlockAndExit; diff --git a/source/components/utilities/utdecode.c b/source/components/utilities/utdecode.c index 6c97c0c53d57..28617dd8bf47 100644 --- a/source/components/utilities/utdecode.c +++ b/source/components/utilities/utdecode.c @@ -527,7 +527,7 @@ AcpiUtGetMutexName ( /* Names for Notify() values, used for debug output */ -static const char *AcpiGbl_NotifyValueNames[ACPI_NOTIFY_MAX + 1] = +static const char *AcpiGbl_GenericNotify[ACPI_NOTIFY_MAX + 1] = { /* 00 */ "Bus Check", /* 01 */ "Device Check", @@ -539,32 +539,87 @@ static const char *AcpiGbl_NotifyValueNames[ACPI_NOTIFY_MAX + 1] = /* 07 */ "Power Fault", /* 08 */ "Capabilities Check", /* 09 */ "Device PLD Check", - /* 10 */ "Reserved", - /* 11 */ "System Locality Update", - /* 12 */ "Shutdown Request" + /* 0A */ "Reserved", + /* 0B */ "System Locality Update", + /* 0C */ "Shutdown Request" }; +static const char *AcpiGbl_DeviceNotify[4] = +{ + /* 80 */ "Status Change", + /* 81 */ "Information Change", + /* 82 */ "Device-Specific Change", + /* 83 */ "Device-Specific Change" +}; + +static const char *AcpiGbl_ProcessorNotify[4] = +{ + /* 80 */ "Performance Capability Change", + /* 81 */ "C-State Change", + /* 82 */ "Throttling Capability Change", + /* 83 */ "Device-Specific Change" +}; + +static const char *AcpiGbl_ThermalNotify[4] = +{ + /* 80 */ "Thermal Status Change", + /* 81 */ "Thermal Trip Point Change", + /* 82 */ "Thermal Device List Change", + /* 83 */ "Thermal Relationship Change" +}; + + const char * AcpiUtGetNotifyName ( - UINT32 NotifyValue) + UINT32 NotifyValue, + ACPI_OBJECT_TYPE Type) { + /* 00 - 0C are common to all object types */ + if (NotifyValue <= ACPI_NOTIFY_MAX) { - return (AcpiGbl_NotifyValueNames[NotifyValue]); + return (AcpiGbl_GenericNotify[NotifyValue]); } - else if (NotifyValue <= ACPI_MAX_SYS_NOTIFY) + + /* 0D - 7F are reserved */ + + if (NotifyValue <= ACPI_MAX_SYS_NOTIFY) { return ("Reserved"); } - else if (NotifyValue <= ACPI_MAX_DEVICE_SPECIFIC_NOTIFY) + + /* 80 - 83 are per-object-type */ + + if (NotifyValue <= 0x83) { - return ("Device Specific"); + switch (Type) + { + case ACPI_TYPE_ANY: + case ACPI_TYPE_DEVICE: + return (AcpiGbl_DeviceNotify [NotifyValue - 0x80]); + + case ACPI_TYPE_PROCESSOR: + return (AcpiGbl_ProcessorNotify [NotifyValue - 0x80]); + + case ACPI_TYPE_THERMAL: + return (AcpiGbl_ThermalNotify [NotifyValue - 0x80]); + + default: + return ("Target object type does not support notifies"); + } } - else + + /* 84 - BF are device-specific */ + + if (NotifyValue <= ACPI_MAX_DEVICE_SPECIFIC_NOTIFY) { - return ("Hardware Specific"); + return ("Device-Specific"); } + + /* C0 and above are hardware-specific */ + + return ("Hardware-Specific"); } #endif diff --git a/source/components/utilities/utstring.c b/source/components/utilities/utstring.c index 8a1ee922bca6..435f6988892d 100644 --- a/source/components/utilities/utstring.c +++ b/source/components/utilities/utstring.c @@ -420,7 +420,7 @@ AcpiUtPrintString ( } AcpiOsPrintf ("\""); - for (i = 0; String[i] && (i < MaxLength); i++) + for (i = 0; (i < MaxLength) && String[i]; i++) { /* Escape sequences */ -- cgit v1.2.3