Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F168757003
D31267.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D31267.diff
View Options
Index: sys/arm64/acpica/acpi_iort.c
===================================================================
--- sys/arm64/acpica/acpi_iort.c
+++ sys/arm64/acpica/acpi_iort.c
@@ -77,6 +77,14 @@
int pxm;
};
+struct iort_named_component
+{
+ UINT32 NodeFlags;
+ UINT64 MemoryProperties;
+ UINT8 MemoryAddressLimit;
+ char DeviceName[32]; /* Path of namespace object */
+};
+
/*
* IORT node. Each node has some device specific data depending on the
* type of the node. The node can also have a set of mappings, OR in
@@ -91,9 +99,10 @@
u_int usecount; /* for bookkeeping */
u_int revision; /* node revision */
union {
- ACPI_IORT_ROOT_COMPLEX pci_rc; /* PCI root complex */
- ACPI_IORT_SMMU smmu;
- ACPI_IORT_SMMU_V3 smmu_v3;
+ ACPI_IORT_ROOT_COMPLEX pci_rc; /* PCI root complex */
+ ACPI_IORT_SMMU smmu;
+ ACPI_IORT_SMMU_V3 smmu_v3;
+ struct iort_named_component named_comp;
} data;
union {
struct iort_map_entry *mappings; /* node mappings */
@@ -105,6 +114,7 @@
static TAILQ_HEAD(, iort_node) pci_nodes = TAILQ_HEAD_INITIALIZER(pci_nodes);
static TAILQ_HEAD(, iort_node) smmu_nodes = TAILQ_HEAD_INITIALIZER(smmu_nodes);
static TAILQ_HEAD(, iort_node) its_groups = TAILQ_HEAD_INITIALIZER(its_groups);
+static TAILQ_HEAD(, iort_node) named_nodes = TAILQ_HEAD_INITIALIZER(named_nodes);
static int
iort_entry_get_id_mapping_index(struct iort_node *node)
@@ -166,6 +176,29 @@
return (entry->out_node);
}
+/*
+ * Perform an additional lookup in case of SMMU node and ITS outtype.
+ */
+static struct iort_node *
+iort_smmu_trymap(struct iort_node *node, u_int outtype, u_int *outid)
+{
+ /* Original node can be not found. */
+ if (!node)
+ return (NULL);
+
+ /* Node can be SMMU or ITS. If SMMU, we need another lookup. */
+ if (outtype == ACPI_IORT_NODE_ITS_GROUP &&
+ (node->type == ACPI_IORT_NODE_SMMU_V3 ||
+ node->type == ACPI_IORT_NODE_SMMU)) {
+ node = iort_entry_lookup(node, *outid, outid);
+ if (node == NULL)
+ return (NULL);
+ }
+
+ KASSERT(node->type == outtype, ("mapping fail"));
+ return (node);
+}
+
/*
* Map a PCI RID to a SMMU node or an ITS node, based on outtype.
*/
@@ -184,21 +217,35 @@
break;
}
- /* Could not find a PCI RC node with segment and device ID. */
- if (out_node == NULL)
- return (NULL);
+ out_node = iort_smmu_trymap(out_node, outtype, &nxtid);
+ if (out_node)
+ *outid = nxtid;
- /* Node can be SMMU or ITS. If SMMU, we need another lookup. */
- if (outtype == ACPI_IORT_NODE_ITS_GROUP &&
- (out_node->type == ACPI_IORT_NODE_SMMU_V3 ||
- out_node->type == ACPI_IORT_NODE_SMMU)) {
- out_node = iort_entry_lookup(out_node, nxtid, &nxtid);
- if (out_node == NULL)
- return (NULL);
+ return (out_node);
+}
+
+/*
+ * Map a named component node to a SMMU node or an ITS node, based on outtype.
+ */
+static struct iort_node *
+iort_named_comp_map(const char *devname, u_int rid, u_int outtype, u_int *outid)
+{
+ struct iort_node *node, *out_node;
+ u_int nxtid;
+
+ out_node = NULL;
+ TAILQ_FOREACH(node, &named_nodes, next) {
+ if (strstr(node->data.named_comp.DeviceName, devname) == NULL)
+ continue;
+ out_node = iort_entry_lookup(node, rid, &nxtid);
+ if (out_node != NULL)
+ break;
}
- KASSERT(out_node->type == outtype, ("mapping fail"));
- *outid = nxtid;
+ out_node = iort_smmu_trymap(out_node, outtype, &nxtid);
+ if (out_node)
+ *outid = nxtid;
+
return (out_node);
}
@@ -279,6 +326,7 @@
ACPI_IORT_ROOT_COMPLEX *pci_rc;
ACPI_IORT_SMMU *smmu;
ACPI_IORT_SMMU_V3 *smmu_v3;
+ ACPI_IORT_NAMED_COMPONENT *named_comp;
struct iort_node *node;
node = malloc(sizeof(*node), M_DEVBUF, M_WAITOK | M_ZERO);
@@ -310,6 +358,19 @@
iort_copy_its(node, node_entry);
TAILQ_INSERT_TAIL(&its_groups, node, next);
break;
+ case ACPI_IORT_NODE_NAMED_COMPONENT:
+ named_comp = (ACPI_IORT_NAMED_COMPONENT *)node_entry->NodeData;
+ memcpy(&node->data.named_comp, named_comp, sizeof(*named_comp));
+
+ /* Copy name of the node separately. */
+ strncpy(node->data.named_comp.DeviceName,
+ named_comp->DeviceName,
+ sizeof(node->data.named_comp.DeviceName));
+ node->data.named_comp.DeviceName[31] = 0;
+
+ iort_copy_data(node, node_entry);
+ TAILQ_INSERT_TAIL(&named_nodes, node, next);
+ break;
default:
printf("ACPI: IORT: Dropping unhandled type %u\n",
node_entry->Type);
@@ -368,7 +429,9 @@
TAILQ_FOREACH(node, &smmu_nodes, next)
for (i = 0; i < node->nentries; i++)
iort_resolve_node(&node->entries.mappings[i], FALSE);
- /* TODO: named nodes */
+ TAILQ_FOREACH(node, &named_nodes, next)
+ for (i = 0; i < node->nentries; i++)
+ iort_resolve_node(&node->entries.mappings[i], TRUE);
}
/*
@@ -587,3 +650,46 @@
return (0);
}
+
+/*
+ * Finds mapping for a named node given name and resource ID and returns the
+ * XREF for MSI interrupt setup and the device ID to use for the interrupt setup.
+ */
+int
+acpi_iort_map_named_msi(const char *devname, u_int rid, u_int *xref,
+ u_int *devid)
+{
+ struct iort_node *node;
+
+ node = iort_named_comp_map(devname, rid, ACPI_IORT_NODE_ITS_GROUP,
+ devid);
+ if (node == NULL)
+ return (ENOENT);
+
+ /* This should be an ITS node */
+ KASSERT(node->type == ACPI_IORT_NODE_ITS_GROUP, ("bad group"));
+
+ /* Return first node, we don't handle more than that now. */
+ *xref = node->entries.its[0].xref;
+ return (0);
+}
+
+int
+acpi_iort_map_named_smmuv3(const char *devname, u_int rid, u_int *xref,
+ u_int *devid)
+{
+ ACPI_IORT_SMMU_V3 *smmu;
+ struct iort_node *node;
+
+ node = iort_named_comp_map(devname, rid, ACPI_IORT_NODE_SMMU_V3, devid);
+ if (node == NULL)
+ return (ENOENT);
+
+ /* This should be an SMMU node. */
+ KASSERT(node->type == ACPI_IORT_NODE_SMMU_V3, ("bad node"));
+
+ smmu = (ACPI_IORT_SMMU_V3 *)&node->data.smmu_v3;
+ *xref = smmu->BaseAddress;
+
+ return (0);
+}
Index: sys/dev/acpica/acpivar.h
===================================================================
--- sys/dev/acpica/acpivar.h
+++ sys/dev/acpica/acpivar.h
@@ -578,6 +578,10 @@
int acpi_iort_map_pci_msi(u_int seg, u_int rid, u_int *xref, u_int *devid);
int acpi_iort_map_pci_smmuv3(u_int seg, u_int rid, u_int *xref, u_int *devid);
int acpi_iort_its_lookup(u_int its_id, u_int *xref, int *pxm);
+int acpi_iort_map_named_msi(const char *devname, u_int rid, u_int *xref,
+ u_int *devid);
+int acpi_iort_map_named_smmuv3(const char *devname, u_int rid, u_int *xref,
+ u_int *devid);
#endif
#endif /* _KERNEL */
#endif /* !_ACPIVAR_H_ */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Aug 31, 12:09 AM (2 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37583936
Default Alt Text
D31267.diff (6 KB)
Attached To
Mode
D31267: Parse named nodes from IORT ACPI on arm64
Attached
Detach File
Event Timeline
Log In to Comment