mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 02:03:56 -06:00
hw/intc/arm_gicv3_its: Implement MOVALL
Implement the ITS MOVALL command, which takes all the pending interrupts on a source redistributor and makes the not-pending on that source redistributor and pending on a destination redistributor. This is a GICv3 ITS command which we forgot to implement. (It is not used by Linux guests.) Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20220122182444.724087-14-peter.maydell@linaro.org
This commit is contained in:
parent
8b8bb0146b
commit
f6d1d9b407
3 changed files with 125 additions and 0 deletions
|
@ -582,6 +582,58 @@ static ItsCmdResult process_mapd(GICv3ITSState *s, uint64_t value,
|
|||
return update_dte(s, devid, valid, size, itt_addr) ? CMD_CONTINUE : CMD_STALL;
|
||||
}
|
||||
|
||||
static ItsCmdResult process_movall(GICv3ITSState *s, uint64_t value,
|
||||
uint32_t offset)
|
||||
{
|
||||
AddressSpace *as = &s->gicv3->dma_as;
|
||||
MemTxResult res = MEMTX_OK;
|
||||
uint64_t rd1, rd2;
|
||||
|
||||
/* No fields in dwords 0 or 1 */
|
||||
offset += NUM_BYTES_IN_DW;
|
||||
offset += NUM_BYTES_IN_DW;
|
||||
value = address_space_ldq_le(as, s->cq.base_addr + offset,
|
||||
MEMTXATTRS_UNSPECIFIED, &res);
|
||||
if (res != MEMTX_OK) {
|
||||
return CMD_STALL;
|
||||
}
|
||||
|
||||
rd1 = FIELD_EX64(value, MOVALL_2, RDBASE1);
|
||||
if (rd1 >= s->gicv3->num_cpu) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: RDBASE1 %" PRId64
|
||||
" out of range (must be less than %d)\n",
|
||||
__func__, rd1, s->gicv3->num_cpu);
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
|
||||
offset += NUM_BYTES_IN_DW;
|
||||
value = address_space_ldq_le(as, s->cq.base_addr + offset,
|
||||
MEMTXATTRS_UNSPECIFIED, &res);
|
||||
if (res != MEMTX_OK) {
|
||||
return CMD_STALL;
|
||||
}
|
||||
|
||||
rd2 = FIELD_EX64(value, MOVALL_3, RDBASE2);
|
||||
if (rd2 >= s->gicv3->num_cpu) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: RDBASE2 %" PRId64
|
||||
" out of range (must be less than %d)\n",
|
||||
__func__, rd2, s->gicv3->num_cpu);
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
|
||||
if (rd1 == rd2) {
|
||||
/* Move to same target must succeed as a no-op */
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
|
||||
/* Move all pending LPIs from redistributor 1 to redistributor 2 */
|
||||
gicv3_redist_movall_lpis(&s->gicv3->cpu[rd1], &s->gicv3->cpu[rd2]);
|
||||
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Current implementation blocks until all
|
||||
* commands are processed
|
||||
|
@ -679,6 +731,9 @@ static void process_cmdq(GICv3ITSState *s)
|
|||
gicv3_redist_update_lpi(&s->gicv3->cpu[i]);
|
||||
}
|
||||
break;
|
||||
case GITS_CMD_MOVALL:
|
||||
result = process_movall(s, data, cq_offset);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue