Page MenuHomeFreeBSD

D36590.diff
No OneTemporary

D36590.diff

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,6 +33,7 @@
#define GIC_IVAR_HW_REV 500
#define GIC_IVAR_BUS 501
+#define GIC_IVAR_VGIC 502
/* GIC_IVAR_BUS values */
#define GIC_BUS_UNKNOWN 0
@@ -42,6 +43,7 @@
__BUS_ACCESSOR(gic, hw_rev, GIC, HW_REV, u_int);
__BUS_ACCESSOR(gic, bus, GIC, BUS, u_int);
+__BUS_ACCESSOR(gic, vgic, GIC, VGIC, u_int);
/* Software Generated Interrupts */
#define GIC_FIRST_SGI 0 /* Irqs 0-15 are SGIs/IPIs. */
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
@@ -456,6 +456,7 @@
gic_v3_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct gic_v3_softc *sc;
+ struct gic_v3_devinfo *di;
sc = device_get_softc(dev);
@@ -481,6 +482,12 @@
("gic_v3_read_ivar: Invalid bus type %u", sc->gic_bus));
*result = sc->gic_bus;
return (0);
+ case GIC_IVAR_VGIC:
+ di = device_get_ivars(child);
+ if (di == NULL)
+ return (EINVAL);
+ *result = di->is_vgic;
+ return (0);
}
return (ENOENT);
diff --git a/sys/arm64/arm64/gic_v3_acpi.c b/sys/arm64/arm64/gic_v3_acpi.c
--- a/sys/arm64/arm64/gic_v3_acpi.c
+++ b/sys/arm64/arm64/gic_v3_acpi.c
@@ -48,6 +48,9 @@
#include "gic_v3_reg.h"
#include "gic_v3_var.h"
+#define GICV3_PRIV_VGIC 0x80000000
+#define GICV3_PRIV_FLAGS 0x80000000
+
struct gic_v3_acpi_devinfo {
struct gic_v3_devinfo di_gic_dinfo;
struct resource_list di_rl;
@@ -86,6 +89,7 @@
ACPI_MADT_GENERIC_DISTRIBUTOR *dist;
int count;
bool rdist_use_gicc;
+ bool have_vgic;
};
static void
@@ -152,6 +156,8 @@
BUS_SET_RESOURCE(madt_data->parent, madt_data->dev,
SYS_RES_MEMORY, madt_data->count, intr->GicrBaseAddress,
count);
+ if (intr->VgicInterrupt == 0)
+ madt_data->have_vgic = false;
default:
break;
@@ -164,6 +170,7 @@
struct madt_table_data madt_data;
ACPI_TABLE_MADT *madt;
vm_paddr_t physaddr;
+ uintptr_t private;
device_t dev;
physaddr = acpi_find_table(ACPI_SIG_MADT);
@@ -210,6 +217,7 @@
madt_data.dev = dev;
madt_data.rdist_use_gicc = false;
+ madt_data.have_vgic = true;
acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length,
rdist_map, &madt_data);
if (madt_data.count == 0) {
@@ -222,7 +230,12 @@
rdist_map, &madt_data);
}
- acpi_set_private(dev, (void *)(uintptr_t)madt_data.dist->Version);
+ private = madt_data.dist->Version;
+ /* Flag that the VGIC is in use */
+ if (madt_data.have_vgic)
+ private |= GICV3_PRIV_VGIC;
+
+ acpi_set_private(dev, (void *)private);
out:
acpi_unmap_table(madt);
@@ -232,7 +245,7 @@
gic_v3_acpi_probe(device_t dev)
{
- switch((uintptr_t)acpi_get_private(dev)) {
+ switch((uintptr_t)acpi_get_private(dev) & ~GICV3_PRIV_FLAGS) {
case ACPI_MADT_GIC_VERSION_V3:
case ACPI_MADT_GIC_VERSION_V4:
break;
@@ -390,9 +403,14 @@
static void
gic_v3_acpi_bus_attach(device_t dev)
{
+ struct gic_v3_acpi_devinfo *di;
+ struct gic_v3_softc *sc;
ACPI_TABLE_MADT *madt;
+ device_t child;
vm_paddr_t physaddr;
+ sc = device_get_softc(dev);
+
physaddr = acpi_find_table(ACPI_SIG_MADT);
if (physaddr == 0)
return;
@@ -405,6 +423,20 @@
acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length,
gic_v3_add_children, dev);
+ /* Add the vgic child if needed */
+ if (((uintptr_t)acpi_get_private(dev) & GICV3_PRIV_FLAGS) != 0) {
+ child = device_add_child(dev, "vgic", -1);
+ if (child == NULL) {
+ device_printf(dev, "Could not add vgic child\n");
+ } else {
+ di = malloc(sizeof(*di), M_GIC_V3, M_WAITOK | M_ZERO);
+ resource_list_init(&di->di_rl);
+ di->di_gic_dinfo.gic_domain = -1;
+ di->di_gic_dinfo.is_vgic = 1;
+ sc->gic_nchildren++;
+ device_set_ivars(child, di);
+ }
+ }
acpi_unmap_table(madt);
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
@@ -212,9 +212,10 @@
gic_v3_fdt_print_child(device_t bus, device_t child)
{
struct gic_v3_ofw_devinfo *di = device_get_ivars(child);
- struct resource_list *rl = &di->di_rl;
+ struct resource_list *rl;
int retval = 0;
+ rl = &di->di_rl;
retval += bus_print_child_header(bus, child);
retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx");
retval += bus_print_child_footer(bus, child);
@@ -228,6 +229,8 @@
struct gic_v3_ofw_devinfo *di;
di = device_get_ivars(child);
+ if (di->di_gic_dinfo.is_vgic)
+ return (NULL);
return (&di->di_dinfo);
}
@@ -352,5 +355,23 @@
}
}
+ /*
+ * If there is a vgic maintanance interupt add a virtual gic
+ * child so we can use this in the vmm module for bhyve.
+ */
+ if (OF_hasprop(parent, "interrupts")) {
+ child = device_add_child(dev, "vgic", -1);
+ if (child == NULL) {
+ device_printf(dev, "Could not add vgic child\n");
+ } else {
+ di = malloc(sizeof(*di), M_GIC_V3, M_WAITOK | M_ZERO);
+ resource_list_init(&di->di_rl);
+ di->di_gic_dinfo.gic_domain = -1;
+ di->di_gic_dinfo.is_vgic = 1;
+ device_set_ivars(child, di);
+ sc->gic_nchildren++;
+ }
+ }
+
return (bus_generic_attach(dev));
}
diff --git a/sys/arm64/arm64/gic_v3_var.h b/sys/arm64/arm64/gic_v3_var.h
--- a/sys/arm64/arm64/gic_v3_var.h
+++ b/sys/arm64/arm64/gic_v3_var.h
@@ -89,6 +89,7 @@
struct gic_v3_devinfo {
int gic_domain;
int msi_xref;
+ int is_vgic;
};
#define GIC_INTR_ISRC(sc, irq) (&sc->gic_irqs[irq].gi_isrc)

File Metadata

Mime Type
text/plain
Expires
Tue, Jan 28, 2:18 AM (10 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16238704
Default Alt Text
D36590.diff (5 KB)

Event Timeline