Page MenuHomeFreeBSD

D35129.id105699.diff
No OneTemporary

D35129.id105699.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.c
===================================================================
--- sys/dev/pci/pci.c
+++ sys/dev/pci/pci.c
@@ -138,6 +138,8 @@
static int pci_get_id_method(device_t dev, device_t child,
enum pci_id_type type, uintptr_t *rid);
+static int pci_get_iommu_method(device_t dev, device_t child,
+ uint32_t *id, uint32_t *xref);
static struct pci_devinfo * pci_fill_devinfo(device_t pcib, device_t bus, int d,
int b, int s, int f, uint16_t vid, uint16_t did);
@@ -213,6 +215,7 @@
DEVMETHOD(pci_msix_pba_bar, pci_msix_pba_bar_method),
DEVMETHOD(pci_msix_table_bar, pci_msix_table_bar_method),
DEVMETHOD(pci_get_id, pci_get_id_method),
+ DEVMETHOD(pci_get_iommu, pci_get_iommu_method),
DEVMETHOD(pci_alloc_devinfo, pci_alloc_devinfo_method),
DEVMETHOD(pci_child_added, pci_child_added_method),
#ifdef PCI_IOV
@@ -6327,6 +6330,13 @@
return (PCIB_GET_ID(device_get_parent(dev), child, type, id));
}
+static int
+pci_get_iommu_method(device_t dev, device_t child, uint32_t *id, uint32_t *xref)
+{
+
+ return (PCIB_GET_IOMMU(device_get_parent(dev), child, id, xref));
+}
+
/* Find the upstream port of a given PCI device in a root complex. */
device_t
pci_find_pcie_root_port(device_t dev)
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,28 @@
#endif
}
+static int
+generic_pcie_get_iommu(device_t pci, device_t child, uint32_t *id,
+ uint32_t *xref)
+{
+ 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);
+
+ err = ofw_bus_iommu_map(node, pci_rid, &iommu_xref, &iommu_rid);
+ if (err == 0) {
+ *id = iommu_rid;
+ *xref = iommu_xref;
+ }
+
+ return (err);
+}
+
int
generic_pcie_get_id(device_t pci, device_t child, enum pci_id_type type,
uintptr_t *id)
@@ -466,6 +488,7 @@
DEVMETHOD(pcib_release_msix, generic_pcie_fdt_release_msix),
DEVMETHOD(pcib_map_msi, generic_pcie_fdt_map_msi),
DEVMETHOD(pcib_get_id, generic_pcie_get_id),
+ DEVMETHOD(pcib_get_iommu, generic_pcie_get_iommu),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),
DEVMETHOD(ofw_bus_get_devinfo, generic_pcie_ofw_get_devinfo),
Index: sys/dev/pci/pci_if.m
===================================================================
--- sys/dev/pci/pci_if.m
+++ sys/dev/pci/pci_if.m
@@ -250,6 +250,13 @@
uintptr_t *id;
};
+METHOD int get_iommu {
+ device_t dev;
+ device_t child;
+ uint32_t *id;
+ uint32_t *xref;
+};
+
METHOD struct pci_devinfo * alloc_devinfo {
device_t dev;
};
Index: sys/dev/pci/pcib_if.m
===================================================================
--- sys/dev/pci/pcib_if.m
+++ sys/dev/pci/pcib_if.m
@@ -186,6 +186,16 @@
uintptr_t *id;
} DEFAULT pcib_get_id;
+#
+# Return the IOMMU Identifier and IOMMU Reference for the device.
+#
+METHOD int get_iommu {
+ device_t pcib;
+ device_t dev;
+ uint32_t *id;
+ uint32_t *xref;
+} DEFAULT pcib_get_iommu;
+
#
# Enable Alternative RID Interpretation if both the downstream port (pcib)
# and the endpoint device (dev) both support it.
Index: sys/dev/pci/pcib_private.h
===================================================================
--- sys/dev/pci/pcib_private.h
+++ sys/dev/pci/pcib_private.h
@@ -197,6 +197,7 @@
int pcib_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr, uint32_t *data);
int pcib_get_id(device_t pcib, device_t dev, enum pci_id_type type,
uintptr_t *id);
+int pcib_get_iommu(device_t pcib, device_t dev, uint32_t *id, uint32_t *xref);
void pcib_decode_rid(device_t pcib, uint16_t rid, int *bus,
int *slot, int *func);
int pcib_request_feature(device_t dev, enum pci_feature feature);
Index: sys/dev/pci/pcib_support.c
===================================================================
--- sys/dev/pci/pcib_support.c
+++ sys/dev/pci/pcib_support.c
@@ -70,6 +70,13 @@
return (0);
}
+int
+pcib_get_iommu(device_t pcib, device_t dev, uint32_t *id, uint32_t *xref)
+{
+
+ return (PCI_GET_IOMMU(device_get_parent(pcib), dev, id, xref));
+}
+
void
pcib_decode_rid(device_t pcib, uint16_t rid, int *bus, int *slot,
int *func)
Index: sys/dev/pci/pcivar.h
===================================================================
--- sys/dev/pci/pcivar.h
+++ sys/dev/pci/pcivar.h
@@ -639,6 +639,12 @@
return (PCI_GET_ID(device_get_parent(dev), dev, type, id));
}
+static __inline int
+pci_get_iommu(device_t dev, uint32_t *id, uint32_t *xref)
+{
+ return (PCI_GET_IOMMU(device_get_parent(dev), dev, id, xref));
+}
+
/*
* This is the deprecated interface, there is no way to tell the difference
* between a failure and a valid value that happens to be the same as the

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 29, 8:37 AM (4 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32322951
Default Alt Text
D35129.id105699.diff (6 KB)

Event Timeline