Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Jul 2015 14:47:24 +0000 (UTC)
From:      Zbigniew Bodek <zbb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r285752 - in head/sys: arm64/arm64 dev/pci
Message-ID:  <201507211447.t6LElO3r098030@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: zbb
Date: Tue Jul 21 14:47:23 2015
New Revision: 285752
URL: https://svnweb.freebsd.org/changeset/base/285752

Log:
  Add support for vendor specific function for PCI devid acquisition in ITS
  
  It is possible that some HW will use different PCI devids,
  hence allow to replace the default domain:bus:slot:func schema
  by implementing and registering custom function.
  
  Obtained from: Semihalf
  Sponsored by:  The FreeBSD Foundation
  Differential Revision: https://reviews.freebsd.org/D3118

Modified:
  head/sys/arm64/arm64/gic_v3_its.c
  head/sys/arm64/arm64/gic_v3_var.h
  head/sys/dev/pci/pcireg.h

Modified: head/sys/arm64/arm64/gic_v3_its.c
==============================================================================
--- head/sys/arm64/arm64/gic_v3_its.c	Tue Jul 21 14:39:34 2015	(r285751)
+++ head/sys/arm64/arm64/gic_v3_its.c	Tue Jul 21 14:47:23 2015	(r285752)
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
 #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_free_tables(struct gic_v
 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 @@ const char *its_ptab_type[] = {
 	[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 @@ its_device_alloc_locked(struct gic_v3_it
 	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_device_asign_lpi_locked(struct gic_v
 	    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.
  */

Modified: head/sys/arm64/arm64/gic_v3_var.h
==============================================================================
--- head/sys/arm64/arm64/gic_v3_var.h	Tue Jul 21 14:39:34 2015	(r285751)
+++ head/sys/arm64/arm64/gic_v3_var.h	Tue Jul 21 14:47:23 2015	(r285752)
@@ -234,6 +234,15 @@ struct gic_v3_its_softc {
 	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 @@ void lpi_mask_irq(device_t, uint32_t);
 	    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));	\
 })
 
 /*

Modified: head/sys/dev/pci/pcireg.h
==============================================================================
--- head/sys/dev/pci/pcireg.h	Tue Jul 21 14:39:34 2015	(r285751)
+++ head/sys/dev/pci/pcireg.h	Tue Jul 21 14:47:23 2015	(r285752)
@@ -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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201507211447.t6LElO3r098030>