summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/arm/arm/gic.c16
-rw-r--r--sys/arm64/arm64/gic.c13
-rw-r--r--sys/arm64/arm64/gic.h1
3 files changed, 21 insertions, 9 deletions
diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c
index c55337e..501d56f 100644
--- a/sys/arm/arm/gic.c
+++ b/sys/arm/arm/gic.c
@@ -108,6 +108,11 @@ __FBSDID("$FreeBSD$");
#define GIC_LAST_PPI 31 /* core) peripheral interrupts. */
#define GIC_FIRST_SPI 32 /* Irqs 32+ are shared peripherals. */
+/* TYPER Registers */
+#define GICD_TYPER_SECURITYEXT 0x400
+#define GIC_SUPPORT_SECEXT(_sc) \
+ ((_sc->typer & GICD_TYPER_SECURITYEXT) == GICD_TYPER_SECURITYEXT)
+
/* First bit is a polarity bit (0 - low, 1 - high) */
#define GICD_ICFGR_POL_LOW (0 << 0)
#define GICD_ICFGR_POL_HIGH (1 << 0)
@@ -172,6 +177,7 @@ struct arm_gic_softc {
uint8_t ver;
struct mtx mutex;
uint32_t nirqs;
+ uint32_t typer;
#ifdef GIC_DEBUG_SPURIOUS
uint32_t last_irq[MAXCPU];
#endif
@@ -299,7 +305,7 @@ arm_gic_init_secondary(device_t dev)
gic_d_write_4(sc, GICD_IPRIORITYR(irq >> 2), 0);
/* Set all the interrupts to be in Group 0 (secure) */
- for (irq = 0; irq < sc->nirqs; irq += 32) {
+ for (irq = 0; GIC_SUPPORT_SECEXT(sc) && irq < sc->nirqs; irq += 32) {
gic_d_write_4(sc, GICD_IGROUPR(irq >> 5), 0);
}
@@ -336,7 +342,7 @@ arm_gic_init_secondary(device_t dev)
gic_d_write_4(sc, GICD_IPRIORITYR(i >> 2), 0);
/* Set all the interrupts to be in Group 0 (secure) */
- for (i = 0; i < sc->nirqs; i += 32) {
+ for (i = 0; GIC_SUPPORT_SECEXT(sc) && i < sc->nirqs; i += 32) {
gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0);
}
@@ -639,8 +645,8 @@ arm_gic_attach(device_t dev)
gic_d_write_4(sc, GICD_CTLR, 0x00);
/* Get the number of interrupts */
- nirqs = gic_d_read_4(sc, GICD_TYPER);
- nirqs = 32 * ((nirqs & 0x1f) + 1);
+ sc->typer = gic_d_read_4(sc, GICD_TYPER);
+ nirqs = 32 * ((sc->typer & 0x1f) + 1);
#ifdef INTRNG
if (arm_gic_register_isrcs(sc, nirqs)) {
@@ -686,7 +692,7 @@ arm_gic_attach(device_t dev)
}
/* Set all the interrupts to be in Group 0 (secure) */
- for (i = 0; i < sc->nirqs; i += 32) {
+ for (i = 0; GIC_SUPPORT_SECEXT(sc) && i < sc->nirqs; i += 32) {
gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0);
}
diff --git a/sys/arm64/arm64/gic.c b/sys/arm64/arm64/gic.c
index 2140086..68b7cab 100644
--- a/sys/arm64/arm64/gic.c
+++ b/sys/arm64/arm64/gic.c
@@ -94,6 +94,11 @@ __FBSDID("$FreeBSD$");
#define GIC_LAST_PPI 31 /* core) peripheral interrupts. */
#define GIC_FIRST_SPI 32 /* Irqs 32+ are shared peripherals. */
+/* TYPER Registers */
+#define GICD_TYPER_SECURITYEXT 0x400
+#define GIC_SUPPORT_SECEXT(_sc) \
+ ((_sc->typer & GICD_TYPER_SECURITYEXT) == GICD_TYPER_SECURITYEXT)
+
/* First bit is a polarity bit (0 - low, 1 - high) */
#define GICD_ICFGR_POL_LOW (0 << 0)
#define GICD_ICFGR_POL_HIGH (1 << 0)
@@ -164,7 +169,7 @@ gic_init_secondary(device_t dev)
gic_d_write_4(sc, GICD_IPRIORITYR(i >> 2), 0);
/* Set all the interrupts to be in Group 0 (secure) */
- for (i = 0; i < sc->nirqs; i += 32) {
+ for (i = 0; GIC_SUPPORT_SECEXT(sc) && i < sc->nirqs; i += 32) {
gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0);
}
@@ -221,8 +226,8 @@ arm_gic_attach(device_t dev)
gic_d_write_4(sc, GICD_CTLR, 0x00);
/* Get the number of interrupts */
- sc->nirqs = gic_d_read_4(sc, GICD_TYPER);
- sc->nirqs = 32 * ((sc->nirqs & 0x1f) + 1);
+ sc->typer = gic_d_read_4(sc, GICD_TYPER);
+ sc->nirqs = 32 * ((sc->typer & 0x1f) + 1);
arm_register_root_pic(dev, sc->nirqs);
@@ -257,7 +262,7 @@ arm_gic_attach(device_t dev)
}
/* Set all the interrupts to be in Group 0 (secure) */
- for (i = 0; i < sc->nirqs; i += 32) {
+ for (i = 0; GIC_SUPPORT_SECEXT(sc) && i < sc->nirqs; i += 32) {
gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0);
}
diff --git a/sys/arm64/arm64/gic.h b/sys/arm64/arm64/gic.h
index d22d43b..a8ba6a8 100644
--- a/sys/arm64/arm64/gic.h
+++ b/sys/arm64/arm64/gic.h
@@ -49,6 +49,7 @@ struct arm_gic_softc {
uint8_t ver;
struct mtx mutex;
uint32_t nirqs;
+ uint32_t typer;
};
DECLARE_CLASS(arm_gicv2m_driver);
OpenPOWER on IntegriCloud