git: b7672a70256b - main - Add OFW_IOMMU id type for pci_get_id() so we can ask parent IOMMU controller to map PCI RID to an IOMMU specifier.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 07 May 2022 09:21:50 UTC
The branch main has been updated by br: URL: https://cgit.FreeBSD.org/src/commit/?id=b7672a70256b9a0d21a8f8d2c8a43d00700b95a7 commit b7672a70256b9a0d21a8f8d2c8a43d00700b95a7 Author: Ruslan Bukin <br@FreeBSD.org> AuthorDate: 2022-05-07 09:17:43 +0000 Commit: Ruslan Bukin <br@FreeBSD.org> CommitDate: 2022-05-07 09:21:09 +0000 Add OFW_IOMMU id type for pci_get_id() so we can ask parent IOMMU controller to map PCI RID to an IOMMU specifier. Sponsored by: UKRI Discussed with: jhb Differential Revision: https://reviews.freebsd.org/D35129 --- sys/dev/pci/pci_host_generic_fdt.c | 27 +++++++++++++++++++++++++++ sys/dev/pci/pci_if.m | 1 + sys/dev/pci/pcib_support.c | 3 +++ sys/dev/pci/pcivar.h | 5 +++++ 4 files changed, 36 insertions(+) diff --git a/sys/dev/pci/pci_host_generic_fdt.c b/sys/dev/pci/pci_host_generic_fdt.c index ef0851afb76c..57ce03d0b94d 100644 --- a/sys/dev/pci/pci_host_generic_fdt.c +++ b/sys/dev/pci/pci_host_generic_fdt.c @@ -373,6 +373,30 @@ generic_pcie_fdt_release_msix(device_t pci, device_t child, int irq) #endif } +static int +generic_pcie_get_iommu(device_t pci, device_t child, uintptr_t *id) +{ + struct pci_id_ofw_iommu *iommu; + uint32_t iommu_rid; + uint32_t iommu_xref; + uint16_t pci_rid; + phandle_t node; + int err; + + node = ofw_bus_get_node(pci); + pci_rid = pci_get_rid(child); + + iommu = (struct pci_id_ofw_iommu *)id; + + err = ofw_bus_iommu_map(node, pci_rid, &iommu_xref, &iommu_rid); + if (err == 0) { + iommu->id = iommu_rid; + iommu->xref = iommu_xref; + } + + return (err); +} + int generic_pcie_get_id(device_t pci, device_t child, enum pci_id_type type, uintptr_t *id) @@ -382,6 +406,9 @@ generic_pcie_get_id(device_t pci, device_t child, enum pci_id_type type, uint32_t rid; uint16_t pci_rid; + if (type == PCI_ID_OFW_IOMMU) + return (generic_pcie_get_iommu(pci, child, id)); + if (type != PCI_ID_MSI) return (pcib_get_id(pci, child, type, id)); diff --git a/sys/dev/pci/pci_if.m b/sys/dev/pci/pci_if.m index a7a2af7bb4a9..36e2172172a8 100644 --- a/sys/dev/pci/pci_if.m +++ b/sys/dev/pci/pci_if.m @@ -59,6 +59,7 @@ HEADER { enum pci_id_type { PCI_ID_RID, PCI_ID_MSI, + PCI_ID_OFW_IOMMU, }; enum pci_feature { diff --git a/sys/dev/pci/pcib_support.c b/sys/dev/pci/pcib_support.c index dcf8275e566d..a0563c58a99b 100644 --- a/sys/dev/pci/pcib_support.c +++ b/sys/dev/pci/pcib_support.c @@ -59,6 +59,9 @@ pcib_get_id(device_t pcib, device_t dev, enum pci_id_type type, uintptr_t *id) { uint8_t bus, slot, func; + if (type == PCI_ID_OFW_IOMMU) + return (PCI_GET_ID(device_get_parent(pcib), dev, type, id)); + if (type != PCI_ID_RID) return (ENXIO); diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h index 74aa704635f7..2454b05b9acc 100644 --- a/sys/dev/pci/pcivar.h +++ b/sys/dev/pci/pcivar.h @@ -127,6 +127,11 @@ struct pcicfg_msix { struct resource *msix_pba_res; /* Resource containing PBA. */ }; +struct pci_id_ofw_iommu { + uint32_t id; + uint32_t xref; +}; + /* Interesting values for HyperTransport */ struct pcicfg_ht { uint8_t ht_slave; /* Non-zero if device is an HT slave. */