hw/arm/virt: Pull "wire CPU interrupts" out of create_gic()
create_gic() is quite long and mixes GICv2 and GICv3 even though they're mostly different in their creation. As a preliminary to splitting it up, pull out the "wire the CPU interrupts to the GIC PPI inputs" code out into its own function. This is a long and self-contained piece of code that is the main thing that we need to do basically the same way for GICv2 and GICv3. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260327111700.795099-59-peter.maydell@linaro.org
Peter Maydell committed
Mar 27, 2026 at 11:16 UTC
a7a9b822be07dd7c907182366b90ef5c0990b0c9
1 file changed
+68
-58
hw/arm/virt.c
+68
-58
@@ -1120,13 +1120,79 @@ static bool gicv3_nmi_present(VirtMachineState *vms)
1120
(vms->gic_version != VIRT_GIC_VERSION_2);
1121
}
1122
1123
+static void gic_connect_ppis(VirtMachineState *vms)
1124
+{
1125
+ /*
1126
+ * Wire the outputs from each CPU's generic timer and the GICv3
1127
+ * maintenance interrupt signal to the appropriate GIC PPI inputs,
1128
+ * and the GIC's IRQ/FIQ/VIRQ/VFIQ/NMI/VINMI interrupt outputs to the
1129
+ * CPU's inputs.
1130
+ */
1131
+ MachineState *ms = MACHINE(vms);
1132
+ unsigned int smp_cpus = ms->smp.cpus;
1133
+ SysBusDevice *gicbusdev = SYS_BUS_DEVICE(vms->gic);
1134
+
1135
+ for (int i = 0; i < smp_cpus; i++) {
1136
+ DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
1137
+ int intidbase = NUM_IRQS + i * GIC_INTERNAL;
1138
+ /*
1139
+ * Mapping from the output timer irq lines from the CPU to the
1140
+ * GIC PPI inputs we use for the virt board.
1141
+ */
1142
+ const int timer_irq[] = {
1143
+ [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,
1144
+ [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
1145
+ [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
1146
+ [GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
1147
+ [GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
1148
+ [GTIMER_S_EL2_PHYS] = ARCH_TIMER_S_EL2_IRQ,
1149
+ [GTIMER_S_EL2_VIRT] = ARCH_TIMER_S_EL2_VIRT_IRQ,
1150
+ };
1151
+
1152
+ for (unsigned irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
1153
+ qdev_connect_gpio_out(cpudev, irq,
1154
+ qdev_get_gpio_in(vms->gic,
1155
+ intidbase + timer_irq[irq]));
1156
+ }
1157
+
1158
+ if (vms->gic_version != VIRT_GIC_VERSION_2) {
1159
+ qemu_irq irq = qdev_get_gpio_in(vms->gic,
1160
+ intidbase + ARCH_GIC_MAINT_IRQ);
1161
+ qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
1162
+ 0, irq);
1163
+ } else if (vms->virt) {
1164
+ qemu_irq irq = qdev_get_gpio_in(vms->gic,
1165
+ intidbase + ARCH_GIC_MAINT_IRQ);
1166
+ sysbus_connect_irq(gicbusdev, i + 4 * smp_cpus, irq);
1167
+ }
1168
+
1169
+ qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
1170
+ qdev_get_gpio_in(vms->gic, intidbase
1171
+ + VIRTUAL_PMU_IRQ));
1172
+
1173
+ sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
1174
+ sysbus_connect_irq(gicbusdev, i + smp_cpus,
1175
+ qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
1176
+ sysbus_connect_irq(gicbusdev, i + 2 * smp_cpus,
1177
+ qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
1178
+ sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus,
1179
+ qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
1180
+
1181
+ if (vms->gic_version != VIRT_GIC_VERSION_2) {
1182
+ sysbus_connect_irq(gicbusdev, i + 4 * smp_cpus,
1183
+ qdev_get_gpio_in(cpudev, ARM_CPU_NMI));
1184
+ sysbus_connect_irq(gicbusdev, i + 5 * smp_cpus,
1185
+ qdev_get_gpio_in(cpudev, ARM_CPU_VINMI));
1186
+ }
1187
+ }
1188
+}
1189
+
1190
static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
1191
{
1192
MachineState *ms = MACHINE(vms);
1193
/* We create a standalone GIC */
1194
SysBusDevice *gicbusdev;
1195
const char *gictype;
1129
- int i;
1196
unsigned int smp_cpus = ms->smp.cpus;
1197
uint32_t nb_redist_regions = 0;
1198
int revision;
@@ -1226,63 +1292,7 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
1292
}
1293
}
1294
1229
- /* Wire the outputs from each CPU's generic timer and the GICv3
1230
- * maintenance interrupt signal to the appropriate GIC PPI inputs,
1231
- * and the GIC's IRQ/FIQ/VIRQ/VFIQ/NMI/VINMI interrupt outputs to the
1232
- * CPU's inputs.
1233
- */
1234
- for (i = 0; i < smp_cpus; i++) {
1235
- DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
1236
- int intidbase = NUM_IRQS + i * GIC_INTERNAL;
1237
- /* Mapping from the output timer irq lines from the CPU to the
1238
- * GIC PPI inputs we use for the virt board.
1239
- */
1240
- const int timer_irq[] = {
1241
- [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,
1242
- [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
1243
- [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
1244
- [GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
1245
- [GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
1246
- [GTIMER_S_EL2_PHYS] = ARCH_TIMER_S_EL2_IRQ,
1247
- [GTIMER_S_EL2_VIRT] = ARCH_TIMER_S_EL2_VIRT_IRQ,
1248
- };
1249
-
1250
- for (unsigned irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
1251
- qdev_connect_gpio_out(cpudev, irq,
1252
- qdev_get_gpio_in(vms->gic,
1253
- intidbase + timer_irq[irq]));
1254
- }
1255
-
1256
- if (vms->gic_version != VIRT_GIC_VERSION_2) {
1257
- qemu_irq irq = qdev_get_gpio_in(vms->gic,
1258
- intidbase + ARCH_GIC_MAINT_IRQ);
1259
- qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
1260
- 0, irq);
1261
- } else if (vms->virt) {
1262
- qemu_irq irq = qdev_get_gpio_in(vms->gic,
1263
- intidbase + ARCH_GIC_MAINT_IRQ);
1264
- sysbus_connect_irq(gicbusdev, i + 4 * smp_cpus, irq);
1265
- }
1266
-
1267
- qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
1268
- qdev_get_gpio_in(vms->gic, intidbase
1269
- + VIRTUAL_PMU_IRQ));
1270
-
1271
- sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
1272
- sysbus_connect_irq(gicbusdev, i + smp_cpus,
1273
- qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
1274
- sysbus_connect_irq(gicbusdev, i + 2 * smp_cpus,
1275
- qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
1276
- sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus,
1277
- qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
1278
-
1279
- if (vms->gic_version != VIRT_GIC_VERSION_2) {
1280
- sysbus_connect_irq(gicbusdev, i + 4 * smp_cpus,
1281
- qdev_get_gpio_in(cpudev, ARM_CPU_NMI));
1282
- sysbus_connect_irq(gicbusdev, i + 5 * smp_cpus,
1283
- qdev_get_gpio_in(cpudev, ARM_CPU_VINMI));
1284
- }
1285
- }
1295
+ gic_connect_ppis(vms);
1296
1297
fdt_add_gic_node(vms);
1298
}