@samitouri / QOSamiQemu / commits / 829ce41fbe

target/arm: GICv5 cpuif: Implement ICC_IAFFIDR_EL1

The CPU system register ICC_IAFFIDR_EL1 is a read-only register that tells the guest what the affinity ID of that CPU is. Implement this register. In real hardware using the stream protocol, the IRS tells the CPU its IAFFID using a DownstreamControl command as part of the handshake process when the IRS-CPU link is brought online. Our analogue of this is to pass the IAFFID as an extra argument to gicv5_set_gicv5state(). (We could have the CPU call into the GIC every time to ask for the value, but this would mean we had to search the cpus[] array for the right CPU to return its IAFFID.) Note that we don't put the IAFFID into the gicv5_cpuif sub-struct, because that part of the CPU struct is zeroed on reset, and we must keep the IAFFID across reset (we only set it up when the GIC device is created). Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Message-id: 20260327111700.795099-35-peter.maydell@linaro.org

Peter Maydell committed Mar 27, 2026 at 11:16 UTC 829ce41fbe712863d9d296e25ef3eced25eb8d98
5 files changed +21 -5
hw/intc/arm_gicv5_common.c
+3 -2
@@ -173,9 +173,10 @@ static void gicv5_common_realize(DeviceState *dev, Error **errp)
173 }
174
175 for (int i = 0; i < cs->num_cpus; i++) {
176 - if (!gicv5_set_gicv5state(cs->cpus[i], cs)) {
176 + if (!gicv5_set_gicv5state(cs->cpus[i], cs, cs->cpu_iaffids[i])) {
177 error_setg(errp,
178 - "CPU %d does not implement GICv5 CPU interface", i);
178 + "CPU %d (IAFFID 0x%x) does not implement GICv5 CPU interface",
179 + i, cs->cpu_iaffids[i]);
180 return;
181 }
182 }
include/hw/intc/arm_gicv5_stream.h
+2 -1
@@ -20,6 +20,7 @@ typedef struct GICv5Common GICv5Common;
20 * gicv5_set_gicv5state
21 * @cpu: CPU object to tell about its IRS
22 * @cs: the GIC IRS it is connected to
23 + * @iaffid: the IAFFID of this CPU
24 *
25 * Set the CPU object's GICv5 pointer to point to this GIC IRS. The
26 * IRS must call this when it is realized, for each CPU it is
@@ -28,7 +29,7 @@ typedef struct GICv5Common GICv5Common;
29 * Returns true on success, false if the CPU doesn't implement the
30 * GICv5 CPU interface.
31 */
31 -bool gicv5_set_gicv5state(ARMCPU *cpu, GICv5Common *cs);
32 +bool gicv5_set_gicv5state(ARMCPU *cpu, GICv5Common *cs, uint32_t iaffid);
33
34 /*
35 * The architected Stream Protocol is asynchronous; commands can be
target/arm/cpu.c
+3 -2
@@ -1159,16 +1159,17 @@ static void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags)
1159 }
1160
1161 #ifndef CONFIG_USER_ONLY
1162 -bool gicv5_set_gicv5state(ARMCPU *cpu, GICv5Common *cs)
1162 +bool gicv5_set_gicv5state(ARMCPU *cpu, GICv5Common *cs, uint32_t iaffid)
1163 {
1164 /*
1165 * Set this CPU's gicv5state pointer to point to the GIC that we are
1166 - * connected to.
1166 + * connected to, and record our IAFFID.
1167 */
1168 if (!cpu_isar_feature(aa64_gcie, cpu)) {
1169 return false;
1170 }
1171 cpu->env.gicv5state = cs;
1172 + cpu->env.gicv5_iaffid = iaffid;
1173 return true;
1174 }
1175 #endif
target/arm/cpu.h
+2
@@ -818,6 +818,8 @@ typedef struct CPUArchState {
818 void *gicv3state;
819 /* Similarly, for a GICv5Common */
820 void *gicv5state;
821 + /* For GICv5, this CPU's IAFFID */
822 + uint64_t gicv5_iaffid;
823 #else /* CONFIG_USER_ONLY */
824 /* For usermode syscall translation. */
825 bool eabi;
target/arm/tcg/gicv5-cpuif.c
+11
@@ -226,6 +226,17 @@ static const ARMCPRegInfo gicv5_cpuif_reginfo[] = {
226 .fieldoffset = offsetof(CPUARMState, gicv5_cpuif.icc_icsr_el1),
227 .resetvalue = 0,
228 },
229 + { .name = "ICC_IAFFIDR_EL1", .state = ARM_CP_STATE_AA64,
230 + .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 10, .opc2 = 5,
231 + .access = PL1_R, .type = ARM_CP_NO_RAW,
232 + /* ICC_IAFFIDR_EL1 holds the IAFFID only, in its low bits */
233 + .fieldoffset = offsetof(CPUARMState, gicv5_iaffid),
234 + /*
235 + * The field is a constant value set in gicv5_set_gicv5state(),
236 + * so don't allow it to be overwritten by reset.
237 + */
238 + .resetfn = arm_cp_reset_ignore,
239 + },
240 };
241
242 void define_gicv5_cpuif_regs(ARMCPU *cpu)