From 7b74351b3c9d31194787464944dd17d3735d3012 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 14 Feb 2022 13:44:04 +0000 Subject: process vlpi WIP, unfinished Signed-off-by: Peter Maydell --- hw/intc/arm_gicv3_redist.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c index 9f8854b372..97a1dcc16a 100644 --- a/hw/intc/arm_gicv3_redist.c +++ b/hw/intc/arm_gicv3_redist.c @@ -909,10 +909,40 @@ void gicv3_redist_vlpi_pending(GICv3CPUState *cs, int irq, int level) void gicv3_redist_process_vlpi(GICv3CPUState *cs, int irq, uint64_t vptaddr, int doorbell, int level) { - /* - * The redistributor handling for being handed a VLPI by the ITS - * will be added in a subsequent commit. - */ + bool bit_changed; + uint64_t vpendbaser_vptaddr = + FIELD_EX64(cs->gicr_vpendbaser, GICR_VPENDBASER, PHYADDR) << 16; + bool vcpu_resident = FIELD_EX64(cs->gicr_vpendbaser, GICR_VPENDBASER, VALID) && + vpendbaser_vptaddr == vptaddr; + + if (vcpu_resident) { + uint32_t idbits = FIELD_EX64(cs->gicr_vpropbaser, GICR_VPROPBASER, IDBITS); + if (irq >= (1ULL << idbits)) { + return; + } + } + + bit_changed = set_pending_table_bit(cs, vptaddr, irq, level); + if (vcpu_resident && bit_changed) { + if (level) { + // TODO do something + } else { + /* + * Only need to recalculate if this was previously teh + * highest priority pending vLPI + */ + if (irq == cs->hppvlpi.irq) { + gicv3_redist_update_vlpi(cs); + } + } + } + + if (!vcpu_resident) { + /* vCPU is not currently resident: ring the doorbell */ + if (doorbell != INTID_SPURIOUS) { + gicv3_redist_process_lpi(cs, doorbell, 1); + } + } } void gicv3_redist_mov_vlpi(GICv3CPUState *src, uint64_t src_vptaddr, -- cgit v1.2.3