summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/arm/arm/gic.c24
-rw-r--r--sys/arm64/arm64/gic.c24
2 files changed, 42 insertions, 6 deletions
diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c
index 124050e..e2295e4 100644
--- a/sys/arm/arm/gic.c
+++ b/sys/arm/arm/gic.c
@@ -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) */
diff --git a/sys/arm64/arm64/gic.c b/sys/arm64/arm64/gic.c
index 0a13b12..74349bc 100644
--- a/sys/arm64/arm64/gic.c
+++ b/sys/arm64/arm64/gic.c
@@ -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) */
OpenPOWER on IntegriCloud