Date: Fri, 31 Jan 2020 11:33:12 +0000 (UTC) From: Andrew Turner <andrew@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r357330 - head/sys/arm64/arm64 Message-ID: <202001311133.00VBXCmb065867@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202001311133.00VBXCmb065867>