aboutsummaryrefslogtreecommitdiff
path: root/sys/arm64/arm64/gic_v3.c
diff options
context:
space:
mode:
authorAndrew Turner <andrew@FreeBSD.org>2016-12-06 15:12:14 +0000
committerAndrew Turner <andrew@FreeBSD.org>2016-12-06 15:12:14 +0000
commitbe04b41da2b489e3eace608f3ee745bcf7693b73 (patch)
tree8e22ad712e2b7450a90a18cf2c03f7707ad0a0a3 /sys/arm64/arm64/gic_v3.c
parentef32958e5ddeab559c6c6d7444ec134011acf16b (diff)
downloadsrc-be04b41da2b489e3eace608f3ee745bcf7693b73.tar.gz
src-be04b41da2b489e3eace608f3ee745bcf7693b73.zip
Notes
Diffstat (limited to 'sys/arm64/arm64/gic_v3.c')
-rw-r--r--sys/arm64/arm64/gic_v3.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/sys/arm64/arm64/gic_v3.c b/sys/arm64/arm64/gic_v3.c
index 8c0161d6c8b5..ebdd23a35b03 100644
--- a/sys/arm64/arm64/gic_v3.c
+++ b/sys/arm64/arm64/gic_v3.c
@@ -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 child, int which, uintptr_t *result)
*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 *sc)
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;