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