aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-11-14 11:22:07 +0000
committerPeter Maydell <peter.maydell@linaro.org>2020-11-14 11:22:07 +0000
commitb50ea0d54bbca7d440315c3d0c0f7a4d6537b180 (patch)
tree77551af72cda7c437999ddfe2255447905e33501
parent5ececc3a0b0086c6168e12f4d032809477b30fe5 (diff)
parentdeef3d2568a7fbaa62d9bee07708cf3a4dc3ac53 (diff)
downloadqemu-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.c21
-rw-r--r--include/hw/intc/ibex_plic.h1
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;