Browse Source

don't store host pointers in soft TLB

this reduces performance by epsilon, but it simplifies hooking into the MMU
confprec
Andrew Waterman 13 years ago
parent
commit
3e4e4191f4
  1. 6
      riscv/mmu.cc
  2. 33
      riscv/mmu.h

6
riscv/mmu.cc

@ -27,7 +27,7 @@ void mmu_t::flush_tlb()
flush_icache();
}
void* mmu_t::refill_tlb(reg_t addr, reg_t bytes, bool store, bool fetch)
reg_t mmu_t::refill_tlb(reg_t addr, reg_t bytes, bool store, bool fetch)
{
reg_t idx = (addr >> PGSHIFT) % TLB_ENTRIES;
reg_t expected_tag = addr & ~(PGSIZE-1);
@ -60,10 +60,10 @@ void* mmu_t::refill_tlb(reg_t addr, reg_t bytes, bool store, bool fetch)
tlb_load_tag[idx] = (pte_perm & PTE_UR) ? expected_tag : -1;
tlb_store_tag[idx] = (pte_perm & PTE_UW) ? expected_tag : -1;
tlb_insn_tag[idx] = (pte_perm & PTE_UX) ? expected_tag : -1;
tlb_data[idx] = (char*)mem + pgbase;
tlb_data[idx] = pgbase;
}
return (char*)mem + paddr;
return paddr;
}
pte_t mmu_t::walk(reg_t addr)

33
riscv/mmu.h

@ -51,8 +51,8 @@ public:
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
@ -75,8 +75,8 @@ public:
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
@ -102,16 +102,16 @@ public:
#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;
}
@ -122,18 +122,21 @@ public:
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];
@ -169,7 +172,7 @@ private:
// 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];
@ -181,13 +184,13 @@ private:
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;

Loading…
Cancel
Save