aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2022-02-14 13:44:04 +0000
committerPeter Maydell <peter.maydell@linaro.org>2022-02-21 10:55:28 +0000
commit7b74351b3c9d31194787464944dd17d3735d3012 (patch)
tree930ab715d66fba686c2d3f0e9997a4509e57f729
parent8c332954f06af724a9d7ef7e6dcfcb4f62d2cdb4 (diff)
process vlpigicv4
WIP, unfinished Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/intc/arm_gicv3_redist.c38
1 files 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,