diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2022-04-08 15:15:28 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2022-04-22 14:44:52 +0100 |
commit | d4014320a430d2ac07f896b9ce38778258060deb (patch) | |
tree | 04a7d2a3453a00cc5e71f6088d66ef48a7d10f23 /hw | |
parent | a686e85d2b4a3b95d97d01dfa3fd4607f1216cf0 (diff) | |
download | qemu-d4014320a430d2ac07f896b9ce38778258060deb.zip qemu-d4014320a430d2ac07f896b9ce38778258060deb.tar.gz qemu-d4014320a430d2ac07f896b9ce38778258060deb.tar.bz2 |
hw/intc/arm_gicv3_its: Implement INV for virtual interrupts
Implement the ITS side of the handling of the INV command for
virtual interrupts; as usual this calls into a redistributor
function which we leave as a stub to fill in later.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220408141550.1271295-20-peter.maydell@linaro.org
Diffstat (limited to 'hw')
-rw-r--r-- | hw/intc/arm_gicv3_its.c | 16 | ||||
-rw-r--r-- | hw/intc/arm_gicv3_redist.c | 8 | ||||
-rw-r--r-- | hw/intc/gicv3_internal.h | 9 |
3 files changed, 31 insertions, 2 deletions
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c index aa0a625..f7c01c2 100644 --- a/hw/intc/arm_gicv3_its.c +++ b/hw/intc/arm_gicv3_its.c @@ -1090,6 +1090,7 @@ static ItsCmdResult process_inv(GICv3ITSState *s, const uint64_t *cmdpkt) ITEntry ite; DTEntry dte; CTEntry cte; + VTEntry vte; ItsCmdResult cmdres; devid = FIELD_EX64(cmdpkt[0], INV_0, DEVICEID); @@ -1118,8 +1119,19 @@ static ItsCmdResult process_inv(GICv3ITSState *s, const uint64_t *cmdpkt) __func__, ite.inttype); return CMD_CONTINUE; } - /* We will implement the vLPI invalidation in a later commit */ - g_assert_not_reached(); + + cmdres = lookup_vte(s, __func__, ite.vpeid, &vte); + if (cmdres != CMD_CONTINUE_OK) { + return cmdres; + } + if (!intid_in_lpi_range(ite.intid) || + ite.intid >= (1ULL << (vte.vptsize + 1))) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: intid 0x%x out of range\n", + __func__, ite.intid); + return CMD_CONTINUE; + } + gicv3_redist_inv_vlpi(&s->gicv3->cpu[vte.rdbase], ite.intid, + vte.vptaddr << 16); break; default: g_assert_not_reached(); diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c index 78650a3..856494b 100644 --- a/hw/intc/arm_gicv3_redist.c +++ b/hw/intc/arm_gicv3_redist.c @@ -808,6 +808,14 @@ void gicv3_redist_process_vlpi(GICv3CPUState *cs, int irq, uint64_t vptaddr, */ } +void gicv3_redist_inv_vlpi(GICv3CPUState *cs, int irq, uint64_t vptaddr) +{ + /* + * The redistributor handling for invalidating cached information + * about a VLPI will be added in a subsequent commit. + */ +} + void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level) { /* Update redistributor state for a change in an external PPI input line */ diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h index 011a11a..f5b8509 100644 --- a/hw/intc/gicv3_internal.h +++ b/hw/intc/gicv3_internal.h @@ -586,6 +586,15 @@ void gicv3_redist_update_lpi_only(GICv3CPUState *cs); */ void gicv3_redist_inv_lpi(GICv3CPUState *cs, int irq); /** + * gicv3_redist_inv_vlpi: + * @cs: GICv3CPUState + * @irq: vLPI to invalidate cached information for + * @vptaddr: (guest) address of vLPI table + * + * Forget or update any cached information associated with this vLPI. + */ +void gicv3_redist_inv_vlpi(GICv3CPUState *cs, int irq, uint64_t vptaddr); +/** * gicv3_redist_mov_lpi: * @src: source redistributor * @dest: destination redistributor |