Page MenuHomeFreeBSD

D60116.id187980.diff
No OneTemporary

D60116.id187980.diff

diff --git a/sys/arm64/arm64/gicv5.c b/sys/arm64/arm64/gicv5.c
--- a/sys/arm64/arm64/gicv5.c
+++ b/sys/arm64/arm64/gicv5.c
@@ -1023,6 +1023,22 @@
isb();
}
+bool
+gicv5_has_virt_support(device_t dev)
+{
+ struct gicv5_softc *sc;
+ uint32_t idr0;
+
+ sc = device_get_softc(dev);
+ /*
+ * VIRT field is guaranteed to be identical between all IRS units.
+ * Arm GIC Architecture Specification (AES 0070) rule RJJPQJ.
+ */
+ idr0 = IRS_CFG_READ_4(sc->gic_irs[0], IRS_IDR0);
+
+ return (idr0 & IRS_IDR0_VIRT);
+}
+
bool
gicv5_add_child(device_t dev, struct gicv5_devinfo *di)
{
@@ -1099,8 +1115,10 @@
*result = sc->gic_bus;
return (0);
case GIC_IVAR_VGIC:
- /* TODO when we have vgic support */
- *result = 0;
+ di = device_get_ivars(child);
+ if (di == NULL)
+ return (EINVAL);
+ *result = di->di_is_vgic;
return (0);
case GIC_IVAR_SUPPORT_LPIS:
di = device_get_ivars(child);
diff --git a/sys/arm64/arm64/gicv5_acpi.c b/sys/arm64/arm64/gicv5_acpi.c
--- a/sys/arm64/arm64/gicv5_acpi.c
+++ b/sys/arm64/arm64/gicv5_acpi.c
@@ -411,6 +411,7 @@
ITS_REGISTER_SIZE);
di->di_base.di_irs = sc->gic_irs[0];
+ di->di_base.di_is_vgic = false;
gicv5_add_child(dev, &di->di_base);
@@ -440,6 +441,23 @@
acpi_unmap_table(madt);
+ if (gicv5_has_virt_support(dev)) {
+ device_t cdev;
+
+ cdev = device_add_child(dev, "vgic", DEVICE_UNIT_ANY);
+ if (cdev == NULL) {
+ device_printf(dev, "Could not add vgic child\n");
+ } else {
+ struct gic_v5_acpi_devinfo *di;
+
+ di = malloc(sizeof(*di), M_DEVBUF, M_WAITOK | M_ZERO);
+ resource_list_init(&di->di_base.di_rl);
+ di->di_base.di_irs = NULL;
+ di->di_base.di_is_vgic = true;
+ device_set_ivars(cdev, di);
+ }
+ }
+
bus_attach_children(dev);
}
diff --git a/sys/arm64/arm64/gicv5_fdt.c b/sys/arm64/arm64/gicv5_fdt.c
--- a/sys/arm64/arm64/gicv5_fdt.c
+++ b/sys/arm64/arm64/gicv5_fdt.c
@@ -97,6 +97,7 @@
di = malloc(sizeof(*di), M_DEVBUF, M_WAITOK | M_ZERO);
di->di_base.di_irs = irs;
+ di->di_base.di_is_vgic = false;
if (ofw_bus_gen_setup_devinfo(&di->di_dinfo, node)) {
if (bootverbose) {
device_printf(dev,
@@ -174,6 +175,23 @@
gicv5_fdt_add_child(dev, child, NULL, addr_cells, size_cells);
}
+
+ if (gicv5_has_virt_support(dev)) {
+ device_t cdev;
+
+ cdev = device_add_child(dev, "vgic", DEVICE_UNIT_ANY);
+ if (cdev == NULL) {
+ device_printf(dev, "Could not add vgic child\n");
+ } else {
+ struct gicv5_fdt_devinfo *di;
+
+ di = malloc(sizeof(*di), M_DEVBUF, M_WAITOK | M_ZERO);
+ resource_list_init(&di->di_base.di_rl);
+ di->di_base.di_irs = NULL;
+ di->di_base.di_is_vgic = true;
+ device_set_ivars(cdev, di);
+ }
+ }
}
static int
diff --git a/sys/arm64/arm64/gicv5var.h b/sys/arm64/arm64/gicv5var.h
--- a/sys/arm64/arm64/gicv5var.h
+++ b/sys/arm64/arm64/gicv5var.h
@@ -58,6 +58,7 @@
struct gicv5_devinfo {
struct resource_list di_rl;
struct gicv5_irs *di_irs;
+ bool di_is_vgic;
};
#define GICV5_IVAR_LPI_START 5000
@@ -66,6 +67,7 @@
void gicv5_attach(device_t);
bool gicv5_add_child(device_t, struct gicv5_devinfo *);
+bool gicv5_has_virt_support(device_t);
int gicv5_intr(void *);
void gicv5_irs_init(device_t, u_int, cpuset_t *);

File Metadata

Mime Type
text/plain
Expires
Wed, Sep 30, 12:41 PM (11 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39945299
Default Alt Text
D60116.id187980.diff (3 KB)

Event Timeline