Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107915552
D32224.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
D32224.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D32224: Add a gic interface to allocate MSI interrupts
Attached
Detach File
Event Timeline
Log In to Comment