From 3d016e2765f9ad5f34e471e345004c6e16438e3c Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 30 Apr 2018 15:06:52 -0700 Subject: [PATCH] Only break out of the simulator loop on WFI, not on CSR writes Breaking out of the loop on WFI was intended to let other threads run when the current thread has no work to do. There's no advantage to doing so on CSR writes, and the unintentional change in thread interleaving broke some test programs that relied on short timer periods. --- riscv/decode.h | 6 ++++++ riscv/execute.cc | 3 ++- riscv/insns/wfi.h | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/riscv/decode.h b/riscv/decode.h index 8fc8ada..9634f57 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -211,11 +211,17 @@ private: STATE.pc = __npc; \ } while(0) +#define wfi() \ + do { set_pc_and_serialize(npc); \ + npc = PC_SERIALIZE_WFI; \ + } while(0) + #define serialize() set_pc_and_serialize(npc) /* Sentinel PC values to serialize simulator pipeline */ #define PC_SERIALIZE_BEFORE 3 #define PC_SERIALIZE_AFTER 5 +#define PC_SERIALIZE_WFI 7 #define invalid_pc(pc) ((pc) & 1) /* Convenience wrappers to simplify softfloat code sequences */ diff --git a/riscv/execute.cc b/riscv/execute.cc index 9d1fb87..d7e586d 100644 --- a/riscv/execute.cc +++ b/riscv/execute.cc @@ -109,7 +109,8 @@ void processor_t::step(size_t n) if (unlikely(invalid_pc(pc))) { \ switch (pc) { \ case PC_SERIALIZE_BEFORE: state.serialized = true; break; \ - case PC_SERIALIZE_AFTER: n = ++instret; break; \ + case PC_SERIALIZE_AFTER: ++instret; break; \ + case PC_SERIALIZE_WFI: n = ++instret; break; \ default: abort(); \ } \ pc = state.pc; \ diff --git a/riscv/insns/wfi.h b/riscv/insns/wfi.h index 16de594..6504b78 100644 --- a/riscv/insns/wfi.h +++ b/riscv/insns/wfi.h @@ -1,2 +1,2 @@ require_privilege(get_field(STATE.mstatus, MSTATUS_TW) ? PRV_M : PRV_S); -set_pc_and_serialize(npc); +wfi(); -- 2.30.2