Browse Source

Fix I$ simulator not making forward progress

mvp
Andrew Waterman 12 years ago
parent
commit
6c99f30d78
  1. 10
      riscv/mmu.h
  2. 28
      riscv/processor.cc

10
riscv/mmu.h

@ -78,11 +78,11 @@ public:
store_func(uint64) store_func(uint64)
// load instruction from memory at aligned address. // load instruction from memory at aligned address.
inline icache_entry_t access_icache(reg_t addr) inline icache_entry_t* access_icache(reg_t addr)
{ {
reg_t idx = (addr / sizeof(insn_t)) % ICACHE_SIZE; reg_t idx = (addr / sizeof(insn_t)) % ICACHE_SIZE;
icache_entry_t entry = icache[idx]; icache_entry_t* entry = &icache[idx];
if (likely(entry.tag == addr)) if (likely(entry->tag == addr))
return entry; return entry;
void* iaddr = translate(addr, sizeof(insn_t), false, true); void* iaddr = translate(addr, sizeof(insn_t), false, true);
@ -99,12 +99,12 @@ public:
icache[idx].tag = -1; icache[idx].tag = -1;
tracer.trace(paddr, sizeof(insn_t), false, true); tracer.trace(paddr, sizeof(insn_t), false, true);
} }
return icache[idx]; return &icache[idx];
} }
inline insn_fetch_t load_insn(reg_t addr) inline insn_fetch_t load_insn(reg_t addr)
{ {
return access_icache(addr).data; return access_icache(addr)->data;
} }
void set_processor(processor_t* p) { proc = p; flush_tlb(); } void set_processor(processor_t* p) { proc = p; flush_tlb(); }

28
riscv/processor.cc

@ -130,31 +130,27 @@ void processor_t::step(size_t n)
else while (n > 0) else while (n > 0)
{ {
size_t idx = (state.pc / sizeof(insn_t)) % ICACHE_SIZE; size_t idx = (state.pc / sizeof(insn_t)) % ICACHE_SIZE;
auto ic_entry_init = &_mmu->icache[idx], ic_entry = ic_entry_init; auto ic_entry = _mmu->access_icache(state.pc), ic_entry_init = ic_entry;
#define update_count() { \
size_t i = ic_entry - ic_entry_init; \
state.count += i; \
if (i >= n) break; \
n -= i; }
#define ICACHE_ACCESS(idx) { \ #define ICACHE_ACCESS(idx) { \
insn_t insn = ic_entry->data.insn.insn; \ insn_t insn = ic_entry->data.insn.insn; \
insn_func_t func = ic_entry->data.func; \ insn_func_t func = ic_entry->data.func; \
if (unlikely(ic_entry->tag != state.pc)) break; \
ic_entry++; \
commit_log(&state, insn); \ commit_log(&state, insn); \
state.pc = func(this, insn, state.pc); } ic_entry++; \
state.pc = func(this, insn, state.pc); \
if (idx < ICACHE_SIZE-1 && unlikely(ic_entry->tag != state.pc)) break; \
}
switch (idx) while (true) switch (idx)
{ {
ICACHE_SWITCH; ICACHE_SWITCH; // auto-generated into icache.h
update_count();
ic_entry_init = ic_entry = &_mmu->icache[0];
} }
_mmu->access_icache(state.pc); size_t i = ic_entry - ic_entry_init;
update_count(); state.count += i;
if (i >= n)
break;
n -= i;
} }
} }
catch(trap_t& t) catch(trap_t& t)

Loading…
Cancel
Save