aboutsummaryrefslogtreecommitdiff
path: root/riscv/plic.cc
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2023-02-04 18:02:19 -0800
committerAndrew Waterman <andrew@sifive.com>2023-03-01 13:34:07 -0800
commitef1638be6cdb6cfb77d77f5ae233e5e196e40125 (patch)
tree07839eb485f33bd71701a0222fc4609eae01fabc /riscv/plic.cc
parentb6d8da39bca349352b69913ef1b2b88b31ddc5b5 (diff)
downloadriscv-isa-sim-ef1638be6cdb6cfb77d77f5ae233e5e196e40125.zip
riscv-isa-sim-ef1638be6cdb6cfb77d77f5ae233e5e196e40125.tar.gz
riscv-isa-sim-ef1638be6cdb6cfb77d77f5ae233e5e196e40125.tar.bz2
Correctly instantiate PLIC contexts for mixed-hart targets
This commit started as an attempt to make the PLIC tolerant of discontiguous hart IDs, but it turns out it was already most of the way there: PLIC contexts can still be dense even if the hart IDs are not. Nevertheless, I wanted to avoid passing the procs vector directly to the plic_t constructor. In removing it, I realized I could also get rid of the smode parameter by querying whether each hart has S-mode. This is also more correct; previously, we were instantiating the PLIC as though all harts had S-mode, regardless of whether they actually did.
Diffstat (limited to 'riscv/plic.cc')
-rw-r--r--riscv/plic.cc13
1 files changed, 8 insertions, 5 deletions
diff --git a/riscv/plic.cc b/riscv/plic.cc
index 45fadd7..5aa0923 100644
--- a/riscv/plic.cc
+++ b/riscv/plic.cc
@@ -1,6 +1,7 @@
#include <sys/time.h>
#include "devices.h"
#include "processor.h"
+#include "sim.h"
#define PLIC_MAX_CONTEXTS 15872
@@ -66,15 +67,17 @@
#define REG_SIZE 0x1000000
-plic_t::plic_t(std::vector<processor_t*>& procs, bool smode, uint32_t ndev)
+plic_t::plic_t(sim_t* sim, uint32_t ndev)
: num_ids(ndev + 1), num_ids_word(((ndev + 1) + (32 - 1)) / 32),
max_prio((1UL << PLIC_PRIO_BITS) - 1), priority{}, level{}
{
- size_t contexts_per_hart = smode ? 2 : 1;
- size_t num_contexts = procs.size() * (smode ? 2 : 1);
+ // PLIC contexts are contiguous in memory even if harts are discontiguous.
+ for (const auto& [hart_id, hart] : sim->get_harts()) {
+ contexts.push_back(plic_context_t(hart, true));
- for (size_t i = 0; i < num_contexts; i++) {
- contexts.push_back(plic_context_t(procs[i / contexts_per_hart], i % contexts_per_hart == 0));
+ if (hart->extension_enabled_const('S')) {
+ contexts.push_back(plic_context_t(hart, false));
+ }
}
}