Add provisional breakpoint support
This commit is contained in:
parent
4f2e2480a8
commit
e3c17b5f74
45
rocket/src/main/scala/breakpoint.scala
Normal file
45
rocket/src/main/scala/breakpoint.scala
Normal 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 }
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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)),
|
||||||
|
Loading…
Reference in New Issue
Block a user