From owner-svn-src-all@freebsd.org Tue Mar 29 13:51:28 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 471EEAE1D4C; Tue, 29 Mar 2016 13:51:28 +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 mx1.freebsd.org (Postfix) with ESMTPS id 0087E11EB; Tue, 29 Mar 2016 13:51:27 +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 u2TDpROh023063; Tue, 29 Mar 2016 13:51:27 GMT (envelope-from andrew@FreeBSD.org) Received: (from andrew@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u2TDpRYd023061; Tue, 29 Mar 2016 13:51:27 GMT (envelope-from andrew@FreeBSD.org) Message-Id: <201603291351.u2TDpRYd023061@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: andrew set sender to andrew@FreeBSD.org using -f From: Andrew Turner Date: Tue, 29 Mar 2016 13:51:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r297390 - 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.21 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, 29 Mar 2016 13:51:28 -0000 Author: andrew Date: Tue Mar 29 13:51:26 2016 New Revision: 297390 URL: https://svnweb.freebsd.org/changeset/base/297390 Log: Read the CPU ID for the current CPU from the GIC. The GIC may have a different ID space than the kernel. Because of this we need to read the ID from the hardware. The hardware will provide this value to the CPU by reading any of the first 8 Interrupt Processor Targets Registers. Obtained from: ABT Systems Ltd Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D5706 Modified: head/sys/arm/arm/gic.c head/sys/arm64/arm64/gic.c Modified: head/sys/arm/arm/gic.c ============================================================================== --- head/sys/arm/arm/gic.c Tue Mar 29 13:31:09 2016 (r297389) +++ head/sys/arm/arm/gic.c Tue Mar 29 13:51:26 2016 (r297390) @@ -376,7 +376,7 @@ arm_gic_attach(device_t dev) { struct arm_gic_softc *sc; int i; - uint32_t icciidr; + uint32_t icciidr, mask; #ifdef ARM_INTRNG phandle_t pxref; intptr_t xref = gic_xref(dev); @@ -437,10 +437,28 @@ arm_gic_attach(device_t dev) gic_d_write_4(sc, GICD_ICENABLER(i >> 5), 0xFFFFFFFF); } + /* Read the current cpuid mask by reading ITARGETSR{0..7} */ + for (i = 0; i < 8; i++) { + mask = gic_d_read_4(sc, GICD_ITARGETSR(i)); + if (mask != 0) + break; + } + /* No mask found, assume we are on CPU interface 0 */ + if (mask == 0) + mask = 1; + + /* Collect the mask in the lower byte */ + mask |= mask >> 16; + mask |= mask >> 8; + /* Distribute this back to the upper bytes */ + mask |= mask << 8; + mask |= mask << 16; + for (i = 0; i < sc->nirqs; i += 4) { gic_d_write_4(sc, GICD_IPRIORITYR(i >> 2), 0); - gic_d_write_4(sc, GICD_ITARGETSR(i >> 2), - 1 << 0 | 1 << 8 | 1 << 16 | 1 << 24); + if (i > 32) { + gic_d_write_4(sc, GICD_ITARGETSR(i >> 2), mask); + } } /* Set all the interrupts to be in Group 0 (secure) */ Modified: head/sys/arm64/arm64/gic.c ============================================================================== --- head/sys/arm64/arm64/gic.c Tue Mar 29 13:31:09 2016 (r297389) +++ head/sys/arm64/arm64/gic.c Tue Mar 29 13:51:26 2016 (r297390) @@ -162,7 +162,7 @@ arm_gic_attach(device_t dev) { struct arm_gic_softc *sc; int i; - uint32_t icciidr; + uint32_t icciidr, mask; if (arm_gic_sc) return (ENXIO); @@ -212,10 +212,28 @@ arm_gic_attach(device_t dev) gic_d_write_4(sc, GICD_ICENABLER(i >> 5), 0xFFFFFFFF); } + /* Read the current cpuid mask by reading ITARGETSR{0..7} */ + for (i = 0; i < 8; i++) { + mask = gic_d_read_4(sc, GICD_ITARGETSR(i)); + if (mask != 0) + break; + } + /* No mask found, assume we are on CPU interface 0 */ + if (mask == 0) + mask = 1; + + /* Collect the mask in the lower byte */ + mask |= mask >> 16; + mask |= mask >> 8; + /* Distribute this back to the upper bytes */ + mask |= mask << 8; + mask |= mask << 16; + for (i = 0; i < sc->nirqs; i += 4) { gic_d_write_4(sc, GICD_IPRIORITYR(i >> 2), 0); - gic_d_write_4(sc, GICD_ITARGETSR(i >> 2), - 1 << 0 | 1 << 8 | 1 << 16 | 1 << 24); + if (i > 32) { + gic_d_write_4(sc, GICD_ITARGETSR(i >> 2), mask); + } } /* Set all the interrupts to be in Group 0 (secure) */