From 9eb988a4c6bad33ede6106cbd76b0e826a13ece1 Mon Sep 17 00:00:00 2001 From: Howard Mao Date: Tue, 22 Sep 2015 09:42:27 -0700 Subject: [PATCH] make sure access to invalid physical address treated as exception --- rocket/src/main/scala/icache.scala | 4 +++- rocket/src/main/scala/nbdcache.scala | 5 ++--- rocket/src/main/scala/rocket.scala | 1 + rocket/src/main/scala/tlb.scala | 16 +++++++++++----- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/rocket/src/main/scala/icache.scala b/rocket/src/main/scala/icache.scala index b6ea99ff..f9650b95 100644 --- a/rocket/src/main/scala/icache.scala +++ b/rocket/src/main/scala/icache.scala @@ -106,7 +106,9 @@ class Frontend(btb_updates_out_of_order: Boolean = false) extends FrontendModule icache.io.req.bits.idx := io.cpu.npc icache.io.invalidate := io.cpu.invalidate icache.io.req.bits.ppn := tlb.io.resp.ppn - icache.io.req.bits.kill := io.cpu.req.valid || tlb.io.resp.miss || icmiss || io.ptw.invalidate + icache.io.req.bits.kill := io.cpu.req.valid || + tlb.io.resp.miss || tlb.io.resp.xcpt_if || + icmiss || io.ptw.invalidate icache.io.resp.ready := !stall && !s1_same_block io.cpu.resp.valid := s2_valid && (s2_xcpt_if || icache.io.resp.valid) diff --git a/rocket/src/main/scala/nbdcache.scala b/rocket/src/main/scala/nbdcache.scala index 1a401f0f..b7aff715 100644 --- a/rocket/src/main/scala/nbdcache.scala +++ b/rocket/src/main/scala/nbdcache.scala @@ -32,7 +32,6 @@ abstract trait L1HellaCacheParameters extends L1CacheParameters { val sdqDepth = params(StoreDataQueueDepth) val nMSHRs = params(NMSHRs) val nIOMSHRs = params(NIOMSHRs) - val mmioBase = params(MMIOBase) } abstract class L1HellaCacheBundle extends Bundle with L1HellaCacheParameters @@ -788,8 +787,8 @@ class HellaCache extends L1HellaCacheModule { io.cpu.xcpt.ma.ld := s1_read && misaligned io.cpu.xcpt.ma.st := s1_write && misaligned - io.cpu.xcpt.pf.ld := !s1_req.phys && s1_read && dtlb.io.resp.xcpt_ld - io.cpu.xcpt.pf.st := !s1_req.phys && s1_write && dtlb.io.resp.xcpt_st + io.cpu.xcpt.pf.ld := s1_read && dtlb.io.resp.xcpt_ld + io.cpu.xcpt.pf.st := s1_write && dtlb.io.resp.xcpt_st assert (!(Reg(next= (io.cpu.xcpt.ma.ld || io.cpu.xcpt.ma.st || io.cpu.xcpt.pf.ld || io.cpu.xcpt.pf.st)) && diff --git a/rocket/src/main/scala/rocket.scala b/rocket/src/main/scala/rocket.scala index cead7ad2..f8d9e862 100644 --- a/rocket/src/main/scala/rocket.scala +++ b/rocket/src/main/scala/rocket.scala @@ -42,6 +42,7 @@ abstract trait CoreParameters extends UsesParameters { val coreDCacheReqTagBits = params(CoreDCacheReqTagBits) val coreMaxAddrBits = math.max(ppnBits,vpnBits+1) + pgIdxBits val vaddrBitsExtended = vaddrBits + (vaddrBits < xLen).toInt + val mmioBase = params(MMIOBase) // Print out log of committed instructions and their writeback values. // Requires post-processing due to out-of-order writebacks. diff --git a/rocket/src/main/scala/tlb.scala b/rocket/src/main/scala/tlb.scala index 87569e10..16f370f3 100644 --- a/rocket/src/main/scala/tlb.scala +++ b/rocket/src/main/scala/tlb.scala @@ -157,20 +157,26 @@ class TLB extends TLBModule { val vm_enabled = io.ptw.status.vm(3) && priv_uses_vm val bad_va = io.req.bits.vpn(vpnBits) != io.req.bits.vpn(vpnBits-1) + val bad_pa = !vm_enabled && io.req.bits.vpn >= UInt(mmioBase >> vpnBits) // it's only a store hit if the dirty bit is set val tag_hits = tag_cam.io.hits & (dirty_array.toBits | ~Mux(io.req.bits.store, w_array, UInt(0))) val tag_hit = tag_hits.orR val tlb_hit = vm_enabled && tag_hit val tlb_miss = vm_enabled && !tag_hit && !bad_va - + when (io.req.valid && tlb_hit) { plru.access(OHToUInt(tag_cam.io.hits)) } + val addrMap = params(NASTIAddrHashMap) + val paddr = Cat(io.resp.ppn, UInt(0, pgIdxBits)) + val addr_ok = addrMap.isValid(paddr) + val addr_prot = addrMap.getProt(paddr) + io.req.ready := state === s_ready - io.resp.xcpt_ld := bad_va || tlb_hit && !(r_array & tag_cam.io.hits).orR - io.resp.xcpt_st := bad_va || tlb_hit && !(w_array & tag_cam.io.hits).orR - io.resp.xcpt_if := bad_va || tlb_hit && !(x_array & tag_cam.io.hits).orR + io.resp.xcpt_ld := !addr_ok || !addr_prot.r || bad_va || tlb_hit && !(r_array & tag_cam.io.hits).orR + io.resp.xcpt_st := !addr_ok || !addr_prot.w || bad_va || tlb_hit && !(w_array & tag_cam.io.hits).orR + io.resp.xcpt_if := !addr_ok || !addr_prot.x || bad_va || tlb_hit && !(x_array & tag_cam.io.hits).orR io.resp.miss := tlb_miss io.resp.ppn := Mux(vm_enabled && !io.req.bits.passthrough, Mux1H(tag_cam.io.hits, tag_ram), io.req.bits.vpn(params(PPNBits)-1,0)) io.resp.hit_idx := tag_cam.io.hits @@ -186,7 +192,7 @@ class TLB extends TLBModule { io.ptw.req.bits.store := r_req.store io.ptw.req.bits.fetch := r_req.instruction - when (io.req.fire() && tlb_miss) { + when (io.req.fire() && tlb_miss && addr_ok) { state := s_request r_refill_tag := lookup_tag r_refill_waddr := repl_waddr