1
0

Add provisional breakpoint support

This commit is contained in:
Andrew Waterman 2016-06-08 20:19:52 -07:00
parent 4f2e2480a8
commit e3c17b5f74
4 changed files with 101 additions and 2 deletions

View File

@ -0,0 +1,45 @@
// See LICENSE for license details.
package rocket
import Chisel._
import Util._
import cde.Parameters
class BPControl extends Bundle {
val matchcond = UInt(width = 2)
val m = Bool()
val h = Bool()
val s = Bool()
val u = Bool()
val r = Bool()
val w = Bool()
val x = Bool()
}
class BreakpointUnit(implicit p: Parameters) extends CoreModule()(p) {
val io = new Bundle {
val bpcontrol = Vec(p(NBreakpoints), new BPControl).asInput
val bpaddress = Vec(p(NBreakpoints), UInt(width = vaddrBits)).asInput
val pc = UInt(INPUT, vaddrBits)
val ea = UInt(INPUT, vaddrBits)
val xcpt_if = Bool(OUTPUT)
val xcpt_ld = Bool(OUTPUT)
val xcpt_st = Bool(OUTPUT)
}
io.xcpt_if := false
io.xcpt_ld := false
io.xcpt_st := false
for (((bpc, bpa), i) <- io.bpcontrol zip io.bpaddress zipWithIndex) {
var mask: UInt = bpc.matchcond(1)
for (i <- 1 until log2Ceil(16))
mask = Cat(mask(i-1) && bpa(i-1), mask)
def matches(x: UInt) = (~x | mask) === (~bpa | mask)
when (matches(io.pc) && bpc.x) { io.xcpt_if := true }
when (matches(io.ea) && bpc.r) { io.xcpt_ld := true }
when (matches(io.ea) && bpc.w) { io.xcpt_st := true }
}
}

View File

@ -7,7 +7,6 @@ import Util._
import Instructions._ import Instructions._
import cde.{Parameters, Field} import cde.{Parameters, Field}
import uncore._ import uncore._
import scala.math._
import junctions.AddrMap import junctions.AddrMap
class MStatus extends Bundle { class MStatus extends Bundle {
@ -126,6 +125,8 @@ class CSRFileIO(implicit p: Parameters) extends CoreBundle {
val rocc = new RoCCInterface().flip val rocc = new RoCCInterface().flip
val interrupt = Bool(OUTPUT) val interrupt = Bool(OUTPUT)
val interrupt_cause = UInt(OUTPUT, xLen) val interrupt_cause = UInt(OUTPUT, xLen)
val bpcontrol = Vec(p(NBreakpoints), new BPControl).asOutput
val bpaddress = Vec(p(NBreakpoints), UInt(width = vaddrBits)).asOutput
} }
class CSRFile(implicit p: Parameters) extends CoreModule()(p) class CSRFile(implicit p: Parameters) extends CoreModule()(p)
@ -171,6 +172,10 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
val reg_dpc = Reg(UInt(width = vaddrBitsExtended)) val reg_dpc = Reg(UInt(width = vaddrBitsExtended))
val reg_dscratch = Reg(UInt(width = xLen)) val reg_dscratch = Reg(UInt(width = xLen))
val reg_tdrselect = Reg(init=UInt(0, log2Up(p(NBreakpoints))))
val reg_bpcontrol = Reg(Vec(p(NBreakpoints), new BPControl))
val reg_bpaddress = Reg(Vec(p(NBreakpoints), UInt(width = vaddrBits)))
val reg_mie = Reg(init=UInt(0, xLen)) val reg_mie = Reg(init=UInt(0, xLen))
val reg_mideleg = Reg(init=UInt(0, xLen)) val reg_mideleg = Reg(init=UInt(0, xLen))
val reg_medeleg = Reg(init=UInt(0, xLen)) val reg_medeleg = Reg(init=UInt(0, xLen))
@ -208,6 +213,8 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
val interruptCause = interruptMSB + PriorityEncoder(all_interrupts) val interruptCause = interruptMSB + PriorityEncoder(all_interrupts)
io.interrupt := all_interrupts.orR io.interrupt := all_interrupts.orR
io.interrupt_cause := interruptCause io.interrupt_cause := interruptCause
io.bpcontrol := reg_bpcontrol
io.bpaddress := reg_bpaddress
val debugIntCause = reg_mip.getWidth val debugIntCause = reg_mip.getWidth
// debug interrupts are only masked by being in debug mode // debug interrupts are only masked by being in debug mode
@ -229,6 +236,9 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
val read_mstatus = io.status.toBits()(xLen-1,0) val read_mstatus = io.status.toBits()(xLen-1,0)
val read_mapping = collection.mutable.LinkedHashMap[Int,Bits]( val read_mapping = collection.mutable.LinkedHashMap[Int,Bits](
CSRs.tdrselect -> reg_tdrselect,
CSRs.tdrdata1 -> (if (p(NBreakpoints) > 0) reg_bpcontrol(reg_tdrselect).toBits else UInt(0)),
CSRs.tdrdata2 -> (if (p(NBreakpoints) > 0) reg_bpaddress(reg_tdrselect) else UInt(0)),
CSRs.mimpid -> UInt(0), CSRs.mimpid -> UInt(0),
CSRs.marchid -> UInt(0), CSRs.marchid -> UInt(0),
CSRs.mvendorid -> UInt(0), CSRs.mvendorid -> UInt(0),
@ -324,7 +334,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
if (usingFPU) decoded_addr(CSRs.fflags) || decoded_addr(CSRs.frm) || decoded_addr(CSRs.fcsr) if (usingFPU) decoded_addr(CSRs.fflags) || decoded_addr(CSRs.frm) || decoded_addr(CSRs.fcsr)
else Bool(false) else Bool(false)
val csr_debug = Bool(usingDebug) && io.rw.addr(5) val csr_debug = Bool(usingDebug) && io.rw.addr(5)
val csr_addr_priv = Cat(io.rw.addr(5), io.rw.addr(9,8)) val csr_addr_priv = Cat(io.rw.addr(6,5).andR, io.rw.addr(9,8))
val priv_sufficient = Cat(reg_debug, reg_mstatus.prv) >= csr_addr_priv val priv_sufficient = Cat(reg_debug, reg_mstatus.prv) >= csr_addr_priv
val read_only = io.rw.addr(11,10).andR val read_only = io.rw.addr(11,10).andR
val cpu_wen = cpu_ren && io.rw.cmd =/= CSR.R && priv_sufficient val cpu_wen = cpu_ren && io.rw.cmd =/= CSR.R && priv_sufficient
@ -523,10 +533,20 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
when (decoded_addr(CSRs.mideleg)) { reg_mideleg := wdata & delegable_interrupts } when (decoded_addr(CSRs.mideleg)) { reg_mideleg := wdata & delegable_interrupts }
when (decoded_addr(CSRs.medeleg)) { reg_medeleg := wdata & delegable_exceptions } when (decoded_addr(CSRs.medeleg)) { reg_medeleg := wdata & delegable_exceptions }
} }
if (p(NBreakpoints) > 0) {
when (decoded_addr(CSRs.tdrselect)) { reg_tdrselect := Mux(wdata(log2Up(p(NBreakpoints))-1,0) >= UInt(p(NBreakpoints)), UInt(0), wdata(log2Up(p(NBreakpoints))-1,0)) }
when (decoded_addr(CSRs.tdrdata1)) {
val newBPC = new BPControl().fromBits(wdata)
reg_bpcontrol(reg_tdrselect) := newBPC
reg_bpcontrol(reg_tdrselect).matchcond := newBPC.matchcond | 1 /* exact/range only */
}
when (decoded_addr(CSRs.tdrdata2)) { reg_bpaddress(reg_tdrselect) := wdata }
}
} }
reg_mip := io.prci.interrupts reg_mip := io.prci.interrupts
reg_dcsr.debugint := io.prci.interrupts.debug reg_dcsr.debugint := io.prci.interrupts.debug
reg_dcsr.hwbpcount := UInt(p(NBreakpoints))
io.rocc.csr.waddr := io.rw.addr io.rocc.csr.waddr := io.rw.addr
io.rocc.csr.wdata := wdata io.rocc.csr.wdata := wdata
@ -537,4 +557,16 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
reg_mstatus.prv := PRV.M reg_mstatus.prv := PRV.M
reg_mstatus.mprv := false reg_mstatus.mprv := false
} }
for (bpc <- reg_bpcontrol) {
bpc.h := false
if (!usingVM) bpc.s := false
if (!usingUser) bpc.u := false
if (!usingVM && !usingUser) bpc.m := true
when (reset) {
bpc.r := false
bpc.w := false
bpc.x := false
}
}
} }

View File

@ -281,6 +281,10 @@ object CSRs {
val mscycle_delta = 0x704 val mscycle_delta = 0x704
val mstime_delta = 0x705 val mstime_delta = 0x705
val msinstret_delta = 0x706 val msinstret_delta = 0x706
val tdrselect = 0x7a0
val tdrdata1 = 0x7a1
val tdrdata2 = 0x7a2
val tdrdata3 = 0x7a3
val dcsr = 0x7b0 val dcsr = 0x7b0
val dpc = 0x7b1 val dpc = 0x7b1
val dscratch = 0x7b2 val dscratch = 0x7b2
@ -344,6 +348,10 @@ object CSRs {
res += mscycle_delta res += mscycle_delta
res += mstime_delta res += mstime_delta
res += msinstret_delta res += msinstret_delta
res += tdrselect
res += tdrdata1
res += tdrdata2
res += tdrdata3
res += dcsr res += dcsr
res += dpc res += dpc
res += dscratch res += dscratch

View File

@ -28,6 +28,7 @@ case object NCustomMRWCSRs extends Field[Int]
case object MtvecWritable extends Field[Boolean] case object MtvecWritable extends Field[Boolean]
case object MtvecInit extends Field[BigInt] case object MtvecInit extends Field[BigInt]
case object ResetVector extends Field[BigInt] case object ResetVector extends Field[BigInt]
case object NBreakpoints extends Field[Int]
trait HasCoreParameters extends HasAddrMapParameters { trait HasCoreParameters extends HasAddrMapParameters {
implicit val p: Parameters implicit val p: Parameters
@ -160,6 +161,8 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) {
val mem_reg_flush_pipe = Reg(Bool()) val mem_reg_flush_pipe = Reg(Bool())
val mem_reg_cause = Reg(UInt()) val mem_reg_cause = Reg(UInt())
val mem_reg_slow_bypass = Reg(Bool()) val mem_reg_slow_bypass = Reg(Bool())
val mem_reg_load = Reg(Bool())
val mem_reg_store = Reg(Bool())
val mem_reg_pc = Reg(UInt()) val mem_reg_pc = Reg(UInt())
val mem_reg_inst = Reg(Bits()) val mem_reg_inst = Reg(Bits())
val mem_reg_wdata = Reg(Bits()) val mem_reg_wdata = Reg(Bits())
@ -222,8 +225,15 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) {
val id_do_fence = id_rocc_busy && id_ctrl.fence || val id_do_fence = id_rocc_busy && id_ctrl.fence ||
id_mem_busy && (id_ctrl.amo && id_amo_aq || id_ctrl.fence_i || id_reg_fence && (id_ctrl.mem || id_ctrl.rocc) || id_csr_en) id_mem_busy && (id_ctrl.amo && id_amo_aq || id_ctrl.fence_i || id_reg_fence && (id_ctrl.mem || id_ctrl.rocc) || id_csr_en)
val bpu = Module(new BreakpointUnit)
bpu.io.bpcontrol := csr.io.bpcontrol
bpu.io.bpaddress := csr.io.bpaddress
bpu.io.pc := id_pc
bpu.io.ea := mem_reg_wdata
val (id_xcpt, id_cause) = checkExceptions(List( val (id_xcpt, id_cause) = checkExceptions(List(
(csr.io.interrupt, csr.io.interrupt_cause), (csr.io.interrupt, csr.io.interrupt_cause),
(bpu.io.xcpt_if, UInt(Causes.breakpoint)),
(io.imem.resp.bits.xcpt_if, UInt(Causes.fault_fetch)), (io.imem.resp.bits.xcpt_if, UInt(Causes.fault_fetch)),
(id_illegal_insn, UInt(Causes.illegal_instruction)))) (id_illegal_insn, UInt(Causes.illegal_instruction))))
@ -344,6 +354,8 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) {
when (ex_reg_valid || ex_reg_xcpt_interrupt) { when (ex_reg_valid || ex_reg_xcpt_interrupt) {
mem_ctrl := ex_ctrl mem_ctrl := ex_ctrl
mem_reg_load := ex_ctrl.mem && isRead(ex_ctrl.mem_cmd)
mem_reg_store := ex_ctrl.mem && isWrite(ex_ctrl.mem_cmd)
mem_reg_btb_hit := ex_reg_btb_hit mem_reg_btb_hit := ex_reg_btb_hit
when (ex_reg_btb_hit) { mem_reg_btb_resp := ex_reg_btb_resp } when (ex_reg_btb_hit) { mem_reg_btb_resp := ex_reg_btb_resp }
mem_reg_flush_pipe := ex_reg_flush_pipe mem_reg_flush_pipe := ex_reg_flush_pipe
@ -359,6 +371,8 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) {
val (mem_xcpt, mem_cause) = checkExceptions(List( val (mem_xcpt, mem_cause) = checkExceptions(List(
(mem_reg_xcpt_interrupt || mem_reg_xcpt, mem_reg_cause), (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)), (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.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.ma.ld, UInt(Causes.misaligned_load)),