Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F154399055
D35129.id105699.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D35129.id105699.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D35129: Add a PCI method for mapping IOMMU
Attached
Detach File
Event Timeline
Log In to Comment