@samitouri / QOSamiQemu / commits / 585dad9e79

target/arm: GICv5 cpuif: Implement PPI pending status registers

The GICv5 PPI pending status is handled by two registers, one of which is write-1-to-set and one of which is write-1-to-clear. The pending state is read-only for PPIs where the handling mode is Edge. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Message-id: 20260327111700.795099-39-peter.maydell@linaro.org

Peter Maydell committed Mar 27, 2026 at 11:16 UTC 585dad9e79e1d64075e99448ee34adbeeeeea056
2 files changed +45
target/arm/cpu.h
+1
@@ -605,6 +605,7 @@ typedef struct CPUArchState {
605 /* Most PPI registers have 1 bit per PPI, so 64 PPIs to a register */
606 uint64_t ppi_active[GICV5_NUM_PPIS / 64];
607 uint64_t ppi_hm[GICV5_NUM_PPIS / 64];
608 + uint64_t ppi_pend[GICV5_NUM_PPIS / 64];
609 } gicv5_cpuif;
610
611 struct {
target/arm/tcg/gicv5-cpuif.c
+44
@@ -199,6 +199,26 @@ static void gic_ppi_sactive_write(CPUARMState *env, const ARMCPRegInfo *ri,
199 raw_write(env, ri, old | value);
200 }
201
202 +static void gic_ppi_cpend_write(CPUARMState *env, const ARMCPRegInfo *ri,
203 + uint64_t value)
204 +{
205 + uint64_t old = raw_read(env, ri);
206 + /* If ICC_PPI_HMR_EL1[n].HM is 1, PEND bits are RO */
207 + uint64_t hm = env->gicv5_cpuif.ppi_hm[ri->opc2 & 1];
208 + value &= ~hm;
209 + raw_write(env, ri, old & ~value);
210 +}
211 +
212 +static void gic_ppi_spend_write(CPUARMState *env, const ARMCPRegInfo *ri,
213 + uint64_t value)
214 +{
215 + uint64_t old = raw_read(env, ri);
216 + /* If ICC_PPI_HMR_EL1[n].HM is 1, PEND bits are RO */
217 + uint64_t hm = env->gicv5_cpuif.ppi_hm[ri->opc2 & 1];
218 + value &= ~hm;
219 + raw_write(env, ri, old | value);
220 +}
221 +
222 static const ARMCPRegInfo gicv5_cpuif_reginfo[] = {
223 /*
224 * Barrier: wait until the effects of a cpuif system register
@@ -314,6 +334,30 @@ static const ARMCPRegInfo gicv5_cpuif_reginfo[] = {
334 .fieldoffset = offsetof(CPUARMState, gicv5_cpuif.ppi_hm[1]),
335 .resetvalue = PPI_HMR1_RESET,
336 },
337 + { .name = "ICC_PPI_CPENDR0_EL1", .state = ARM_CP_STATE_AA64,
338 + .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 13, .opc2 = 4,
339 + .access = PL1_RW, .type = ARM_CP_ALIAS | ARM_CP_IO | ARM_CP_NO_RAW,
340 + .fieldoffset = offsetof(CPUARMState, gicv5_cpuif.ppi_pend[0]),
341 + .writefn = gic_ppi_cpend_write,
342 + },
343 + { .name = "ICC_PPI_CPENDR1_EL1", .state = ARM_CP_STATE_AA64,
344 + .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 13, .opc2 = 5,
345 + .access = PL1_RW, .type = ARM_CP_ALIAS | ARM_CP_IO | ARM_CP_NO_RAW,
346 + .fieldoffset = offsetof(CPUARMState, gicv5_cpuif.ppi_pend[1]),
347 + .writefn = gic_ppi_cpend_write,
348 + },
349 + { .name = "ICC_PPI_SPENDR0_EL1", .state = ARM_CP_STATE_AA64,
350 + .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 13, .opc2 = 6,
351 + .access = PL1_RW, .type = ARM_CP_IO | ARM_CP_NO_RAW,
352 + .fieldoffset = offsetof(CPUARMState, gicv5_cpuif.ppi_pend[0]),
353 + .writefn = gic_ppi_spend_write,
354 + },
355 + { .name = "ICC_PPI_SPENDR0_EL1", .state = ARM_CP_STATE_AA64,
356 + .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 13, .opc2 = 7,
357 + .access = PL1_RW, .type = ARM_CP_IO | ARM_CP_NO_RAW,
358 + .fieldoffset = offsetof(CPUARMState, gicv5_cpuif.ppi_pend[1]),
359 + .writefn = gic_ppi_spend_write,
360 + },
361 };
362
363 void define_gicv5_cpuif_regs(ARMCPU *cpu)