From owner-svn-src-head@freebsd.org Tue Dec 6 15:12:17 2016 Return-Path: Delivered-To: svn-src-head@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 0F45DC69759; Tue, 6 Dec 2016 15:12:17 +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 BD804687; Tue, 6 Dec 2016 15:12:16 +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 uB6FCFsl031124; Tue, 6 Dec 2016 15:12:15 GMT (envelope-from andrew@FreeBSD.org) Received: (from andrew@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uB6FCF8r031116; Tue, 6 Dec 2016 15:12:15 GMT (envelope-from andrew@FreeBSD.org) Message-Id: <201612061512.uB6FCF8r031116@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: andrew set sender to andrew@FreeBSD.org using -f From: Andrew Turner Date: Tue, 6 Dec 2016 15:12:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r309622 - 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-head@freebsd.org X-Mailman-Version: 2.1.23 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: Tue, 06 Dec 2016 15:12:17 -0000 Author: andrew Date: Tue Dec 6 15:12:14 2016 New Revision: 309622 URL: https://svnweb.freebsd.org/changeset/base/309622 Log: Create two GIC ivars to find the bus type and GIC hardware version. These will be used by the gicv2m and ITS ACPI drivers to only attach to the correct parent. Obtained from: ABT Systems Ltd Sponsored by: The FreeBSD Foundation Modified: head/sys/arm/arm/gic.c head/sys/arm/arm/gic.h head/sys/arm/arm/gic_common.h head/sys/arm/arm/gic_fdt.c head/sys/arm64/arm64/gic_v3.c head/sys/arm64/arm64/gic_v3_fdt.c head/sys/arm64/arm64/gic_v3_reg.h head/sys/arm64/arm64/gic_v3_var.h Modified: head/sys/arm/arm/gic.c ============================================================================== --- head/sys/arm/arm/gic.c Tue Dec 6 14:31:47 2016 (r309621) +++ head/sys/arm/arm/gic.c Tue Dec 6 15:12:14 2016 (r309622) @@ -467,6 +467,9 @@ arm_gic_attach(device_t dev) "pn 0x%x, arch 0x%x, rev 0x%x, implementer 0x%x irqs %u\n", GICD_IIDR_PROD(icciidr), GICD_IIDR_VAR(icciidr), GICD_IIDR_REV(icciidr), GICD_IIDR_IMPL(icciidr), sc->nirqs); +#ifdef INTRNG + sc->gic_iidr = icciidr; +#endif /* Set all global interrupts to be level triggered, active low. */ for (i = 32; i < sc->nirqs; i += 16) { @@ -611,6 +614,33 @@ arm_gic_alloc_resource(device_t bus, dev count, flags)); } +static int +arm_gic_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) +{ + struct arm_gic_softc *sc; + + sc = device_get_softc(dev); + + switch(which) { + case GIC_IVAR_HW_REV: + KASSERT(GICD_IIDR_VAR(sc->gic_iidr) < 3 && + GICD_IIDR_VAR(sc->gic_iidr) != 0, + ("arm_gic_read_ivar: Unknown IIDR revision %u (%.08x)", + GICD_IIDR_VAR(sc->gic_iidr), sc->gic_iidr)); + *result = GICD_IIDR_VAR(sc->gic_iidr); + return (0); + case GIC_IVAR_BUS: + KASSERT(sc->gic_bus != GIC_BUS_UNKNOWN, + ("arm_gic_read_ivar: Unknown bus type")); + KASSERT(sc->gic_bus <= GIC_BUS_MAX, + ("arm_gic_read_ivar: Invalid bus type %u", sc->gic_bus)); + *result = sc->gic_bus; + return (0); + } + + return (ENOENT); +} + int arm_gic_intr(void *arg) { @@ -1307,6 +1337,7 @@ static device_method_t arm_gic_methods[] DEVMETHOD(bus_alloc_resource, arm_gic_alloc_resource), DEVMETHOD(bus_release_resource, bus_generic_release_resource), DEVMETHOD(bus_activate_resource,bus_generic_activate_resource), + DEVMETHOD(bus_read_ivar, arm_gic_read_ivar), /* Interrupt controller interface */ DEVMETHOD(pic_disable_intr, arm_gic_disable_intr), Modified: head/sys/arm/arm/gic.h ============================================================================== --- head/sys/arm/arm/gic.h Tue Dec 6 14:31:47 2016 (r309621) +++ head/sys/arm/arm/gic.h Tue Dec 6 15:12:14 2016 (r309622) @@ -75,6 +75,9 @@ struct arm_gic_softc { #endif #ifdef INTRNG + uint32_t gic_iidr; + u_int gic_bus; + int nranges; struct arm_gic_range * ranges; #endif Modified: head/sys/arm/arm/gic_common.h ============================================================================== --- head/sys/arm/arm/gic_common.h Tue Dec 6 14:31:47 2016 (r309621) +++ head/sys/arm/arm/gic_common.h Tue Dec 6 15:12:14 2016 (r309622) @@ -32,6 +32,18 @@ #ifndef _GIC_COMMON_H_ #define _GIC_COMMON_H_ +#define GIC_IVAR_HW_REV 500 +#define GIC_IVAR_BUS 501 + +/* GIC_IVAR_BUS values */ +#define GIC_BUS_UNKNOWN 0 +#define GIC_BUS_FDT 1 +#define GIC_BUS_ACPI 2 +#define GIC_BUS_MAX 2 + +__BUS_ACCESSOR(gic, hw_rev, GIC, HW_REV, u_int); +__BUS_ACCESSOR(gic, bus, GIC, BUS, u_int); + /* Common register values */ #define GICD_CTLR 0x0000 /* v1 ICDDCR */ #define GICD_TYPER 0x0004 /* v1 ICDICTR */ Modified: head/sys/arm/arm/gic_fdt.c ============================================================================== --- head/sys/arm/arm/gic_fdt.c Tue Dec 6 14:31:47 2016 (r309621) +++ head/sys/arm/arm/gic_fdt.c Tue Dec 6 15:12:14 2016 (r309622) @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #ifdef INTRNG struct arm_gic_devinfo { @@ -140,6 +141,10 @@ gic_fdt_attach(device_t dev) #endif int err; +#ifdef INTRNG + sc->base.gic_bus = GIC_BUS_FDT; +#endif + err = arm_gic_attach(dev); if (err != 0) return (err); Modified: head/sys/arm64/arm64/gic_v3.c ============================================================================== --- head/sys/arm64/arm64/gic_v3.c Tue Dec 6 14:31:47 2016 (r309621) +++ head/sys/arm64/arm64/gic_v3.c Tue Dec 6 15:12:14 2016 (r309622) @@ -297,6 +297,13 @@ gic_v3_attach(device_t dev) } } + /* + * Read the Peripheral ID2 register. This is an implementation + * defined register, but seems to be implemented in all GICv3 + * parts and Linux expects it to be there. + */ + sc->gic_pidr2 = gic_d_read(sc, 4, GICD_PIDR2); + /* Get the number of supported interrupt identifier bits */ sc->gic_idbits = GICD_TYPER_IDBITS(typer); @@ -358,6 +365,21 @@ gic_v3_read_ivar(device_t dev, device_t *result = (uintptr_t)rman_get_virtual( sc->gic_redists.pcpu[PCPU_GET(cpuid)]); return (0); + case GIC_IVAR_HW_REV: + KASSERT( + GICR_PIDR2_ARCH(sc->gic_pidr2) == GICR_PIDR2_ARCH_GICv3 || + GICR_PIDR2_ARCH(sc->gic_pidr2) == GICR_PIDR2_ARCH_GICv4, + ("gic_v3_read_ivar: Invalid GIC architecture: %d (%.08X)", + GICR_PIDR2_ARCH(sc->gic_pidr2), sc->gic_pidr2)); + *result = GICR_PIDR2_ARCH(sc->gic_pidr2); + return (0); + case GIC_IVAR_BUS: + KASSERT(sc->gic_bus != GIC_BUS_UNKNOWN, + ("gic_v3_read_ivar: Unknown bus type")); + KASSERT(sc->gic_bus <= GIC_BUS_MAX, + ("gic_v3_read_ivar: Invalid bus type %u", sc->gic_bus)); + *result = sc->gic_bus; + return (0); } return (ENOENT); @@ -1101,7 +1123,7 @@ gic_v3_redist_find(struct gic_v3_softc * r_bsh = rman_get_bushandle(&r_res); pidr2 = bus_read_4(&r_res, GICR_PIDR2); - switch (pidr2 & GICR_PIDR2_ARCH_MASK) { + switch (GICR_PIDR2_ARCH(pidr2)) { case GICR_PIDR2_ARCH_GICv3: /* fall through */ case GICR_PIDR2_ARCH_GICv4: break; Modified: head/sys/arm64/arm64/gic_v3_fdt.c ============================================================================== --- head/sys/arm64/arm64/gic_v3_fdt.c Tue Dec 6 14:31:47 2016 (r309621) +++ head/sys/arm64/arm64/gic_v3_fdt.c Tue Dec 6 15:12:14 2016 (r309622) @@ -123,6 +123,7 @@ gic_v3_fdt_attach(device_t dev) sc = device_get_softc(dev); sc->dev = dev; + sc->gic_bus = GIC_BUS_FDT; /* * Recover number of the Re-Distributor regions. Modified: head/sys/arm64/arm64/gic_v3_reg.h ============================================================================== --- head/sys/arm64/arm64/gic_v3_reg.h Tue Dec 6 14:31:47 2016 (r309621) +++ head/sys/arm64/arm64/gic_v3_reg.h Tue Dec 6 15:12:14 2016 (r309622) @@ -80,9 +80,12 @@ #define GICD_PIDR1 0xFFE4 #define GICD_PIDR2 0xFFE8 +#define GICR_PIDR2_ARCH_SHIFT 4 #define GICR_PIDR2_ARCH_MASK 0xF0 -#define GICR_PIDR2_ARCH_GICv3 0x30 -#define GICR_PIDR2_ARCH_GICv4 0x40 +#define GICR_PIDR2_ARCH(x) \ + (((x) & GICR_PIDR2_ARCH_MASK) >> GICR_PIDR2_ARCH_SHIFT) +#define GICR_PIDR2_ARCH_GICv3 0x3 +#define GICR_PIDR2_ARCH_GICv4 0x4 #define GICD_PIDR3 0xFFEC Modified: head/sys/arm64/arm64/gic_v3_var.h ============================================================================== --- head/sys/arm64/arm64/gic_v3_var.h Tue Dec 6 14:31:47 2016 (r309621) +++ head/sys/arm64/arm64/gic_v3_var.h Tue Dec 6 15:12:14 2016 (r309622) @@ -68,6 +68,9 @@ struct gic_v3_softc { /* Re-Distributors */ struct gic_redists gic_redists; + uint32_t gic_pidr2; + u_int gic_bus; + u_int gic_nirqs; u_int gic_idbits;