Index: sys/dev/pci/pci_host_generic_fdt.c =================================================================== --- sys/dev/pci/pci_host_generic_fdt.c +++ sys/dev/pci/pci_host_generic_fdt.c @@ -373,6 +373,30 @@ #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 @@ 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)); Index: sys/dev/pci/pci_if.m =================================================================== --- sys/dev/pci/pci_if.m +++ sys/dev/pci/pci_if.m @@ -59,6 +59,7 @@ enum pci_id_type { PCI_ID_RID, PCI_ID_MSI, + PCI_ID_OFW_IOMMU, }; enum pci_feature { Index: sys/dev/pci/pcib_support.c =================================================================== --- sys/dev/pci/pcib_support.c +++ sys/dev/pci/pcib_support.c @@ -59,6 +59,9 @@ { 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); Index: sys/dev/pci/pcivar.h =================================================================== --- sys/dev/pci/pcivar.h +++ sys/dev/pci/pcivar.h @@ -127,6 +127,11 @@ 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. */