#include "amlcode.h"
#include "acdispat.h"
#include "acinterp.h"
+#include "acparser.h"
#define _COMPONENT ACPI_NAMESPACE
ACPI_PARSE_OBJECT *Parent;
ACPI_OPERAND_OBJECT *ObjDesc = NULL;
ACPI_STATUS Status = AE_OK;
+ BOOLEAN ModuleLevelCode = FALSE;
UINT16 ReferenceCount;
UINT32 Index;
UINT32 i;
ACPI_FUNCTION_TRACE (DsBuildInternalPackageObj);
+ /* Check if we are executing module level code */
+
+ if (WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL)
+ {
+ ModuleLevelCode = TRUE;
+ }
+
/* Find the parent of a possibly nested package */
Parent = Op->Common.Parent;
/*
* 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.
+ * objects) if necessary. the count is 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.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;
}
- ObjDesc->Package.Count = ElementCount;
+ /* First arg is element count. Second arg begins the initializer list */
+
Arg = Op->Common.Value.Arg;
Arg = Arg->Common.Next;
- if (Arg)
+ /*
+ * If we are executing module-level code, we will defer the
+ * full resolution of the package elements in order to support
+ * forward references from the elements. This provides
+ * compatibility with other ACPI implementations.
+ */
+ if (ModuleLevelCode)
{
- ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID;
+ ObjDesc->Package.AmlStart = WalkState->Aml;
+ ObjDesc->Package.AmlLength = 0;
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_PARSE,
+ "%s: Deferring resolution of Package elements\n",
+ ACPI_GET_FUNCTION_NAME));
}
/*
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 (!ModuleLevelCode)
+ {
+ /*
+ * Initialize this package element. This function handles the
+ * resolution of named references within the package.
+ * Forward references from module-level code are deferred
+ * until all ACPI tables are loaded.
+ */
+ AcpiDsInitPackageElement (0, ObjDesc->Package.Elements[i],
+ NULL, &ObjDesc->Package.Elements[i]);
+ }
}
if (*ObjDescPtr)
* NumElements count.
*
* Note: this is not an error, the package is padded out
- * with NULLs.
+ * with NULLs as per the ACPI specification.
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Package List length (%u) smaller than NumElements "
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO,
+ "%s: Package List length (%u) smaller than NumElements "
"count (%u), padded with null elements\n",
- i, ElementCount));
+ ACPI_GET_FUNCTION_NAME, i, ElementCount));
+ }
+
+ /* Module-level packages will be resolved later */
+
+ if (!ModuleLevelCode)
+ {
+ ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID;
}
- ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID;
Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc);
return_ACPI_STATUS (Status);
}
ACPI_OPERAND_OBJECT **ElementPtr)
{
ACPI_STATUS Status;
+ ACPI_STATUS Status2;
ACPI_GENERIC_STATE ScopeInfo;
ACPI_OPERAND_OBJECT *Element = *ElementPtr;
ACPI_NAMESPACE_NODE *ResolvedNode;
ACPI_NAMESPACE_NODE *OriginalNode;
- char *ExternalPath = NULL;
+ char *ExternalPath = "";
ACPI_OBJECT_TYPE Type;
if (Element->Reference.Resolved)
{
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_PARSE,
+ "%s: Package element is already resolved\n",
+ ACPI_GET_FUNCTION_NAME));
+
return_VOID;
}
ScopeInfo.Scope.Node = Element->Reference.Node; /* Prefix node */
- Status = AcpiNsLookup (&ScopeInfo,
- (char *) Element->Reference.Aml, /* Pointer to AML path */
+ Status = AcpiNsLookup (&ScopeInfo, (char *) Element->Reference.Aml,
ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
NULL, &ResolvedNode);
if (ACPI_FAILURE (Status))
{
- Status = AcpiNsExternalizeName (ACPI_UINT32_MAX,
- (char *) Element->Reference.Aml,
- NULL, &ExternalPath);
+ if ((Status == AE_NOT_FOUND) && AcpiGbl_IgnorePackageResolutionErrors)
+ {
+ /*
+ * Optionally be silent about the NOT_FOUND case for the referenced
+ * name. Although this is potentially a serious problem,
+ * it can generate a lot of noise/errors on platforms whose
+ * firmware carries around a bunch of unused Package objects.
+ * To disable these errors, set this global to TRUE:
+ * AcpiGbl_IgnorePackageResolutionErrors
+ *
+ * If the AML actually tries to use such a package, the unresolved
+ * element(s) will be replaced with NULL elements.
+ */
+
+ /* Referenced name not found, set the element to NULL */
+
+ AcpiUtRemoveReference (*ElementPtr);
+ *ElementPtr = NULL;
+ return_VOID;
+ }
+
+ Status2 = AcpiNsExternalizeName (ACPI_UINT32_MAX,
+ (char *) Element->Reference.Aml, NULL, &ExternalPath);
ACPI_EXCEPTION ((AE_INFO, Status,
- "Could not find/resolve named package element: %s", ExternalPath));
+ "While resolving a named reference package element - %s",
+ ExternalPath));
+ if (ACPI_SUCCESS (Status2))
+ {
+ ACPI_FREE (ExternalPath);
+ }
+
+ /* Could not resolve name, set the element to NULL */
- ACPI_FREE (ExternalPath);
+ AcpiUtRemoveReference (*ElementPtr);
*ElementPtr = NULL;
return_VOID;
}
*ElementPtr = NULL;
return_VOID;
}
-#if 0
- 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 refers to a temporary name [%4.4s], "
- "inserting a NULL element",
- ResolvedNode->Name.Ascii));
- *ElementPtr = NULL;
- return_VOID;
- }
-#endif
/*
* Special handling for Alias objects. We need ResolvedNode to point
return_VOID;
}
-#if 0
-/* TBD - alias support */
- /*
- * 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)
{
/*