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. */