diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2020-11-14 11:22:07 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2020-11-14 11:22:07 +0000 |
commit | b50ea0d54bbca7d440315c3d0c0f7a4d6537b180 (patch) | |
tree | 77551af72cda7c437999ddfe2255447905e33501 | |
parent | 5ececc3a0b0086c6168e12f4d032809477b30fe5 (diff) | |
parent | deef3d2568a7fbaa62d9bee07708cf3a4dc3ac53 (diff) | |
download | qemu-b50ea0d54bbca7d440315c3d0c0f7a4d6537b180.zip qemu-b50ea0d54bbca7d440315c3d0c0f7a4d6537b180.tar.gz qemu-b50ea0d54bbca7d440315c3d0c0f7a4d6537b180.tar.bz2 |
Merge remote-tracking branch 'remotes/alistair/tags/pull-riscv-to-apply-20201113-1' into staging
Two small additional fixes for the Ibex PLIC.
# gpg: Signature made Sat 14 Nov 2020 05:44:22 GMT
# gpg: using RSA key F6C4AC46D4934868D3B8CE8F21E10D29DF977054
# gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [full]
# Primary key fingerprint: F6C4 AC46 D493 4868 D3B8 CE8F 21E1 0D29 DF97 7054
* remotes/alistair/tags/pull-riscv-to-apply-20201113-1:
intc/ibex_plic: Ensure we don't loose interrupts
intc/ibex_plic: Fix some typos in the comments
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | hw/intc/ibex_plic.c | 21 | ||||
-rw-r--r-- | include/hw/intc/ibex_plic.h | 1 |
2 files changed, 19 insertions, 3 deletions
diff --git a/hw/intc/ibex_plic.c b/hw/intc/ibex_plic.c index 235e6b8..341c9db 100644 --- a/hw/intc/ibex_plic.c +++ b/hw/intc/ibex_plic.c @@ -45,9 +45,10 @@ static void ibex_plic_irqs_set_pending(IbexPlicState *s, int irq, bool level) if (s->claimed[pending_num] & 1 << (irq % 32)) { /* - * The interrupt has been claimed, but not compelted. + * The interrupt has been claimed, but not completed. * The pending bit can't be set. */ + s->hidden_pending[pending_num] |= level << (irq % 32); return; } @@ -133,7 +134,7 @@ static uint64_t ibex_plic_read(void *opaque, hwaddr addr, int pending_num = s->claim / 32; s->pending[pending_num] &= ~(1 << (s->claim % 32)); - /* Set the interrupt as claimed, but not compelted */ + /* Set the interrupt as claimed, but not completed */ s->claimed[pending_num] |= 1 << (s->claim % 32); /* Return the current claimed interrupt */ @@ -176,8 +177,21 @@ static void ibex_plic_write(void *opaque, hwaddr addr, s->claim = 0; } if (s->claimed[value / 32] & 1 << (value % 32)) { + int pending_num = value / 32; + /* This value was already claimed, clear it. */ - s->claimed[value / 32] &= ~(1 << (value % 32)); + s->claimed[pending_num] &= ~(1 << (value % 32)); + + if (s->hidden_pending[pending_num] & (1 << (value % 32))) { + /* + * If the bit in hidden_pending is set then that means we + * received an interrupt between claiming and completing + * the interrupt that hasn't since been de-asserted. + * On hardware this would trigger an interrupt, so let's + * trigger one here as well. + */ + s->pending[pending_num] |= 1 << (value % 32); + } } } @@ -239,6 +253,7 @@ static void ibex_plic_realize(DeviceState *dev, Error **errp) int i; s->pending = g_new0(uint32_t, s->pending_num); + s->hidden_pending = g_new0(uint32_t, s->pending_num); s->claimed = g_new0(uint32_t, s->pending_num); s->source = g_new0(uint32_t, s->source_num); s->priority = g_new0(uint32_t, s->priority_num); diff --git a/include/hw/intc/ibex_plic.h b/include/hw/intc/ibex_plic.h index 37f0335..7fc495d 100644 --- a/include/hw/intc/ibex_plic.h +++ b/include/hw/intc/ibex_plic.h @@ -33,6 +33,7 @@ struct IbexPlicState { MemoryRegion mmio; uint32_t *pending; + uint32_t *hidden_pending; uint32_t *claimed; uint32_t *source; uint32_t *priority; |