diff options
author | Andrew Turner <andrew@FreeBSD.org> | 2016-12-06 15:12:14 +0000 |
---|---|---|
committer | Andrew Turner <andrew@FreeBSD.org> | 2016-12-06 15:12:14 +0000 |
commit | be04b41da2b489e3eace608f3ee745bcf7693b73 (patch) | |
tree | 8e22ad712e2b7450a90a18cf2c03f7707ad0a0a3 /sys/arm64/arm64/gic_v3.c | |
parent | ef32958e5ddeab559c6c6d7444ec134011acf16b (diff) | |
download | src-be04b41da2b489e3eace608f3ee745bcf7693b73.tar.gz src-be04b41da2b489e3eace608f3ee745bcf7693b73.zip |
Notes
Diffstat (limited to 'sys/arm64/arm64/gic_v3.c')
-rw-r--r-- | sys/arm64/arm64/gic_v3.c | 24 |
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; |