[ACPICA]
authorThomas Faber <thomas.faber@reactos.org>
Wed, 26 Jul 2017 14:49:35 +0000 (14:49 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Wed, 26 Jul 2017 14:49:35 +0000 (14:49 +0000)
- Update to version 20170629
CORE-13538 #resolve

svn path=/trunk/; revision=75412

21 files changed:
reactos/drivers/bus/acpi/CMakeLists.txt
reactos/drivers/bus/acpi/acpica/dispatcher/dspkginit.c [deleted file]
reactos/drivers/bus/acpi/acpica/executer/excreate.c
reactos/drivers/bus/acpi/acpica/hardware/hwxfsleep.c
reactos/drivers/bus/acpi/acpica/include/acapps.h
reactos/drivers/bus/acpi/acpica/include/aclocal.h
reactos/drivers/bus/acpi/acpica/include/acobject.h
reactos/drivers/bus/acpi/acpica/include/acpixf.h
reactos/drivers/bus/acpi/acpica/include/actables.h
reactos/drivers/bus/acpi/acpica/include/actbl.h
reactos/drivers/bus/acpi/acpica/include/actbl2.h
reactos/drivers/bus/acpi/acpica/include/platform/acenv.h
reactos/drivers/bus/acpi/acpica/include/platform/aclinux.h
reactos/drivers/bus/acpi/acpica/namespace/nsaccess.c
reactos/drivers/bus/acpi/acpica/parser/psobject.c
reactos/drivers/bus/acpi/acpica/tables/tbdata.c
reactos/drivers/bus/acpi/acpica/tables/tbinstal.c
reactos/drivers/bus/acpi/acpica/tables/tbutils.c
reactos/drivers/bus/acpi/acpica/tables/tbxface.c
reactos/drivers/bus/acpi/acpica/tables/tbxfload.c
reactos/drivers/bus/acpi/acpica/utilities/utresrc.c

index 2d813df..97847f3 100644 (file)
@@ -156,6 +156,7 @@ list(APPEND ACPICA_SOURCE
     acpica/utilities/utownerid.c
     acpica/utilities/utpredef.c
     # acpica/utilities/utprint.c
+    # acpica/utilities/utresdecode.c
     acpica/utilities/utresrc.c
     acpica/utilities/utstate.c
     acpica/utilities/utstring.c
diff --git a/reactos/drivers/bus/acpi/acpica/dispatcher/dspkginit.c b/reactos/drivers/bus/acpi/acpica/dispatcher/dspkginit.c
deleted file mode 100644 (file)
index 5763255..0000000
+++ /dev/null
@@ -1,530 +0,0 @@
-/******************************************************************************
- *
- * Module Name: dspkginit - Completion of deferred package initialization
- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000 - 2017, Intel Corp.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- *    substantially similar to the "NO WARRANTY" disclaimer below
- *    ("Disclaimer") and any redistribution must be conditioned upon
- *    including a substantially similar Disclaimer requirement for further
- *    binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- *    of any contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGES.
- */
-
-#include "acpi.h"
-#include "accommon.h"
-#include "acnamesp.h"
-#include "amlcode.h"
-#include "acdispat.h"
-#include "acinterp.h"
-
-
-#define _COMPONENT          ACPI_NAMESPACE
-        ACPI_MODULE_NAME    ("dspkginit")
-
-
-/* Local prototypes */
-
-static void
-AcpiDsResolvePackageElement (
-    ACPI_OPERAND_OBJECT     **Element);
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiDsBuildInternalPackageObj
- *
- * PARAMETERS:  WalkState       - Current walk state
- *              Op              - Parser object to be translated
- *              ElementCount    - Number of elements in the package - this is
- *                                the NumElements argument to Package()
- *              ObjDescPtr      - Where the ACPI internal object is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Translate a parser Op package object to the equivalent
- *              namespace object
- *
- * NOTE: The number of elements in the package will be always be the NumElements
- * count, regardless of the number of elements in the package list. If
- * NumElements is smaller, only that many package list elements are used.
- * if NumElements is larger, the Package object is padded out with
- * objects of type Uninitialized (as per ACPI spec.)
- *
- * Even though the ASL compilers do not allow NumElements to be smaller
- * than the Package list length (for the fixed length package opcode), some
- * BIOS code modifies the AML on the fly to adjust the NumElements, and
- * this code compensates for that. This also provides compatibility with
- * other AML interpreters.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiDsBuildInternalPackageObj (
-    ACPI_WALK_STATE         *WalkState,
-    ACPI_PARSE_OBJECT       *Op,
-    UINT32                  ElementCount,
-    ACPI_OPERAND_OBJECT     **ObjDescPtr)
-{
-    ACPI_PARSE_OBJECT       *Arg;
-    ACPI_PARSE_OBJECT       *Parent;
-    ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
-    ACPI_STATUS             Status = AE_OK;
-    UINT16                  Index;
-    UINT16                  ReferenceCount;
-    UINT32                  i;
-
-
-    ACPI_FUNCTION_TRACE (DsBuildInternalPackageObj);
-
-
-    /* Find the parent of a possibly nested package */
-
-    Parent = Op->Common.Parent;
-    while ((Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
-           (Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP))
-    {
-        Parent = Parent->Common.Parent;
-    }
-
-    /*
-     * If we are evaluating a Named package object of the form:
-     *      Name (xxxx, Package)
-     * the package object already exists, otherwise it must be created.
-     */
-    ObjDesc = *ObjDescPtr;
-    if (!ObjDesc)
-    {
-        ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE);
-        *ObjDescPtr = ObjDesc;
-        if (!ObjDesc)
-        {
-            return_ACPI_STATUS (AE_NO_MEMORY);
-        }
-
-printf ("****DS: BuildPkg - Create package object %p\n", ObjDesc);
-
-        ObjDesc->Package.Node = Parent->Common.Node;
-    }
-
-//
-printf ("****DS: BuildPkg, from DsEvalDataObjectOperands - Valid: %X, Pass %u, %p\n",
-    ObjDesc->Package.Flags & AOPOBJ_DATA_VALID,
-    WalkState->PassNumber, ObjDesc);
-
-// just in case
-if (ObjDesc->Package.Flags & AOPOBJ_DATA_VALID)
-{
-    return_ACPI_STATUS (AE_OK);
-}
-
-    /*
-     * Allocate the element array (array of pointers to the individual
-     * objects) based on the NumElements parameter. Add an extra pointer slot
-     * so that the list is always null terminated.
-     */
-    ObjDesc->Package.Elements = ACPI_ALLOCATE_ZEROED (
-        ((ACPI_SIZE) ElementCount + 1) * sizeof (void *));
-
-    if (!ObjDesc->Package.Elements)
-    {
-        AcpiUtDeleteObjectDesc (ObjDesc);
-        return_ACPI_STATUS (AE_NO_MEMORY);
-    }
-
-    ObjDesc->Package.Count = ElementCount;
-
-    /*
-     * Initialize the elements of the package, up to the NumElements count.
-     * Package is automatically padded with uninitialized (NULL) elements
-     * if NumElements is greater than the package list length. Likewise,
-     * Package is truncated if NumElements is less than the list length.
-     */
-    Arg = Op->Common.Value.Arg;
-    Arg = Arg->Common.Next;
-
-    if (Arg)
-    {
-        printf ("****DS: Mark package evaluated\n");
-        ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID;
-    }
-
-    for (i = 0; Arg && (i < ElementCount); i++)
-    {
-printf ("****DS: Eval package element\n");
-
-        if (Arg->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP)
-        {
-// Maybe this is just temp code:
-/*
-if (!Arg->Common.Node)
-{
-    printf ("****DS: No attached NS node\n");
-    return_ACPI_STATUS (AE_AML_INTERNAL);
-}
-else  */         if (Arg->Common.Node->Type == ACPI_TYPE_METHOD)
-            {
-
-                /*
-                 * A method reference "looks" to the parser to be a method
-                 * invocation, so we special case it here
-                 */
-                Arg->Common.AmlOpcode = AML_INT_NAMEPATH_OP;
-                Status = AcpiDsBuildInternalObject (
-                    WalkState, Arg, &ObjDesc->Package.Elements[i]);
-            }
-            else
-            {
-                /* This package element is already built, just get it */
-
-                ObjDesc->Package.Elements[i] =
-                    ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node);
-            }
-        }
-        else
-        {
-            Status = AcpiDsBuildInternalObject (
-                WalkState, Arg, &ObjDesc->Package.Elements[i]);
-            if (Status == AE_NOT_FOUND)
-            {
-// remove or fix
-                ACPI_ERROR ((AE_INFO, "%-48s", "****DS namepath not found"));
-            }
-
-            /*
-             * Initialize this package element. This function handles the
-             * resolution of named references within the package.
-             */
-            AcpiDsInitPackageElement (0, ObjDesc->Package.Elements[i],
-                NULL, &ObjDesc->Package.Elements[i]);
-        }
-
-        if (*ObjDescPtr)
-        {
-            /* Existing package, get existing reference count */
-
-            ReferenceCount = (*ObjDescPtr)->Common.ReferenceCount;
-            if (ReferenceCount > 1)
-            {
-                /* Make new element ref count match original ref count */
-
-                for (Index = 0; Index < (ReferenceCount - 1); Index++)
-                {
-                    AcpiUtAddReference ((ObjDesc->Package.Elements[i]));
-                }
-            }
-        }
-
-        Arg = Arg->Common.Next;
-    }
-
-    /* Check for match between NumElements and actual length of PackageList */
-
-    if (Arg)
-    {
-        //ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID;
-
-
-        /*
-         * NumElements was exhausted, but there are remaining elements in the
-         * PackageList. Truncate the package to NumElements.
-         *
-         * Note: technically, this is an error, from ACPI spec: "It is an error
-         * for NumElements to be less than the number of elements in the
-         * PackageList". However, we just print a message and
-         * no exception is returned. This provides Windows compatibility. Some
-         * BIOSs will alter the NumElements on the fly, creating this type
-         * of ill-formed package object.
-         */
-        while (Arg)
-        {
-            /*
-             * We must delete any package elements that were created earlier
-             * and are not going to be used because of the package truncation.
-             */
-            if (Arg->Common.Node)
-            {
-                AcpiUtRemoveReference (
-                    ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node));
-                Arg->Common.Node = NULL;
-            }
-
-            /* Find out how many elements there really are */
-
-            i++;
-            Arg = Arg->Common.Next;
-        }
-
-        ACPI_INFO ((
-            "Actual Package length (%u) is larger than "
-            "NumElements field (%u), truncated",
-            i, ElementCount));
-    }
-    else if (i < ElementCount)
-    {
-        /*
-         * Arg list (elements) was exhausted, but we did not reach
-         * NumElements count.
-         *
-         * Note: this is not an error, the package is padded out
-         * with NULLs.
-         */
-        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
-            "Package List length (%u) smaller than NumElements "
-            "count (%u), padded with null elements\n",
-            i, ElementCount));
-    }
-
-    Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc);
-    return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiDsInitPackageElement
- *
- * PARAMETERS:  ACPI_PKG_CALLBACK
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Resolve a named reference element within a package object
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiDsInitPackageElement (
-    UINT8                   ObjectType,
-    ACPI_OPERAND_OBJECT     *SourceObject,
-    ACPI_GENERIC_STATE      *State,
-    void                    *Context)
-{
-    ACPI_OPERAND_OBJECT     **ElementPtr;
-
-
-    if (!SourceObject)
-    {
-        return (AE_OK);
-    }
-
-    /*
-     * The following code is a bit of a hack to workaround a (current)
-     * limitation of the ACPI_PKG_CALLBACK interface. We need a pointer
-     * to the location within the element array because a new object
-     * may be created and stored there.
-     */
-    if (Context)
-    {
-        /* A direct call was made to this function */
-
-        ElementPtr = (ACPI_OPERAND_OBJECT **) Context;
-    }
-    else
-    {
-        /* Call came from AcpiUtWalkPackageTree */
-
-        ElementPtr = State->Pkg.ThisTargetObj;
-    }
-
-    /* We are only interested in reference objects/elements */
-
-    if (SourceObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
-    {
-        /* Resolve the (named) reference to a namespace node */
-
-        AcpiDsResolvePackageElement (ElementPtr);
-    }
-    else if (SourceObject->Common.Type == ACPI_TYPE_PACKAGE)
-    {
-        SourceObject->Package.Flags |= AOPOBJ_DATA_VALID;
-    }
-
-    return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiDsResolvePackageElement
- *
- * PARAMETERS:  ElementPtr          - Pointer to a reference object
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Resolve a package element that is a reference to a named
- *              object.
- *
- ******************************************************************************/
-
-static void
-AcpiDsResolvePackageElement (
-    ACPI_OPERAND_OBJECT     **ElementPtr)
-{
-    ACPI_STATUS             Status;
-    ACPI_GENERIC_STATE      ScopeInfo;
-    ACPI_OPERAND_OBJECT     *Element = *ElementPtr;
-    ACPI_NAMESPACE_NODE     *ResolvedNode;
-    ACPI_OBJECT_TYPE        Type;
-
-
-    ACPI_FUNCTION_TRACE (DsResolvePackageElement);
-
-
-    /* Check if reference element is already resolved */
-
-    if (Element->Reference.Resolved)
-    {
-        return_VOID;
-    }
-
-    /* Element must be a reference object of correct type */
-
-    ScopeInfo.Scope.Node = Element->Reference.Node; /* Prefix node */
-
-    Status = AcpiNsLookup (&ScopeInfo,
-        (char *) Element->Reference.Aml,            /* Pointer to AML path */
-        ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS2,
-        ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
-        NULL, &ResolvedNode);
-
-    if (ACPI_FAILURE (Status))
-    {
-        ACPI_EXCEPTION ((AE_INFO, Status,
-            "Could not resolve package element"));
-        return_VOID;
-    }
-
-    else if (ResolvedNode->Type == ACPI_TYPE_ANY)
-    {
-        /* Named reference not resolved, return a NULL package element */
-
-        ACPI_ERROR ((AE_INFO,
-            "Could not resolve package element [%4.4s] in [%4.4s]",
-            ResolvedNode->Name.Ascii, ScopeInfo.Scope.Node->Name.Ascii));
-        *ElementPtr = NULL;
-        return_VOID;
-    }
-
-    else if (ResolvedNode->Flags & ANOBJ_TEMPORARY)
-    {
-        /*
-         * A temporary node found here indicates that the reference is
-         * to a node that was created within this method. We are not
-         * going to allow it (especially if the package is returned
-         * from the method) -- the temporary node will be deleted out
-         * from under the method. (05/2017).
-         */
-        ACPI_ERROR ((AE_INFO,
-            "Package element is a temporary name [%4.4s], "
-            "returning NULL element",
-            ResolvedNode->Name.Ascii));
-        *ElementPtr = NULL;
-        return_VOID;
-    }
-
-    /* Update the reference object */
-
-    Element->Reference.Resolved = TRUE;
-    Element->Reference.Node = ResolvedNode;
-    Type = Element->Reference.Node->Type;
-
-    /*
-     * Attempt to resolve the node to a value before we insert it into
-     * the package. If this is a reference to a common data type,
-     * resolve it immediately. According to the ACPI spec, package
-     * elements can only be "data objects" or method references.
-     * Attempt to resolve to an Integer, Buffer, String or Package.
-     * If cannot, return the named reference (for things like Devices,
-     * Methods, etc.) Buffer Fields and Fields will resolve to simple
-     * objects (int/buf/str/pkg).
-     *
-     * NOTE: References to things like Devices, Methods, Mutexes, etc.
-     * will remain as named references. This behavior is not described
-     * in the ACPI spec, but it appears to be an oversight.
-     */
-    Status = AcpiExResolveNodeToValue (&ResolvedNode, NULL);
-    if (ACPI_FAILURE (Status))
-    {
-        return_VOID;
-    }
-
-#if 0
-    /*
-     * Special handling for Alias objects. We need to setup the type
-     * and the Op->Common.Node to point to the Alias target. Note,
-     * Alias has at most one level of indirection internally.
-     */
-    Type = Op->Common.Node->Type;
-    if (Type == ACPI_TYPE_LOCAL_ALIAS)
-    {
-        Type = ObjDesc->Common.Type;
-        Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
-            Op->Common.Node->Object);
-    }
-#endif
-
-    switch (Type)
-    {
-    /*
-     * These object types are a result of named references, so we will
-     * leave them as reference objects. In other words, these types
-     * have no intrinsic "value".
-     */
-    case ACPI_TYPE_DEVICE:
-    case ACPI_TYPE_THERMAL:
-
-        /* TBD: This may not be necesssary */
-
-        AcpiUtAddReference (ResolvedNode->Object);
-        break;
-
-    case ACPI_TYPE_MUTEX:
-    case ACPI_TYPE_METHOD:
-    case ACPI_TYPE_POWER:
-    case ACPI_TYPE_PROCESSOR:
-    case ACPI_TYPE_EVENT:
-    case ACPI_TYPE_REGION:
-
-        break;
-
-    default:
-        /*
-         * For all other types - the node was resolved to an actual
-         * operand object with a value, return the object
-         */
-        *ElementPtr = (ACPI_OPERAND_OBJECT *) ResolvedNode;
-        break;
-    }
-
-    return_VOID;
-}
index a8fba63..8fcf7bf 100644 (file)
@@ -94,6 +94,12 @@ AcpiExCreateAlias (
         TargetNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, TargetNode->Object);
     }
 
+    /* Ensure that the target node is valid */
+    if (!TargetNode)
+    {
+        return_ACPI_STATUS (AE_NULL_OBJECT);
+    }
+
     /*
      * For objects that can never change (i.e., the NS node will
      * permanently point to the same object), we can simply attach
index 00bbed6..2396ab6 100644 (file)
@@ -76,9 +76,18 @@ AcpiHwSleepDispatch (
 
 static ACPI_SLEEP_FUNCTIONS         AcpiSleepDispatch[] =
 {
-    {ACPI_HW_OPTIONAL_FUNCTION (AcpiHwLegacySleep),    AcpiHwExtendedSleep},
-    {ACPI_HW_OPTIONAL_FUNCTION (AcpiHwLegacyWakePrep), AcpiHwExtendedWakePrep},
-    {ACPI_HW_OPTIONAL_FUNCTION (AcpiHwLegacyWake),     AcpiHwExtendedWake}
+    {ACPI_STRUCT_INIT (legacy_function,
+                       ACPI_HW_OPTIONAL_FUNCTION (AcpiHwLegacySleep)),
+     ACPI_STRUCT_INIT (extended_function,
+                       AcpiHwExtendedSleep) },
+    {ACPI_STRUCT_INIT (legacy_function,
+                       ACPI_HW_OPTIONAL_FUNCTION (AcpiHwLegacyWakePrep)),
+     ACPI_STRUCT_INIT (extended_function,
+                       AcpiHwExtendedWakePrep) },
+    {ACPI_STRUCT_INIT (legacy_function,
+                       ACPI_HW_OPTIONAL_FUNCTION (AcpiHwLegacyWake)),
+     ACPI_STRUCT_INIT (extended_function,
+                       AcpiHwExtendedWake) }
 };
 
 
index 38afbf3..b3a8ead 100644 (file)
@@ -118,6 +118,10 @@ AcGetAllTablesFromFile (
     UINT8                   GetOnlyAmlTables,
     ACPI_NEW_TABLE_DESC     **ReturnListHead);
 
+void
+AcDeleteTableList (
+    ACPI_NEW_TABLE_DESC     *ListHead);
+
 BOOLEAN
 AcIsFileBinary (
     FILE                    *File);
index 21019ed..faf5bcf 100644 (file)
@@ -220,6 +220,7 @@ typedef struct acpi_namespace_node
 #define ANOBJ_EVALUATED                 0x20    /* Set on first evaluation of node */
 #define ANOBJ_ALLOCATED_BUFFER          0x40    /* Method AML buffer is dynamic (InstallMethod) */
 
+#define IMPLICIT_EXTERNAL               0x02    /* iASL only: This object created implicitly via External */
 #define ANOBJ_IS_EXTERNAL               0x08    /* iASL only: This object created via External() */
 #define ANOBJ_METHOD_NO_RETVAL          0x10    /* iASL only: Method has no return value */
 #define ANOBJ_METHOD_SOME_NO_RETVAL     0x20    /* iASL only: Method has at least one return value */
@@ -1038,7 +1039,7 @@ typedef struct acpi_parse_obj_named
 
 /* This version is used by the iASL compiler only */
 
-#define ACPI_MAX_PARSEOP_NAME   20
+#define ACPI_MAX_PARSEOP_NAME       20
 
 typedef struct acpi_parse_obj_asl
 {
@@ -1082,11 +1083,12 @@ typedef union acpi_parse_object
 
 typedef struct asl_comment_state
 {
-    UINT8                   CommentType;
-    UINT32                  SpacesBefore;
-    ACPI_PARSE_OBJECT       *Latest_Parse_Node;
-    ACPI_PARSE_OBJECT       *ParsingParenBraceNode;
-    BOOLEAN                 CaptureComments;
+    UINT8                           CommentType;
+    UINT32                          SpacesBefore;
+    ACPI_PARSE_OBJECT               *LatestParseOp;
+    ACPI_PARSE_OBJECT               *ParsingParenBraceNode;
+    BOOLEAN                         CaptureComments;
+
 } ASL_COMMENT_STATE;
 
 
index a402569..2a43055 100644 (file)
@@ -133,7 +133,9 @@ typedef struct acpi_object_integer
     UINT32                          Length;
 
 
-typedef struct acpi_object_string   /* Null terminated, ASCII characters only */
+/* Null terminated, ASCII characters only */
+
+typedef struct acpi_object_string
 {
     ACPI_OBJECT_COMMON_HEADER
     ACPI_COMMON_BUFFER_INFO         (char)              /* String in AML stream or allocated string */
@@ -251,8 +253,9 @@ typedef struct acpi_object_method
     union acpi_operand_object       *NotifyList[2];     /* Handlers for system/device notifies */\
     union acpi_operand_object       *Handler;           /* Handler for Address space */
 
+/* COMMON NOTIFY for POWER, PROCESSOR, DEVICE, and THERMAL */
 
-typedef struct acpi_object_notify_common    /* COMMON NOTIFY for POWER, PROCESSOR, DEVICE, and THERMAL */
+typedef struct acpi_object_notify_common
 {
     ACPI_OBJECT_COMMON_HEADER
     ACPI_COMMON_NOTIFY_INFO
@@ -323,8 +326,9 @@ typedef struct acpi_object_thermal_zone
     UINT8                           StartFieldBitOffset;/* Bit offset within first field datum (0-63) */\
     UINT8                           AccessLength;       /* For serial regions/fields */
 
+/* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */
 
-typedef struct acpi_object_field_common                 /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */
+typedef struct acpi_object_field_common
 {
     ACPI_OBJECT_COMMON_HEADER
     ACPI_COMMON_FIELD_INFO
index 526705e..94398aa 100644 (file)
@@ -46,7 +46,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20170531
+#define ACPI_CA_VERSION                 0x20170629
 
 #include "acconfig.h"
 #include "actypes.h"
@@ -162,13 +162,14 @@ ACPI_INIT_GLOBAL (UINT8,            AcpiGbl_CreateOsiMethod, TRUE);
 ACPI_INIT_GLOBAL (UINT8,            AcpiGbl_UseDefaultRegisterWidths, TRUE);
 
 /*
- * Whether or not to verify the table checksum before installation. Set
- * this to TRUE to verify the table checksum before install it to the table
- * manager. Note that enabling this option causes errors to happen in some
- * OSPMs during early initialization stages. Default behavior is to do such
- * verification.
+ * Whether or not to validate (map) an entire table to verify
+ * checksum/duplication in early stage before install. Set this to TRUE to
+ * allow early table validation before install it to the table manager.
+ * Note that enabling this option causes errors to happen in some OSPMs
+ * during early initialization stages. Default behavior is to allow such
+ * validation.
  */
-ACPI_INIT_GLOBAL (UINT8,            AcpiGbl_VerifyTableChecksum, TRUE);
+ACPI_INIT_GLOBAL (UINT8,            AcpiGbl_EnableTableValidation, TRUE);
 
 /*
  * Optionally enable output from the AML Debug Object.
index 88e959d..d5b06a4 100644 (file)
@@ -98,7 +98,8 @@ AcpiTbValidateTempTable (
 ACPI_STATUS
 AcpiTbVerifyTempTable (
     ACPI_TABLE_DESC         *TableDesc,
-    char                    *Signature);
+    char                    *Signature,
+    UINT32                  *TableIndex);
 
 BOOLEAN
 AcpiTbIsTableLoaded (
@@ -194,6 +195,11 @@ ACPI_STATUS
 AcpiTbUnloadTable (
     UINT32                  TableIndex);
 
+void
+AcpiTbNotifyTable (
+    UINT32                          Event,
+    void                            *Table);
+
 void
 AcpiTbTerminate (
     void);
index 8a1bfa5..8c5d2cd 100644 (file)
@@ -409,12 +409,27 @@ typedef struct acpi_table_desc
 
 } ACPI_TABLE_DESC;
 
+/*
+ * Maximum value of the ValidationCount field in ACPI_TABLE_DESC.
+ * When reached, ValidationCount cannot be changed any more and the table will
+ * be permanently regarded as validated.
+ *
+ * This is to prevent situations in which unbalanced table get/put operations
+ * may cause premature table unmapping in the OS to happen.
+ *
+ * The maximum validation count can be defined to any value, but should be
+ * greater than the maximum number of OS early stage mapping slots to avoid
+ * leaking early stage table mappings to the late stage.
+ */
+#define ACPI_MAX_TABLE_VALIDATIONS          ACPI_UINT16_MAX
+
 /* Masks for Flags field above */
 
 #define ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL  (0) /* Virtual address, external maintained */
 #define ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL (1) /* Physical address, internally mapped */
 #define ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL  (2) /* Virtual address, internallly allocated */
 #define ACPI_TABLE_ORIGIN_MASK              (3)
+#define ACPI_TABLE_IS_VERIFIED              (4)
 #define ACPI_TABLE_IS_LOADED                (8)
 
 
index e809688..cb1b638 100644 (file)
@@ -766,7 +766,7 @@ typedef struct acpi_ibft_target
  * IORT - IO Remapping Table
  *
  * Conforms to "IO Remapping Table System Software on ARM Platforms",
- * Document number: ARM DEN 0049B, October 2015
+ * Document number: ARM DEN 0049C, May 2017
  *
  ******************************************************************************/
 
@@ -905,6 +905,8 @@ typedef struct acpi_iort_smmu
 #define ACPI_IORT_SMMU_V2               0x00000001  /* Generic SMMUv2 */
 #define ACPI_IORT_SMMU_CORELINK_MMU400  0x00000002  /* ARM Corelink MMU-400 */
 #define ACPI_IORT_SMMU_CORELINK_MMU500  0x00000003  /* ARM Corelink MMU-500 */
+#define ACPI_IORT_SMMU_CORELINK_MMU401  0x00000004  /* ARM Corelink MMU-401 */
+#define ACPI_IORT_SMMU_CAVIUM_THUNDERX  0x00000005  /* Cavium ThunderX SMMUv2 */
 
 /* Masks for Flags field above */
 
@@ -928,18 +930,28 @@ typedef struct acpi_iort_smmu_v3
     UINT32                  Flags;
     UINT32                  Reserved;
     UINT64                  VatosAddress;
-    UINT32                  Model;                 /* O: generic SMMUv3 */
+    UINT32                  Model;
     UINT32                  EventGsiv;
     UINT32                  PriGsiv;
     UINT32                  GerrGsiv;
     UINT32                  SyncGsiv;
+    UINT8                   Pxm;
+    UINT8                   Reserved1;
+    UINT16                  Reserved2;
 
 } ACPI_IORT_SMMU_V3;
 
+/* Values for Model field above */
+
+#define ACPI_IORT_SMMU_V3_GENERIC           0x00000000  /* Generic SMMUv3 */
+#define ACPI_IORT_SMMU_V3_HISILICON_HI161X  0x00000001  /* HiSilicon Hi161x SMMUv3 */
+#define ACPI_IORT_SMMU_V3_CAVIUM_CN99XX     0x00000002  /* Cavium CN99xx SMMUv3 */
+
 /* Masks for Flags field above */
 
 #define ACPI_IORT_SMMU_V3_COHACC_OVERRIDE   (1)
 #define ACPI_IORT_SMMU_V3_HTTU_OVERRIDE     (1<<1)
+#define ACPI_IORT_SMMU_V3_PXM_VALID         (1<<3)
 
 
 /*******************************************************************************
index ddfdbef..3ed6263 100644 (file)
 #define ACPI_INLINE
 #endif
 
+/* Use ordered initialization if compiler doesn't support designated. */
+#ifndef ACPI_STRUCT_INIT
+#define ACPI_STRUCT_INIT(field, value)  value
+#endif
+
 /*
  * Configurable calling conventions:
  *
index 5bfa34d..2e92a85 100644 (file)
 #define ACPI_MSG_BIOS_ERROR     KERN_ERR "ACPI BIOS Error (bug): "
 #define ACPI_MSG_BIOS_WARNING   KERN_WARNING "ACPI BIOS Warning (bug): "
 
+/*
+ * Linux wants to use designated initializers for function pointer structs.
+ */
+#define ACPI_STRUCT_INIT(field, value)  .field = value
+
 #else /* !__KERNEL__ */
 
 #define ACPI_USE_STANDARD_HEADERS
index 9016712..f176c73 100644 (file)
@@ -656,6 +656,13 @@ AcpiNsLookup (
                     ThisNode = (ACPI_NAMESPACE_NODE *) ThisNode->Object;
                 }
             }
+#ifdef ACPI_ASL_COMPILER
+            if (!AcpiGbl_DisasmFlag &&
+                (ThisNode->Flags & ANOBJ_IS_EXTERNAL))
+            {
+                ThisNode->Flags |= IMPLICIT_EXTERNAL;
+            }
+#endif
         }
 
         /* Special handling for the last segment (NumSegments == 0) */
index 59fc7db..c4e3463 100644 (file)
@@ -379,6 +379,31 @@ AcpiPsCreateOp (
     {
         Status = AcpiPsBuildNamedOp (WalkState, AmlOpStart, Op, &NamedOp);
         AcpiPsFreeOp (Op);
+
+#ifdef ACPI_ASL_COMPILER
+        if (AcpiGbl_DisasmFlag && WalkState->Opcode == AML_EXTERNAL_OP &&
+            Status == AE_NOT_FOUND)
+        {
+            /*
+             * If parsing of AML_EXTERNAL_OP's name path fails, then skip
+             * past this opcode and keep parsing. This is a much better
+             * alternative than to abort the entire disassembler. At this
+             * point, the ParserState is at the end of the namepath of the
+             * external declaration opcode. Setting WalkState->Aml to
+             * WalkState->ParserState.Aml + 2 moves increments the
+             * WalkState->Aml past the object type and the paramcount of the
+             * external opcode. For the error message, only print the AML
+             * offset. We could attempt to print the name but this may cause
+             * a segmentation fault when printing the namepath because the
+             * AML may be incorrect.
+             */
+            AcpiOsPrintf (
+                "// Invalid external declaration at AML offset 0x%x.\n",
+                WalkState->Aml - WalkState->ParserState.AmlStart);
+            WalkState->Aml = WalkState->ParserState.Aml + 2;
+            return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
+        }
+#endif
         if (ACPI_FAILURE (Status))
         {
             return_ACPI_STATUS (Status);
index 254a99f..97c6890 100644 (file)
 #define _COMPONENT          ACPI_TABLES
         ACPI_MODULE_NAME    ("tbdata")
 
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiTbCheckDuplication (
+    ACPI_TABLE_DESC         *TableDesc,
+    UINT32                  *TableIndex);
+
+static BOOLEAN
+AcpiTbCompareTables (
+    ACPI_TABLE_DESC         *TableDesc,
+    UINT32                  TableIndex);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiTbCompareTables
+ *
+ * PARAMETERS:  TableDesc           - Table 1 descriptor to be compared
+ *              TableIndex          - Index of table 2 to be compared
+ *
+ * RETURN:      TRUE if both tables are identical.
+ *
+ * DESCRIPTION: This function compares a table with another table that has
+ *              already been installed in the root table list.
+ *
+ ******************************************************************************/
+
+static BOOLEAN
+AcpiTbCompareTables (
+    ACPI_TABLE_DESC         *TableDesc,
+    UINT32                  TableIndex)
+{
+    ACPI_STATUS             Status = AE_OK;
+    BOOLEAN                 IsIdentical;
+    ACPI_TABLE_HEADER       *Table;
+    UINT32                  TableLength;
+    UINT8                   TableFlags;
+
+
+    Status = AcpiTbAcquireTable (&AcpiGbl_RootTableList.Tables[TableIndex],
+        &Table, &TableLength, &TableFlags);
+    if (ACPI_FAILURE (Status))
+    {
+        return (FALSE);
+    }
+
+    /*
+     * Check for a table match on the entire table length,
+     * not just the header.
+     */
+    IsIdentical = (BOOLEAN)((TableDesc->Length != TableLength ||
+        memcmp (TableDesc->Pointer, Table, TableLength)) ?
+        FALSE : TRUE);
+
+    /* Release the acquired table */
+
+    AcpiTbReleaseTable (Table, TableLength, TableFlags);
+    return (IsIdentical);
+}
+
 
 /*******************************************************************************
  *
@@ -369,7 +429,7 @@ AcpiTbValidateTempTable (
     ACPI_TABLE_DESC         *TableDesc)
 {
 
-    if (!TableDesc->Pointer && !AcpiGbl_VerifyTableChecksum)
+    if (!TableDesc->Pointer && !AcpiGbl_EnableTableValidation)
     {
         /*
          * Only validates the header of the table.
@@ -387,12 +447,94 @@ AcpiTbValidateTempTable (
 }
 
 
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiTbCheckDuplication
+ *
+ * PARAMETERS:  TableDesc           - Table descriptor
+ *              TableIndex          - Where the table index is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Avoid installing duplicated tables. However table override and
+ *              user aided dynamic table load is allowed, thus comparing the
+ *              address of the table is not sufficient, and checking the entire
+ *              table content is required.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiTbCheckDuplication (
+    ACPI_TABLE_DESC         *TableDesc,
+    UINT32                  *TableIndex)
+{
+    UINT32                  i;
+
+
+    ACPI_FUNCTION_TRACE (TbCheckDuplication);
+
+
+    /* Check if table is already registered */
+
+    for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
+    {
+        /* Do not compare with unverified tables */
+
+        if (!(AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_VERIFIED))
+        {
+            continue;
+        }
+
+        /*
+         * Check for a table match on the entire table length,
+         * not just the header.
+         */
+        if (!AcpiTbCompareTables (TableDesc, i))
+        {
+            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.
+         */
+        if (AcpiGbl_RootTableList.Tables[i].Flags &
+            ACPI_TABLE_IS_LOADED)
+        {
+            /* Table is still loaded, this is an error */
+
+            return_ACPI_STATUS (AE_ALREADY_EXISTS);
+        }
+        else
+        {
+            *TableIndex = i;
+            return_ACPI_STATUS (AE_CTRL_TERMINATE);
+        }
+    }
+
+    /* Indicate no duplication to the caller */
+
+    return_ACPI_STATUS (AE_OK);
+}
+
+
 /******************************************************************************
  *
  * FUNCTION:    AcpiTbVerifyTempTable
  *
  * PARAMETERS:  TableDesc           - Table descriptor
  *              Signature           - Table signature to verify
+ *              TableIndex          - Where the table index is returned
  *
  * RETURN:      Status
  *
@@ -404,7 +546,8 @@ AcpiTbValidateTempTable (
 ACPI_STATUS
 AcpiTbVerifyTempTable (
     ACPI_TABLE_DESC         *TableDesc,
-    char                    *Signature)
+    char                    *Signature,
+    UINT32                  *TableIndex)
 {
     ACPI_STATUS             Status = AE_OK;
 
@@ -432,10 +575,10 @@ AcpiTbVerifyTempTable (
         goto InvalidateAndExit;
     }
 
-    /* Verify the checksum */
-
-    if (AcpiGbl_VerifyTableChecksum)
+    if (AcpiGbl_EnableTableValidation)
     {
+        /* Verify the checksum */
+
         Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
         if (ACPI_FAILURE (Status))
         {
@@ -448,9 +591,32 @@ AcpiTbVerifyTempTable (
 
             goto InvalidateAndExit;
         }
+
+        /* Avoid duplications */
+
+        if (TableIndex)
+        {
+            Status = AcpiTbCheckDuplication (TableDesc, TableIndex);
+            if (ACPI_FAILURE (Status))
+            {
+                if (Status != AE_CTRL_TERMINATE)
+                {
+                    ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
+                        "%4.4s 0x%8.8X%8.8X"
+                        " Table is duplicated",
+                        AcpiUtValidNameseg (TableDesc->Signature.Ascii) ?
+                            TableDesc->Signature.Ascii : "????",
+                        ACPI_FORMAT_UINT64 (TableDesc->Address)));
+                }
+
+                goto InvalidateAndExit;
+            }
+        }
+
+        TableDesc->Flags |= ACPI_TABLE_IS_VERIFIED;
     }
 
-    return_ACPI_STATUS (AE_OK);
+    return_ACPI_STATUS (Status);
 
 InvalidateAndExit:
     AcpiTbInvalidateTable (TableDesc);
@@ -476,6 +642,8 @@ AcpiTbResizeRootTableList (
 {
     ACPI_TABLE_DESC         *Tables;
     UINT32                  TableCount;
+    UINT32                  CurrentTableCount, MaxTableCount;
+    UINT32                  i;
 
 
     ACPI_FUNCTION_TRACE (TbResizeRootTableList);
@@ -500,9 +668,9 @@ AcpiTbResizeRootTableList (
         TableCount = AcpiGbl_RootTableList.CurrentTableCount;
     }
 
+    MaxTableCount = TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT;
     Tables = ACPI_ALLOCATE_ZEROED (
-        ((ACPI_SIZE) TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT) *
-        sizeof (ACPI_TABLE_DESC));
+        ((ACPI_SIZE) MaxTableCount) * sizeof (ACPI_TABLE_DESC));
     if (!Tables)
     {
         ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
@@ -511,10 +679,19 @@ AcpiTbResizeRootTableList (
 
     /* Copy and free the previous table array */
 
+    CurrentTableCount = 0;
     if (AcpiGbl_RootTableList.Tables)
     {
-        memcpy (Tables, AcpiGbl_RootTableList.Tables,
-            (ACPI_SIZE) TableCount * sizeof (ACPI_TABLE_DESC));
+        for (i = 0; i < TableCount; i++)
+        {
+            if (AcpiGbl_RootTableList.Tables[i].Address)
+            {
+                memcpy (Tables + CurrentTableCount,
+                    AcpiGbl_RootTableList.Tables + i,
+                    sizeof (ACPI_TABLE_DESC));
+                CurrentTableCount++;
+            }
+        }
 
         if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
         {
@@ -523,8 +700,8 @@ AcpiTbResizeRootTableList (
     }
 
     AcpiGbl_RootTableList.Tables = Tables;
-    AcpiGbl_RootTableList.MaxTableCount =
-        TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT;
+    AcpiGbl_RootTableList.MaxTableCount = MaxTableCount;
+    AcpiGbl_RootTableList.CurrentTableCount = CurrentTableCount;
     AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
 
     return_ACPI_STATUS (AE_OK);
@@ -921,14 +1098,9 @@ AcpiTbLoadTable (
         AcpiEvUpdateGpes (OwnerId);
     }
 
-    /* Invoke table handler if present */
-
-    if (AcpiGbl_TableHandler)
-    {
-        (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
-            AcpiGbl_TableHandlerContext);
-    }
+    /* Invoke table handler */
 
+    AcpiTbNotifyTable (ACPI_TABLE_EVENT_LOAD, Table);
     return_ACPI_STATUS (Status);
 }
 
@@ -962,24 +1134,19 @@ AcpiTbInstallAndLoadTable (
     ACPI_FUNCTION_TRACE (TbInstallAndLoadTable);
 
 
-    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
-
     /* Install the table and load it into the namespace */
 
     Status = AcpiTbInstallStandardTable (Address, Flags, TRUE,
         Override, &i);
     if (ACPI_FAILURE (Status))
     {
-        goto UnlockAndExit;
+        goto Exit;
     }
 
-    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
     Status = AcpiTbLoadTable (i, AcpiGbl_RootNode);
-    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
 
-UnlockAndExit:
+Exit:
     *TableIndex = i;
-    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
     return_ACPI_STATUS (Status);
 }
 
@@ -1014,16 +1181,12 @@ AcpiTbUnloadTable (
         return_ACPI_STATUS (AE_NOT_EXIST);
     }
 
-    /* Invoke table handler if present */
+    /* Invoke table handler */
 
-    if (AcpiGbl_TableHandler)
+    Status = AcpiGetTableByIndex (TableIndex, &Table);
+    if (ACPI_SUCCESS (Status))
     {
-        Status = AcpiGetTableByIndex (TableIndex, &Table);
-        if (ACPI_SUCCESS (Status))
-        {
-            (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD, Table,
-                AcpiGbl_TableHandlerContext);
-        }
+        AcpiTbNotifyTable (ACPI_TABLE_EVENT_UNLOAD, Table);
     }
 
     /* Delete the portion of the namespace owned by this table */
@@ -1038,3 +1201,31 @@ AcpiTbUnloadTable (
     AcpiTbSetTableLoadedFlag (TableIndex, FALSE);
     return_ACPI_STATUS (Status);
 }
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiTbNotifyTable
+ *
+ * PARAMETERS:  Event               - Table event
+ *              Table               - Validated table pointer
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Notify a table event to the users.
+ *
+ ******************************************************************************/
+
+void
+AcpiTbNotifyTable (
+    UINT32                          Event,
+    void                            *Table)
+{
+    /* Invoke table handler if present */
+
+    if (AcpiGbl_TableHandler)
+    {
+        (void) AcpiGbl_TableHandler (Event, Table,
+            AcpiGbl_TableHandlerContext);
+    }
+}
index 53e9e43..94b5342 100644 (file)
 #define _COMPONENT          ACPI_TABLES
         ACPI_MODULE_NAME    ("tbinstal")
 
-/* Local prototypes */
-
-static BOOLEAN
-AcpiTbCompareTables (
-    ACPI_TABLE_DESC         *TableDesc,
-    UINT32                  TableIndex);
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiTbCompareTables
- *
- * PARAMETERS:  TableDesc           - Table 1 descriptor to be compared
- *              TableIndex          - Index of table 2 to be compared
- *
- * RETURN:      TRUE if both tables are identical.
- *
- * DESCRIPTION: This function compares a table with another table that has
- *              already been installed in the root table list.
- *
- ******************************************************************************/
-
-static BOOLEAN
-AcpiTbCompareTables (
-    ACPI_TABLE_DESC         *TableDesc,
-    UINT32                  TableIndex)
-{
-    ACPI_STATUS             Status = AE_OK;
-    BOOLEAN                 IsIdentical;
-    ACPI_TABLE_HEADER       *Table;
-    UINT32                  TableLength;
-    UINT8                   TableFlags;
-
-
-    Status = AcpiTbAcquireTable (&AcpiGbl_RootTableList.Tables[TableIndex],
-        &Table, &TableLength, &TableFlags);
-    if (ACPI_FAILURE (Status))
-    {
-        return (FALSE);
-    }
-
-    /*
-     * Check for a table match on the entire table length,
-     * not just the header.
-     */
-    IsIdentical = (BOOLEAN)((TableDesc->Length != TableLength ||
-        memcmp (TableDesc->Pointer, Table, TableLength)) ?
-        FALSE : TRUE);
-
-    /* Release the acquired table */
-
-    AcpiTbReleaseTable (Table, TableLength, TableFlags);
-    return (IsIdentical);
-}
-
 
 /*******************************************************************************
  *
@@ -229,105 +174,48 @@ AcpiTbInstallStandardTable (
         goto ReleaseAndExit;
     }
 
+    /* Acquire the table lock */
+
+    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+
     /* Validate and verify a table before installation */
 
-    Status = AcpiTbVerifyTempTable (&NewTableDesc, NULL);
+    Status = AcpiTbVerifyTempTable (&NewTableDesc, NULL, &i);
     if (ACPI_FAILURE (Status))
     {
-        goto ReleaseAndExit;
-    }
-
-    if (Reload)
-    {
-        /*
-         * 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)) &&
-           (strncmp (NewTableDesc.Signature.Ascii, "OEM", 3)))
-        {
-            ACPI_BIOS_ERROR ((AE_INFO,
-                "Table has invalid signature [%4.4s] (0x%8.8X), "
-                "must be SSDT or OEMx",
-                AcpiUtValidNameseg (NewTableDesc.Signature.Ascii) ?
-                    NewTableDesc.Signature.Ascii : "????",
-                NewTableDesc.Signature.Integer));
-
-            Status = AE_BAD_SIGNATURE;
-            goto ReleaseAndExit;
-        }
-
-        /* Check if table is already registered */
-
-        for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
+        if (Status == AE_CTRL_TERMINATE)
         {
             /*
-             * Check for a table match on the entire table length,
-             * not just the header.
+             * 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.
              */
-            if (!AcpiTbCompareTables (&NewTableDesc, i))
-            {
-                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.
-             */
-            if (AcpiGbl_RootTableList.Tables[i].Flags &
-                ACPI_TABLE_IS_LOADED)
-            {
-                /* Table is still loaded, this is an error */
-
-                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;
-                return_ACPI_STATUS (AE_OK);
-            }
+            AcpiTbUninstallTable (&NewTableDesc);
+            (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+            *TableIndex = i;
+            return_ACPI_STATUS (AE_OK);
         }
+        goto UnlockAndExit;
     }
 
     /* Add the table to the global root table list */
 
     AcpiTbInstallTableWithOverride (&NewTableDesc, Override, TableIndex);
 
-    /* Invoke table handler if present */
+    /* Invoke table handler */
 
-    if (AcpiGbl_TableHandler)
-    {
-        (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_INSTALL,
-            NewTableDesc.Pointer, AcpiGbl_TableHandlerContext);
-    }
+    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+    AcpiTbNotifyTable (ACPI_TABLE_EVENT_INSTALL, NewTableDesc.Pointer);
+    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+
+UnlockAndExit:
+
+    /* Release the table lock */
+
+    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
 
 ReleaseAndExit:
 
@@ -395,9 +283,11 @@ AcpiTbOverrideTable (
 
 FinishOverride:
 
-    /* Validate and verify a table before overriding */
-
-    Status = AcpiTbVerifyTempTable (&NewTableDesc, NULL);
+    /*
+     * Validate and verify a table before overriding, no nested table
+     * duplication check as it's too complicated and unnecessary.
+     */
+    Status = AcpiTbVerifyTempTable (&NewTableDesc, NULL, NULL);
     if (ACPI_FAILURE (Status))
     {
         return;
index 006e8d9..d47d8d0 100644 (file)
@@ -451,14 +451,19 @@ AcpiTbGetTable (
         }
     }
 
-    TableDesc->ValidationCount++;
-    if (TableDesc->ValidationCount == 0)
+    if (TableDesc->ValidationCount < ACPI_MAX_TABLE_VALIDATIONS)
     {
-        ACPI_ERROR ((AE_INFO,
-            "Table %p, Validation count is zero after increment\n",
-            TableDesc));
-        TableDesc->ValidationCount--;
-        return_ACPI_STATUS (AE_LIMIT);
+        TableDesc->ValidationCount++;
+
+        /*
+         * Detect ValidationCount overflows to ensure that the warning
+         * message will only be printed once.
+         */
+        if (TableDesc->ValidationCount >= ACPI_MAX_TABLE_VALIDATIONS)
+        {
+            ACPI_WARNING((AE_INFO,
+                "Table %p, Validation count overflows\n", TableDesc));
+        }
     }
 
     *OutTable = TableDesc->Pointer;
@@ -489,14 +494,21 @@ AcpiTbPutTable (
     ACPI_FUNCTION_TRACE (AcpiTbPutTable);
 
 
-    if (TableDesc->ValidationCount == 0)
+    if (TableDesc->ValidationCount < ACPI_MAX_TABLE_VALIDATIONS)
     {
-        ACPI_WARNING ((AE_INFO,
-            "Table %p, Validation count is zero before decrement\n",
-            TableDesc));
-        return_VOID;
+        TableDesc->ValidationCount--;
+
+        /*
+         * Detect ValidationCount underflows to ensure that the warning
+         * message will only be printed once.
+         */
+        if (TableDesc->ValidationCount >= ACPI_MAX_TABLE_VALIDATIONS)
+        {
+            ACPI_WARNING ((AE_INFO,
+                "Table %p, Validation count underflows\n", TableDesc));
+            return_VOID;
+        }
     }
-    TableDesc->ValidationCount--;
 
     if (TableDesc->ValidationCount == 0)
     {
index 473cccd..17e23ba 100644 (file)
@@ -184,6 +184,7 @@ AcpiReallocateRootTable (
     void)
 {
     ACPI_STATUS             Status;
+    ACPI_TABLE_DESC         *TableDesc;
     UINT32                  i;
 
 
@@ -199,6 +200,8 @@ AcpiReallocateRootTable (
         return_ACPI_STATUS (AE_SUPPORT);
     }
 
+    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+
     /*
      * Ensure OS early boot logic, which is required by some hosts. If the
      * table state is reported to be wrong, developers should fix the
@@ -207,17 +210,41 @@ AcpiReallocateRootTable (
      */
     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
     {
-        if (AcpiGbl_RootTableList.Tables[i].Pointer)
+        TableDesc = &AcpiGbl_RootTableList.Tables[i];
+        if (TableDesc->Pointer)
         {
             ACPI_ERROR ((AE_INFO,
                 "Table [%4.4s] is not invalidated during early boot stage",
-                AcpiGbl_RootTableList.Tables[i].Signature.Ascii));
+                TableDesc->Signature.Ascii));
         }
     }
 
-    AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE;
+    if (!AcpiGbl_EnableTableValidation)
+    {
+        /*
+         * Now it's safe to do full table validation. We can do deferred
+         * table initilization here once the flag is set.
+         */
+        AcpiGbl_EnableTableValidation = TRUE;
+        for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
+        {
+            TableDesc = &AcpiGbl_RootTableList.Tables[i];
+            if (!(TableDesc->Flags & ACPI_TABLE_IS_VERIFIED))
+            {
+                Status = AcpiTbVerifyTempTable (TableDesc, NULL, NULL);
+                if (ACPI_FAILURE (Status))
+                {
+                    AcpiTbUninstallTable (TableDesc);
+                }
+            }
+        }
+    }
 
+    AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE;
     Status = AcpiTbResizeRootTableList ();
+    AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
+
+    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
     return_ACPI_STATUS (Status);
 }
 
@@ -414,6 +441,11 @@ AcpiPutTable (
     ACPI_FUNCTION_TRACE (AcpiPutTable);
 
 
+    if (!Table)
+    {
+        return_VOID;
+    }
+
     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
 
     /* Walk the root table list */
index 3858bb0..c9bfe42 100644 (file)
@@ -228,11 +228,11 @@ AcpiTbLoadNamespace (
     {
         Table = &AcpiGbl_RootTableList.Tables[i];
 
-        if (!AcpiGbl_RootTableList.Tables[i].Address ||
+        if (!Table->Address ||
             (!ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_SSDT) &&
              !ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_PSDT) &&
              !ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_OSDT)) ||
-             ACPI_FAILURE (AcpiTbValidateTable (Table)))
+            ACPI_FAILURE (AcpiTbValidateTable (Table)))
         {
             continue;
         }
index 2a32078..bb1454b 100644 (file)
@@ -195,11 +195,9 @@ AcpiUtWalkAmlResources (
     ACPI_FUNCTION_TRACE (UtWalkAmlResources);
 
 
-    /*
-     * The absolute minimum resource template is one EndTag descriptor.
-     * However, we will treat a lone EndTag as just a simple buffer.
-     */
-    if (AmlLength <= sizeof (AML_RESOURCE_END_TAG))
+    /* The absolute minimum resource template is one EndTag descriptor */
+
+    if (AmlLength < sizeof (AML_RESOURCE_END_TAG))
     {
         return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
     }
@@ -270,10 +268,8 @@ AcpiUtWalkAmlResources (
                 *Context = Aml;
             }
 
-            /*
-             * Normal exit. Note: We allow the buffer to be larger than
-             * the resource template, as long as the END_TAG exists.
-             */
+            /* Normal exit */
+
             return_ACPI_STATUS (AE_OK);
         }