diff options
author | Andrew Waterman <andrew@sifive.com> | 2022-12-29 11:42:53 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-29 11:42:53 -0800 |
commit | f11c7b64b488a64a613bbc4ba02f83e929998d14 (patch) | |
tree | a8789fdecba029cb77804c4d9473a4c8ae475857 | |
parent | 591e6229238f914c5304df1b726e5b0d35d10f68 (diff) | |
parent | 20e7f5363b6a383b4baa01f3c8a9b29fc47549a4 (diff) | |
download | riscv-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.cc | 5 | ||||
-rw-r--r-- | riscv/processor.cc | 4 | ||||
-rw-r--r-- | riscv/processor.h | 1 |
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; |