Date: Sat, 7 Aug 2021 17:33:14 GMT From: "Bjoern A. Zeeb" <bz@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: d178b1f878ae - main - Parse named nodes from IORT ACPI on arm64 Message-ID: <202108071733.177HXEEt015921@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=d178b1f878ae5b1b4e574bcf34d21b60855bf5a0 commit d178b1f878ae5b1b4e574bcf34d21b60855bf5a0 Author: Dmitry Salychev <dsl@mcusim.org> AuthorDate: 2021-08-07 17:17:57 +0000 Commit: Bjoern A. Zeeb <bz@FreeBSD.org> CommitDate: 2021-08-07 17:30:38 +0000 Parse named nodes from IORT ACPI on arm64 Add the ability to map named components from IORT to their SMMU or ITS node in order to setup interrupts. It is now possible to find a node by its name (substring) and resource ID similar to PCI nodes. This is needed by work on a driver for NXP's Second Generation Data Path Acceleration Architecture (DPAA2). Reviewed by: andrew MFC after: 2 weeks Differential Revision:: https://reviews.freebsd.org/D31267 --- sys/arm64/acpica/acpi_iort.c | 138 ++++++++++++++++++++++++++++++++++++++----- sys/dev/acpica/acpivar.h | 4 ++ 2 files changed, 126 insertions(+), 16 deletions(-) diff --git a/sys/arm64/acpica/acpi_iort.c b/sys/arm64/acpica/acpi_iort.c index ec5cf799b333..e35531731251 100644 --- a/sys/arm64/acpica/acpi_iort.c +++ b/sys/arm64/acpica/acpi_iort.c @@ -77,6 +77,14 @@ struct iort_its_entry { 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 @@ struct iort_node { 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 @@ struct iort_node { 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 @@ iort_entry_lookup(struct iort_node *node, u_int id, u_int *outid) 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 @@ iort_pci_rc_map(u_int seg, u_int rid, u_int outtype, u_int *outid) 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 @@ iort_add_nodes(ACPI_IORT_NODE *node_entry, u_int node_offset) 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_add_nodes(ACPI_IORT_NODE *node_entry, u_int node_offset) 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 @@ iort_post_process_mappings(void) 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 @@ acpi_iort_map_pci_smmuv3(u_int seg, u_int rid, u_int *xref, u_int *sid) 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); +} diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h index 980a004e2c35..1f64b479d414 100644 --- a/sys/dev/acpica/acpivar.h +++ b/sys/dev/acpica/acpivar.h @@ -578,6 +578,10 @@ int acpi_get_domain(device_t dev, device_t child, int *domain); 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_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202108071733.177HXEEt015921>