Page MenuHomeFreeBSD

D6227.id15938.diff
No OneTemporary

D6227.id15938.diff

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

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)

Event Timeline