aboutsummaryrefslogtreecommitdiff
path: root/hw/arm/virt.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/arm/virt.c')
-rw-r--r--hw/arm/virt.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index e5e7606946..9b9bc5091e 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -529,6 +529,7 @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
SysBusDevice *gicbusdev;
const char *gictype;
int type = vms->gic_version, i;
+ uint32_t nb_redist_regions = 0;
gictype = (type == 3) ? gicv3_class_name() : gic_class_name();
@@ -548,14 +549,28 @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
uint32_t redist0_count = MIN(smp_cpus, redist0_capacity);
- qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1);
+ nb_redist_regions = virt_gicv3_redist_region_count(vms);
+
+ qdev_prop_set_uint32(gicdev, "len-redist-region-count",
+ nb_redist_regions);
qdev_prop_set_uint32(gicdev, "redist-region-count[0]", redist0_count);
+
+ if (nb_redist_regions == 2) {
+ uint32_t redist1_capacity =
+ vms->memmap[VIRT_GIC_REDIST2].size / GICV3_REDIST_SIZE;
+
+ qdev_prop_set_uint32(gicdev, "redist-region-count[1]",
+ MIN(smp_cpus - redist0_count, redist1_capacity));
+ }
}
qdev_init_nofail(gicdev);
gicbusdev = SYS_BUS_DEVICE(gicdev);
sysbus_mmio_map(gicbusdev, 0, vms->memmap[VIRT_GIC_DIST].base);
if (type == 3) {
sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_REDIST].base);
+ if (nb_redist_regions == 2) {
+ sysbus_mmio_map(gicbusdev, 2, vms->memmap[VIRT_GIC_REDIST2].base);
+ }
} else {
sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_CPU].base);
}
@@ -1351,6 +1366,7 @@ static void machvirt_init(MachineState *machine)
*/
if (vms->gic_version == 3) {
virt_max_cpus = vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
+ virt_max_cpus += vms->memmap[VIRT_GIC_REDIST2].size / GICV3_REDIST_SIZE;
} else {
virt_max_cpus = GIC_NCPU;
}