badvaddr = addr; \
throw trap_load_address_misaligned; \
} \
- void* paddr = translate(addr, sizeof(type##_t), false, false); \
- return *(type##_t*)paddr; \
+ reg_t paddr = translate(addr, sizeof(type##_t), false, false); \
+ return *(type##_t*)(mem + paddr); \
}
// load value from memory at aligned address; zero extend to register width
badvaddr = addr; \
throw trap_store_address_misaligned; \
} \
- void* paddr = translate(addr, sizeof(type##_t), true, false); \
- *(type##_t*)paddr = val; \
+ reg_t paddr = translate(addr, sizeof(type##_t), true, false); \
+ *(type##_t*)(mem + paddr) = val; \
}
// store value to memory at aligned address
#ifdef RISCV_ENABLE_RVC
if(addr % 4 == 2 && rvc) // fetch across word boundary
{
- void* addr_lo = translate(addr, 2, false, true);
+ reg_t addr_lo = translate(addr, 2, false, true);
insn_fetch_t fetch;
- fetch.insn.bits = *(uint16_t*)addr_lo;
+ fetch.insn.bits = *(uint16_t*)(mem + addr_lo);
size_t dispatch_idx = fetch.insn.bits % processor_t::DISPATCH_TABLE_SIZE;
fetch.func = processor_t::dispatch_table[dispatch_idx];
if(!INSN_IS_RVC(fetch.insn.bits))
{
- void* addr_hi = translate(addr+2, 2, false, true);
- fetch.insn.bits |= (uint32_t)*(uint16_t*)addr_hi << 16;
+ reg_t addr_hi = translate(addr+2, 2, false, true);
+ fetch.insn.bits |= (uint32_t)*(uint16_t*)(mem + addr_hi) << 16;
}
return fetch;
}
insn_fetch_t fetch;
if (unlikely(icache_tag[idx] != addr))
{
- void* paddr = translate(addr, sizeof(insn_t), false, true);
- fetch.insn = *(insn_t*)paddr;
+ reg_t paddr = translate(addr, sizeof(insn_t), false, true);
+ fetch.insn = *(insn_t*)(mem + paddr);
size_t dispatch_idx = fetch.insn.bits % processor_t::DISPATCH_TABLE_SIZE;
fetch.func = processor_t::dispatch_table[dispatch_idx];
- reg_t idx = ((uintptr_t)paddr/sizeof(insn_t)) % ICACHE_ENTRIES;
+ reg_t idx = (paddr/sizeof(insn_t)) % ICACHE_ENTRIES;
icache_tag[idx] = addr;
icache_data[idx] = fetch.insn;
icache_func[idx] = fetch.func;
- if (tracer.interested_in_range(addr, addr + sizeof(insn_t), false, true))
+ if (tracer.interested_in_range(paddr, paddr + sizeof(insn_t), false, true))
+ {
icache_tag[idx] = -1;
+ tracer.trace(paddr, sizeof(insn_t), false, true);
+ }
}
fetch.insn = icache_data[idx];;
fetch.func = icache_func[idx];
// implement a TLB for simulator performance
static const reg_t TLB_ENTRIES = 256;
- char* tlb_data[TLB_ENTRIES];
+ reg_t tlb_data[TLB_ENTRIES];
reg_t tlb_insn_tag[TLB_ENTRIES];
reg_t tlb_load_tag[TLB_ENTRIES];
reg_t tlb_store_tag[TLB_ENTRIES];
reg_t icache_tag[ICACHE_ENTRIES];
// finish translation on a TLB miss and upate the TLB
- void* refill_tlb(reg_t addr, reg_t bytes, bool store, bool fetch);
+ reg_t refill_tlb(reg_t addr, reg_t bytes, bool store, bool fetch);
// perform a page table walk for a given virtual address
pte_t walk(reg_t addr);
// translate a virtual address to a physical address
- void* translate(reg_t addr, reg_t bytes, bool store, bool fetch)
+ reg_t translate(reg_t addr, reg_t bytes, bool store, bool fetch)
{
reg_t idx = (addr >> PGSHIFT) % TLB_ENTRIES;