svn commit: r352501 - stable/12/sys/arm64/arm64

Jayachandran C. jchandra at FreeBSD.org
Wed Sep 18 23:23:36 UTC 2019


Author: jchandra
Date: Wed Sep 18 23:23:34 2019
New Revision: 352501
URL: https://svnweb.freebsd.org/changeset/base/352501

Log:
  MFC r348377-r348379, r349347
  
  r348377:
  gic_v3: consolidate per-cpu redistributor information
  
  Update 'struct gic_redists' to consolidate all per-cpu redistributor
  information into a new 'struct redist_pcpu'. Provide a new interface
  (GICV3_IVAR_REDIST) for the GIC driver, which can be used to retrieve
  the per-cpu data.
  
  This per-cpu redistributor struct will be later used to improve the
  GIC ITS setup.
  
  While there, remove some unused fields in gic_v3_var.h interface.
  No functional changes.
  
  Reviewed by:	andrew
  Differential Revision:	https://reviews.freebsd.org/D19842
  
  r348378:
  gicv3_its: refactor LPI init into a new function
  
  Move the per-cpu LPI intialization to a separate function. This is
  in preparation for a commit that does LPI init only once for a CPU,
  even when there are multiple ITS blocks associated with the CPU.
  
  No functional changes in this commit.
  
  Reviewed by:	andrew
  Differential Revision:	https://reviews.freebsd.org/D19843
  
  r348379:
  gicv3_its: do LPI init only once per CPU
  
  The initialization required for LPIs (setting up pending tables etc.)
  has to be done just once per CPU, even in the case where there are
  multiple ITS blocks associated with the CPU.
  
  Add a flag lpi_enabled in the per-cpu distributor info for this and
  use it to ensure that we call its_init_cpu_lpi() just once.
  
  This enables us to support platforms where multiple GIC ITS blocks
  can generate LPIs to a CPU.
  
  Reviewed by:	andrew
  Differential Revision:	https://reviews.freebsd.org/D19844
  
  r349347:
  arm64 gicv3_its: enable all ITS blocks for a CPU
  
  We now support multiple ITS blocks raising interrupts to a CPU.
  Add all available CPUs to the ITS when no NUMA information is
  available.
  
  This reverts the check added in r340602, at that tim we did not
  suppport multiple ITS blocks for a CPU.
  
  Differential Revision:	https://reviews.freebsd.org/D20417

Modified:
  stable/12/sys/arm64/arm64/gic_v3.c
  stable/12/sys/arm64/arm64/gic_v3_var.h
  stable/12/sys/arm64/arm64/gicv3_its.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/arm64/arm64/gic_v3.c
==============================================================================
--- stable/12/sys/arm64/arm64/gic_v3.c	Wed Sep 18 23:18:26 2019	(r352500)
+++ stable/12/sys/arm64/arm64/gic_v3.c	Wed Sep 18 23:23:34 2019	(r352501)
@@ -183,36 +183,44 @@ uint32_t
 gic_r_read_4(device_t dev, bus_size_t offset)
 {
 	struct gic_v3_softc *sc;
+	struct resource *rdist;
 
 	sc = device_get_softc(dev);
-	return (bus_read_4(sc->gic_redists.pcpu[PCPU_GET(cpuid)], offset));
+	rdist = &sc->gic_redists.pcpu[PCPU_GET(cpuid)]->res;
+	return (bus_read_4(rdist, offset));
 }
 
 uint64_t
 gic_r_read_8(device_t dev, bus_size_t offset)
 {
 	struct gic_v3_softc *sc;
+	struct resource *rdist;
 
 	sc = device_get_softc(dev);
-	return (bus_read_8(sc->gic_redists.pcpu[PCPU_GET(cpuid)], offset));
+	rdist = &sc->gic_redists.pcpu[PCPU_GET(cpuid)]->res;
+	return (bus_read_8(rdist, offset));
 }
 
 void
 gic_r_write_4(device_t dev, bus_size_t offset, uint32_t val)
 {
 	struct gic_v3_softc *sc;
+	struct resource *rdist;
 
 	sc = device_get_softc(dev);
-	bus_write_4(sc->gic_redists.pcpu[PCPU_GET(cpuid)], offset, val);
+	rdist = &sc->gic_redists.pcpu[PCPU_GET(cpuid)]->res;
+	bus_write_4(rdist, offset, val);
 }
 
 void
 gic_r_write_8(device_t dev, bus_size_t offset, uint64_t val)
 {
 	struct gic_v3_softc *sc;
+	struct resource *rdist;
 
 	sc = device_get_softc(dev);
-	bus_write_8(sc->gic_redists.pcpu[PCPU_GET(cpuid)], offset, val);
+	rdist = &sc->gic_redists.pcpu[PCPU_GET(cpuid)]->res;
+	bus_write_8(rdist, offset, val);
 }
 
 /*
@@ -384,8 +392,11 @@ gic_v3_read_ivar(device_t dev, device_t child, int whi
 		return (0);
 	case GICV3_IVAR_REDIST_VADDR:
 		*result = (uintptr_t)rman_get_virtual(
-		    sc->gic_redists.pcpu[PCPU_GET(cpuid)]);
+		    &sc->gic_redists.pcpu[PCPU_GET(cpuid)]->res);
 		return (0);
+	case GICV3_IVAR_REDIST:
+		*result = (uintptr_t)sc->gic_redists.pcpu[PCPU_GET(cpuid)];
+		return (0);
 	case GIC_IVAR_HW_REV:
 		KASSERT(
 		    GICR_PIDR2_ARCH(sc->gic_pidr2) == GICR_PIDR2_ARCH_GICv3 ||
@@ -979,7 +990,7 @@ gic_v3_wait_for_rwp(struct gic_v3_softc *sc, enum gic_
 		res = sc->gic_dist;
 		break;
 	case REDIST:
-		res = sc->gic_redists.pcpu[cpuid];
+		res = &sc->gic_redists.pcpu[cpuid]->res;
 		break;
 	default:
 		KASSERT(0, ("%s: Attempt to wait for unknown RWP", __func__));
@@ -1173,7 +1184,8 @@ gic_v3_redist_find(struct gic_v3_softc *sc)
 				KASSERT(sc->gic_redists.pcpu[cpuid] != NULL,
 				    ("Invalid pointer to per-CPU redistributor"));
 				/* Copy res contents to its final destination */
-				*sc->gic_redists.pcpu[cpuid] = r_res;
+				sc->gic_redists.pcpu[cpuid]->res = r_res;
+				sc->gic_redists.pcpu[cpuid]->lpi_enabled = false;
 				if (bootverbose) {
 					device_printf(sc->dev,
 					    "CPU%u Re-Distributor has been found\n",

Modified: stable/12/sys/arm64/arm64/gic_v3_var.h
==============================================================================
--- stable/12/sys/arm64/arm64/gic_v3_var.h	Wed Sep 18 23:18:26 2019	(r352500)
+++ stable/12/sys/arm64/arm64/gic_v3_var.h	Wed Sep 18 23:23:34 2019	(r352501)
@@ -40,10 +40,10 @@ DECLARE_CLASS(gic_v3_driver);
 
 struct gic_v3_irqsrc;
 
-struct redist_lpis {
-	vm_offset_t		conf_base;
-	vm_offset_t		pend_base[MAXCPU];
-	uint64_t		flags;
+struct redist_pcpu {
+	struct resource		res;		/* mem resource for redist */
+	vm_offset_t		pend_base;
+	bool			lpi_enabled;	/* redist LPI configured? */
 };
 
 struct gic_redists {
@@ -55,10 +55,8 @@ struct gic_redists {
 	struct resource **	regions;
 	/* Number of Re-Distributor regions */
 	u_int			nregions;
-	/* Per-CPU Re-Distributor handler */
-	struct resource *	pcpu[MAXCPU];
-	/* LPIs data */
-	struct redist_lpis	lpis;
+	/* Per-CPU Re-Distributor data */
+	struct redist_pcpu	*pcpu[MAXCPU];
 };
 
 struct gic_v3_softc {
@@ -97,9 +95,11 @@ MALLOC_DECLARE(M_GIC_V3);
 /* ivars */
 #define	GICV3_IVAR_NIRQS	1000
 #define	GICV3_IVAR_REDIST_VADDR	1001
+#define	GICV3_IVAR_REDIST	1002
 
 __BUS_ACCESSOR(gicv3, nirqs, GICV3, NIRQS, u_int);
 __BUS_ACCESSOR(gicv3, redist_vaddr, GICV3, REDIST_VADDR, void *);
+__BUS_ACCESSOR(gicv3, redist, GICV3, REDIST, void *);
 
 /* Device methods */
 int gic_v3_attach(device_t dev);
@@ -131,7 +131,7 @@ void gic_r_write_8(device_t, bus_size_t, uint64_t var)
 	u_int cpu = PCPU_GET(cpuid);		\
 						\
 	bus_read_##len(				\
-	    sc->gic_redists.pcpu[cpu],		\
+	    &sc->gic_redists.pcpu[cpu]->res,	\
 	    reg);				\
 })
 
@@ -140,7 +140,7 @@ void gic_r_write_8(device_t, bus_size_t, uint64_t var)
 	u_int cpu = PCPU_GET(cpuid);		\
 						\
 	bus_write_##len(			\
-	    sc->gic_redists.pcpu[cpu],		\
+	    &sc->gic_redists.pcpu[cpu]->res,	\
 	    reg, val);				\
 })
 

Modified: stable/12/sys/arm64/arm64/gicv3_its.c
==============================================================================
--- stable/12/sys/arm64/arm64/gicv3_its.c	Wed Sep 18 23:18:26 2019	(r352500)
+++ stable/12/sys/arm64/arm64/gicv3_its.c	Wed Sep 18 23:23:34 2019	(r352501)
@@ -572,25 +572,17 @@ gicv3_its_pendtables_init(struct gicv3_its_softc *sc)
 	}
 }
 
-static int
-its_init_cpu(device_t dev, struct gicv3_its_softc *sc)
+static void
+its_init_cpu_lpi(device_t dev, struct gicv3_its_softc *sc)
 {
 	device_t gicv3;
-	vm_paddr_t target;
 	uint64_t xbaser, tmp;
 	uint32_t ctlr;
 	u_int cpuid;
 
 	gicv3 = device_get_parent(dev);
 	cpuid = PCPU_GET(cpuid);
-	if (!CPU_ISSET(cpuid, &sc->sc_cpus))
-		return (0);
 
-	/* Check if the ITS is enabled on this CPU */
-	if ((gic_r_read_4(gicv3, GICR_TYPER) & GICR_TYPER_PLPIS) == 0) {
-		return (ENXIO);
-	}
-
 	/* Disable LPIs */
 	ctlr = gic_r_read_4(gicv3, GICR_CTLR);
 	ctlr &= ~GICR_CTLR_LPI_ENABLE;
@@ -659,10 +651,36 @@ its_init_cpu(device_t dev, struct gicv3_its_softc *sc)
 
 	/* Make sure the GIC has seen everything */
 	dsb(sy);
+}
 
+static int
+its_init_cpu(device_t dev, struct gicv3_its_softc *sc)
+{
+	device_t gicv3;
+	vm_paddr_t target;
+	u_int cpuid;
+	struct redist_pcpu *rpcpu;
+
+	gicv3 = device_get_parent(dev);
+	cpuid = PCPU_GET(cpuid);
+	if (!CPU_ISSET(cpuid, &sc->sc_cpus))
+		return (0);
+
+	/* Check if the ITS is enabled on this CPU */
+	if ((gic_r_read_4(gicv3, GICR_TYPER) & GICR_TYPER_PLPIS) == 0)
+		return (ENXIO);
+
+	rpcpu = gicv3_get_redist(dev);
+
+	/* Do per-cpu LPI init once */
+	if (!rpcpu->lpi_enabled) {
+		its_init_cpu_lpi(dev, sc);
+		rpcpu->lpi_enabled = true;
+	}
+
 	if ((gic_its_read_8(sc, GITS_TYPER) & GITS_TYPER_PTA) != 0) {
 		/* This ITS wants the redistributor physical address */
-		target = vtophys(gicv3_get_redist_vaddr(dev));
+		target = vtophys(rman_get_virtual(&rpcpu->res));
 	} else {
 		/* This ITS wants the unique processor number */
 		target = GICR_TYPER_CPUNUM(gic_r_read_8(gicv3, GICR_TYPER));
@@ -727,9 +745,7 @@ gicv3_its_attach(device_t dev)
 		if (domain < MAXMEMDOM)
 			CPU_COPY(&cpuset_domain[domain], &sc->sc_cpus);
 	} else {
-		/* XXX : cannot handle more than one ITS per cpu */
-		if (device_get_unit(dev) == 0)
-			CPU_COPY(&all_cpus, &sc->sc_cpus);
+		CPU_COPY(&all_cpus, &sc->sc_cpus);
 	}
 
 	/* Allocate the command circular buffer */


More information about the svn-src-all mailing list