svn commit: r357330 - head/sys/arm64/arm64

Andrew Turner andrew at FreeBSD.org
Fri Jan 31 11:33:12 UTC 2020


Author: andrew
Date: Fri Jan 31 11:33:11 2020
New Revision: 357330
URL: https://svnweb.freebsd.org/changeset/base/357330

Log:
  Call the MAPTI command earlier in the ITS driver
  
  The GICv3 Software Overview suggests when allocating a new MSI/MSI-X
  interrupt we need to call MAPD followed by MAPTI. Unfortunately the code
  would place a MOVI command between these. This is invalid as it needs
  values set by the MAPTI to be present.
  
  Re-order so we allocate a temporary CPU for the interrupt, then use the
  MAPTI command to assign the MSI to it.
  
  MFC after:	2 weeks
  Sponsored by:	DARPA, AFRL

Modified:
  head/sys/arm64/arm64/gicv3_its.c

Modified: head/sys/arm64/arm64/gicv3_its.c
==============================================================================
--- head/sys/arm64/arm64/gicv3_its.c	Fri Jan 31 11:31:14 2020	(r357329)
+++ head/sys/arm64/arm64/gicv3_its.c	Fri Jan 31 11:33:11 2020	(r357330)
@@ -928,21 +928,29 @@ gicv3_its_post_filter(device_t dev, struct intr_irqsrc
 }
 
 static int
-gicv3_its_bind_intr(device_t dev, struct intr_irqsrc *isrc)
+gicv3_its_select_cpu(device_t dev, struct intr_irqsrc *isrc)
 {
-	struct gicv3_its_irqsrc *girq;
 	struct gicv3_its_softc *sc;
 
 	sc = device_get_softc(dev);
-	girq = (struct gicv3_its_irqsrc *)isrc;
 	if (CPU_EMPTY(&isrc->isrc_cpu)) {
 		sc->gic_irq_cpu = intr_irq_next_cpu(sc->gic_irq_cpu,
 		    &sc->sc_cpus);
 		CPU_SETOF(sc->gic_irq_cpu, &isrc->isrc_cpu);
 	}
 
-	its_cmd_movi(dev, girq);
+	return (0);
+}
 
+static int
+gicv3_its_bind_intr(device_t dev, struct intr_irqsrc *isrc)
+{
+	struct gicv3_its_irqsrc *girq;
+
+	gicv3_its_select_cpu(dev, isrc);
+
+	girq = (struct gicv3_its_irqsrc *)isrc;
+	its_cmd_movi(dev, girq);
 	return (0);
 }
 
@@ -1129,6 +1137,10 @@ gicv3_its_alloc_msi(device_t dev, device_t child, int 
 		girq = &sc->sc_irqs[irq];
 		girq->gi_its_dev = its_dev;
 		srcs[i] = (struct intr_irqsrc *)girq;
+
+		/* Map the message to the given IRQ */
+		gicv3_its_select_cpu(dev, (struct intr_irqsrc *)girq);
+		its_cmd_mapti(dev, girq);
 	}
 	its_dev->lpis.lpi_busy += count;
 	*pic = dev;
@@ -1189,6 +1201,10 @@ gicv3_its_alloc_msix(device_t dev, device_t child, dev
 	girq = &sc->sc_irqs[irq];
 	girq->gi_its_dev = its_dev;
 
+	/* Map the message to the given IRQ */
+	gicv3_its_select_cpu(dev, (struct intr_irqsrc *)girq);
+	its_cmd_mapti(dev, girq);
+
 	*pic = dev;
 	*isrcp = (struct intr_irqsrc *)girq;
 
@@ -1228,9 +1244,6 @@ gicv3_its_map_msi(device_t dev, device_t child, struct
 
 	sc = device_get_softc(dev);
 	girq = (struct gicv3_its_irqsrc *)isrc;
-
-	/* Map the message to the given IRQ */
-	its_cmd_mapti(dev, girq);
 
 	*addr = vtophys(rman_get_virtual(sc->sc_its_res)) + GITS_TRANSLATER;
 	*data = girq->gi_irq - girq->gi_its_dev->lpis.lpi_base;


More information about the svn-src-head mailing list