Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151387240
D3118.id7139.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D3118.id7139.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
@@ -44,6 +44,7 @@
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <vm/vm.h>
@@ -89,6 +90,7 @@
static void its_init_commandq(struct gic_v3_its_softc *);
static int its_init_cpu(struct gic_v3_its_softc *);
static void its_init_cpu_collection(struct gic_v3_its_softc *);
+static uint32_t its_get_devid(device_t);
static int its_cmd_send(struct gic_v3_its_softc *, struct its_cmd_desc *);
@@ -133,6 +135,23 @@
[GITS_BASER_TYPE_RES7] = "Reserved (7)",
};
+/*
+ * Vendor specific quirks.
+ * One needs to add appropriate entry to its_quirks[]
+ * table if the imlementation varies from the generic ARM ITS.
+ */
+
+/* Cavium ThunderX PCI devid acquire function */
+static uint32_t its_get_devid_thunder(device_t);
+
+static const struct its_quirks its_quirks[] = {
+ {
+ .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,
+ },
+};
+
static struct gic_v3_its_softc *its_sc;
#define gic_its_read(sc, len, reg) \
@@ -1300,7 +1319,7 @@
if (newdev != NULL)
return (newdev);
- devid = PCI_DEVID(pci_dev);
+ devid = its_get_devid(pci_dev);
/* There was no previously created device. Create one now */
newdev = malloc(sizeof(*newdev), M_GIC_V3_ITS, (M_WAITOK | M_ZERO));
@@ -1353,6 +1372,73 @@
its_dev->lpis.lpi_free);
its_dev->lpis.lpi_free--;
}
+
+/*
+ * ITS quirks.
+ * 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_RID(pci_get_bus(pci_dev), pci_get_slot(pci_dev),
+ pci_get_function(pci_dev));
+
+ /* ECAM is on bus=0 */
+ if (bus == 0) {
+ return ((pci_get_domain(pci_dev) << PCI_RID_DOMAIN_SHIFT) |
+ bsf);
+ /* PEM otherwise */
+ } else {
+ /* PEM number is equal to domain */
+ pem = pci_get_domain(pci_dev);
+
+ /* Hardcode appropriate PEM numbers */
+ 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 __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));
+ }
+ }
+
+ return (its_get_devid_default(pci_dev));
+}
+
/*
* Message signalled interrupts handling.
*/
Index: sys/arm64/arm64/gic_v3_var.h
===================================================================
--- sys/arm64/arm64/gic_v3_var.h
+++ sys/arm64/arm64/gic_v3_var.h
@@ -234,6 +234,15 @@
struct mtx its_spin_mtx;
};
+/* Stuff that is specific to the vendor's implementation */
+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;
+};
+
extern devclass_t gic_v3_its_devclass;
int gic_v3_its_detach(device_t);
@@ -277,13 +286,12 @@
reg, val); \
})
-#define PCI_DEVID(pci_dev) \
-({ \
- (((pci_get_domain(pci_dev) >> 2) << 19) | \
- ((pci_get_domain(pci_dev) % 4) << 16) | \
- (pci_get_bus(pci_dev) << 8) | \
- (pci_get_slot(pci_dev) << 3) | \
- (pci_get_function(pci_dev) << 0)); \
+#define PCI_DEVID_GENERIC(pci_dev) \
+({ \
+ ((pci_get_domain(pci_dev) << PCI_RID_DOMAIN_SHIFT) | \
+ (pci_get_bus(pci_dev) << PCI_RID_BUS_SHIFT) | \
+ (pci_get_slot(pci_dev) << PCI_RID_SLOT_SHIFT) | \
+ (pci_get_function(pci_dev) << PCI_RID_FUNC_SHIFT)); \
})
/*
Index: sys/dev/pci/pcireg.h
===================================================================
--- sys/dev/pci/pcireg.h
+++ sys/dev/pci/pcireg.h
@@ -51,6 +51,7 @@
#define PCIE_ARI_SLOTMAX 0
#define PCIE_ARI_FUNCMAX 255
+#define PCI_RID_DOMAIN_SHIFT 16
#define PCI_RID_BUS_SHIFT 8
#define PCI_RID_SLOT_SHIFT 3
#define PCI_RID_FUNC_SHIFT 0
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Apr 9, 2:01 AM (2 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31127993
Default Alt Text
D3118.id7139.diff (4 KB)
Attached To
Mode
D3118: Add support for vendor specific function for PCI devid acquisition
Attached
Detach File
Event Timeline
Log In to Comment