Update breakpoints to match @timsifive's debug spec
This commit is contained in:
parent
9ca82dd397
commit
1e3339e97c
@ -4,79 +4,80 @@ package rocket
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import Util._
|
import Util._
|
||||||
|
import uncore.util._
|
||||||
import cde.Parameters
|
import cde.Parameters
|
||||||
|
|
||||||
class TDRSelect(implicit p: Parameters) extends CoreBundle()(p) {
|
|
||||||
val tdrmode = Bool()
|
|
||||||
val reserved = UInt(width = xLen - 1 - log2Up(nTDR))
|
|
||||||
val tdrindex = UInt(width = log2Up(nTDR))
|
|
||||||
|
|
||||||
def nTDR = p(NBreakpoints)
|
|
||||||
}
|
|
||||||
|
|
||||||
class BPControl(implicit p: Parameters) extends CoreBundle()(p) {
|
class BPControl(implicit p: Parameters) extends CoreBundle()(p) {
|
||||||
val tdrtype = UInt(width = 4)
|
val ttype = UInt(width = 4)
|
||||||
val bpamaskmax = UInt(width = 5)
|
val dmode = Bool()
|
||||||
val reserved = UInt(width = xLen-28)
|
val maskmax = UInt(width = 6)
|
||||||
val bpaction = UInt(width = 8)
|
val reserved = UInt(width = xLen-24)
|
||||||
val bpmatch = UInt(width = 4)
|
val action = Bool()
|
||||||
|
val chain = Bool()
|
||||||
|
val zero = UInt(width = 2)
|
||||||
|
val tmatch = UInt(width = 2)
|
||||||
val m = Bool()
|
val m = Bool()
|
||||||
val h = Bool()
|
val h = Bool()
|
||||||
val s = Bool()
|
val s = Bool()
|
||||||
val u = Bool()
|
val u = Bool()
|
||||||
val r = Bool()
|
|
||||||
val w = Bool()
|
|
||||||
val x = Bool()
|
val x = Bool()
|
||||||
|
val w = Bool()
|
||||||
|
val r = Bool()
|
||||||
|
|
||||||
def tdrType = 1
|
def tType = 2
|
||||||
def bpaMaskMax = 4
|
def maskMax = 4
|
||||||
def enabled(mstatus: MStatus) = Cat(m, h, s, u)(mstatus.prv)
|
def enabled(mstatus: MStatus) = !mstatus.debug && Cat(m, h, s, u)(mstatus.prv)
|
||||||
}
|
}
|
||||||
|
|
||||||
class BP(implicit p: Parameters) extends CoreBundle()(p) {
|
class BP(implicit p: Parameters) extends CoreBundle()(p) {
|
||||||
val control = new BPControl
|
val control = new BPControl
|
||||||
val address = UInt(width = vaddrBits)
|
val address = UInt(width = vaddrBits)
|
||||||
|
|
||||||
def mask(dummy: Int = 0) = {
|
def mask(dummy: Int = 0) =
|
||||||
var mask: UInt = control.bpmatch(1)
|
(0 until control.maskMax-1).scanLeft(control.tmatch(0))((m, i) => m && address(i)).asUInt
|
||||||
for (i <- 1 until control.bpaMaskMax)
|
|
||||||
mask = Cat(mask(i-1) && address(i-1), mask)
|
|
||||||
mask
|
|
||||||
}
|
|
||||||
|
|
||||||
def pow2AddressMatch(x: UInt) =
|
def pow2AddressMatch(x: UInt) =
|
||||||
(~x | mask()) === (~address | mask())
|
(~x | mask()) === (~address | mask())
|
||||||
|
|
||||||
|
def rangeAddressMatch(x: UInt) =
|
||||||
|
(x >= address) ^ control.tmatch(0)
|
||||||
|
|
||||||
|
def addressMatch(x: UInt) =
|
||||||
|
Mux(control.tmatch(1), rangeAddressMatch(x), pow2AddressMatch(x))
|
||||||
}
|
}
|
||||||
|
|
||||||
class BreakpointUnit(implicit p: Parameters) extends CoreModule()(p) {
|
class BreakpointUnit(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val status = new MStatus().asInput
|
val status = new MStatus().asInput
|
||||||
val bp = Vec(p(NBreakpoints), new BP).asInput
|
val bp = Vec(n, new BP).asInput
|
||||||
val pc = UInt(INPUT, vaddrBits)
|
val pc = UInt(INPUT, vaddrBits)
|
||||||
val ea = UInt(INPUT, vaddrBits)
|
val ea = UInt(INPUT, vaddrBits)
|
||||||
val xcpt_if = Bool(OUTPUT)
|
val xcpt_if = Bool(OUTPUT)
|
||||||
val xcpt_ld = Bool(OUTPUT)
|
val xcpt_ld = Bool(OUTPUT)
|
||||||
val xcpt_st = Bool(OUTPUT)
|
val xcpt_st = Bool(OUTPUT)
|
||||||
|
val debug_if = Bool(OUTPUT)
|
||||||
|
val debug_ld = Bool(OUTPUT)
|
||||||
|
val debug_st = Bool(OUTPUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
io.xcpt_if := false
|
io.xcpt_if := false
|
||||||
io.xcpt_ld := false
|
io.xcpt_ld := false
|
||||||
io.xcpt_st := false
|
io.xcpt_st := false
|
||||||
|
io.debug_if := false
|
||||||
|
io.debug_ld := false
|
||||||
|
io.debug_st := false
|
||||||
|
|
||||||
for (bp <- io.bp) {
|
io.bp.foldLeft((Bool(true), Bool(true), Bool(true))) { case ((ri, wi, xi), bp) =>
|
||||||
when (bp.control.enabled(io.status)) {
|
val en = bp.control.enabled(io.status)
|
||||||
when (bp.pow2AddressMatch(io.pc) && bp.control.x) { io.xcpt_if := true }
|
val r = en && ri && bp.control.r && bp.addressMatch(io.ea)
|
||||||
when (bp.pow2AddressMatch(io.ea) && bp.control.r) { io.xcpt_ld := true }
|
val w = en && wi && bp.control.w && bp.addressMatch(io.ea)
|
||||||
when (bp.pow2AddressMatch(io.ea) && bp.control.w) { io.xcpt_st := true }
|
val x = en && xi && bp.control.x && bp.addressMatch(io.pc)
|
||||||
}
|
val end = !bp.control.chain
|
||||||
}
|
|
||||||
|
|
||||||
if (!io.bp.isEmpty) for ((bpl, bph) <- io.bp zip io.bp.tail) {
|
when (end && r) { io.xcpt_ld := !bp.control.action; io.debug_ld := bp.control.action }
|
||||||
def matches(x: UInt) = !(x < bpl.address) && x < bph.address
|
when (end && w) { io.xcpt_st := !bp.control.action; io.debug_st := bp.control.action }
|
||||||
when (bph.control.enabled(io.status) && bph.control.bpmatch === 1) {
|
when (end && x) { io.xcpt_if := !bp.control.action; io.debug_if := bp.control.action }
|
||||||
when (matches(io.pc) && bph.control.x) { io.xcpt_if := true }
|
|
||||||
when (matches(io.ea) && bph.control.r) { io.xcpt_ld := true }
|
(end || r, end || w, end || x)
|
||||||
when (matches(io.ea) && bph.control.w) { io.xcpt_st := true }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ class DCSR extends Bundle {
|
|||||||
val xdebugver = UInt(width = 2)
|
val xdebugver = UInt(width = 2)
|
||||||
val ndreset = Bool()
|
val ndreset = Bool()
|
||||||
val fullreset = Bool()
|
val fullreset = Bool()
|
||||||
val hwbpcount = UInt(width = 12)
|
val zero3 = UInt(width = 12)
|
||||||
val ebreakm = Bool()
|
val ebreakm = Bool()
|
||||||
val ebreakh = Bool()
|
val ebreakh = Bool()
|
||||||
val ebreaks = Bool()
|
val ebreaks = Bool()
|
||||||
@ -101,6 +101,11 @@ object CSR
|
|||||||
val R = UInt(5,SZ)
|
val R = UInt(5,SZ)
|
||||||
|
|
||||||
val ADDRSZ = 12
|
val ADDRSZ = 12
|
||||||
|
val debugIntCause = new MIP().getWidth
|
||||||
|
val debugTriggerCause = {
|
||||||
|
require(debugIntCause >= Causes.all.max)
|
||||||
|
debugIntCause
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CSRFileIO(implicit p: Parameters) extends CoreBundle {
|
class CSRFileIO(implicit p: Parameters) extends CoreBundle {
|
||||||
@ -133,7 +138,7 @@ 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 bp = Vec(p(NBreakpoints), new BP).asOutput
|
val bp = Vec(nBreakpoints, new BP).asOutput
|
||||||
}
|
}
|
||||||
|
|
||||||
class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
||||||
@ -155,12 +160,12 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
|
|
||||||
val (supported_interrupts, delegable_interrupts) = {
|
val (supported_interrupts, delegable_interrupts) = {
|
||||||
val sup = Wire(init=new MIP().fromBits(0))
|
val sup = Wire(init=new MIP().fromBits(0))
|
||||||
sup.ssip := Bool(p(UseVM))
|
sup.ssip := Bool(usingVM)
|
||||||
sup.msip := true
|
sup.msip := true
|
||||||
sup.stip := Bool(p(UseVM))
|
sup.stip := Bool(usingVM)
|
||||||
sup.mtip := true
|
sup.mtip := true
|
||||||
sup.meip := true
|
sup.meip := true
|
||||||
sup.seip := Bool(p(UseVM))
|
sup.seip := Bool(usingVM)
|
||||||
sup.rocc := usingRoCC
|
sup.rocc := usingRoCC
|
||||||
|
|
||||||
val del = Wire(init=sup)
|
val del = Wire(init=sup)
|
||||||
@ -189,8 +194,8 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
assert(!io.singleStep || io.retire <= UInt(1))
|
assert(!io.singleStep || io.retire <= UInt(1))
|
||||||
assert(!reg_singleStepped || io.retire === UInt(0))
|
assert(!reg_singleStepped || io.retire === UInt(0))
|
||||||
|
|
||||||
val reg_tdrselect = Reg(new TDRSelect)
|
val reg_tselect = Reg(UInt(width = log2Up(nBreakpoints)))
|
||||||
val reg_bp = Reg(Vec(1 << log2Up(p(NBreakpoints)), new BP))
|
val reg_bp = Reg(Vec(1 << log2Up(nBreakpoints), new BP))
|
||||||
|
|
||||||
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))
|
||||||
@ -228,13 +233,12 @@ 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.singleStep || reg_singleStepped
|
io.interrupt := all_interrupts.orR && !io.singleStep || reg_singleStepped
|
||||||
io.interrupt_cause := interruptCause
|
io.interrupt_cause := interruptCause
|
||||||
io.bp := reg_bp take p(NBreakpoints)
|
io.bp := reg_bp take nBreakpoints
|
||||||
|
|
||||||
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
|
||||||
when (Bool(usingDebug) && reg_dcsr.debugint && !reg_debug) {
|
when (Bool(usingDebug) && reg_dcsr.debugint && !reg_debug) {
|
||||||
io.interrupt := true
|
io.interrupt := true
|
||||||
io.interrupt_cause := interruptMSB + debugIntCause
|
io.interrupt_cause := interruptMSB + CSR.debugIntCause
|
||||||
}
|
}
|
||||||
|
|
||||||
val system_insn = io.rw.cmd === CSR.I
|
val system_insn = io.rw.cmd === CSR.I
|
||||||
@ -251,9 +255,9 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
val read_mstatus = io.status.asUInt()(xLen-1,0)
|
val read_mstatus = io.status.asUInt()(xLen-1,0)
|
||||||
|
|
||||||
val read_mapping = collection.mutable.LinkedHashMap[Int,Bits](
|
val read_mapping = collection.mutable.LinkedHashMap[Int,Bits](
|
||||||
CSRs.tdrselect -> reg_tdrselect.asUInt,
|
CSRs.tselect -> reg_tselect,
|
||||||
CSRs.tdrdata1 -> reg_bp(reg_tdrselect.tdrindex).control.asUInt,
|
CSRs.tdata1 -> reg_bp(reg_tselect).control.asUInt,
|
||||||
CSRs.tdrdata2 -> reg_bp(reg_tdrselect.tdrindex).address,
|
CSRs.tdata2 -> reg_bp(reg_tselect).address.sextTo(xLen),
|
||||||
CSRs.mimpid -> UInt(0),
|
CSRs.mimpid -> UInt(0),
|
||||||
CSRs.marchid -> UInt(0),
|
CSRs.marchid -> UInt(0),
|
||||||
CSRs.mvendorid -> UInt(0),
|
CSRs.mvendorid -> UInt(0),
|
||||||
@ -276,11 +280,14 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
CSRs.mcause -> reg_mcause,
|
CSRs.mcause -> reg_mcause,
|
||||||
CSRs.mhartid -> io.prci.id)
|
CSRs.mhartid -> io.prci.id)
|
||||||
|
|
||||||
if (usingDebug) {
|
val debug_csrs = collection.mutable.LinkedHashMap[Int,Bits](
|
||||||
read_mapping += CSRs.dcsr -> reg_dcsr.asUInt
|
CSRs.dcsr -> reg_dcsr.asUInt,
|
||||||
read_mapping += CSRs.dpc -> reg_dpc.asUInt
|
CSRs.dpc -> reg_dpc.asUInt,
|
||||||
read_mapping += CSRs.dscratch -> reg_dscratch.asUInt
|
CSRs.dscratch -> reg_dscratch.asUInt
|
||||||
}
|
)
|
||||||
|
|
||||||
|
if (usingDebug)
|
||||||
|
read_mapping ++= debug_csrs
|
||||||
|
|
||||||
if (usingFPU) {
|
if (usingFPU) {
|
||||||
read_mapping += CSRs.fflags -> reg_fflags
|
read_mapping += CSRs.fflags -> reg_fflags
|
||||||
@ -337,14 +344,17 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
val decoded_addr = read_mapping map { case (k, v) => k -> (io.rw.addr === k) }
|
val decoded_addr = read_mapping map { case (k, v) => k -> (io.rw.addr === k) }
|
||||||
|
|
||||||
val addr_valid = decoded_addr.values.reduce(_||_)
|
val addr_valid = decoded_addr.values.reduce(_||_)
|
||||||
val fp_csr =
|
val fp_csr =
|
||||||
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_addr_priv = 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 debug_csr_mask = 0x090 // only debug CSRs have address bits 7 and 4 set
|
||||||
|
require((read_mapping -- debug_csrs.keys).keys.forall(x => (x & debug_csr_mask) != debug_csr_mask))
|
||||||
|
require(debug_csrs.keys.forall(x => (x & debug_csr_mask) == debug_csr_mask))
|
||||||
|
val csr_debug = Bool(usingDebug) && (io.rw.addr & debug_csr_mask) === debug_csr_mask
|
||||||
|
val priv_sufficient = reg_debug || (!csr_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
|
||||||
val wen = cpu_wen && !read_only
|
val wen = cpu_wen && !read_only
|
||||||
@ -374,13 +384,14 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
Mux(insn_call, reg_mstatus.prv + Causes.user_ecall,
|
Mux(insn_call, reg_mstatus.prv + Causes.user_ecall,
|
||||||
Mux[UInt](insn_break, Causes.breakpoint, Causes.illegal_instruction)))
|
Mux[UInt](insn_break, Causes.breakpoint, Causes.illegal_instruction)))
|
||||||
val cause_lsbs = cause(log2Up(xLen)-1,0)
|
val cause_lsbs = cause(log2Up(xLen)-1,0)
|
||||||
val causeIsDebugInt = cause(xLen-1) && cause_lsbs === debugIntCause
|
val causeIsDebugInt = cause(xLen-1) && cause_lsbs === CSR.debugIntCause
|
||||||
val causeIsDebugBreak = cause === Causes.breakpoint && Cat(reg_dcsr.ebreakm, reg_dcsr.ebreakh, reg_dcsr.ebreaks, reg_dcsr.ebreaku)(reg_mstatus.prv)
|
val causeIsDebugTrigger = !cause(xLen-1) && cause_lsbs === CSR.debugTriggerCause
|
||||||
val trapToDebug = Bool(usingDebug) && (reg_singleStepped || causeIsDebugInt || causeIsDebugBreak || reg_debug)
|
val causeIsDebugBreak = !cause(xLen-1) && insn_break && Cat(reg_dcsr.ebreakm, reg_dcsr.ebreakh, reg_dcsr.ebreaks, reg_dcsr.ebreaku)(reg_mstatus.prv)
|
||||||
val delegate = Bool(p(UseVM)) && reg_mstatus.prv < PRV.M && Mux(cause(xLen-1), reg_mideleg(cause_lsbs), reg_medeleg(cause_lsbs))
|
val trapToDebug = Bool(usingDebug) && (reg_singleStepped || causeIsDebugInt || causeIsDebugTrigger || causeIsDebugBreak || reg_debug)
|
||||||
|
val delegate = Bool(usingVM) && 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))
|
val debugTVec = Mux(reg_debug, UInt(0x808), UInt(0x800))
|
||||||
val tvec = Mux(trapToDebug, debugTVec, Mux(delegate, reg_stvec.sextTo(vaddrBitsExtended), reg_mtvec))
|
val tvec = Mux(trapToDebug, debugTVec, Mux(delegate, reg_stvec.sextTo(vaddrBitsExtended), reg_mtvec))
|
||||||
val epc = Mux(csr_debug, reg_dpc, Mux(Bool(p(UseVM)) && !csr_addr_priv(1), reg_sepc, reg_mepc))
|
val epc = Mux(csr_debug, reg_dpc, Mux(Bool(usingVM) && !csr_addr_priv(1), reg_sepc, reg_mepc))
|
||||||
io.fatc := insn_sfence_vm
|
io.fatc := insn_sfence_vm
|
||||||
io.evec := Mux(exception, tvec, epc)
|
io.evec := Mux(exception, tvec, epc)
|
||||||
io.ptbr := reg_sptbr
|
io.ptbr := reg_sptbr
|
||||||
@ -403,7 +414,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
when (trapToDebug) {
|
when (trapToDebug) {
|
||||||
reg_debug := true
|
reg_debug := true
|
||||||
reg_dpc := epc
|
reg_dpc := epc
|
||||||
reg_dcsr.cause := Mux(reg_singleStepped, UInt(4), Mux(causeIsDebugInt, UInt(3), UInt(1)))
|
reg_dcsr.cause := Mux(reg_singleStepped, 4, Mux(causeIsDebugInt, 3, Mux[UInt](causeIsDebugTrigger, 2, 1)))
|
||||||
reg_dcsr.prv := trimPrivilege(reg_mstatus.prv)
|
reg_dcsr.prv := trimPrivilege(reg_mstatus.prv)
|
||||||
}.elsewhen (delegate) {
|
}.elsewhen (delegate) {
|
||||||
reg_sepc := epc
|
reg_sepc := epc
|
||||||
@ -425,7 +436,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
when (insn_ret) {
|
when (insn_ret) {
|
||||||
when (Bool(p(UseVM)) && !csr_addr_priv(1)) {
|
when (Bool(usingVM) && !csr_addr_priv(1)) {
|
||||||
when (reg_mstatus.spp.toBool) { reg_mstatus.sie := reg_mstatus.spie }
|
when (reg_mstatus.spp.toBool) { reg_mstatus.sie := reg_mstatus.spie }
|
||||||
reg_mstatus.spie := false
|
reg_mstatus.spie := false
|
||||||
reg_mstatus.spp := PRV.U
|
reg_mstatus.spp := PRV.U
|
||||||
@ -537,45 +548,48 @@ 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) {
|
if (nBreakpoints > 0) {
|
||||||
val newTDR = new TDRSelect().fromBits(wdata)
|
when (decoded_addr(CSRs.tselect)) { reg_tselect := wdata }
|
||||||
when (decoded_addr(CSRs.tdrselect)) { reg_tdrselect.tdrindex := newTDR.tdrindex }
|
|
||||||
|
|
||||||
when (reg_tdrselect.tdrmode || reg_debug) {
|
val bp = reg_bp(reg_tselect)
|
||||||
when (decoded_addr(CSRs.tdrdata1)) {
|
when (!bp.control.dmode || reg_debug) {
|
||||||
|
when (decoded_addr(CSRs.tdata1)) {
|
||||||
val newBPC = new BPControl().fromBits(wdata)
|
val newBPC = new BPControl().fromBits(wdata)
|
||||||
reg_bp(reg_tdrselect.tdrindex).control := newBPC
|
val dMode = newBPC.dmode && reg_debug
|
||||||
reg_bp(reg_tdrselect.tdrindex).control.bpmatch := newBPC.bpmatch & 2 /* exact/NAPOT only */
|
bp.control := newBPC
|
||||||
|
bp.control.dmode := dMode
|
||||||
|
bp.control.action := dMode && newBPC.action
|
||||||
}
|
}
|
||||||
when (decoded_addr(CSRs.tdrdata2)) { reg_bp(reg_tdrselect.tdrindex).address := wdata }
|
when (decoded_addr(CSRs.tdata2)) { bp.address := 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))
|
|
||||||
|
|
||||||
reg_sptbr.asid := 0
|
reg_sptbr.asid := 0
|
||||||
reg_tdrselect.reserved := 0
|
if (nBreakpoints <= 1) reg_tselect := 0
|
||||||
reg_tdrselect.tdrmode := true // TODO support D-mode breakpoint theft
|
if (nBreakpoints >= 1)
|
||||||
if (reg_bp.isEmpty) reg_tdrselect.tdrindex := 0
|
reg_bp(nBreakpoints-1).control.chain := false
|
||||||
for (bpc <- reg_bp map {_.control}) {
|
for (bpc <- reg_bp map {_.control}) {
|
||||||
bpc.tdrtype := bpc.tdrType
|
bpc.ttype := bpc.tType
|
||||||
bpc.bpamaskmax := bpc.bpaMaskMax
|
bpc.maskmax := bpc.maskMax
|
||||||
bpc.reserved := 0
|
bpc.reserved := 0
|
||||||
bpc.bpaction := 0
|
bpc.zero := 0
|
||||||
bpc.h := false
|
bpc.h := false
|
||||||
if (!usingVM) bpc.s := false
|
if (!usingVM) bpc.s := false
|
||||||
if (!usingUser) bpc.u := false
|
if (!usingUser) bpc.u := false
|
||||||
if (!usingVM && !usingUser) bpc.m := true
|
if (!usingVM && !usingUser) bpc.m := true
|
||||||
when (reset) {
|
when (reset) {
|
||||||
|
bpc.action := false
|
||||||
|
bpc.dmode := false
|
||||||
bpc.r := false
|
bpc.r := false
|
||||||
bpc.w := false
|
bpc.w := false
|
||||||
bpc.x := false
|
bpc.x := false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (bp <- reg_bp drop p(NBreakpoints))
|
for (bp <- reg_bp drop nBreakpoints)
|
||||||
bp := new BP().fromBits(0)
|
bp := new BP().fromBits(0)
|
||||||
|
|
||||||
def legalizePrivilege(priv: UInt): UInt =
|
def legalizePrivilege(priv: UInt): UInt =
|
||||||
|
@ -280,10 +280,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 tselect = 0x7a0
|
||||||
val tdrdata1 = 0x7a1
|
val tdata1 = 0x7a1
|
||||||
val tdrdata2 = 0x7a2
|
val tdata2 = 0x7a2
|
||||||
val tdrdata3 = 0x7a3
|
val tdata3 = 0x7a3
|
||||||
val dcsr = 0x7b0
|
val dcsr = 0x7b0
|
||||||
val dpc = 0x7b1
|
val dpc = 0x7b1
|
||||||
val dscratch = 0x7b2
|
val dscratch = 0x7b2
|
||||||
@ -346,10 +346,10 @@ object CSRs {
|
|||||||
res += mscycle_delta
|
res += mscycle_delta
|
||||||
res += mstime_delta
|
res += mstime_delta
|
||||||
res += msinstret_delta
|
res += msinstret_delta
|
||||||
res += tdrselect
|
res += tselect
|
||||||
res += tdrdata1
|
res += tdata1
|
||||||
res += tdrdata2
|
res += tdata2
|
||||||
res += tdrdata3
|
res += tdata3
|
||||||
res += dcsr
|
res += dcsr
|
||||||
res += dpc
|
res += dpc
|
||||||
res += dscratch
|
res += dscratch
|
||||||
|
@ -43,6 +43,7 @@ trait HasCoreParameters extends HasAddrMapParameters {
|
|||||||
val usingRoCC = !p(BuildRoCC).isEmpty
|
val usingRoCC = !p(BuildRoCC).isEmpty
|
||||||
val fastLoadWord = p(FastLoadWord)
|
val fastLoadWord = p(FastLoadWord)
|
||||||
val fastLoadByte = p(FastLoadByte)
|
val fastLoadByte = p(FastLoadByte)
|
||||||
|
val nBreakpoints = p(NBreakpoints)
|
||||||
|
|
||||||
val retireWidth = p(RetireWidth)
|
val retireWidth = p(RetireWidth)
|
||||||
val fetchWidth = p(FetchWidth)
|
val fetchWidth = p(FetchWidth)
|
||||||
@ -245,7 +246,7 @@ 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)
|
val bpu = Module(new BreakpointUnit(nBreakpoints))
|
||||||
bpu.io.status := csr.io.status
|
bpu.io.status := csr.io.status
|
||||||
bpu.io.bp := csr.io.bp
|
bpu.io.bp := csr.io.bp
|
||||||
bpu.io.pc := ibuf.io.pc
|
bpu.io.pc := ibuf.io.pc
|
||||||
@ -254,6 +255,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) {
|
|||||||
val id_xcpt_if = ibuf.io.inst(0).bits.pf0 || ibuf.io.inst(0).bits.pf1
|
val id_xcpt_if = ibuf.io.inst(0).bits.pf0 || ibuf.io.inst(0).bits.pf1
|
||||||
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.debug_if, UInt(CSR.debugTriggerCause)),
|
||||||
(bpu.io.xcpt_if, UInt(Causes.breakpoint)),
|
(bpu.io.xcpt_if, UInt(Causes.breakpoint)),
|
||||||
(id_xcpt_if, UInt(Causes.fault_fetch)),
|
(id_xcpt_if, UInt(Causes.fault_fetch)),
|
||||||
(id_illegal_insn, UInt(Causes.illegal_instruction))))
|
(id_illegal_insn, UInt(Causes.illegal_instruction))))
|
||||||
@ -408,7 +410,9 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val mem_breakpoint = (mem_reg_load && bpu.io.xcpt_ld) || (mem_reg_store && bpu.io.xcpt_st)
|
val mem_breakpoint = (mem_reg_load && bpu.io.xcpt_ld) || (mem_reg_store && bpu.io.xcpt_st)
|
||||||
|
val mem_debug_breakpoint = (mem_reg_load && bpu.io.debug_ld) || (mem_reg_store && bpu.io.debug_st)
|
||||||
val (mem_new_xcpt, mem_new_cause) = checkExceptions(List(
|
val (mem_new_xcpt, mem_new_cause) = checkExceptions(List(
|
||||||
|
(mem_debug_breakpoint, UInt(CSR.debugTriggerCause)),
|
||||||
(mem_breakpoint, UInt(Causes.breakpoint)),
|
(mem_breakpoint, UInt(Causes.breakpoint)),
|
||||||
(mem_npc_misaligned, UInt(Causes.misaligned_fetch)),
|
(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.st, UInt(Causes.misaligned_store)),
|
||||||
|
Loading…
Reference in New Issue
Block a user