This patchset implements initial support of emulation of Arm's new interrupt controller architecture, GICv5.
The most recent version of the GICv5 spec (currently 00EAC0) is at: https://developer.arm.com/documentation/aes0070/latest/ The emulation is at an "experimental" level, both because the GICv5 specification is still at an early-access level and minor changes are possible, and also because this emulation is missing some functionality which I plan to add later but which would have made this initial patchset even larger and later. To quote the docs patch: - guest-visible behaviour may change when the final version of the specification is released and QEMU implements it - migration support is not yet implemented - the GICv5 is not exposed to the guest via ACPI tables, only via DTB - the way the interrupt controller is exposed to the guest and the command line syntax for enabling it may change The current implementation supports only an EL1 guest (no EL2 or EL3 and no Realm support), and does not implement the ITS (no MSI support). The GICv5 is supported by the "virt" board, and can be enabled with "-machine gic-version=x-5" (the 'x' standing for "experimental"). Like the GICv3/v4, the GICv5 has both a system component part (the Interrupt Routing Service, IRS), and a part in the CPU itself (the CPU interface). Our GICv3 model puts both of these into code in hw/intc/, and has the cpuif part install itself into an existing CPU object by adding new system registers there. This works, but in retrospect I feel that it's a bit awkward and we would have done better to make our design a bit closer to the hardware setup, where the CPU interface is really part of the CPU and talks to the system component over an architected protocol. So for GICv5 I have taken that route: the IRS is in hw/intc/arm_gicv5.c, and the CPU interface is in target/arm/tcg/gicv5-cpuif.c. They communicate via a set of functions which loosely match the "stream protocol" defined in the GICv5 architecture spec (with some simplifications that result from QEMU being strictly synchronous because we always hold the BQL when executing any GICv5 emulation code; the hardware has to handle the IRS and the CPU executing in parallel and the communications channel not being instantaneous transmission). Although the EL2/EL3/Realm functionality is not present in this patchset, I have implemented some of the foundations for it where I thought it made sense, to avoid having to refactor it later. Similarly, the class structure makes the usual "common baseclass + TCG subclass" split, as we are going to want a KVM subclass when we add KVM support. In a few places I have noted possible opportunities for performance optimisation; these are probably best left until we've done some analysis that shows them to be necessary. This patchset is sufficient to be able to boot a Linux guest at EL1 (directly via -kernel): all the kernel support for GICv5 is upstream as of Linux 6.19. One or two of the patches in here have appeared on list separately; I've put in the Reviewed-by tags in those cases. I'm optimistic that we can get this into the upcoming 11.0 release, but that will depend on how code review goes :-) thanks -- PMM Peter Maydell (65): hw/core: Permit devices to define an array of link properties hw/intc: Skeleton of GICv5 IRS classes hw/arm/Kconfig: select ARM_GICV5 for ARM_VIRT board hw/intc/arm_gicv5: Implement skeleton code for IRS register frames hw/intc/arm_gicv5: Add migration blocker hw/intc/arm_gicv5: Create and validate QOM properties hw/intc/arm_gicv5: Create inbound GPIO lines for SPIs hw/intc/arm_gicv5: Define macros for config frame registers hw/intc/arm_gicv5: Implement IRS ID regs hw/intc/arm_gicv5: Add link property for MemoryRegion for DMA hw/intc/arm_gicv5: Implement gicv5_class_name() hw/intc/arm_gicv5: Add defines for GICv5 architected PPIs target/arm: GICv5 cpuif: Initial skeleton and GSB barrier insns target/arm: Set up pointer to GICv5 in each CPU hw/intc/arm_gicv5: Implement IRS_IST_{BASER, STATUSR, CFGR} hw/intc/arm_gicv5: Cache LPI IST config in a struct hw/intc/arm_gicv5: Implement gicv5_set_priority() target/arm: GICv5 cpuif: Implement the GIC CDPRI instruction hw/intc/arm_gicv5: Implement IRS_MAP_L2_ISTR hw/intc/arm_gicv5: Implement remaining set-config functions target/arm: GICv5 cpuif: Implement GIC CD* insns for setting config hw/intc/arm_gicv5: Create backing state for SPIs hw/intc/arm_gicv5: Make gicv5_set_* update SPI state hw/intc/arm_gicv5: Implement gicv5_request_config() target/arm: GICv5 cpuif: Implement GIC CDRCFG and ICC_ICSR_EL1 hw/intc/arm_gicv5: Implement IRS_SPI_{SELR,STATUSR,CFGR,DOMAINR} hw/intc/arm_gicv5: Update SPI state for CLEAR/SET events hw/intc/arm_gicv5: Implement IRS_CR0 and IRS_CR1 hw/intc/arm_gicv5: Implement IRS_SYNCR and IRS_SYNC_STATUSR hw/intc/arm_gicv5: Implement IRS_PE_{CR0,SELR,STATUSR} hw/intc/arm_gicv5: Implement CoreSight ID registers hw/intc/arm_gicv5: Cache pending LPIs in a hash table target/arm: GICv5 cpuif: Implement ICC_IAFFIDR_EL1 target/arm: GICv5 cpuif: Implement ICC_IDR0_EL1 target/arm: GICv5 cpuif: Implement GICv5 PPI active set/clear registers target/arm: GICv5 cpuif: Implement PPI handling mode register target/arm: GICv5 cpuif: Implement PPI pending status registers target/arm: GICv5 cpuif: Implement PPI enable register target/arm: GICv5 cpuif: Implement PPI priority registers target/arm: GICv5 cpuif: Implement ICC_APR_EL1 and ICC_HAPR_EL1 target/arm: GICv5 cpuif: Calculate the highest priority PPI hw/intc/arm_gicv5: Calculate HPPI in the IRS target/arm: GICv5 cpuif: Implement ICC_CR0_EL1 target/arm: GICv5 cpuif: Implement ICC_PCR_EL1 target/arm: GICv5 cpuif: Implement ICC_HPPIR_EL1 hw/intc/arm_gicv5: Implement Activate command target/arm: GICv5 cpuif: Implement GICR CDIA command target/arm: GICv5 cpuif: Implement GIC CDEOI hw/intc/arm_gicv5: Implement Deactivate command target/arm: GICv5 cpuif: Implement GIC CDDI target/arm: GICv5 cpuif: Signal IRQ or FIQ target/arm: Connect internal interrupt sources up as GICv5 PPIs target/arm: Add has_gcie property to enable FEAT_GCIE hw/intc/arm_gicv3_cpuif: Don't allow GICv3 if CPU has GICv5 cpuif hw/arm/virt: Update error message for bad gic-version option hw/arm/virt: Remember CPU phandles rather than looking them up by name hw/arm/virt: Move MSI controller creation out of create_gic() hw/arm/virt: Pull "wire CPU interrupts" out of create_gic() hw/arm/virt: Split GICv2 and GICv3/4 creation hw/arm/virt: Create and connect GICv5 hw/arm/virt: Advertise GICv5 in the DTB hw/arm/virt: Handle GICv5 in interrupt bindings for PPIs hw/arm/virt: Use correct interrupt type for GICv5 SPIs in the DTB hw/arm/virt: Enable GICv5 CPU interface when using GICv5 hw/arm/virt: Allow user to select GICv5 docs/system/arm/virt.rst | 19 + hw/arm/Kconfig | 1 + hw/arm/virt.c | 524 ++++++-- hw/core/qdev-properties.c | 78 ++ hw/intc/Kconfig | 4 + hw/intc/arm_gicv3.c | 2 +- hw/intc/arm_gicv3_cpuif.c | 14 +- hw/intc/arm_gicv5.c | 1933 ++++++++++++++++++++++++++++ hw/intc/arm_gicv5_common.c | 227 ++++ hw/intc/gicv3_internal.h | 2 +- hw/intc/meson.build | 4 + hw/intc/trace-events | 23 + include/hw/arm/fdt.h | 10 + include/hw/arm/virt.h | 15 + include/hw/core/qdev-properties.h | 40 + include/hw/intc/arm_gicv5.h | 51 + include/hw/intc/arm_gicv5_common.h | 238 ++++ include/hw/intc/arm_gicv5_stream.h | 229 ++++ include/hw/intc/arm_gicv5_types.h | 111 ++ include/qom/object.h | 19 + meson.build | 1 + qom/object.c | 42 +- target/arm/cpregs-pmu.c | 9 +- target/arm/cpu-features.h | 11 + target/arm/cpu.c | 62 + target/arm/cpu.h | 28 + target/arm/helper.c | 21 + target/arm/internals.h | 9 + target/arm/tcg/gicv5-cpuif.c | 958 ++++++++++++++ target/arm/tcg/meson.build | 1 + target/arm/tcg/trace-events | 11 + target/arm/tcg/trace.h | 1 + 32 files changed, 4542 insertions(+), 156 deletions(-) create mode 100644 hw/intc/arm_gicv5.c create mode 100644 hw/intc/arm_gicv5_common.c create mode 100644 include/hw/intc/arm_gicv5.h create mode 100644 include/hw/intc/arm_gicv5_common.h create mode 100644 include/hw/intc/arm_gicv5_stream.h create mode 100644 include/hw/intc/arm_gicv5_types.h create mode 100644 target/arm/tcg/gicv5-cpuif.c create mode 100644 target/arm/tcg/trace-events create mode 100644 target/arm/tcg/trace.h -- 2.43.0
