Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150489422
D6227.id15938.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D6227.id15938.diff
View Options
Index: sys/arm64/arm64/gic_v3_its.c
===================================================================
--- sys/arm64/arm64/gic_v3_its.c
+++ sys/arm64/arm64/gic_v3_its.c
@@ -62,6 +62,7 @@
#define GIC_V3_ITS_QUIRK_THUNDERX_PEM_BUS_OFFSET 88
#include "pic_if.h"
+#include "pcib_if.h"
/* Device and PIC methods */
static int gic_v3_its_attach(device_t);
@@ -150,7 +151,6 @@
/* Cavium ThunderX PCI devid acquire function */
static uint32_t its_get_devbits_thunder(device_t);
-static uint32_t its_get_devid_thunder(device_t);
static const struct its_quirks its_quirks[] = {
{
@@ -160,7 +160,6 @@
*/
.cpuid = CPU_ID_RAW(CPU_IMPL_CAVIUM, CPU_PART_THUNDER, 0, 0),
.cpuid_mask = CPU_IMPL_MASK | CPU_PART_MASK,
- .devid_func = its_get_devid_thunder,
.devbits_func = its_get_devbits_thunder,
},
};
@@ -1572,46 +1571,6 @@
* Add vendor specific PCI devid function here.
*/
static uint32_t
-its_get_devid_thunder(device_t pci_dev)
-{
- int bsf;
- int pem;
- uint32_t bus;
-
- bus = pci_get_bus(pci_dev);
- bsf = pci_get_rid(pci_dev);
-
- /* Check if accessing internal PCIe (low bus numbers) */
- if (bus < GIC_V3_ITS_QUIRK_THUNDERX_PEM_BUS_OFFSET) {
- return ((pci_get_domain(pci_dev) << PCI_RID_DOMAIN_SHIFT) |
- bsf);
- /* PEM otherwise */
- } else {
- /* PEM (PCIe MAC/root complex) number is equal to domain */
- pem = pci_get_domain(pci_dev);
-
- /*
- * Set appropriate device ID (passed by the HW along with
- * the transaction to memory) for different root complex
- * numbers using hard-coded domain portion for each group.
- */
- if (pem < 3)
- return ((0x1 << PCI_RID_DOMAIN_SHIFT) | bsf);
-
- if (pem < 6)
- return ((0x3 << PCI_RID_DOMAIN_SHIFT) | bsf);
-
- if (pem < 9)
- return ((0x9 << PCI_RID_DOMAIN_SHIFT) | bsf);
-
- if (pem < 12)
- return ((0xB << PCI_RID_DOMAIN_SHIFT) | bsf);
- }
-
- return (0);
-}
-
-static uint32_t
its_get_devbits_thunder(device_t dev)
{
uint32_t devid_bits;
@@ -1673,28 +1632,13 @@
return (its_get_devbits_default(dev));
}
-static __inline uint32_t
-its_get_devid_default(device_t pci_dev)
-{
-
- return (PCI_DEVID_GENERIC(pci_dev));
-}
-
static uint32_t
its_get_devid(device_t pci_dev)
{
- const struct its_quirks *quirk;
- size_t i;
-
- for (i = 0; i < nitems(its_quirks); i++) {
- quirk = &its_quirks[i];
- if (CPU_MATCH_RAW(quirk->cpuid_mask, quirk->cpuid)) {
- if (quirk->devid_func != NULL)
- return ((*quirk->devid_func)(pci_dev));
- }
- }
+ device_t bus;
- return (its_get_devid_default(pci_dev));
+ bus = device_get_parent(pci_dev);
+ return (PCIB_GET_MSI_RID(device_get_parent(bus), pci_dev));
}
/*
Index: sys/arm64/arm64/gic_v3_var.h
===================================================================
--- sys/arm64/arm64/gic_v3_var.h
+++ sys/arm64/arm64/gic_v3_var.h
@@ -247,12 +247,10 @@
/* Stuff that is specific to the vendor's implementation */
typedef uint32_t (*its_devbits_func_t)(device_t);
-typedef uint32_t (*its_devid_func_t)(device_t);
struct its_quirks {
uint64_t cpuid;
uint64_t cpuid_mask;
- its_devid_func_t devid_func;
its_devbits_func_t devbits_func;
};
Index: sys/arm64/cavium/thunder_pcie_fdt.c
===================================================================
--- sys/arm64/cavium/thunder_pcie_fdt.c
+++ sys/arm64/cavium/thunder_pcie_fdt.c
@@ -45,16 +45,22 @@
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
#include <dev/pci/pci_host_generic.h>
#include "thunder_pcie_common.h"
+#include "pcib_if.h"
+
#ifdef THUNDERX_PASS_1_1_ERRATA
static struct resource * thunder_pcie_fdt_alloc_resource(device_t, device_t,
int, int *, rman_res_t, rman_res_t, rman_res_t, u_int);
#endif
static int thunder_pcie_fdt_attach(device_t);
static int thunder_pcie_fdt_probe(device_t);
+static uint32_t thunder_pcie_fdt_get_msi_rid(device_t, device_t);
static device_method_t thunder_pcie_fdt_methods[] = {
/* Device interface */
@@ -64,6 +70,9 @@
DEVMETHOD(bus_alloc_resource, thunder_pcie_fdt_alloc_resource),
#endif
+ /* pcib interface */
+ DEVMETHOD(pcib_get_msi_rid, thunder_pcie_fdt_get_msi_rid),
+
/* End */
DEVMETHOD_END
};
@@ -112,6 +121,20 @@
return (pci_host_generic_attach(dev));
}
+static uint32_t
+thunder_pcie_fdt_get_msi_rid(device_t pci, device_t child)
+{
+ phandle_t node;
+ int bsf;
+
+ node = ofw_bus_get_node(pci);
+ if (OF_hasprop(node, "msi-map"))
+ return (generic_pcie_get_msi_rid(pci, child));
+
+ bsf = pci_get_rid(child);
+ return ((pci_get_domain(child) << PCI_RID_DOMAIN_SHIFT) | bsf);
+}
+
#ifdef THUNDERX_PASS_1_1_ERRATA
static struct resource *
thunder_pcie_fdt_alloc_resource(device_t dev, device_t child, int type, int *rid,
Index: sys/arm64/cavium/thunder_pcie_pem.c
===================================================================
--- sys/arm64/cavium/thunder_pcie_pem.c
+++ sys/arm64/cavium/thunder_pcie_pem.c
@@ -131,6 +131,7 @@
static int thunder_pem_map_msi(device_t, device_t, int, uint64_t *, uint32_t *);
static int thunder_pem_alloc_msix(device_t, device_t, int *);
static int thunder_pem_release_msix(device_t, device_t, int);
+static uint32_t thunder_pem_get_msi_rid(device_t, device_t);
static int thunder_pem_attach(device_t);
static int thunder_pem_deactivate_resource(device_t, device_t, int, int,
struct resource *);
@@ -182,6 +183,7 @@
DEVMETHOD(pcib_release_msix, thunder_pem_release_msix),
DEVMETHOD(pcib_alloc_msi, thunder_pem_alloc_msi),
DEVMETHOD(pcib_release_msi, thunder_pem_release_msi),
+ DEVMETHOD(pcib_get_msi_rid, thunder_pem_get_msi_rid),
DEVMETHOD_END
};
@@ -360,6 +362,34 @@
return (arm_release_msix(pci, child, irq));
}
+static uint32_t
+thunder_pem_get_msi_rid(device_t pci, device_t child)
+{
+ int bsf;
+ int pem;
+
+ bsf = pci_get_rid(child);
+
+ /* PEM (PCIe MAC/root complex) number is equal to domain */
+ pem = pci_get_domain(child);
+
+ /*
+ * Set appropriate device ID (passed by the HW along with
+ * the transaction to memory) for different root complex
+ * numbers using hard-coded domain portion for each group.
+ */
+ if (pem < 3)
+ return ((0x1 << PCI_RID_DOMAIN_SHIFT) | bsf);
+ if (pem < 6)
+ return ((0x3 << PCI_RID_DOMAIN_SHIFT) | bsf);
+ if (pem < 9)
+ return ((0x9 << PCI_RID_DOMAIN_SHIFT) | bsf);
+ if (pem < 12)
+ return ((0xB << PCI_RID_DOMAIN_SHIFT) | bsf);
+
+ return (0);
+}
+
static int
thunder_pem_identify(device_t dev)
{
Index: sys/arm64/cavium/thunder_pcie_pem_fdt.c
===================================================================
--- sys/arm64/cavium/thunder_pcie_pem_fdt.c
+++ sys/arm64/cavium/thunder_pcie_pem_fdt.c
@@ -54,12 +54,18 @@
#include "thunder_pcie_common.h"
#include "thunder_pcie_pem.h"
+#include "pcib_if.h"
+
static int thunder_pem_fdt_probe(device_t);
+static uint32_t thunder_pem_fdt_get_msi_rid(device_t, device_t);
static device_method_t thunder_pem_fdt_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, thunder_pem_fdt_probe),
+ /* pcib interface */
+ DEVMETHOD(pcib_get_msi_rid, thunder_pem_fdt_get_msi_rid),
+
/* End */
DEVMETHOD_END
};
@@ -88,3 +94,17 @@
return (ENXIO);
}
+
+static uint32_t
+thunder_pem_fdt_get_msi_rid(device_t dev, device_t child)
+{
+ phandle_t node;
+ uint32_t rid;
+ uint16_t pci_rid;
+
+ node = ofw_bus_get_node(dev);
+ pci_rid = pci_get_rid(child);
+
+ ofw_bus_msimap(node, pci_rid, NULL, &rid);
+ return (rid);
+}
Index: sys/dev/ofw/ofw_bus_subr.h
===================================================================
--- sys/dev/ofw/ofw_bus_subr.h
+++ sys/dev/ofw/ofw_bus_subr.h
@@ -76,6 +76,9 @@
int ofw_bus_search_intrmap(void *, int, void *, int, void *, int, void *,
void *, void *, int, phandle_t *);
+/* Routines for processing msi maps */
+int ofw_bus_msimap(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,
struct resource_list *);
Index: sys/dev/ofw/ofw_bus_subr.c
===================================================================
--- sys/dev/ofw/ofw_bus_subr.c
+++ sys/dev/ofw/ofw_bus_subr.c
@@ -397,6 +397,57 @@
}
int
+ofw_bus_msimap(phandle_t node, uint16_t pci_rid, phandle_t *msi_parent,
+ uint32_t *msi_rid)
+{
+ pcell_t *map, mask, msi_base, rid_base, rid_length;
+ ssize_t len;
+ uint32_t masked_rid, rid;
+ int err, i;
+
+ /* TODO: This should be OF_searchprop_alloc if we had it */
+ len = OF_getencprop_alloc(node, "msi-map", sizeof(*map), (void **)&map);
+ if (len < 0) {
+ if (msi_parent != NULL) {
+ *msi_parent = 0;
+ OF_getprop(node, "msi-parent", msi_parent,
+ sizeof(*msi_parent));
+ }
+ if (msi_rid != NULL)
+ *msi_rid = pci_rid;
+ return (0);
+ }
+
+ err = ENOENT;
+ rid = 0;
+ mask = 0xffffffff;
+ OF_getencprop(node, "msi-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;
+
+ msi_base = map[i + 2];
+
+ if (msi_parent != NULL)
+ *msi_parent = map[i + 1];
+ if (msi_rid != NULL)
+ *msi_rid = masked_rid - rid_base + msi_base;
+ err = 0;
+ break;
+ }
+
+ free(map, M_OFWPROP);
+
+ return (err);
+}
+
+int
ofw_bus_reg_to_rl(device_t dev, phandle_t node, pcell_t acells, pcell_t scells,
struct resource_list *rl)
{
Index: sys/dev/pci/pci_host_generic.h
===================================================================
--- sys/dev/pci/pci_host_generic.h
+++ sys/dev/pci/pci_host_generic.h
@@ -69,5 +69,6 @@
struct resource *pci_host_generic_alloc_resource(device_t,
device_t, int, int *, rman_res_t, rman_res_t, rman_res_t, u_int);
int pci_host_generic_attach(device_t);
+uint32_t generic_pcie_get_msi_rid(device_t, device_t);
#endif /* __PCI_HOST_GENERIC_H_ */
Index: sys/dev/pci/pci_host_generic.c
===================================================================
--- sys/dev/pci/pci_host_generic.c
+++ sys/dev/pci/pci_host_generic.c
@@ -713,6 +713,20 @@
#endif
}
+uint32_t
+generic_pcie_get_msi_rid(device_t pci, device_t child)
+{
+ phandle_t node;
+ uint32_t rid;
+ uint16_t pci_rid;
+
+ node = ofw_bus_get_node(pci);
+ pci_rid = pci_get_rid(child);
+
+ ofw_bus_msimap(node, pci_rid, NULL, &rid);
+ return (rid);
+}
+
static device_method_t generic_pcie_methods[] = {
DEVMETHOD(device_probe, generic_pcie_probe),
DEVMETHOD(device_attach, pci_host_generic_attach),
@@ -736,6 +750,7 @@
DEVMETHOD(pcib_alloc_msix, generic_pcie_alloc_msix),
DEVMETHOD(pcib_release_msix, generic_pcie_release_msix),
DEVMETHOD(pcib_map_msi, generic_pcie_map_msi),
+ DEVMETHOD(pcib_get_msi_rid, generic_pcie_get_msi_rid),
/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_devinfo, generic_pcie_ofw_get_devinfo),
Index: sys/dev/pci/pci_pci.c
===================================================================
--- sys/dev/pci/pci_pci.c
+++ sys/dev/pci/pci_pci.c
@@ -104,6 +104,7 @@
DEVMETHOD(pcib_alloc_msix, pcib_alloc_msix),
DEVMETHOD(pcib_release_msix, pcib_release_msix),
DEVMETHOD(pcib_map_msi, pcib_map_msi),
+ DEVMETHOD(pcib_get_msi_rid, pcib_get_msi_rid),
DEVMETHOD(pcib_power_for_sleep, pcib_power_for_sleep),
DEVMETHOD(pcib_get_rid, pcib_ari_get_rid),
DEVMETHOD(pcib_try_enable_ari, pcib_try_enable_ari),
@@ -2024,6 +2025,16 @@
return (0);
}
+/* Pass request for the MSI/MSI-X Requester ID up to the parent bridge. */
+uint32_t
+pcib_get_msi_rid(device_t pcib, device_t dev)
+{
+ device_t bus;
+
+ bus = device_get_parent(pcib);
+ return (PCIB_GET_MSI_RID(device_get_parent(bus), dev));
+}
+
/* Pass request for device power state up to parent bridge. */
int
pcib_power_for_sleep(device_t pcib, device_t dev, int *pstate)
Index: sys/dev/pci/pcib_if.m
===================================================================
--- sys/dev/pci/pcib_if.m
+++ sys/dev/pci/pcib_if.m
@@ -163,6 +163,15 @@
};
#
+# Return the MSI/MSI-X Routing Identifier for the device. This is used
+# by the MSI/MSI-X interrupt controller on some architectures.
+#
+METHOD uint32_t get_msi_rid {
+ device_t pcib;
+ device_t dev;
+};
+
+#
# Return the device power state to be used during a system sleep state
# transition such as suspend and resume.
#
Index: sys/dev/pci/pcib_private.h
===================================================================
--- sys/dev/pci/pcib_private.h
+++ sys/dev/pci/pcib_private.h
@@ -170,6 +170,7 @@
int pcib_alloc_msix(device_t pcib, device_t dev, int *irq);
int pcib_release_msix(device_t pcib, device_t dev, int irq);
int pcib_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr, uint32_t *data);
+uint32_t pcib_get_msi_rid(device_t pcib, device_t dev);
uint16_t pcib_get_rid(device_t pcib, device_t dev);
void pcib_decode_rid(device_t pcib, uint16_t rid, int *bus,
int *slot, int *func);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Apr 2, 4:12 PM (7 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30729100
Default Alt Text
D6227.id15938.diff (12 KB)
Attached To
Mode
D6227: Add a pcib interface to translate the rid for MSI
Attached
Detach File
Event Timeline
Log In to Comment