Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107791214
D31768.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D31768.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D31768: Add support for gicv2m as a child of gicv3
Attached
Detach File
Event Timeline
Log In to Comment