diff options
author | Jiajie Chen <c@jia.je> | 2023-03-13 12:09:08 +0800 |
---|---|---|
committer | Jiajie Chen <c@jia.je> | 2023-04-07 01:00:46 +0800 |
commit | 960755b19263cb2924dd2906482600b4ad99e21f (patch) | |
tree | b750b09577f56cdf09f5396b822622de90fa6468 /riscv/plic.cc | |
parent | eb75ab37a17ff4f8597b7b40283a08c38d2a6ff6 (diff) | |
download | riscv-isa-sim-960755b19263cb2924dd2906482600b4ad99e21f.zip riscv-isa-sim-960755b19263cb2924dd2906482600b4ad99e21f.tar.gz riscv-isa-sim-960755b19263cb2924dd2906482600b4ad99e21f.tar.bz2 |
Implement pending bits for plic
Diffstat (limited to 'riscv/plic.cc')
-rw-r--r-- | riscv/plic.cc | 22 |
1 files changed, 21 insertions, 1 deletions
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; |