don't store host pointers in soft TLB
authorAndrew Waterman <waterman@cs.berkeley.edu>
Fri, 15 Feb 2013 08:25:01 +0000 (00:25 -0800)
committerAndrew Waterman <waterman@cs.berkeley.edu>
Fri, 15 Feb 2013 08:25:01 +0000 (00:25 -0800)
this reduces performance by epsilon, but it simplifies hooking into the MMU

riscv/mmu.cc
riscv/mmu.h

index 0cc10352a7aa3d9ce0165703e2f1177e078f5775..84c94592266fa84828c24172a08ae3322183cc7c 100644 (file)
@@ -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)
index 7400df825917e73651ade23824245e7642fcf717..b2a48e6f3b0d94375823a3ea5cf5a0bf41615c42 100644 (file)
@@ -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;