Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/cortex Fix size of LPI pending table allocation...



details:   https://anonhg.NetBSD.org/src/rev/247f854b5447
branches:  trunk
changeset: 962148:247f854b5447
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sun Jun 30 11:11:38 2019 +0000

description:
Fix size of LPI pending table allocation and enable caching of LPI conf
and pending tables where possible.

diffstat:

 sys/arch/arm/cortex/gicv3.c |  56 ++++++++++++++++++++++++++++++++++----------
 sys/arch/arm/cortex/gicv3.h |   3 +-
 2 files changed, 45 insertions(+), 14 deletions(-)

diffs (147 lines):

diff -r ff10e15bed93 -r 247f854b5447 sys/arch/arm/cortex/gicv3.c
--- a/sys/arch/arm/cortex/gicv3.c       Sun Jun 30 10:10:19 2019 +0000
+++ b/sys/arch/arm/cortex/gicv3.c       Sun Jun 30 11:11:38 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gicv3.c,v 1.19 2019/06/26 23:00:09 jmcneill Exp $ */
+/* $NetBSD: gicv3.c,v 1.20 2019/06/30 11:11:38 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -31,7 +31,7 @@
 #define        _INTR_PRIVATE
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gicv3.c,v 1.19 2019/06/26 23:00:09 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gicv3.c,v 1.20 2019/06/30 11:11:38 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -41,6 +41,8 @@
 #include <sys/systm.h>
 #include <sys/cpu.h>
 
+#include <machine/cpufunc.h>
+
 #include <arm/locore.h>
 #include <arm/armreg.h>
 
@@ -516,10 +518,13 @@
 
        while ((bit = ffs(mask)) != 0) {
                sc->sc_lpiconf.base[irqbase + bit - 1] |= GIC_LPICONF_Enable;
+               if (sc->sc_lpiconf_flush)
+                       cpu_dcache_wb_range((vaddr_t)&sc->sc_lpiconf.base[irqbase + bit - 1], 1);
                mask &= ~__BIT(bit - 1);
        }
 
-       bus_dmamap_sync(sc->sc_dmat, sc->sc_lpiconf.map, irqbase, 32, BUS_DMASYNC_PREWRITE);
+       if (!sc->sc_lpiconf_flush)
+               __asm __volatile ("dsb ishst");
 }
 
 static void
@@ -530,10 +535,13 @@
 
        while ((bit = ffs(mask)) != 0) {
                sc->sc_lpiconf.base[irqbase + bit - 1] &= ~GIC_LPICONF_Enable;
+               if (sc->sc_lpiconf_flush)
+                       cpu_dcache_wb_range((vaddr_t)&sc->sc_lpiconf.base[irqbase + bit - 1], 1);
                mask &= ~__BIT(bit - 1);
        }
 
-       bus_dmamap_sync(sc->sc_dmat, sc->sc_lpiconf.map, irqbase, 32, BUS_DMASYNC_PREWRITE);
+       if (!sc->sc_lpiconf_flush)
+               __asm __volatile ("dsb ishst");
 }
 
 static void
@@ -543,7 +551,10 @@
 
        sc->sc_lpiconf.base[is->is_irq] = IPL_TO_LPIPRIO(sc, is->is_ipl) | GIC_LPICONF_Res1;
 
-       bus_dmamap_sync(sc->sc_dmat, sc->sc_lpiconf.map, is->is_irq, 1, BUS_DMASYNC_PREWRITE);
+       if (sc->sc_lpiconf_flush)
+               cpu_dcache_wb_range((vaddr_t)&sc->sc_lpiconf.base[is->is_irq], 1);
+       else
+               __asm __volatile ("dsb ishst");
 }
 
 static void
@@ -551,6 +562,7 @@
 {
        struct gicv3_softc * const sc = LPITOSOFTC(pic);
        struct gicv3_lpi_callback *cb;
+       uint64_t propbase, pendbase;
        uint32_t ctlr;
 
        /* If physical LPIs are not supported on this redistributor, just return. */
@@ -568,18 +580,36 @@
        arm_dsb();
 
        /* Setup the LPI configuration table */
-       const uint64_t propbase = sc->sc_lpiconf.segs[0].ds_addr |
+       propbase = sc->sc_lpiconf.segs[0].ds_addr |
            __SHIFTIN(ffs(pic->pic_maxsources) - 1, GICR_PROPBASER_IDbits) |
-           __SHIFTIN(GICR_Shareability_NS, GICR_PROPBASER_Shareability) |
-           __SHIFTIN(GICR_Cache_NORMAL_NC, GICR_PROPBASER_InnerCache);
+           __SHIFTIN(GICR_Shareability_IS, GICR_PROPBASER_Shareability) |
+           __SHIFTIN(GICR_Cache_NORMAL_RA_WA_WB, GICR_PROPBASER_InnerCache);
        gicr_write_8(sc, ci->ci_gic_redist, GICR_PROPBASER, propbase);
+       propbase = gicr_read_8(sc, ci->ci_gic_redist, GICR_PROPBASER);
+       if (__SHIFTOUT(propbase, GICR_PROPBASER_Shareability) != GICR_Shareability_IS) {
+               if (__SHIFTOUT(propbase, GICR_PROPBASER_Shareability) == GICR_Shareability_NS) {
+                       propbase &= ~GICR_PROPBASER_Shareability;
+                       propbase |= __SHIFTIN(GICR_Shareability_NS, GICR_PROPBASER_Shareability);
+                       propbase &= ~GICR_PROPBASER_InnerCache;
+                       propbase |= __SHIFTIN(GICR_Cache_NORMAL_NC, GICR_PROPBASER_InnerCache);
+                       gicr_write_8(sc, ci->ci_gic_redist, GICR_PROPBASER, propbase);
+               }
+               sc->sc_lpiconf_flush = true;
+       }
 
        /* Setup the LPI pending table */
-       const uint64_t pendbase = sc->sc_lpipend[cpu_index(ci)].segs[0].ds_addr |
-           __SHIFTIN(GICR_Shareability_NS, GICR_PENDBASER_Shareability) |
-           __SHIFTIN(GICR_Cache_NORMAL_NC, GICR_PENDBASER_InnerCache) |
-           GICR_PENDBASER_PTZ;
+       pendbase = sc->sc_lpipend[cpu_index(ci)].segs[0].ds_addr |
+           __SHIFTIN(GICR_Shareability_IS, GICR_PENDBASER_Shareability) |
+           __SHIFTIN(GICR_Cache_NORMAL_RA_WA_WB, GICR_PENDBASER_InnerCache);
        gicr_write_8(sc, ci->ci_gic_redist, GICR_PENDBASER, pendbase);
+       pendbase = gicr_read_8(sc, ci->ci_gic_redist, GICR_PENDBASER);
+       if (__SHIFTOUT(pendbase, GICR_PENDBASER_Shareability) == GICR_Shareability_NS) {
+               pendbase &= ~GICR_PENDBASER_Shareability;
+               pendbase |= __SHIFTIN(GICR_Shareability_NS, GICR_PENDBASER_Shareability);
+               pendbase &= ~GICR_PENDBASER_InnerCache;
+               pendbase |= __SHIFTIN(GICR_Cache_NORMAL_NC, GICR_PENDBASER_InnerCache);
+               gicr_write_8(sc, ci->ci_gic_redist, GICR_PENDBASER, pendbase);
+       }
 
        /* Enable LPIs */
        ctlr = gicr_read_4(sc, ci->ci_gic_redist, GICR_CTLR);
@@ -666,7 +696,7 @@
        /*
         * Allocate LPI pending tables
         */
-       const bus_size_t lpipend_sz = sc->sc_lpi.pic_maxsources / NBBY;
+       const bus_size_t lpipend_sz = (8192 + sc->sc_lpi.pic_maxsources) / NBBY;
        for (int cpuindex = 0; cpuindex < ncpu; cpuindex++) {
                gicv3_dma_alloc(sc, &sc->sc_lpipend[cpuindex], lpipend_sz, 0x10000);
                KASSERT((sc->sc_lpipend[cpuindex].segs[0].ds_addr & ~GICR_PENDBASER_Physical_Address) == 0);
diff -r ff10e15bed93 -r 247f854b5447 sys/arch/arm/cortex/gicv3.h
--- a/sys/arch/arm/cortex/gicv3.h       Sun Jun 30 10:10:19 2019 +0000
+++ b/sys/arch/arm/cortex/gicv3.h       Sun Jun 30 11:11:38 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gicv3.h,v 1.6 2019/06/26 23:10:42 jmcneill Exp $ */
+/* $NetBSD: gicv3.h,v 1.7 2019/06/30 11:11:38 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -68,6 +68,7 @@
 
        /* LPI configuration table */
        struct gicv3_dma        sc_lpiconf;
+       bool                    sc_lpiconf_flush;
 
        /* LPI pending tables */
        struct gicv3_dma        sc_lpipend[MAXCPUS];



Home | Main Index | Thread Index | Old Index