From c85ea7b98769a5a97faf9ec0d11bba3c0bc4cd3b Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 9 Jun 2016 12:33:43 -0700 Subject: [PATCH] Set badaddr on breakpoints --- rocket/src/main/scala/csr.scala | 18 ++++-------------- rocket/src/main/scala/rocket.scala | 24 +++++++++++++++--------- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/rocket/src/main/scala/csr.scala b/rocket/src/main/scala/csr.scala index 07210d88..8df9c129 100644 --- a/rocket/src/main/scala/csr.scala +++ b/rocket/src/main/scala/csr.scala @@ -118,6 +118,7 @@ class CSRFileIO(implicit p: Parameters) extends CoreBundle { val custom_mrw_csrs = Vec(nCustomMrwCsrs, UInt(INPUT, xLen)) val cause = UInt(INPUT, xLen) val pc = UInt(INPUT, vaddrBitsExtended) + val badaddr = UInt(INPUT, vaddrBitsExtended) val fatc = Bool(OUTPUT) val time = UInt(OUTPUT, xLen) val fcsr_rm = Bits(OUTPUT, FPConstants.RM_SZ) @@ -365,7 +366,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) Mux[UInt](insn_break, Causes.breakpoint, Causes.illegal_instruction))) val cause_lsbs = cause(log2Up(xLen)-1,0) val causeIsDebugInt = cause(xLen-1) && cause_lsbs === debugIntCause - val causeIsDebugBreak = insn_break && Cat(reg_dcsr.ebreakm, reg_dcsr.ebreakh, reg_dcsr.ebreaks, reg_dcsr.ebreaku)(reg_mstatus.prv) + val causeIsDebugBreak = cause === Causes.breakpoint && Cat(reg_dcsr.ebreakm, reg_dcsr.ebreakh, reg_dcsr.ebreaks, reg_dcsr.ebreaku)(reg_mstatus.prv) val trapToDebug = Bool(usingDebug) && (causeIsDebugInt || causeIsDebugBreak || reg_debug) val delegate = Bool(p(UseVM)) && reg_mstatus.prv < PRV.M && Mux(cause(xLen-1), reg_mideleg(cause_lsbs), reg_medeleg(cause_lsbs)) val debugTVec = Mux(reg_debug, UInt(0x808), UInt(0x800)) @@ -383,17 +384,6 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) io.status.sd_rv32 := io.status.sd when (io.exception || csr_xcpt) { - def compressVAddr(addr: UInt) = - if (vaddrBitsExtended == vaddrBits) addr - else { - val (upper, lower) = Split(addr, vaddrBits) - val sign = Mux(lower.toSInt < SInt(0), upper.andR, upper.orR) - Cat(sign, lower) - } - val ldst = - cause === Causes.fault_load || cause === Causes.misaligned_load || - cause === Causes.fault_store || cause === Causes.misaligned_store - val badaddr = Mux(ldst, compressVAddr(io.rw.wdata), io.pc) val epc = ~(~io.pc | (coreInstBytes-1)) val pie = read_mstatus(reg_mstatus.prv) @@ -405,7 +395,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) }.elsewhen (delegate) { reg_sepc := epc reg_scause := cause - reg_sbadaddr := badaddr + reg_sbadaddr := io.badaddr reg_mstatus.spie := pie reg_mstatus.spp := reg_mstatus.prv reg_mstatus.sie := false @@ -413,7 +403,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) }.otherwise { reg_mepc := epc reg_mcause := cause - reg_mbadaddr := badaddr + reg_mbadaddr := io.badaddr reg_mstatus.mpie := pie reg_mstatus.mpp := reg_mstatus.prv reg_mstatus.mie := false diff --git a/rocket/src/main/scala/rocket.scala b/rocket/src/main/scala/rocket.scala index 396c4b82..50f45f77 100644 --- a/rocket/src/main/scala/rocket.scala +++ b/rocket/src/main/scala/rocket.scala @@ -171,6 +171,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) { val wb_reg_valid = Reg(Bool()) val wb_reg_xcpt = Reg(Bool()) + val wb_reg_mem_xcpt = Reg(Bool()) val wb_reg_replay = Reg(Bool()) val wb_reg_cause = Reg(UInt()) val wb_reg_rocc_pending = Reg(init=Bool(false)) @@ -369,15 +370,18 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) { } } + val (mem_new_xcpt, mem_new_cause) = checkExceptions(List( + (mem_reg_load && bpu.io.xcpt_ld, UInt(Causes.breakpoint)), + (mem_reg_store && bpu.io.xcpt_st, UInt(Causes.breakpoint)), + (want_take_pc_mem && mem_npc_misaligned, UInt(Causes.misaligned_fetch)), + (mem_ctrl.mem && io.dmem.xcpt.ma.st, UInt(Causes.misaligned_store)), + (mem_ctrl.mem && io.dmem.xcpt.ma.ld, UInt(Causes.misaligned_load)), + (mem_ctrl.mem && io.dmem.xcpt.pf.st, UInt(Causes.fault_store)), + (mem_ctrl.mem && io.dmem.xcpt.pf.ld, UInt(Causes.fault_load)))) + val (mem_xcpt, mem_cause) = checkExceptions(List( - (mem_reg_xcpt_interrupt || mem_reg_xcpt, mem_reg_cause), - (mem_reg_valid && mem_reg_load && bpu.io.xcpt_ld, UInt(Causes.breakpoint)), - (mem_reg_valid && mem_reg_store && bpu.io.xcpt_st, UInt(Causes.breakpoint)), - (want_take_pc_mem && mem_npc_misaligned, UInt(Causes.misaligned_fetch)), - (mem_reg_valid && mem_ctrl.mem && io.dmem.xcpt.ma.st, UInt(Causes.misaligned_store)), - (mem_reg_valid && mem_ctrl.mem && io.dmem.xcpt.ma.ld, UInt(Causes.misaligned_load)), - (mem_reg_valid && mem_ctrl.mem && io.dmem.xcpt.pf.st, UInt(Causes.fault_store)), - (mem_reg_valid && mem_ctrl.mem && io.dmem.xcpt.pf.ld, UInt(Causes.fault_load)))) + (mem_reg_xcpt_interrupt || mem_reg_xcpt, mem_reg_cause), + (mem_reg_valid && mem_new_xcpt, mem_new_cause))) val dcache_kill_mem = mem_reg_valid && mem_ctrl.wxd && io.dmem.replay_next // structural hazard on writeback port val fpu_kill_mem = mem_reg_valid && mem_ctrl.fp && io.fpu.nack_mem @@ -390,6 +394,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) { wb_reg_valid := !ctrl_killm wb_reg_replay := replay_mem && !take_pc_wb wb_reg_xcpt := mem_xcpt && !take_pc_wb + wb_reg_mem_xcpt := mem_reg_valid && mem_new_xcpt && !(mem_reg_xcpt_interrupt || mem_reg_xcpt) when (mem_xcpt) { wb_reg_cause := mem_cause } when (mem_reg_valid || mem_reg_replay || mem_reg_xcpt_interrupt) { wb_ctrl := mem_ctrl @@ -459,6 +464,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) { io.rocc.csr <> csr.io.rocc.csr csr.io.rocc.interrupt <> io.rocc.interrupt csr.io.pc := wb_reg_pc + csr.io.badaddr := Mux(wb_reg_mem_xcpt, encodeVirtualAddress(wb_reg_wdata, wb_reg_wdata), wb_reg_pc) csr.io.uarch_counters.foreach(_ := Bool(false)) io.ptw.ptbr := csr.io.ptbr io.ptw.invalidate := csr.io.fatc @@ -625,7 +631,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) { def checkHazards(targets: Seq[(Bool, UInt)], cond: UInt => Bool) = targets.map(h => h._1 && cond(h._2)).reduce(_||_) - def encodeVirtualAddress(a0: UInt, ea: UInt) = if (xLen == 32) ea else { + def encodeVirtualAddress(a0: UInt, ea: UInt) = if (vaddrBitsExtended == vaddrBits) ea else { // efficient means to compress 64-bit VA into vaddrBits+1 bits // (VA is bad if VA(vaddrBits) != VA(vaddrBits-1)) val a = a0 >> vaddrBits-1