Page MenuHomeFreeBSD

D32224.diff
No OneTemporary

D32224.diff

diff --git a/sys/arm/arm/gic.h b/sys/arm/arm/gic.h
--- a/sys/arm/arm/gic.h
+++ b/sys/arm/arm/gic.h
@@ -63,10 +63,6 @@
int nranges;
struct arm_gic_range * ranges;
-
- u_int sc_spi_start;
- u_int sc_spi_end;
- u_int sc_spi_count;
};
DECLARE_CLASS(arm_gic_driver);
@@ -74,6 +70,8 @@
struct arm_gicv2m_softc {
struct resource *sc_mem;
uintptr_t sc_xref;
+ u_int sc_spi_start;
+ u_int sc_spi_count;
};
DECLARE_CLASS(arm_gicv2m_driver);
diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c
--- a/sys/arm/arm/gic.c
+++ b/sys/arm/arm/gic.c
@@ -75,6 +75,7 @@
#include <arm/arm/gic.h>
#include <arm/arm/gic_common.h>
+#include "gic_if.h"
#include "pic_if.h"
#include "msi_if.h"
@@ -501,12 +502,6 @@
("arm_gic_read_ivar: Invalid bus type %u", sc->gic_bus));
*result = sc->gic_bus;
return (0);
- case GIC_IVAR_MBI_START:
- *result = sc->sc_spi_start;
- return (0);
- case GIC_IVAR_MBI_COUNT:
- *result = sc->sc_spi_count;
- return (0);
}
return (ENOENT);
@@ -523,32 +518,6 @@
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->sc_spi_start == 0);
- MPASS(sc->sc_spi_count == 0);
- MPASS(value >= GIC_FIRST_SPI);
- MPASS(value < sc->nirqs);
-
- sc->sc_spi_start = value;
- return (0);
- case GIC_IVAR_MBI_COUNT:
- MPASS(sc->sc_spi_start != 0);
- MPASS(sc->sc_spi_count == 0);
-
- sc->sc_spi_count = value;
- sc->sc_spi_end = sc->sc_spi_start + sc->sc_spi_count;
-
- MPASS(sc->sc_spi_end <= sc->nirqs);
-
- /* Reserve these interrupts for MSI/MSI-X use */
- arm_gic_reserve_msi_range(dev, sc->sc_spi_start,
- sc->sc_spi_count);
-
- return (0);
}
return (ENOENT);
@@ -1044,8 +1013,8 @@
#endif
static int
-arm_gic_alloc_msi(device_t dev, device_t child, int count, int maxcount,
- device_t *pic, struct intr_irqsrc **srcs)
+arm_gic_alloc_msi(device_t dev, u_int mbi_start, u_int mbi_count, int count,
+ int maxcount, struct intr_irqsrc **isrc)
{
struct arm_gic_softc *sc;
int i, irq, end_irq;
@@ -1059,7 +1028,7 @@
mtx_lock_spin(&sc->mutex);
found = false;
- for (irq = sc->sc_spi_start; irq < sc->sc_spi_end; irq++) {
+ for (irq = mbi_start; irq < mbi_start + mbi_count; irq++) {
/* Start on an aligned interrupt */
if ((irq & (maxcount - 1)) != 0)
continue;
@@ -1070,7 +1039,7 @@
/* Check this range is valid */
for (end_irq = irq; end_irq != irq + count; end_irq++) {
/* No free interrupts */
- if (end_irq == sc->sc_spi_end) {
+ if (end_irq == mbi_start + mbi_count) {
found = false;
break;
}
@@ -1090,7 +1059,7 @@
}
/* Not enough interrupts were found */
- if (!found || irq == sc->sc_spi_end) {
+ if (!found || irq == mbi_start + mbi_count) {
mtx_unlock_spin(&sc->mutex);
return (ENXIO);
}
@@ -1102,15 +1071,13 @@
mtx_unlock_spin(&sc->mutex);
for (i = 0; i < count; i++)
- srcs[i] = (struct intr_irqsrc *)&sc->gic_irqs[irq + i];
- *pic = dev;
+ isrc[i] = (struct intr_irqsrc *)&sc->gic_irqs[irq + i];
return (0);
}
static int
-arm_gic_release_msi(device_t dev, device_t child, int count,
- struct intr_irqsrc **isrc)
+arm_gic_release_msi(device_t dev, int count, struct intr_irqsrc **isrc)
{
struct arm_gic_softc *sc;
struct gic_irqsrc *gi;
@@ -1134,8 +1101,8 @@
}
static int
-arm_gic_alloc_msix(device_t dev, device_t child, device_t *pic,
- struct intr_irqsrc **isrcp)
+arm_gic_alloc_msix(device_t dev, u_int mbi_start, u_int mbi_count,
+ struct intr_irqsrc **isrc)
{
struct arm_gic_softc *sc;
int irq;
@@ -1144,14 +1111,14 @@
mtx_lock_spin(&sc->mutex);
/* Find an unused interrupt */
- for (irq = sc->sc_spi_start; irq < sc->sc_spi_end; irq++) {
+ for (irq = mbi_start; irq < mbi_start + mbi_count; irq++) {
KASSERT((sc->gic_irqs[irq].gi_flags & GI_FLAG_MSI) != 0,
("%s: Non-MSI interrupt found", __func__));
if ((sc->gic_irqs[irq].gi_flags & GI_FLAG_MSI_USED) == 0)
break;
}
/* No free interrupt was found */
- if (irq == sc->sc_spi_end) {
+ if (irq == mbi_start + mbi_count) {
mtx_unlock_spin(&sc->mutex);
return (ENXIO);
}
@@ -1160,14 +1127,13 @@
sc->gic_irqs[irq].gi_flags |= GI_FLAG_MSI_USED;
mtx_unlock_spin(&sc->mutex);
- *isrcp = (struct intr_irqsrc *)&sc->gic_irqs[irq];
- *pic = dev;
+ *isrc = (struct intr_irqsrc *)&sc->gic_irqs[irq];
return (0);
}
static int
-arm_gic_release_msix(device_t dev, device_t child, struct intr_irqsrc *isrc)
+arm_gic_release_msix(device_t dev, struct intr_irqsrc *isrc)
{
struct arm_gic_softc *sc;
struct gic_irqsrc *gi;
@@ -1211,11 +1177,12 @@
DEVMETHOD(pic_ipi_setup, arm_gic_ipi_setup),
#endif
- /* MSI/MSI-X */
- DEVMETHOD(msi_alloc_msi, arm_gic_alloc_msi),
- DEVMETHOD(msi_release_msi, arm_gic_release_msi),
- DEVMETHOD(msi_alloc_msix, arm_gic_alloc_msix),
- DEVMETHOD(msi_release_msix, arm_gic_release_msix),
+ /* GIC */
+ DEVMETHOD(gic_reserve_msi_range, arm_gic_reserve_msi_range),
+ DEVMETHOD(gic_alloc_msi, arm_gic_alloc_msi),
+ DEVMETHOD(gic_release_msi, arm_gic_release_msi),
+ DEVMETHOD(gic_alloc_msix, arm_gic_alloc_msix),
+ DEVMETHOD(gic_release_msix, arm_gic_release_msix),
{ 0, 0 }
};
@@ -1238,7 +1205,6 @@
{
struct arm_gicv2m_softc *sc;
uint32_t typer;
- u_int spi_start, spi_count;
int rid;
sc = device_get_softc(dev);
@@ -1252,16 +1218,18 @@
}
typer = bus_read_4(sc->sc_mem, GICV2M_MSI_TYPER);
- spi_start = MSI_TYPER_SPI_BASE(typer);
- spi_count = MSI_TYPER_SPI_COUNT(typer);
- gic_set_mbi_start(dev, spi_start);
- gic_set_mbi_count(dev, spi_count);
+ sc->sc_spi_start = MSI_TYPER_SPI_BASE(typer);
+ sc->sc_spi_count = MSI_TYPER_SPI_COUNT(typer);
+
+ /* Reserve these interrupts for MSI/MSI-X use */
+ GIC_RESERVE_MSI_RANGE(device_get_parent(dev), sc->sc_spi_start,
+ sc->sc_spi_count);
intr_msi_register(dev, sc->sc_xref);
if (bootverbose)
- device_printf(dev, "using spi %u to %u\n", spi_start,
- spi_start + spi_count - 1);
+ device_printf(dev, "using spi %u to %u\n", sc->sc_spi_start,
+ sc->sc_spi_start + sc->sc_spi_count - 1);
return (0);
}
@@ -1270,28 +1238,47 @@
arm_gicv2m_alloc_msi(device_t dev, device_t child, int count, int maxcount,
device_t *pic, struct intr_irqsrc **srcs)
{
- return (MSI_ALLOC_MSI(device_get_parent(dev), child, count, maxcount,
- pic, srcs));
+ struct arm_gicv2m_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+ error = GIC_ALLOC_MSI(device_get_parent(dev), sc->sc_spi_start,
+ sc->sc_spi_count, count, maxcount, srcs);
+ if (error != 0)
+ return (error);
+
+ *pic = dev;
+ return (0);
}
static int
arm_gicv2m_release_msi(device_t dev, device_t child, int count,
struct intr_irqsrc **isrc)
{
- return (MSI_RELEASE_MSI(device_get_parent(dev), child, count, isrc));
+ return (GIC_RELEASE_MSI(device_get_parent(dev), count, isrc));
}
static int
arm_gicv2m_alloc_msix(device_t dev, device_t child, device_t *pic,
struct intr_irqsrc **isrcp)
{
- return (MSI_ALLOC_MSIX(device_get_parent(dev), child, pic, isrcp));
+ struct arm_gicv2m_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+ error = GIC_ALLOC_MSIX(device_get_parent(dev), sc->sc_spi_start,
+ sc->sc_spi_count, isrcp);
+ if (error != 0)
+ return (error);
+
+ *pic = dev;
+ return (0);
}
static int
arm_gicv2m_release_msix(device_t dev, device_t child, struct intr_irqsrc *isrc)
{
- return (MSI_RELEASE_MSIX(device_get_parent(dev), child, isrc));
+ return (GIC_RELEASE_MSIX(device_get_parent(dev), isrc));
}
static int
diff --git a/sys/arm/arm/gic_common.h b/sys/arm/arm/gic_common.h
--- a/sys/arm/arm/gic_common.h
+++ b/sys/arm/arm/gic_common.h
@@ -33,8 +33,6 @@
#define GIC_IVAR_HW_REV 500
#define GIC_IVAR_BUS 501
-#define GIC_IVAR_MBI_START 510
-#define GIC_IVAR_MBI_COUNT 511
/* GIC_IVAR_BUS values */
#define GIC_BUS_UNKNOWN 0
@@ -44,8 +42,6 @@
__BUS_ACCESSOR(gic, hw_rev, GIC, HW_REV, u_int);
__BUS_ACCESSOR(gic, bus, GIC, BUS, u_int);
-__BUS_ACCESSOR(gic, mbi_start, GIC, MBI_START, u_int);
-__BUS_ACCESSOR(gic, mbi_count, GIC, MBI_COUNT, u_int);
/* Software Generated Interrupts */
#define GIC_FIRST_SGI 0 /* Irqs 0-15 are SGIs/IPIs. */
diff --git a/sys/arm/arm/gic_if.m b/sys/arm/arm/gic_if.m
new file mode 100644
--- /dev/null
+++ b/sys/arm/arm/gic_if.m
@@ -0,0 +1,39 @@
+
+INTERFACE gic;
+
+HEADER {
+ struct intr_irqsrc;
+};
+
+METHOD void reserve_msi_range {
+ device_t dev;
+ u_int mbi_start;
+ u_int mbi_count;
+};
+
+METHOD int alloc_msi {
+ device_t dev;
+ u_int mbi_start;
+ u_int mbi_count;
+ int count;
+ int maxcount;
+ struct intr_irqsrc **isrc;
+};
+
+METHOD int release_msi {
+ device_t dev;
+ int count;
+ struct intr_irqsrc **isrc;
+};
+
+METHOD int alloc_msix {
+ device_t dev;
+ u_int mbi_start;
+ u_int mbi_count;
+ struct intr_irqsrc **isrc;
+};
+
+METHOD int release_msix {
+ device_t dev;
+ struct intr_irqsrc *isrc;
+};
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
@@ -69,6 +69,7 @@
#include <dev/acpica/acpivar.h>
#endif
+#include "gic_if.h"
#include "pic_if.h"
#include "msi_if.h"
@@ -95,6 +96,12 @@
static pic_ipi_setup_t gic_v3_ipi_setup;
#endif
+static gic_reserve_msi_range_t gic_v3_reserve_msi_range;
+static gic_alloc_msi_t gic_v3_gic_alloc_msi;
+static gic_release_msi_t gic_v3_gic_release_msi;
+static gic_alloc_msix_t gic_v3_gic_alloc_msix;
+static gic_release_msix_t gic_v3_gic_release_msix;
+
static msi_alloc_msi_t gic_v3_alloc_msi;
static msi_release_msi_t gic_v3_release_msi;
static msi_alloc_msix_t gic_v3_alloc_msix;
@@ -139,6 +146,13 @@
DEVMETHOD(msi_release_msix, gic_v3_release_msix),
DEVMETHOD(msi_map_msi, gic_v3_map_msi),
+ /* GIC */
+ DEVMETHOD(gic_reserve_msi_range, gic_v3_reserve_msi_range),
+ DEVMETHOD(gic_alloc_msi, gic_v3_gic_alloc_msi),
+ DEVMETHOD(gic_release_msi, gic_v3_gic_release_msi),
+ DEVMETHOD(gic_alloc_msix, gic_v3_gic_alloc_msix),
+ DEVMETHOD(gic_release_msix, gic_v3_gic_release_msix),
+
/* End */
DEVMETHOD_END
};
@@ -467,12 +481,6 @@
("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);
@@ -491,30 +499,6 @@
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);
-
- 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);
}
return (ENOENT);
@@ -1385,8 +1369,8 @@
*/
static int
-gic_v3_alloc_msi(device_t dev, device_t child, int count, int maxcount,
- device_t *pic, struct intr_irqsrc **srcs)
+gic_v3_gic_alloc_msi(device_t dev, u_int mbi_start, u_int mbi_count,
+ int count, int maxcount, struct intr_irqsrc **isrc)
{
struct gic_v3_softc *sc;
int i, irq, end_irq;
@@ -1400,7 +1384,7 @@
mtx_lock(&sc->gic_mbi_mtx);
found = false;
- for (irq = sc->gic_mbi_start; irq < sc->gic_mbi_end; irq++) {
+ for (irq = mbi_start; irq < mbi_start + mbi_count; irq++) {
/* Start on an aligned interrupt */
if ((irq & (maxcount - 1)) != 0)
continue;
@@ -1411,7 +1395,7 @@
/* Check this range is valid */
for (end_irq = irq; end_irq != irq + count; end_irq++) {
/* No free interrupts */
- if (end_irq == sc->gic_mbi_end) {
+ if (end_irq == mbi_start + mbi_count) {
found = false;
break;
}
@@ -1431,7 +1415,7 @@
}
/* Not enough interrupts were found */
- if (!found || irq == sc->gic_mbi_end) {
+ if (!found || irq == mbi_start + mbi_count) {
mtx_unlock(&sc->gic_mbi_mtx);
return (ENXIO);
}
@@ -1443,15 +1427,13 @@
mtx_unlock(&sc->gic_mbi_mtx);
for (i = 0; i < count; i++)
- srcs[i] = (struct intr_irqsrc *)&sc->gic_irqs[irq + i];
- *pic = dev;
+ isrc[i] = (struct intr_irqsrc *)&sc->gic_irqs[irq + i];
return (0);
}
static int
-gic_v3_release_msi(device_t dev, device_t child, int count,
- struct intr_irqsrc **isrc)
+gic_v3_gic_release_msi(device_t dev, int count, struct intr_irqsrc **isrc)
{
struct gic_v3_softc *sc;
struct gic_v3_irqsrc *gi;
@@ -1475,7 +1457,7 @@
}
static int
-gic_v3_alloc_msix(device_t dev, device_t child, device_t *pic,
+gic_v3_gic_alloc_msix(device_t dev, u_int mbi_start, u_int mbi_count,
struct intr_irqsrc **isrcp)
{
struct gic_v3_softc *sc;
@@ -1485,14 +1467,14 @@
mtx_lock(&sc->gic_mbi_mtx);
/* Find an unused interrupt */
- for (irq = sc->gic_mbi_start; irq < sc->gic_mbi_end; irq++) {
+ for (irq = mbi_start; irq < mbi_start + mbi_count; irq++) {
KASSERT((sc->gic_irqs[irq].gi_flags & GI_FLAG_MSI) != 0,
("%s: Non-MSI interrupt found", __func__));
if ((sc->gic_irqs[irq].gi_flags & GI_FLAG_MSI_USED) == 0)
break;
}
/* No free interrupt was found */
- if (irq == sc->gic_mbi_end) {
+ if (irq == mbi_start + mbi_count) {
mtx_unlock(&sc->gic_mbi_mtx);
return (ENXIO);
}
@@ -1502,13 +1484,12 @@
mtx_unlock(&sc->gic_mbi_mtx);
*isrcp = (struct intr_irqsrc *)&sc->gic_irqs[irq];
- *pic = dev;
return (0);
}
static int
-gic_v3_release_msix(device_t dev, device_t child, struct intr_irqsrc *isrc)
+gic_v3_gic_release_msix(device_t dev, struct intr_irqsrc *isrc)
{
struct gic_v3_softc *sc;
struct gic_v3_irqsrc *gi;
@@ -1526,6 +1507,54 @@
return (0);
}
+static int
+gic_v3_alloc_msi(device_t dev, device_t child, int count, int maxcount,
+ device_t *pic, struct intr_irqsrc **isrc)
+{
+ struct gic_v3_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+ error = gic_v3_gic_alloc_msi(dev, sc->gic_mbi_start,
+ sc->gic_mbi_end - sc->gic_mbi_start, count, maxcount, isrc);
+ if (error != 0)
+ return (error);
+
+ *pic = dev;
+ return (0);
+}
+
+static int
+gic_v3_release_msi(device_t dev, device_t child, int count,
+ struct intr_irqsrc **isrc)
+{
+ return (gic_v3_gic_release_msi(dev, count, isrc));
+}
+
+static int
+gic_v3_alloc_msix(device_t dev, device_t child, device_t *pic,
+ struct intr_irqsrc **isrc)
+{
+ struct gic_v3_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+ error = gic_v3_gic_alloc_msix(dev, sc->gic_mbi_start,
+ sc->gic_mbi_end - sc->gic_mbi_start, isrc);
+ if (error != 0)
+ return (error);
+
+ *pic = dev;
+
+ return (0);
+}
+
+static int
+gic_v3_release_msix(device_t dev, device_t child, struct intr_irqsrc *isrc)
+{
+ return (gic_v3_gic_release_msix(dev, isrc));
+}
+
static int
gic_v3_map_msi(device_t dev, device_t child, struct intr_irqsrc *isrc,
uint64_t *addr, uint32_t *data)
diff --git a/sys/conf/files.arm b/sys/conf/files.arm
--- a/sys/conf/files.arm
+++ b/sys/conf/files.arm
@@ -32,6 +32,7 @@
arm/arm/generic_timer.c optional generic_timer
arm/arm/gic.c optional gic
arm/arm/gic_fdt.c optional gic fdt
+arm/arm/gic_if.m optional gic
arm/arm/identcpu-v6.c standard
arm/arm/in_cksum.c optional inet | inet6
arm/arm/in_cksum_arm.S optional inet | inet6
diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64
--- a/sys/conf/files.arm64
+++ b/sys/conf/files.arm64
@@ -20,6 +20,7 @@
arm/arm/gic.c standard
arm/arm/gic_acpi.c optional acpi
arm/arm/gic_fdt.c optional fdt
+arm/arm/gic_if.m standard
arm/arm/pmu.c standard
arm/arm/pmu_fdt.c optional fdt
arm64/acpica/acpi_iort.c optional acpi

File Metadata

Mime Type
text/plain
Expires
Mon, Jan 20, 9:07 AM (20 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15976317
Default Alt Text
D32224.diff (15 KB)

Event Timeline