diff options
author | Alistair Francis <alistair.francis@wdc.com> | 2022-01-06 07:39:31 +1000 |
---|---|---|
committer | Alistair Francis <alistair.francis@wdc.com> | 2022-01-08 15:46:09 +1000 |
commit | fb926d57cc56499523f1559f58371e09198ed75e (patch) | |
tree | 892dd7cfe1c9b56752d3f0aa836e7008c825f71d /hw | |
parent | 83b92b8efca6634406361d62dbf9d3e8369a2a20 (diff) | |
download | qemu-fb926d57cc56499523f1559f58371e09198ed75e.zip qemu-fb926d57cc56499523f1559f58371e09198ed75e.tar.gz qemu-fb926d57cc56499523f1559f58371e09198ed75e.tar.bz2 |
hw/intc: sifive_plic: Cleanup the write function
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Message-Id: <20220105213937.1113508-3-alistair.francis@opensource.wdc.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/intc/sifive_plic.c | 76 |
1 files changed, 27 insertions, 49 deletions
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c index a9f7a1b..698492c 100644 --- a/hw/intc/sifive_plic.c +++ b/hw/intc/sifive_plic.c @@ -33,6 +33,11 @@ #define RISCV_DEBUG_PLIC 0 +static bool addr_between(uint32_t addr, uint32_t base, uint32_t num) +{ + return addr >= base && addr - base < num; +} + static PLICMode char_to_mode(char c) { switch (c) { @@ -269,80 +274,53 @@ static void sifive_plic_write(void *opaque, hwaddr addr, uint64_t value, { SiFivePLICState *plic = opaque; - /* writes must be 4 byte words */ - if ((addr & 0x3) != 0) { - goto err; - } - - if (addr >= plic->priority_base && /* 4 bytes per source */ - addr < plic->priority_base + (plic->num_sources << 2)) - { + if (addr_between(addr, plic->priority_base, plic->num_sources << 2)) { uint32_t irq = ((addr - plic->priority_base) >> 2) + 1; + plic->source_priority[irq] = value & 7; - if (RISCV_DEBUG_PLIC) { - qemu_log("plic: write priority: irq=%d priority=%d\n", - irq, plic->source_priority[irq]); - } sifive_plic_update(plic); - return; - } else if (addr >= plic->pending_base && /* 1 bit per source */ - addr < plic->pending_base + (plic->num_sources >> 3)) - { + } else if (addr_between(addr, plic->pending_base, + plic->num_sources >> 3)) { qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid pending write: 0x%" HWADDR_PRIx "", __func__, addr); - return; - } else if (addr >= plic->enable_base && /* 1 bit per source */ - addr < plic->enable_base + plic->num_addrs * plic->enable_stride) - { + } else if (addr_between(addr, plic->enable_base, + plic->num_addrs * plic->enable_stride)) { uint32_t addrid = (addr - plic->enable_base) / plic->enable_stride; uint32_t wordid = (addr & (plic->enable_stride - 1)) >> 2; + if (wordid < plic->bitfield_words) { plic->enable[addrid * plic->bitfield_words + wordid] = value; - if (RISCV_DEBUG_PLIC) { - qemu_log("plic: write enable: hart%d-%c word=%d value=%x\n", - plic->addr_config[addrid].hartid, - mode_to_char(plic->addr_config[addrid].mode), wordid, - plic->enable[addrid * plic->bitfield_words + wordid]); - } - return; + } else { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Invalid enable write 0x%" HWADDR_PRIx "\n", + __func__, addr); } - } else if (addr >= plic->context_base && /* 4 bytes per reg */ - addr < plic->context_base + plic->num_addrs * plic->context_stride) - { + } else if (addr_between(addr, plic->context_base, + plic->num_addrs * plic->context_stride)) { uint32_t addrid = (addr - plic->context_base) / plic->context_stride; uint32_t contextid = (addr & (plic->context_stride - 1)); + if (contextid == 0) { - if (RISCV_DEBUG_PLIC) { - qemu_log("plic: write priority: hart%d-%c priority=%x\n", - plic->addr_config[addrid].hartid, - mode_to_char(plic->addr_config[addrid].mode), - plic->target_priority[addrid]); - } if (value <= plic->num_priorities) { plic->target_priority[addrid] = value; sifive_plic_update(plic); } - return; } else if (contextid == 4) { - if (RISCV_DEBUG_PLIC) { - qemu_log("plic: write claim: hart%d-%c irq=%x\n", - plic->addr_config[addrid].hartid, - mode_to_char(plic->addr_config[addrid].mode), - (uint32_t)value); - } if (value < plic->num_sources) { sifive_plic_set_claimed(plic, value, false); sifive_plic_update(plic); } - return; + } else { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Invalid context write 0x%" HWADDR_PRIx "\n", + __func__, addr); } + } else { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Invalid register write 0x%" HWADDR_PRIx "\n", + __func__, addr); } - -err: - qemu_log_mask(LOG_GUEST_ERROR, - "%s: Invalid register write 0x%" HWADDR_PRIx "\n", - __func__, addr); } static const MemoryRegionOps sifive_plic_ops = { |