From owner-svn-src-all@freebsd.org Tue May 17 13:12:27 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9270EB3CB79; Tue, 17 May 2016 13:12:27 +0000 (UTC) (envelope-from bz@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 mx1.freebsd.org (Postfix) with ESMTPS id 50E6B285F; Tue, 17 May 2016 13:12:27 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u4HDCQES040940; Tue, 17 May 2016 13:12:26 GMT (envelope-from bz@FreeBSD.org) Received: (from bz@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u4HDCQDc040937; Tue, 17 May 2016 13:12:26 GMT (envelope-from bz@FreeBSD.org) Message-Id: <201605171312.u4HDCQDc040937@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: bz set sender to bz@FreeBSD.org using -f From: "Bjoern A. Zeeb" Date: Tue, 17 May 2016 13:12:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r300051 - in head/sys: arm/arm arm64/arm64 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 May 2016 13:12:27 -0000 Author: bz Date: Tue May 17 13:12:26 2016 New Revision: 300051 URL: https://svnweb.freebsd.org/changeset/base/300051 Log: The GIC (v2 at least) has a bit in the TYPER register to indicate whether the GIC supports the Security Extensions or not. This bit is not the same as the CPU one. Currently we are not checking for either before trying to write to the special registers. This can lead to problems on hardware or simulators that do not provide the security extensions. Add the missing checks. Their interactions with the CPU flag is not entirely clear to me but using a macro will make it easier to quickly adjust the condition once the CPU bits are sorted as well. Reviewed by: br Sponsored by: DARPA/AFRL Differential Revision: https://reviews.freebsd.org/D6397 Modified: head/sys/arm/arm/gic.c head/sys/arm64/arm64/gic.c head/sys/arm64/arm64/gic.h Modified: head/sys/arm/arm/gic.c ============================================================================== --- head/sys/arm/arm/gic.c Tue May 17 12:52:31 2016 (r300050) +++ head/sys/arm/arm/gic.c Tue May 17 13:12:26 2016 (r300051) @@ -108,6 +108,11 @@ __FBSDID("$FreeBSD$"); #define GIC_LAST_PPI 31 /* core) peripheral interrupts. */ #define GIC_FIRST_SPI 32 /* Irqs 32+ are shared peripherals. */ +/* TYPER Registers */ +#define GICD_TYPER_SECURITYEXT 0x400 +#define GIC_SUPPORT_SECEXT(_sc) \ + ((_sc->typer & GICD_TYPER_SECURITYEXT) == GICD_TYPER_SECURITYEXT) + /* First bit is a polarity bit (0 - low, 1 - high) */ #define GICD_ICFGR_POL_LOW (0 << 0) #define GICD_ICFGR_POL_HIGH (1 << 0) @@ -172,6 +177,7 @@ struct arm_gic_softc { uint8_t ver; struct mtx mutex; uint32_t nirqs; + uint32_t typer; #ifdef GIC_DEBUG_SPURIOUS uint32_t last_irq[MAXCPU]; #endif @@ -299,7 +305,7 @@ arm_gic_init_secondary(device_t dev) gic_d_write_4(sc, GICD_IPRIORITYR(irq >> 2), 0); /* Set all the interrupts to be in Group 0 (secure) */ - for (irq = 0; irq < sc->nirqs; irq += 32) { + for (irq = 0; GIC_SUPPORT_SECEXT(sc) && irq < sc->nirqs; irq += 32) { gic_d_write_4(sc, GICD_IGROUPR(irq >> 5), 0); } @@ -336,7 +342,7 @@ arm_gic_init_secondary(device_t dev) gic_d_write_4(sc, GICD_IPRIORITYR(i >> 2), 0); /* Set all the interrupts to be in Group 0 (secure) */ - for (i = 0; i < sc->nirqs; i += 32) { + for (i = 0; GIC_SUPPORT_SECEXT(sc) && i < sc->nirqs; i += 32) { gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0); } @@ -639,8 +645,8 @@ arm_gic_attach(device_t dev) gic_d_write_4(sc, GICD_CTLR, 0x00); /* Get the number of interrupts */ - nirqs = gic_d_read_4(sc, GICD_TYPER); - nirqs = 32 * ((nirqs & 0x1f) + 1); + sc->typer = gic_d_read_4(sc, GICD_TYPER); + nirqs = 32 * ((sc->typer & 0x1f) + 1); #ifdef INTRNG if (arm_gic_register_isrcs(sc, nirqs)) { @@ -686,7 +692,7 @@ arm_gic_attach(device_t dev) } /* Set all the interrupts to be in Group 0 (secure) */ - for (i = 0; i < sc->nirqs; i += 32) { + for (i = 0; GIC_SUPPORT_SECEXT(sc) && i < sc->nirqs; i += 32) { gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0); } Modified: head/sys/arm64/arm64/gic.c ============================================================================== --- head/sys/arm64/arm64/gic.c Tue May 17 12:52:31 2016 (r300050) +++ head/sys/arm64/arm64/gic.c Tue May 17 13:12:26 2016 (r300051) @@ -94,6 +94,11 @@ __FBSDID("$FreeBSD$"); #define GIC_LAST_PPI 31 /* core) peripheral interrupts. */ #define GIC_FIRST_SPI 32 /* Irqs 32+ are shared peripherals. */ +/* TYPER Registers */ +#define GICD_TYPER_SECURITYEXT 0x400 +#define GIC_SUPPORT_SECEXT(_sc) \ + ((_sc->typer & GICD_TYPER_SECURITYEXT) == GICD_TYPER_SECURITYEXT) + /* First bit is a polarity bit (0 - low, 1 - high) */ #define GICD_ICFGR_POL_LOW (0 << 0) #define GICD_ICFGR_POL_HIGH (1 << 0) @@ -164,7 +169,7 @@ gic_init_secondary(device_t dev) gic_d_write_4(sc, GICD_IPRIORITYR(i >> 2), 0); /* Set all the interrupts to be in Group 0 (secure) */ - for (i = 0; i < sc->nirqs; i += 32) { + for (i = 0; GIC_SUPPORT_SECEXT(sc) && i < sc->nirqs; i += 32) { gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0); } @@ -221,8 +226,8 @@ arm_gic_attach(device_t dev) gic_d_write_4(sc, GICD_CTLR, 0x00); /* Get the number of interrupts */ - sc->nirqs = gic_d_read_4(sc, GICD_TYPER); - sc->nirqs = 32 * ((sc->nirqs & 0x1f) + 1); + sc->typer = gic_d_read_4(sc, GICD_TYPER); + sc->nirqs = 32 * ((sc->typer & 0x1f) + 1); arm_register_root_pic(dev, sc->nirqs); @@ -257,7 +262,7 @@ arm_gic_attach(device_t dev) } /* Set all the interrupts to be in Group 0 (secure) */ - for (i = 0; i < sc->nirqs; i += 32) { + for (i = 0; GIC_SUPPORT_SECEXT(sc) && i < sc->nirqs; i += 32) { gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0); } Modified: head/sys/arm64/arm64/gic.h ============================================================================== --- head/sys/arm64/arm64/gic.h Tue May 17 12:52:31 2016 (r300050) +++ head/sys/arm64/arm64/gic.h Tue May 17 13:12:26 2016 (r300051) @@ -49,6 +49,7 @@ struct arm_gic_softc { uint8_t ver; struct mtx mutex; uint32_t nirqs; + uint32_t typer; }; DECLARE_CLASS(arm_gicv2m_driver);