aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2022-12-29 11:42:53 -0800
committerGitHub <noreply@github.com>2022-12-29 11:42:53 -0800
commitf11c7b64b488a64a613bbc4ba02f83e929998d14 (patch)
treea8789fdecba029cb77804c4d9473a4c8ae475857
parent591e6229238f914c5304df1b726e5b0d35d10f68 (diff)
parent20e7f5363b6a383b4baa01f3c8a9b29fc47549a4 (diff)
downloadriscv-isa-sim-f11c7b64b488a64a613bbc4ba02f83e929998d14.zip
riscv-isa-sim-f11c7b64b488a64a613bbc4ba02f83e929998d14.tar.gz
riscv-isa-sim-f11c7b64b488a64a613bbc4ba02f83e929998d14.tar.bz2
Merge pull request #1197 from riscv-software-src/wfi
Prevent processor_t from retiring instructions after a WFI
-rw-r--r--riscv/execute.cc5
-rw-r--r--riscv/processor.cc4
-rw-r--r--riscv/processor.h1
3 files changed, 10 insertions, 0 deletions
diff --git a/riscv/execute.cc b/riscv/execute.cc
index d36ccf6..c922602 100644
--- a/riscv/execute.cc
+++ b/riscv/execute.cc
@@ -242,6 +242,10 @@ void processor_t::step(size_t n)
try
{
take_pending_interrupt();
+ if (unlikely(in_wfi)) {
+ // No unmasked pending interrupt, so remain in wfi
+ throw wait_for_interrupt_t();
+ }
if (unlikely(slow_path()))
{
@@ -321,6 +325,7 @@ void processor_t::step(size_t n)
// allows us to switch to other threads only once per idle loop in case
// there is activity.
n = ++instret;
+ in_wfi = true;
}
state.minstret->bump(instret);
diff --git a/riscv/processor.cc b/riscv/processor.cc
index e289958..16fa77a 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -35,6 +35,7 @@ processor_t::processor_t(const isa_parser_t *isa, const char* varch,
: debug(false), halt_request(HR_NONE), isa(isa), sim(sim), id(id), xlen(0),
histogram_enabled(false), log_commits_enabled(false),
log_file(log_file), sout_(sout_.rdbuf()), halt_on_reset(halt_on_reset),
+ in_wfi(false),
impl_table(256, false), last_pc(1), executions(1), TM(4)
{
VU.p = this;
@@ -627,6 +628,9 @@ void processor_t::take_interrupt(reg_t pending_interrupts)
return;
}
+ // Exit WFI if there are any pending interrupts
+ in_wfi = false;
+
// M-ints have higher priority over HS-ints and VS-ints
const reg_t mie = get_field(state.mstatus->read(), MSTATUS_MIE);
const reg_t m_enabled = state.prv < PRV_M || (state.prv == PRV_M && mie);
diff --git a/riscv/processor.h b/riscv/processor.h
index 8bf2cc7..f65faf6 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -292,6 +292,7 @@ private:
FILE *log_file;
std::ostream sout_; // needed for socket command interface -s, also used for -d and -l, but not for --log
bool halt_on_reset;
+ bool in_wfi;
std::vector<bool> impl_table;
std::vector<insn_desc_t> instructions;