aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2023-04-25 14:44:17 -0700
committerGitHub <noreply@github.com>2023-04-25 14:44:17 -0700
commit87e0a1f86e16e4d3048e0afe7b2c51c821a108ed (patch)
tree73e2c39fbb500bb8c3d4661d6f3d45d46b3e3522
parent19a7f343af6fa197f3234e0630d10bd1e8db9849 (diff)
parent960755b19263cb2924dd2906482600b4ad99e21f (diff)
downloadriscv-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.h1
-rw-r--r--riscv/plic.cc22
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;