@samitouri / QOSamiQemu / commits / 2f82555dda

target/arm: Set up pointer to GICv5 in each CPU

The qdev link property array gives the IRS a pointer to each CPU that is connected to it, but the CPU also needs a pointer to the IRS so that it can issue commands. Set this up in a similar way to how we do it for the GICv3: have the GIC's realize function call gicv5_set_gicv5state() to set a pointer in the CPUARMState. The CPU will only allow this link to be made if it actually implements the GICv5 CPU interface; it will be the responsibility of the board code to configure the CPU to have a GICv5 cpuif if it wants to connect a GICv5 to it. 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-16-peter.maydell@linaro.org

Peter Maydell committed Mar 27, 2026 at 11:16 UTC 2f82555dda7923ad11d883480b2ee5e624c60e9f
4 files changed +59
hw/intc/arm_gicv5_common.c
+9
@@ -8,6 +8,7 @@
8
9 #include "qemu/osdep.h"
10 #include "hw/intc/arm_gicv5_common.h"
11 +#include "hw/intc/arm_gicv5_stream.h"
12 #include "hw/core/qdev-properties.h"
13 #include "qapi/error.h"
14 #include "trace.h"
@@ -127,6 +128,14 @@ static void gicv5_common_realize(DeviceState *dev, Error **errp)
128 return;
129 }
130
131 + for (int i = 0; i < cs->num_cpus; i++) {
132 + if (!gicv5_set_gicv5state(cs->cpus[i], cs)) {
133 + error_setg(errp,
134 + "CPU %d does not implement GICv5 CPU interface", i);
135 + return;
136 + }
137 + }
138 +
139 address_space_init(&cs->dma_as, cs->dma, "gicv5-sysmem");
140
141 trace_gicv5_common_realize(cs->irsid, cs->num_cpus,
include/hw/intc/arm_gicv5_stream.h new
+32
@@ -0,0 +1,32 @@
1 +/*
2 + * Interface between GICv5 CPU interface and GICv5 IRS
3 + * Loosely modelled on the GICv5 Stream Protocol interface documented
4 + * in the GICv5 specification.
5 + *
6 + * Copyright (c) 2025 Linaro Limited
7 + *
8 + * SPDX-License-Identifier: GPL-2.0-or-later
9 + */
10 +
11 +#ifndef HW_INTC_ARM_GICV5_STREAM_H
12 +#define HW_INTC_ARM_GICV5_STREAM_H
13 +
14 +#include "target/arm/cpu-qom.h"
15 +
16 +typedef struct GICv5Common GICv5Common;
17 +
18 +/**
19 + * gicv5_set_gicv5state
20 + * @cpu: CPU object to tell about its IRS
21 + * @cs: the GIC IRS it is connected to
22 + *
23 + * Set the CPU object's GICv5 pointer to point to this GIC IRS. The
24 + * IRS must call this when it is realized, for each CPU it is
25 + * connected to.
26 + *
27 + * Returns true on success, false if the CPU doesn't implement the
28 + * GICv5 CPU interface.
29 + */
30 +bool gicv5_set_gicv5state(ARMCPU *cpu, GICv5Common *cs);
31 +
32 +#endif
target/arm/cpu.c
+16
@@ -39,6 +39,7 @@
39 #if !defined(CONFIG_USER_ONLY)
40 #include "hw/core/loader.h"
41 #include "hw/core/boards.h"
42 +#include "hw/intc/arm_gicv5_stream.h"
43 #ifdef CONFIG_TCG
44 #include "hw/intc/armv7m_nvic.h"
45 #endif /* CONFIG_TCG */
@@ -1157,6 +1158,21 @@ static void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags)
1158 }
1159 }
1160
1161 +#ifndef CONFIG_USER_ONLY
1162 +bool gicv5_set_gicv5state(ARMCPU *cpu, GICv5Common *cs)
1163 +{
1164 + /*
1165 + * Set this CPU's gicv5state pointer to point to the GIC that we are
1166 + * connected to.
1167 + */
1168 + if (!cpu_isar_feature(aa64_gcie, cpu)) {
1169 + return false;
1170 + }
1171 + cpu->env.gicv5state = cs;
1172 + return true;
1173 +}
1174 +#endif
1175 +
1176 uint64_t arm_build_mp_affinity(int idx, uint8_t clustersz)
1177 {
1178 uint32_t Aff1 = idx / clustersz;
target/arm/cpu.h
+2
@@ -811,6 +811,8 @@ typedef struct CPUArchState {
811 const struct arm_boot_info *boot_info;
812 /* Store GICv3CPUState to access from this struct */
813 void *gicv3state;
814 + /* Similarly, for a GICv5Common */
815 + void *gicv5state;
816 #else /* CONFIG_USER_ONLY */
817 /* For usermode syscall translation. */
818 bool eabi;