diff options
author | Andrew Waterman <andrew@sifive.com> | 2023-04-25 14:44:17 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-25 14:44:17 -0700 |
commit | 87e0a1f86e16e4d3048e0afe7b2c51c821a108ed (patch) | |
tree | 73e2c39fbb500bb8c3d4661d6f3d45d46b3e3522 | |
parent | 19a7f343af6fa197f3234e0630d10bd1e8db9849 (diff) | |
parent | 960755b19263cb2924dd2906482600b4ad99e21f (diff) | |
download | riscv-isa-sim-87e0a1f86e16e4d3048e0afe7b2c51c821a108ed.zip riscv-isa-sim-87e0a1f86e16e4d3048e0afe7b2c51c821a108ed.tar.gz riscv-isa-sim-87e0a1f86e16e4d3048e0afe7b2c51c821a108ed.tar.bz2 |
Merge pull request #1281 from jiegec/plic-pending
Implement pending bits for plic
-rw-r--r-- | riscv/devices.h | 1 | ||||
-rw-r--r-- | riscv/plic.cc | 22 |
2 files changed, 22 insertions, 1 deletions
diff --git a/riscv/devices.h b/riscv/devices.h index 0b12f00..02d9e98 100644 --- a/riscv/devices.h +++ b/riscv/devices.h @@ -114,6 +114,7 @@ class plic_t : public abstract_device_t, public abstract_interrupt_controller_t uint32_t context_claim(plic_context_t *c); bool priority_read(reg_t offset, uint32_t *val); bool priority_write(reg_t offset, uint32_t val); + bool pending_read(reg_t offset, uint32_t *val); bool context_enable_read(const plic_context_t *context, reg_t offset, uint32_t *val); bool context_enable_write(plic_context_t *context, diff --git a/riscv/plic.cc b/riscv/plic.cc index aeec229..37a5f53 100644 --- a/riscv/plic.cc +++ b/riscv/plic.cc @@ -48,6 +48,9 @@ #define PRIORITY_BASE 0 #define PRIORITY_PER_ID 4 +/* Each interrupt source has a pending bit associated with it. */ +#define PENDING_BASE 0x1000 + /* * Each hart context has a vector of interupt enable bits associated with it. * There's one bit for each interrupt source. @@ -156,6 +159,21 @@ bool plic_t::priority_write(reg_t offset, uint32_t val) return true; } +bool plic_t::pending_read(reg_t offset, uint32_t *val) +{ + uint32_t id_word = (offset >> 2); + + if (id_word < num_ids_word) { + *val = 0; + for (auto context: contexts) { + *val |= context.pending[id_word]; + } + } else + *val = 0; + + return true; +} + bool plic_t::context_enable_read(const plic_context_t *c, reg_t offset, uint32_t *val) { @@ -313,8 +331,10 @@ bool plic_t::load(reg_t addr, size_t len, uint8_t* bytes) return false; } - if (PRIORITY_BASE <= addr && addr < ENABLE_BASE) { + if (PRIORITY_BASE <= addr && addr < PENDING_BASE) { ret = priority_read(addr, &val); + } else if (PENDING_BASE <= addr && addr < ENABLE_BASE) { + ret = pending_read(addr - PENDING_BASE, &val); } else if (ENABLE_BASE <= addr && addr < CONTEXT_BASE) { uint32_t cntx = (addr - ENABLE_BASE) / ENABLE_PER_HART; addr -= cntx * ENABLE_PER_HART + ENABLE_BASE; |