diff options
author | Anup Patel <anup@brainfault.org> | 2021-12-14 11:25:55 +0530 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2022-04-20 10:20:10 +0530 |
commit | 5a433081f4ce1a49ee83d1a81cf4922e7542a20c (patch) | |
tree | c99dfe8db908caf9319c905e5bba388b3206d43a /riscv/devices.h | |
parent | d5b1a65c0e3a0b6b46eb66d5d0284bf3a6cc1e0c (diff) | |
download | spike-5a433081f4ce1a49ee83d1a81cf4922e7542a20c.zip spike-5a433081f4ce1a49ee83d1a81cf4922e7542a20c.tar.gz spike-5a433081f4ce1a49ee83d1a81cf4922e7542a20c.tar.bz2 |
Add PLIC emulation
We need an interrupt controller in Spike which will allow us to
emulate more real-world devices such as UART, VirtIO net, VirtIO
block, etc.
The RISC-V PLIC (or SiFive PLIC) is the commonly used interrupt
controller in existing RISC-V platforms so this patch adds PLIC
emulation for Spike.
Signed-off-by: Anup Patel <anup@brainfault.org>
Diffstat (limited to 'riscv/devices.h')
-rw-r--r-- | riscv/devices.h | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/riscv/devices.h b/riscv/devices.h index 934904a..c9e4f66 100644 --- a/riscv/devices.h +++ b/riscv/devices.h @@ -72,6 +72,51 @@ class clint_t : public abstract_device_t { std::vector<mtimecmp_t> mtimecmp; }; +#define PLIC_MAX_DEVICES 1024 + +struct plic_context { + uint32_t num; + processor_t *proc; + bool mmode; + + uint8_t priority_threshold; + uint32_t enable[PLIC_MAX_DEVICES/32]; + uint32_t pending[PLIC_MAX_DEVICES/32]; + uint8_t pending_priority[PLIC_MAX_DEVICES]; + uint32_t claimed[PLIC_MAX_DEVICES/32]; +}; +typedef struct plic_context plic_context_t; + +class plic_t : public abstract_device_t, public abstract_interrupt_controller_t { + public: + plic_t(std::vector<processor_t*>&, bool smode, uint32_t ndev); + bool load(reg_t addr, size_t len, uint8_t* bytes); + bool store(reg_t addr, size_t len, const uint8_t* bytes); + void set_interrupt_level(uint32_t id, int lvl); + size_t size() { return PLIC_SIZE; } + private: + std::vector<processor_t*>& procs; + std::vector<plic_context_t> contexts; + uint32_t num_ids; + uint32_t num_ids_word; + uint32_t max_prio; + uint8_t priority[PLIC_MAX_DEVICES]; + uint32_t level[PLIC_MAX_DEVICES/32]; + uint32_t context_best_pending(plic_context_t *c); + void context_update(plic_context_t *context); + 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 context_enable_read(plic_context_t *context, + reg_t offset, uint32_t *val); + bool context_enable_write(plic_context_t *context, + reg_t offset, uint32_t val); + bool context_read(plic_context_t *context, + reg_t offset, uint32_t *val); + bool context_write(plic_context_t *context, + reg_t offset, uint32_t val); +}; + class mmio_plugin_device_t : public abstract_device_t { public: mmio_plugin_device_t(const std::string& name, const std::string& args); |