diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2020-08-23 11:38:52 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2020-08-23 11:38:52 +0100 |
| commit | 152be6de9100e58b5d896272e951d4c910bd735a (patch) | |
| tree | 14921e4e322f04245debd096caad615418bd17ed /hw/intc | |
| parent | d7df0ceee0fd2e512cd214a9074ebeeb40da3099 (diff) | |
| parent | 01c41d15de13104774d08e951db24815c8cffc79 (diff) | |
| download | focaccia-qemu-152be6de9100e58b5d896272e951d4c910bd735a.tar.gz focaccia-qemu-152be6de9100e58b5d896272e951d4c910bd735a.zip | |
Merge remote-tracking branch 'remotes/alistair/tags/pull-riscv-to-apply-20200821-1' into staging
The first RISC-V PR for the 5.2 window. This includes: - NaNBox fixes - Vector extension improvements - a L2 cache controller - PMP fixes - Upgrade to OpenSBI v0.8 and the generic platform - Fixes for the Ibex PLIC # gpg: Signature made Sat 22 Aug 2020 06:38:18 BST # 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-20200821-1: hw/intc: ibex_plic: Honour source priorities hw/intc: ibex_plic: Don't allow repeat interrupts on claimed lines hw/intc: ibex_plic: Update the pending irqs target/riscv: Change the TLB page size depends on PMP entries. target/riscv: Fix the translation of physical address gitlab-ci/opensbi: Update GitLab CI to build generic platform hw/riscv: spike: Change the default bios to use generic platform image hw/riscv: Use pre-built bios image of generic platform for virt & sifive_u roms/Makefile: Build the generic platform for RISC-V OpenSBI firmware roms/opensbi: Upgrade from v0.7 to v0.8 configure: Create symbolic links for pc-bios/*.elf files riscv: Fix bug in setting pmpcfg CSR for RISCV64 hw/riscv: sifive_u: Add a dummy L2 cache controller device target/riscv: check before allocating TCG temps target/riscv: Clean up fmv.w.x target/riscv: Check nanboxed inputs in trans_rvf.inc.c target/riscv: Check nanboxed inputs to fp helpers target/riscv: Generate nanboxed results from trans_rvf.inc.c target/riscv: Generalize gen_nanbox_fpr to gen_nanbox_s target/riscv: Generate nanboxed results from fp helpers Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/intc')
| -rw-r--r-- | hw/intc/ibex_plic.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/hw/intc/ibex_plic.c b/hw/intc/ibex_plic.c index 41079518c6..f49fa67c91 100644 --- a/hw/intc/ibex_plic.c +++ b/hw/intc/ibex_plic.c @@ -43,12 +43,22 @@ static void ibex_plic_irqs_set_pending(IbexPlicState *s, int irq, bool level) { int pending_num = irq / 32; + if (s->claimed[pending_num] & 1 << (irq % 32)) { + /* + * The interrupt has been claimed, but not compelted. + * The pending bit can't be set. + */ + return; + } + s->pending[pending_num] |= level << (irq % 32); } static bool ibex_plic_irqs_pending(IbexPlicState *s, uint32_t context) { int i; + uint32_t max_irq = 0; + uint32_t max_prio = s->threshold; for (i = 0; i < s->pending_num; i++) { uint32_t irq_num = ctz64(s->pending[i]) + (i * 32); @@ -58,14 +68,17 @@ static bool ibex_plic_irqs_pending(IbexPlicState *s, uint32_t context) continue; } - if (s->priority[irq_num] > s->threshold) { - if (!s->claim) { - s->claim = irq_num; - } - return true; + if (s->priority[irq_num] > max_prio) { + max_irq = irq_num; + max_prio = s->priority[irq_num]; } } + if (max_irq) { + s->claim = max_irq; + return true; + } + return false; } @@ -120,7 +133,14 @@ 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 */ + s->claimed[pending_num] |= 1 << (s->claim % 32); + + /* Return the current claimed interrupt */ ret = s->claim; + + /* Update the interrupt status after the claim */ + ibex_plic_update(s); } return ret; @@ -140,6 +160,7 @@ static void ibex_plic_write(void *opaque, hwaddr addr, } else if (addr_between(addr, s->priority_base, s->priority_num)) { uint32_t irq = ((addr - s->priority_base) >> 2) + 1; s->priority[irq] = value & 7; + ibex_plic_update(s); } else if (addr_between(addr, s->enable_base, s->enable_num)) { uint32_t enable_reg = (addr - s->enable_base) / 4; @@ -151,6 +172,10 @@ static void ibex_plic_write(void *opaque, hwaddr addr, /* Interrupt was completed */ s->claim = 0; } + if (s->claimed[value / 32] & 1 << (value % 32)) { + /* This value was already claimed, clear it. */ + s->claimed[value / 32] &= ~(1 << (value % 32)); + } } ibex_plic_update(s); @@ -211,6 +236,7 @@ static void ibex_plic_realize(DeviceState *dev, Error **errp) int i; s->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); s->enable = g_new0(uint32_t, s->enable_num); |