Page MenuHomeFreeBSD

D35129.id105734.diff
No OneTemporary

D35129.id105734.diff

Index: sys/dev/ofw/ofw_bus_subr.h
===================================================================
--- sys/dev/ofw/ofw_bus_subr.h
+++ sys/dev/ofw/ofw_bus_subr.h
@@ -92,8 +92,9 @@
int ofw_bus_search_intrmap(void *, int, void *, int, void *, int, void *,
void *, void *, int, phandle_t *);
-/* Routines for processing msi maps */
+/* Routines for processing msi and iommu maps. */
int ofw_bus_msimap(phandle_t, uint16_t, phandle_t *, uint32_t *);
+int ofw_bus_iommu_map(phandle_t, uint16_t, phandle_t *, uint32_t *);
/* Routines for parsing device-tree data into resource lists. */
int ofw_bus_reg_to_rl(device_t, phandle_t, pcell_t, pcell_t,
Index: sys/dev/ofw/ofw_bus_subr.c
===================================================================
--- sys/dev/ofw/ofw_bus_subr.c
+++ sys/dev/ofw/ofw_bus_subr.c
@@ -491,6 +491,50 @@
return (err);
}
+int
+ofw_bus_iommu_map(phandle_t node, uint16_t pci_rid, phandle_t *iommu_parent,
+ uint32_t *iommu_rid)
+{
+ pcell_t mask, iommu_base, rid_base, rid_length;
+ uint32_t masked_rid;
+ pcell_t map[4];
+ ssize_t len;
+ int err, i;
+
+ len = OF_getproplen(node, "iommu-map");
+ if (len <= 0)
+ return (ENOENT);
+ if (len > sizeof(map))
+ return (ENOMEM);
+
+ len = OF_getencprop(node, "iommu-map", map, 16);
+
+ err = ENOENT;
+ mask = 0xffffffff;
+ OF_getencprop(node, "iommu-map-mask", &mask, sizeof(mask));
+
+ masked_rid = pci_rid & mask;
+ for (i = 0; i < len; i += 4) {
+ rid_base = map[i + 0];
+ rid_length = map[i + 3];
+
+ if (masked_rid < rid_base ||
+ masked_rid >= (rid_base + rid_length))
+ continue;
+
+ iommu_base = map[i + 2];
+
+ if (iommu_parent != NULL)
+ *iommu_parent = map[i + 1];
+ if (iommu_rid != NULL)
+ *iommu_rid = masked_rid - rid_base + iommu_base;
+ err = 0;
+ break;
+ }
+
+ return (err);
+}
+
static int
ofw_bus_reg_to_rl_helper(device_t dev, phandle_t node, pcell_t acells, pcell_t scells,
struct resource_list *rl, const char *reg_source)
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_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_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_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_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_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_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. */

File Metadata

Mime Type
text/plain
Expires
Sun, Jul 5, 11:56 AM (20 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34708589
Default Alt Text
D35129.id105734.diff (3 KB)

Event Timeline