summaryrefslogtreecommitdiffstats
path: root/sys/contrib/dev/acpica/common/dmextern.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/dev/acpica/common/dmextern.c')
-rw-r--r--sys/contrib/dev/acpica/common/dmextern.c520
1 files changed, 443 insertions, 77 deletions
diff --git a/sys/contrib/dev/acpica/common/dmextern.c b/sys/contrib/dev/acpica/common/dmextern.c
index a8aecf8..e303674 100644
--- a/sys/contrib/dev/acpica/common/dmextern.c
+++ b/sys/contrib/dev/acpica/common/dmextern.c
@@ -199,6 +199,9 @@ static const char *AcpiGbl_DmTypeNames[] =
#define METHOD_SEPARATORS " \t,()\n"
+static const char *ExternalConflictMessage =
+ " // Conflicts with a later declaration";
+
/* Local prototypes */
@@ -211,6 +214,16 @@ AcpiDmNormalizeParentPrefix (
ACPI_PARSE_OBJECT *Op,
char *Path);
+static ACPI_STATUS
+AcpiDmGetExternalAndInternalPath (
+ ACPI_NAMESPACE_NODE *Node,
+ char **ExternalPath,
+ char **InternalPath);
+
+static ACPI_STATUS
+AcpiDmRemoveRootPrefix (
+ char **Path);
+
static void
AcpiDmAddPathToExternalList (
char *Path,
@@ -226,6 +239,21 @@ AcpiDmCreateNewExternal (
UINT32 Value,
UINT16 Flags);
+static void
+AcpiDmCheckForExternalConflict (
+ char *Path);
+
+static ACPI_STATUS
+AcpiDmResolveExternal (
+ char *Path,
+ UINT8 Type,
+ ACPI_NAMESPACE_NODE **Node);
+
+
+static void
+AcpiDmConflictingDeclaration (
+ char *Path);
+
/*******************************************************************************
*
@@ -582,7 +610,7 @@ AcpiDmGetExternalsFromFile (
{
/* Add the external(s) to the namespace */
- AcpiDmAddExternalsToNamespace ();
+ AcpiDmAddExternalListToNamespace ();
AcpiOsPrintf ("%s: Imported %u external method definitions\n",
Gbl_ExternalRefFilename, ImportCount);
@@ -698,6 +726,86 @@ AcpiDmAddOpToExternalList (
/*******************************************************************************
*
+ * FUNCTION: AcpiDmGetExternalAndInternalPath
+ *
+ * PARAMETERS: Node - Namespace node for object to be added
+ * ExternalPath - Will contain the external path of the node
+ * InternalPath - Will contain the internal path of the node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Get the External and Internal path from the given node.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDmGetExternalAndInternalPath (
+ ACPI_NAMESPACE_NODE *Node,
+ char **ExternalPath,
+ char **InternalPath)
+{
+ ACPI_STATUS Status;
+
+
+ if (!Node)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Get the full external and internal pathnames to the node */
+
+ *ExternalPath = AcpiNsGetExternalPathname (Node);
+ if (!*ExternalPath)
+ {
+ return (AE_BAD_PATHNAME);
+ }
+
+ Status = AcpiNsInternalizeName (*ExternalPath, InternalPath);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (*ExternalPath);
+ return (Status);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmRemoveRootPrefix
+ *
+ * PARAMETERS: Path - Remove Root prefix from this Path
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Remove the root prefix character '\' from Path.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDmRemoveRootPrefix (
+ char **Path)
+{
+ char *InputPath = *Path;
+
+
+ if ((*InputPath == AML_ROOT_PREFIX) && (InputPath[1]))
+ {
+ if (!memmove(InputPath, InputPath+1, strlen(InputPath)))
+ {
+ return (AE_ERROR);
+ }
+
+ *Path = InputPath;
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: AcpiDmAddNodeToExternalList
*
* PARAMETERS: Node - Namespace node for object to be added
@@ -727,46 +835,27 @@ AcpiDmAddNodeToExternalList (
{
char *ExternalPath;
char *InternalPath;
- char *Temp;
ACPI_STATUS Status;
ACPI_FUNCTION_TRACE (DmAddNodeToExternalList);
-
- if (!Node)
- {
- return_VOID;
- }
-
/* Get the full external and internal pathnames to the node */
- ExternalPath = AcpiNsGetExternalPathname (Node);
- if (!ExternalPath)
- {
- return_VOID;
- }
-
- Status = AcpiNsInternalizeName (ExternalPath, &InternalPath);
+ Status = AcpiDmGetExternalAndInternalPath (Node, &ExternalPath, &InternalPath);
if (ACPI_FAILURE (Status))
{
- ACPI_FREE (ExternalPath);
return_VOID;
}
/* Remove the root backslash */
- if ((*ExternalPath == AML_ROOT_PREFIX) && (ExternalPath[1]))
+ Status = AcpiDmRemoveRootPrefix (&ExternalPath);
+ if (ACPI_FAILURE (Status))
{
- Temp = ACPI_ALLOCATE_ZEROED (strlen (ExternalPath) + 1);
- if (!Temp)
- {
- return_VOID;
- }
-
- strcpy (Temp, &ExternalPath[1]);
ACPI_FREE (ExternalPath);
- ExternalPath = Temp;
+ ACPI_FREE (InternalPath);
+ return_VOID;
}
/* Create the new External() declaration node */
@@ -1013,68 +1102,171 @@ AcpiDmCreateNewExternal (
/*******************************************************************************
*
- * FUNCTION: AcpiDmAddExternalsToNamespace
+ * FUNCTION: AcpiDmResolveExternal
*
- * PARAMETERS: None
+ * PARAMETERS: Path - Path of the external
+ * Type - Type of the external
+ * Node - Input node for AcpiNsLookup
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Resolve the external within the namespace by AcpiNsLookup.
+ * If the returned node is an external and has the same type
+ * we assume that it was either an existing external or a
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDmResolveExternal (
+ char *Path,
+ UINT8 Type,
+ ACPI_NAMESPACE_NODE **Node)
+{
+ ACPI_STATUS Status;
+
+
+ Status = AcpiNsLookup (NULL, Path, Type,
+ ACPI_IMODE_LOAD_PASS1,
+ ACPI_NS_ERROR_IF_FOUND | ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
+ NULL, Node);
+
+ if (!Node)
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "while adding external to namespace [%s]", Path));
+ }
+
+ /* Note the asl code "external(a) external(a)" is acceptable ASL */
+
+ else if ((*Node)->Type == Type &&
+ (*Node)->Flags & ANOBJ_IS_EXTERNAL)
+ {
+ return (AE_OK);
+ }
+ else
+ {
+ ACPI_EXCEPTION ((AE_INFO, AE_ERROR,
+ "[%s] has conflicting declarations", Path));
+ }
+
+ return (AE_ERROR);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCreateSubobjectForExternal
+ *
+ * PARAMETERS: Type - Type of the external
+ * Node - Namespace node from AcpiNsLookup
+ * ParamCount - Value to be used for Method
*
* RETURN: None
*
- * DESCRIPTION: Add all externals to the namespace. Allows externals to be
+ * DESCRIPTION: Add one external to the namespace. Allows external to be
* "resolved".
*
******************************************************************************/
void
-AcpiDmAddExternalsToNamespace (
- void)
+AcpiDmCreateSubobjectForExternal (
+ UINT8 Type,
+ ACPI_NAMESPACE_NODE **Node,
+ UINT32 ParamCount)
{
- ACPI_STATUS Status;
- ACPI_NAMESPACE_NODE *Node;
ACPI_OPERAND_OBJECT *ObjDesc;
- ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;
- while (External)
+ switch (Type)
{
- /* Add the external name (object) into the namespace */
+ case ACPI_TYPE_METHOD:
- Status = AcpiNsLookup (NULL, External->InternalPath, External->Type,
- ACPI_IMODE_LOAD_PASS1,
- ACPI_NS_ERROR_IF_FOUND | ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
- NULL, &Node);
+ /* For methods, we need to save the argument count */
- if (ACPI_FAILURE (Status))
- {
- ACPI_EXCEPTION ((AE_INFO, Status,
- "while adding external to namespace [%s]",
- External->Path));
- }
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
+ ObjDesc->Method.ParamCount = (UINT8) ParamCount;
+ (*Node)->Object = ObjDesc;
+ break;
- else switch (External->Type)
- {
- case ACPI_TYPE_METHOD:
+ case ACPI_TYPE_REGION:
- /* For methods, we need to save the argument count */
+ /* Regions require a region sub-object */
- ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
- ObjDesc->Method.ParamCount = (UINT8) External->Value;
- Node->Object = ObjDesc;
- break;
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
+ ObjDesc->Region.Node = *Node;
+ (*Node)->Object = ObjDesc;
+ break;
- case ACPI_TYPE_REGION:
+ default:
- /* Regions require a region sub-object */
+ break;
+ }
+}
- ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
- ObjDesc->Region.Node = Node;
- Node->Object = ObjDesc;
- break;
- default:
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddOneExternalToNamespace
+ *
+ * PARAMETERS: Path - External parse object
+ * Type - Type of parse object
+ * ParamCount - External method parameter count
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Add one external to the namespace by resolvign the external
+ * (by performing a namespace lookup) and annotating the resulting
+ * namespace node with the approperiate information if the type
+ * is ACPI_TYPE_REGION or ACPI_TYPE_METHOD.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmAddOneExternalToNamespace (
+ char *Path,
+ UINT8 Type,
+ UINT32 ParamCount)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
- break;
- }
+ Status = AcpiDmResolveExternal (Path, Type, &Node);
+
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ AcpiDmCreateSubobjectForExternal (Type, &Node, ParamCount);
+
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddExternalListToNamespace
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Add all externals within AcpiGbl_ExternalList to the namespace.
+ * Allows externals to be "resolved".
+ *
+ ******************************************************************************/
+
+void
+AcpiDmAddExternalListToNamespace (
+ void)
+{
+ ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;
+
+
+ while (External)
+ {
+ AcpiDmAddOneExternalToNamespace (External->InternalPath,
+ External->Type, External->Value);
External = External->Next;
}
}
@@ -1082,23 +1274,28 @@ AcpiDmAddExternalsToNamespace (
/*******************************************************************************
*
- * FUNCTION: AcpiDmGetExternalMethodCount
+ * FUNCTION: AcpiDmGetUnresolvedExternalMethodCount
*
* PARAMETERS: None
*
- * RETURN: The number of control method externals in the external list
+ * RETURN: The number of unresolved control method externals in the
+ * external list
*
- * DESCRIPTION: Return the number of method externals that have been generated.
- * If any control method externals have been found, we must
- * re-parse the entire definition block with the new information
- * (number of arguments for the methods.) This is limitation of
- * AML, we don't know the number of arguments from the control
- * method invocation itself.
+ * DESCRIPTION: Return the number of unresolved external methods that have been
+ * generated. If any unresolved control method externals have been
+ * found, we must re-parse the entire definition block with the new
+ * information (number of arguments for the methods.)
+ * This is limitation of AML, we don't know the number of arguments
+ * from the control method invocation itself.
+ *
+ * Note: resolved external control methods are external control
+ * methods encoded with the AML_EXTERNAL_OP bytecode within the
+ * AML being disassembled.
*
******************************************************************************/
UINT32
-AcpiDmGetExternalMethodCount (
+AcpiDmGetUnresolvedExternalMethodCount (
void)
{
ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;
@@ -1107,7 +1304,8 @@ AcpiDmGetExternalMethodCount (
while (External)
{
- if (External->Type == ACPI_TYPE_METHOD)
+ if (External->Type == ACPI_TYPE_METHOD &&
+ !(External->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE))
{
Count++;
}
@@ -1251,6 +1449,11 @@ AcpiDmEmitExternals (
}
}
+ if (AcpiGbl_ExternalList->Flags &= ACPI_EXT_CONFLICTING_DECLARATION)
+ {
+ AcpiOsPrintf ("%s", ExternalConflictMessage);
+ AcpiDmConflictingDeclaration (AcpiGbl_ExternalList->Path);
+ }
AcpiOsPrintf ("\n");
}
@@ -1273,6 +1476,106 @@ AcpiDmEmitExternals (
/*******************************************************************************
*
+ * FUNCTION: AcpiDmMarkExternalConflict
+ *
+ * PARAMETERS: Path - Namepath to search
+ *
+ * RETURN: ExternalList
+ *
+ * DESCRIPTION: Search the AcpiGbl_ExternalList for a matching path
+ *
+ ******************************************************************************/
+
+void
+AcpiDmMarkExternalConflict (
+ ACPI_NAMESPACE_NODE *Node)
+{
+ ACPI_EXTERNAL_LIST *ExternalList = AcpiGbl_ExternalList;
+ char *ExternalPath;
+ char *InternalPath;
+ char *Temp;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (DmMarkExternalConflict);
+
+
+ if (Node->Flags & ANOBJ_IS_EXTERNAL)
+ {
+ return_VOID;
+ }
+
+ /* Get the full external and internal pathnames to the node */
+
+ Status = AcpiDmGetExternalAndInternalPath (Node,
+ &ExternalPath, &InternalPath);
+ if (ACPI_FAILURE (Status))
+ {
+ return_VOID;
+ }
+
+ /* Remove the root backslash */
+
+ Status = AcpiDmRemoveRootPrefix (&InternalPath);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (InternalPath);
+ ACPI_FREE (ExternalPath);
+ return_VOID;
+ }
+
+ while (ExternalList)
+ {
+ Temp = ExternalList->InternalPath;
+ if ((*ExternalList->InternalPath == AML_ROOT_PREFIX) &&
+ (ExternalList->InternalPath[1]))
+ {
+ Temp++;
+ }
+
+ if (!strcmp (ExternalList->InternalPath, InternalPath))
+ {
+ ExternalList->Flags |= ACPI_EXT_CONFLICTING_DECLARATION;
+ }
+ ExternalList = ExternalList->Next;
+ }
+
+ ACPI_FREE (InternalPath);
+ ACPI_FREE (ExternalPath);
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmConflictingDeclaration
+ *
+ * PARAMETERS: Path - Path with conflicting declaration
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit a warning when printing conflicting ASL external
+ * declarations.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmConflictingDeclaration (
+ char *Path)
+{
+ fprintf (stderr,
+ " Warning - Emitting ASL code \"External (%s)\"\n"
+ " This is a conflicting declaration with some "
+ "other declaration within the ASL code.\n"
+ " This external declaration may need to be "
+ "deleted in order to recompile the dsl file.\n\n",
+ Path);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: AcpiDmEmitExternal
*
* PARAMETERS: Op External Parse Object
@@ -1280,7 +1583,8 @@ AcpiDmEmitExternals (
* RETURN: None
*
* DESCRIPTION: Emit an External() ASL statement for the current External
- * parse object
+ * parse object. Note: External Ops are named types so the
+ * namepath is contained within NameOp->Name.Path.
*
******************************************************************************/
@@ -1290,14 +1594,76 @@ AcpiDmEmitExternal (
ACPI_PARSE_OBJECT *TypeOp)
{
AcpiOsPrintf ("External (");
- AcpiDmNamestring (NameOp->Common.Value.Name);
- AcpiOsPrintf ("%s)\n",
+ AcpiDmNamestring (NameOp->Named.Path);
+ AcpiOsPrintf ("%s)",
AcpiDmGetObjectTypeName ((ACPI_OBJECT_TYPE) TypeOp->Common.Value.Integer));
+ AcpiDmCheckForExternalConflict (NameOp->Named.Path);
+ AcpiOsPrintf ("\n");
}
/*******************************************************************************
*
+ * FUNCTION: AcpiDmCheckForExternalConflict
+ *
+ * PARAMETERS: Path - Path to check
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Search the External List to see if the input Path has a
+ * conflicting declaration.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmCheckForExternalConflict (
+ char *Path)
+{
+ ACPI_EXTERNAL_LIST *ExternalList = AcpiGbl_ExternalList;
+ char *ListItemPath;
+ char *InputPath;
+
+
+ if (!Path)
+ {
+ return;
+ }
+
+ /* Move past the root prefix '\' */
+
+ InputPath = Path;
+ if ((*InputPath == AML_ROOT_PREFIX) && InputPath[1])
+ {
+ InputPath++;
+ }
+
+ while (ExternalList)
+ {
+ ListItemPath = ExternalList->Path;
+ if (ListItemPath)
+ {
+ /* Move past the root prefix '\' */
+
+ if ((*ListItemPath == AML_ROOT_PREFIX) &&
+ ListItemPath[1])
+ {
+ ListItemPath++;
+ }
+
+ if (!strcmp (ListItemPath, InputPath) &&
+ (ExternalList->Flags & ACPI_EXT_CONFLICTING_DECLARATION))
+ {
+ AcpiOsPrintf ("%s", ExternalConflictMessage);
+ AcpiDmConflictingDeclaration (Path);
+
+ return;
+ }
+ }
+ ExternalList = ExternalList->Next;
+ }
+}
+/*******************************************************************************
+ *
* FUNCTION: AcpiDmUnresolvedWarning
*
* PARAMETERS: Type - Where to output the warning.
@@ -1311,7 +1677,7 @@ AcpiDmEmitExternal (
*
******************************************************************************/
-#if 0
+/*
Summary of the external control method problem:
When the -e option is used with disassembly, the various SSDTs are simply
@@ -1380,7 +1746,7 @@ disassembler, otherwise it does not know how to handle the method invocations.
In other words, if ABCD and EFGH are actually external control methods
appearing in an SSDT, the disassembler does not know what to do unless
the owning SSDT has been loaded via the -e option.
-#endif
+*/
static char ExternalWarningPart1[600];
static char ExternalWarningPart2[400];
OpenPOWER on IntegriCloud