Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108651180
D36590.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D36590.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D36590: Teach the GICv3 driver about a vgic child
Attached
Detach File
Event Timeline
Log In to Comment