|
@@ -247,11 +247,22 @@ static const VMStateDescription vmstate_gicv3 = {
|
|
};
|
|
};
|
|
|
|
|
|
void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
|
|
void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
|
|
- const MemoryRegionOps *ops)
|
|
|
|
|
|
+ const MemoryRegionOps *ops, Error **errp)
|
|
{
|
|
{
|
|
SysBusDevice *sbd = SYS_BUS_DEVICE(s);
|
|
SysBusDevice *sbd = SYS_BUS_DEVICE(s);
|
|
|
|
+ int rdist_capacity = 0;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
|
|
+ for (i = 0; i < s->nb_redist_regions; i++) {
|
|
|
|
+ rdist_capacity += s->redist_region_count[i];
|
|
|
|
+ }
|
|
|
|
+ if (rdist_capacity < s->num_cpu) {
|
|
|
|
+ error_setg(errp, "Capacity of the redist regions(%d) "
|
|
|
|
+ "is less than number of vcpus(%d)",
|
|
|
|
+ rdist_capacity, s->num_cpu);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
/* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
|
|
/* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
|
|
* GPIO array layout is thus:
|
|
* GPIO array layout is thus:
|
|
* [0..N-1] spi
|
|
* [0..N-1] spi
|
|
@@ -277,11 +288,18 @@ void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
|
|
|
|
|
|
memory_region_init_io(&s->iomem_dist, OBJECT(s), ops, s,
|
|
memory_region_init_io(&s->iomem_dist, OBJECT(s), ops, s,
|
|
"gicv3_dist", 0x10000);
|
|
"gicv3_dist", 0x10000);
|
|
- memory_region_init_io(&s->iomem_redist, OBJECT(s), ops ? &ops[1] : NULL, s,
|
|
|
|
- "gicv3_redist", 0x20000 * s->num_cpu);
|
|
|
|
-
|
|
|
|
sysbus_init_mmio(sbd, &s->iomem_dist);
|
|
sysbus_init_mmio(sbd, &s->iomem_dist);
|
|
- sysbus_init_mmio(sbd, &s->iomem_redist);
|
|
|
|
|
|
+
|
|
|
|
+ s->iomem_redist = g_new0(MemoryRegion, s->nb_redist_regions);
|
|
|
|
+ for (i = 0; i < s->nb_redist_regions; i++) {
|
|
|
|
+ char *name = g_strdup_printf("gicv3_redist_region[%d]", i);
|
|
|
|
+
|
|
|
|
+ memory_region_init_io(&s->iomem_redist[i], OBJECT(s),
|
|
|
|
+ ops ? &ops[1] : NULL, s, name,
|
|
|
|
+ s->redist_region_count[i] * GICV3_REDIST_SIZE);
|
|
|
|
+ sysbus_init_mmio(sbd, &s->iomem_redist[i]);
|
|
|
|
+ g_free(name);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
|
|
static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
|
|
@@ -363,6 +381,13 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void arm_gicv3_finalize(Object *obj)
|
|
|
|
+{
|
|
|
|
+ GICv3State *s = ARM_GICV3_COMMON(obj);
|
|
|
|
+
|
|
|
|
+ g_free(s->redist_region_count);
|
|
|
|
+}
|
|
|
|
+
|
|
static void arm_gicv3_common_reset(DeviceState *dev)
|
|
static void arm_gicv3_common_reset(DeviceState *dev)
|
|
{
|
|
{
|
|
GICv3State *s = ARM_GICV3_COMMON(dev);
|
|
GICv3State *s = ARM_GICV3_COMMON(dev);
|
|
@@ -467,6 +492,8 @@ static Property arm_gicv3_common_properties[] = {
|
|
DEFINE_PROP_UINT32("num-irq", GICv3State, num_irq, 32),
|
|
DEFINE_PROP_UINT32("num-irq", GICv3State, num_irq, 32),
|
|
DEFINE_PROP_UINT32("revision", GICv3State, revision, 3),
|
|
DEFINE_PROP_UINT32("revision", GICv3State, revision, 3),
|
|
DEFINE_PROP_BOOL("has-security-extensions", GICv3State, security_extn, 0),
|
|
DEFINE_PROP_BOOL("has-security-extensions", GICv3State, security_extn, 0),
|
|
|
|
+ DEFINE_PROP_ARRAY("redist-region-count", GICv3State, nb_redist_regions,
|
|
|
|
+ redist_region_count, qdev_prop_uint32, uint32_t),
|
|
DEFINE_PROP_END_OF_LIST(),
|
|
DEFINE_PROP_END_OF_LIST(),
|
|
};
|
|
};
|
|
|
|
|
|
@@ -488,6 +515,7 @@ static const TypeInfo arm_gicv3_common_type = {
|
|
.instance_size = sizeof(GICv3State),
|
|
.instance_size = sizeof(GICv3State),
|
|
.class_size = sizeof(ARMGICv3CommonClass),
|
|
.class_size = sizeof(ARMGICv3CommonClass),
|
|
.class_init = arm_gicv3_common_class_init,
|
|
.class_init = arm_gicv3_common_class_init,
|
|
|
|
+ .instance_finalize = arm_gicv3_finalize,
|
|
.abstract = true,
|
|
.abstract = true,
|
|
.interfaces = (InterfaceInfo []) {
|
|
.interfaces = (InterfaceInfo []) {
|
|
{ TYPE_ARM_LINUX_BOOT_IF },
|
|
{ TYPE_ARM_LINUX_BOOT_IF },
|