@samitouri / QOSamiQemu / commits / a7a9b822be

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 }