From owner-svn-src-head@freebsd.org Fri Jan 31 10:30:13 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 986C923B781; Fri, 31 Jan 2020 10:30:13 +0000 (UTC) (envelope-from andrew@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 488D4j3WRrz4Q9g; Fri, 31 Jan 2020 10:30:13 +0000 (UTC) (envelope-from andrew@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 73DC7C8EE; Fri, 31 Jan 2020 10:30:13 +0000 (UTC) (envelope-from andrew@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 00VAUDo8024206; Fri, 31 Jan 2020 10:30:13 GMT (envelope-from andrew@FreeBSD.org) Received: (from andrew@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 00VAUDTU024205; Fri, 31 Jan 2020 10:30:13 GMT (envelope-from andrew@FreeBSD.org) Message-Id: <202001311030.00VAUDTU024205@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: andrew set sender to andrew@FreeBSD.org using -f From: Andrew Turner Date: Fri, 31 Jan 2020 10:30:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r357324 - head/sys/arm64/arm64 X-SVN-Group: head X-SVN-Commit-Author: andrew X-SVN-Commit-Paths: head/sys/arm64/arm64 X-SVN-Commit-Revision: 357324 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 31 Jan 2020 10:30:13 -0000 Author: andrew Date: Fri Jan 31 10:30:13 2020 New Revision: 357324 URL: https://svnweb.freebsd.org/changeset/base/357324 Log: Only create one ITS configuration table When there are multiple ITS devices in the system we would allocate a configuration table for each, however only one table is needed as all the ITS devices share this. Allocate a table only when the global table is unset. While here fix the type of this to be a pointer to a uint8_t array as the entries are all 8 bits wide. 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 09:51:38 2020 (r357323) +++ head/sys/arm64/arm64/gicv3_its.c Fri Jan 31 10:30:13 2020 (r357324) @@ -224,6 +224,7 @@ struct its_col { struct gicv3_its_irqsrc { struct intr_irqsrc gi_isrc; u_int gi_irq; + u_int gi_lpi; struct its_dev *gi_its_dev; }; @@ -241,7 +242,7 @@ struct gicv3_its_softc { * TODO: We should get these from the parent as we only want a * single copy of each across the interrupt controller. */ - vm_offset_t sc_conf_base; + uint8_t *sc_conf_base; vm_offset_t sc_pend_base[MAXCPU]; /* Command handling */ @@ -263,6 +264,8 @@ struct gicv3_its_softc { u_int sc_its_flags; }; +static void *conf_base; + typedef void (its_quirk_func_t)(device_t); static its_quirk_func_t its_quirk_cavium_22375; @@ -542,17 +545,29 @@ gicv3_its_table_init(device_t dev, struct gicv3_its_so static void gicv3_its_conftable_init(struct gicv3_its_softc *sc) { + void *conf_table; - sc->sc_conf_base = (vm_offset_t)contigmalloc(LPI_CONFTAB_SIZE, - M_GICV3_ITS, M_WAITOK, 0, LPI_CONFTAB_MAX_ADDR, LPI_CONFTAB_ALIGN, - 0); + conf_table = (void *)atomic_load_ptr((uintptr_t *)&conf_base); + if (conf_table == NULL) { + conf_table = contigmalloc(LPI_CONFTAB_SIZE, + M_GICV3_ITS, M_WAITOK, 0, LPI_CONFTAB_MAX_ADDR, + LPI_CONFTAB_ALIGN, 0); + if (atomic_cmpset_ptr((uintptr_t *)&conf_base, + (uintptr_t)NULL, (uintptr_t)conf_table) == 0) { + contigfree(conf_table, LPI_CONFTAB_SIZE, M_GICV3_ITS); + conf_table = + (void *)atomic_load_ptr((uintptr_t *)&conf_base); + } + } + sc->sc_conf_base = conf_table; + /* Set the default configuration */ - memset((void *)sc->sc_conf_base, GIC_PRIORITY_MAX | LPI_CONF_GROUP1, + memset(sc->sc_conf_base, GIC_PRIORITY_MAX | LPI_CONF_GROUP1, LPI_CONFTAB_SIZE); /* Flush the table to memory */ - cpu_dcache_wb_range(sc->sc_conf_base, LPI_CONFTAB_SIZE); + cpu_dcache_wb_range((vm_offset_t)sc->sc_conf_base, LPI_CONFTAB_SIZE); } static void @@ -792,6 +807,7 @@ gicv3_its_attach(device_t dev) name = device_get_nameunit(dev); for (i = 0; i < sc->sc_irq_length; i++) { sc->sc_irqs[i].gi_irq = i; + sc->sc_irqs[i].gi_lpi = i + sc->sc_irq_base - GIC_FIRST_LPI; err = intr_isrc_register(&sc->sc_irqs[i].gi_isrc, dev, 0, "%s,%u", name, i); } @@ -824,13 +840,13 @@ gicv3_its_disable_intr(device_t dev, struct intr_irqsr sc = device_get_softc(dev); girq = (struct gicv3_its_irqsrc *)isrc; - conf = (uint8_t *)sc->sc_conf_base; + conf = sc->sc_conf_base; - conf[girq->gi_irq] &= ~LPI_CONF_ENABLE; + conf[girq->gi_lpi] &= ~LPI_CONF_ENABLE; if ((sc->sc_its_flags & ITS_FLAGS_LPI_CONF_FLUSH) != 0) { /* Clean D-cache under command. */ - cpu_dcache_wb_range((vm_offset_t)&conf[girq->gi_irq], 1); + cpu_dcache_wb_range((vm_offset_t)&conf[girq->gi_lpi], 1); } else { /* DSB inner shareable, store */ dsb(ishst); @@ -848,13 +864,13 @@ gicv3_its_enable_intr(device_t dev, struct intr_irqsrc sc = device_get_softc(dev); girq = (struct gicv3_its_irqsrc *)isrc; - conf = (uint8_t *)sc->sc_conf_base; + conf = sc->sc_conf_base; - conf[girq->gi_irq] |= LPI_CONF_ENABLE; + conf[girq->gi_lpi] |= LPI_CONF_ENABLE; if ((sc->sc_its_flags & ITS_FLAGS_LPI_CONF_FLUSH) != 0) { /* Clean D-cache under command. */ - cpu_dcache_wb_range((vm_offset_t)&conf[girq->gi_irq], 1); + cpu_dcache_wb_range((vm_offset_t)&conf[girq->gi_lpi], 1); } else { /* DSB inner shareable, store */ dsb(ishst);