Page MenuHomeFreeBSD

D31768.diff
No OneTemporary

D31768.diff

diff --git a/sys/arm64/arm64/gic_v3.c b/sys/arm64/arm64/gic_v3.c
--- a/sys/arm64/arm64/gic_v3.c
+++ b/sys/arm64/arm64/gic_v3.c
@@ -78,6 +78,7 @@
static bus_get_domain_t gic_v3_get_domain;
static bus_read_ivar_t gic_v3_read_ivar;
+static bus_write_ivar_t gic_v3_write_ivar;
static pic_disable_intr_t gic_v3_disable_intr;
static pic_enable_intr_t gic_v3_enable_intr;
@@ -113,6 +114,7 @@
/* Bus interface */
DEVMETHOD(bus_get_domain, gic_v3_get_domain),
DEVMETHOD(bus_read_ivar, gic_v3_read_ivar),
+ DEVMETHOD(bus_write_ivar, gic_v3_write_ivar),
/* Interrupt controller interface */
DEVMETHOD(pic_disable_intr, gic_v3_disable_intr),
@@ -242,6 +244,33 @@
bus_write_8(rdist, offset, val);
}
+static void
+gic_v3_reserve_msi_range(device_t dev, u_int start, u_int count)
+{
+ struct gic_v3_softc *sc;
+ int i;
+
+ sc = device_get_softc(dev);
+
+ KASSERT((start + count) < sc->gic_nirqs,
+ ("%s: Trying to allocate too many MSI IRQs: %d + %d > %d", __func__,
+ start, count, sc->gic_nirqs));
+ for (i = 0; i < count; i++) {
+ KASSERT(sc->gic_irqs[start + i].gi_isrc.isrc_handlers == 0,
+ ("%s: MSI interrupt %d already has a handler", __func__,
+ count + i));
+ KASSERT(sc->gic_irqs[start + i].gi_pol == INTR_POLARITY_CONFORM,
+ ("%s: MSI interrupt %d already has a polarity", __func__,
+ count + i));
+ KASSERT(sc->gic_irqs[start + i].gi_trig == INTR_TRIGGER_CONFORM,
+ ("%s: MSI interrupt %d already has a trigger", __func__,
+ count + i));
+ sc->gic_irqs[start + i].gi_pol = INTR_POLARITY_HIGH;
+ sc->gic_irqs[start + i].gi_trig = INTR_TRIGGER_EDGE;
+ sc->gic_irqs[start + i].gi_flags |= GI_FLAG_MSI;
+ }
+}
+
/*
* Device interface.
*/
@@ -332,15 +361,10 @@
}
}
+ mtx_init(&sc->gic_mbi_mtx, "GICv3 mbi lock", NULL, MTX_DEF);
if (sc->gic_mbi_start > 0) {
- /* Reserve these interrupts for MSI/MSI-X use */
- for (irq = sc->gic_mbi_start; irq <= sc->gic_mbi_end; irq++) {
- sc->gic_irqs[irq].gi_pol = INTR_POLARITY_HIGH;
- sc->gic_irqs[irq].gi_trig = INTR_TRIGGER_EDGE;
- sc->gic_irqs[irq].gi_flags |= GI_FLAG_MSI;
- }
-
- mtx_init(&sc->gic_mbi_mtx, "GICv3 mbi lock", NULL, MTX_DEF);
+ gic_v3_reserve_msi_range(dev, sc->gic_mbi_start,
+ sc->gic_mbi_end - sc->gic_mbi_start);
if (bootverbose) {
device_printf(dev, "using spi %u to %u\n", sc->gic_mbi_start,
@@ -442,6 +466,56 @@
KASSERT(sc->gic_bus <= GIC_BUS_MAX,
("gic_v3_read_ivar: Invalid bus type %u", sc->gic_bus));
*result = sc->gic_bus;
+ return (0);
+ case GIC_IVAR_MBI_START:
+ *result = sc->gic_mbi_start;
+ return (0);
+ case GIC_IVAR_MBI_COUNT:
+ *result = sc->gic_mbi_end - sc->gic_mbi_start;
+ return (0);
+ }
+
+ return (ENOENT);
+}
+
+static int
+gic_v3_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
+{
+ struct gic_v3_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ switch(which) {
+ case GICV3_IVAR_NIRQS:
+ case GICV3_IVAR_REDIST:
+ case GIC_IVAR_HW_REV:
+ case GIC_IVAR_BUS:
+ return (EINVAL);
+ case GIC_IVAR_MBI_START:
+ /*
+ * GIC_IVAR_MBI_START must be set once and first. This allows
+ * us to reserve the registers when GIC_IVAR_MBI_COUNT is set.
+ */
+ MPASS(sc->gic_mbi_start == 0);
+ MPASS(sc->gic_mbi_end == 0);
+ MPASS(value >= GIC_FIRST_SPI);
+ MPASS(value < sc->gic_nirqs);
+
+ sc->gic_mbi_start = value;
+ return (0);
+ case GIC_IVAR_MBI_COUNT:
+ MPASS(sc->gic_mbi_start != 0);
+ MPASS(sc->gic_mbi_end == 0);
+ MPASS(value >= sc->gic_mbi_start);
+ MPASS(value >= GIC_FIRST_SPI);
+
+ sc->gic_mbi_end = value - sc->gic_mbi_start;
+
+ MPASS(sc->gic_mbi_end <= sc->gic_nirqs);
+
+ /* Reserve these interrupts for MSI/MSI-X use */
+ gic_v3_reserve_msi_range(dev, sc->gic_mbi_start, value);
+
return (0);
}
diff --git a/sys/arm64/arm64/gic_v3_fdt.c b/sys/arm64/arm64/gic_v3_fdt.c
--- a/sys/arm64/arm64/gic_v3_fdt.c
+++ b/sys/arm64/arm64/gic_v3_fdt.c
@@ -143,7 +143,7 @@
if (ret % 2 == 0) {
/* Limit to a single range for now. */
sc->gic_mbi_start = mbi_ranges[0];
- sc->gic_mbi_end = mbi_ranges[0] + mbi_ranges[1] - 1;
+ sc->gic_mbi_end = mbi_ranges[0] + mbi_ranges[1];
} else {
if (bootverbose)
device_printf(dev, "Malformed mbi-ranges property\n");

File Metadata

Mime Type
text/plain
Expires
Sun, Jan 19, 5:40 AM (20 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15927269
Default Alt Text
D31768.diff (4 KB)

Event Timeline