Browse Source

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.
pull/204/head
Andrew Waterman 8 years ago
parent
commit
3d016e2765
  1. 6
      riscv/decode.h
  2. 3
      riscv/execute.cc
  3. 2
      riscv/insns/wfi.h

6
riscv/decode.h

@ -211,11 +211,17 @@ private:
STATE.pc = __npc; \ STATE.pc = __npc; \
} while(0) } while(0)
#define wfi() \
do { set_pc_and_serialize(npc); \
npc = PC_SERIALIZE_WFI; \
} while(0)
#define serialize() set_pc_and_serialize(npc) #define serialize() set_pc_and_serialize(npc)
/* Sentinel PC values to serialize simulator pipeline */ /* Sentinel PC values to serialize simulator pipeline */
#define PC_SERIALIZE_BEFORE 3 #define PC_SERIALIZE_BEFORE 3
#define PC_SERIALIZE_AFTER 5 #define PC_SERIALIZE_AFTER 5
#define PC_SERIALIZE_WFI 7
#define invalid_pc(pc) ((pc) & 1) #define invalid_pc(pc) ((pc) & 1)
/* Convenience wrappers to simplify softfloat code sequences */ /* Convenience wrappers to simplify softfloat code sequences */

3
riscv/execute.cc

@ -109,7 +109,8 @@ void processor_t::step(size_t n)
if (unlikely(invalid_pc(pc))) { \ if (unlikely(invalid_pc(pc))) { \
switch (pc) { \ switch (pc) { \
case PC_SERIALIZE_BEFORE: state.serialized = true; break; \ 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(); \ default: abort(); \
} \ } \
pc = state.pc; \ pc = state.pc; \

2
riscv/insns/wfi.h

@ -1,2 +1,2 @@
require_privilege(get_field(STATE.mstatus, MSTATUS_TW) ? PRV_M : PRV_S); require_privilege(get_field(STATE.mstatus, MSTATUS_TW) ? PRV_M : PRV_S);
set_pc_and_serialize(npc); wfi();

Loading…
Cancel
Save