1
0

First stab at debug interrupts

This commit is contained in:
Andrew Waterman 2016-06-01 16:57:10 -07:00
parent 51379621d6
commit 9949347569
6 changed files with 108 additions and 18 deletions

View File

@ -11,6 +11,7 @@ import scala.math._
import junctions.AddrHashMap
class MStatus extends Bundle {
val debug = Bool() // not truly part of mstatus, but convenient
val prv = UInt(width = PRV.SZ) // not truly part of mstatus, but convenient
val sd = Bool()
val zero3 = UInt(width = 31)
@ -35,6 +36,26 @@ class MStatus extends Bundle {
val uie = Bool()
}
class DCSR extends Bundle {
val xdebugver = UInt(width = 2)
val ndreset = Bool()
val fullreset = Bool()
val hwbpcount = UInt(width = 12)
val ebreakm = Bool()
val ebreakh = Bool()
val ebreaks = Bool()
val ebreaku = Bool()
val zero2 = Bool()
val stopcycle = Bool()
val stoptime = Bool()
val cause = UInt(width = 3)
val debugint = Bool()
val zero1 = Bool()
val halt = Bool()
val step = Bool()
val prv = UInt(width = PRV.SZ)
}
class MIP extends Bundle {
val rocc = Bool()
val meip = Bool()
@ -116,6 +137,11 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
reset_mstatus.prv := PRV.M
val reg_mstatus = Reg(init=reset_mstatus)
val reset_dcsr = Wire(init=new DCSR().fromBits(0))
reset_dcsr.xdebugver := 1
reset_dcsr.prv := PRV.M
val reg_dcsr = Reg(init=reset_dcsr)
val (supported_interrupts, delegable_interrupts) = {
val sup = Wire(init=new MIP().fromBits(0))
sup.ssip := Bool(p(UseVM))
@ -141,6 +167,10 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
Causes.fault_store,
Causes.user_ecall).map(1 << _).sum)
val reg_debug = Reg(init=Bool(false))
val reg_dpc = Reg(UInt(width = vaddrBitsExtended))
val reg_dscratch = Reg(UInt(width = xLen))
val reg_mie = Reg(init=UInt(0, xLen))
val reg_mideleg = Reg(init=UInt(0, xLen))
val reg_medeleg = Reg(init=UInt(0, xLen))
@ -171,11 +201,20 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
val read_mip = mip.toBits & supported_interrupts
val pending_interrupts = read_mip & reg_mie
val m_interrupts = Mux(reg_mstatus.prv < PRV.M || (reg_mstatus.prv === PRV.M && reg_mstatus.mie), pending_interrupts & ~reg_mideleg, UInt(0))
val s_interrupts = Mux(reg_mstatus.prv < PRV.S || (reg_mstatus.prv === PRV.S && reg_mstatus.sie), pending_interrupts & reg_mideleg, UInt(0))
val m_interrupts = Mux(!reg_debug && (reg_mstatus.prv < PRV.M || (reg_mstatus.prv === PRV.M && reg_mstatus.mie)), pending_interrupts & ~reg_mideleg, UInt(0))
val s_interrupts = Mux(!reg_debug && (reg_mstatus.prv < PRV.S || (reg_mstatus.prv === PRV.S && reg_mstatus.sie)), pending_interrupts & reg_mideleg, UInt(0))
val all_interrupts = m_interrupts | s_interrupts
val interruptMSB = BigInt(1) << (xLen-1)
val interruptCause = interruptMSB + PriorityEncoder(all_interrupts)
io.interrupt := all_interrupts.orR
io.interrupt_cause := (io.interrupt << (xLen-1)) + PriorityEncoder(all_interrupts)
io.interrupt_cause := interruptCause
val debugIntCause = reg_mip.getWidth
// debug interrupts are only masked by being in debug mode
when (Bool(usingDebug) && reg_dcsr.debugint && !reg_debug) {
io.interrupt := true
io.interrupt_cause := interruptMSB + debugIntCause
}
val system_insn = io.rw.cmd === CSR.I
val cpu_ren = io.rw.cmd =/= CSR.N && !system_insn
@ -212,6 +251,12 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
CSRs.mcause -> reg_mcause,
CSRs.mhartid -> io.prci.id)
if (usingDebug) {
read_mapping += CSRs.dcsr -> reg_dcsr.toBits
read_mapping += CSRs.dpc -> reg_dpc.toBits
read_mapping += CSRs.dscratch -> reg_dscratch.toBits
}
if (usingFPU) {
read_mapping += CSRs.fflags -> reg_fflags
read_mapping += CSRs.frm -> reg_frm
@ -278,8 +323,9 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
val fp_csr =
if (usingFPU) decoded_addr(CSRs.fflags) || decoded_addr(CSRs.frm) || decoded_addr(CSRs.fcsr)
else Bool(false)
val csr_addr_priv = io.rw.addr(9,8)
val priv_sufficient = reg_mstatus.prv >= csr_addr_priv
val csr_debug = Bool(usingDebug) && io.rw.addr(5)
val csr_addr_priv = Cat(io.rw.addr(5), io.rw.addr(9,8))
val priv_sufficient = Cat(reg_debug, reg_mstatus.prv) >= csr_addr_priv
val read_only = io.rw.addr(11,10).andR
val cpu_wen = cpu_ren && io.rw.cmd =/= CSR.R && priv_sufficient
val wen = cpu_wen && !read_only
@ -308,9 +354,12 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
Mux(insn_call, reg_mstatus.prv + Causes.user_ecall,
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 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 tvec = Mux(delegate, reg_stvec.sextTo(vaddrBitsExtended), reg_mtvec)
val epc = Mux(Bool(p(UseVM)) && !csr_addr_priv(1), reg_sepc, reg_mepc)
val tvec = Mux(trapToDebug, UInt(0x800), 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))
io.fatc := insn_sfence_vm
io.evec := Mux(io.exception || csr_xcpt, tvec, epc)
io.ptbr := reg_sptbr
@ -318,6 +367,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
io.eret := insn_ret
io.status := reg_mstatus
io.status.sd := io.status.fs.andR || io.status.xs.andR
io.status.debug := reg_debug
if (xLen == 32)
io.status.sd_rv32 := io.status.sd
@ -336,7 +386,12 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
val epc = ~(~io.pc | (coreInstBytes-1))
val pie = read_mstatus(reg_mstatus.prv)
when (delegate) {
when (trapToDebug) {
reg_debug := true
reg_dpc := epc
reg_dcsr.cause := Mux(causeIsDebugInt, UInt(3), UInt(1))
reg_dcsr.prv := reg_mstatus.prv
}.elsewhen (delegate) {
reg_sepc := epc
reg_scause := cause
reg_sbadaddr := badaddr
@ -361,6 +416,9 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
reg_mstatus.spie := false
reg_mstatus.spp := PRV.U
reg_mstatus.prv := reg_mstatus.spp
}.elsewhen (csr_debug) {
reg_mstatus.prv := reg_dcsr.prv
reg_debug := false
}.otherwise {
when (reg_mstatus.mpp(1)) { reg_mstatus.mie := reg_mstatus.mpie }
.elsewhen (Bool(usingVM) && reg_mstatus.mpp(0)) { reg_mstatus.sie := reg_mstatus.mpie }
@ -382,13 +440,14 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
reg_fflags := reg_fflags | io.fcsr_flags.bits
}
val supportedModes = Vec((PRV.M +: (if (usingUser) Some(PRV.U) else None) ++: (if (usingVM) Seq(PRV.S) else Nil)).map(UInt(_)))
when (wen) {
when (decoded_addr(CSRs.mstatus)) {
val new_mstatus = new MStatus().fromBits(wdata)
reg_mstatus.mie := new_mstatus.mie
reg_mstatus.mpie := new_mstatus.mpie
val supportedModes = Vec((PRV.M +: (if (usingUser) Some(PRV.U) else None) ++: (if (usingVM) Seq(PRV.S) else Nil)).map(UInt(_)))
if (supportedModes.size > 1) {
reg_mstatus.mprv := new_mstatus.mprv
when (supportedModes contains new_mstatus.mpp) { reg_mstatus.mpp := new_mstatus.mpp }
@ -428,6 +487,17 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
when (decoded_addr(CSRs.frm)) { reg_frm := wdata }
when (decoded_addr(CSRs.fcsr)) { reg_fflags := wdata; reg_frm := wdata >> reg_fflags.getWidth }
}
if (usingDebug) {
when (decoded_addr(CSRs.dcsr)) {
val new_dcsr = new DCSR().fromBits(wdata)
reg_dcsr.ebreakm := new_dcsr.ebreakm
if (usingVM) reg_dcsr.ebreaks := new_dcsr.ebreaks
if (usingUser) reg_dcsr.ebreaku := new_dcsr.ebreaku
if (supportedModes.size > 1) reg_dcsr.prv := new_dcsr.prv
}
when (decoded_addr(CSRs.dpc)) { reg_dpc := ~(~wdata | (coreInstBytes-1)) }
when (decoded_addr(CSRs.dscratch)) { reg_dscratch := wdata }
}
if (usingVM) {
when (decoded_addr(CSRs.sstatus)) {
val new_sstatus = new MStatus().fromBits(wdata)
@ -455,6 +525,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
}
reg_mip := io.prci.interrupts
reg_dcsr.debugint := io.prci.interrupts.debug
io.rocc.csr.waddr := io.rw.addr
io.rocc.csr.wdata := wdata

View File

@ -110,10 +110,8 @@ class IDecode(implicit val p: Parameters) extends DecodeConstants
FENCE-> List(Y,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.N,N,Y,N),
FENCE_I-> List(Y,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, Y,M_FLUSH_ALL,MT_X, N,N,N,N,N,N,CSR.N,Y,N,N),
SFENCE_VM-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.I,N,N,N),
SCALL-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.I,N,N,N),
SBREAK-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.I,N,N,N),
SRET-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.I,N,N,N),
MRET-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.I,N,N,N),
WFI-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.I,N,N,N),
CSRRW-> List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.W,N,N,N),
@ -124,6 +122,19 @@ class IDecode(implicit val p: Parameters) extends DecodeConstants
CSRRCI-> List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,N,N,N,Y,CSR.C,N,N,N))
}
class SDecode(implicit val p: Parameters) extends DecodeConstants
{
val table: Array[(BitPat, List[BitPat])] = Array(
SFENCE_VM-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.I,N,N,N),
SRET-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.I,N,N,N))
}
class DebugDecode(implicit val p: Parameters) extends DecodeConstants
{
val table: Array[(BitPat, List[BitPat])] = Array(
DRET-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.I,N,N,N))
}
class I64Decode(implicit val p: Parameters) extends DecodeConstants
{
val table: Array[(BitPat, List[BitPat])] = Array(

View File

@ -98,6 +98,7 @@ object Instructions {
def SRET = BitPat("b00010000001000000000000001110011")
def HRET = BitPat("b00100000001000000000000001110011")
def MRET = BitPat("b00110000001000000000000001110011")
def DRET = BitPat("b01111011001000000000000001110011")
def SFENCE_VM = BitPat("b000100000100?????000000001110011")
def WFI = BitPat("b00010000010100000000000001110011")
def CSRRW = BitPat("b?????????????????001?????1110011")
@ -272,7 +273,6 @@ object CSRs {
val mcause = 0x342
val mbadaddr = 0x343
val mip = 0x344
val mipi = 0x345
val mucounteren = 0x310
val mscounteren = 0x311
val mucycle_delta = 0x700
@ -281,6 +281,9 @@ object CSRs {
val mscycle_delta = 0x704
val mstime_delta = 0x705
val msinstret_delta = 0x706
val dcsr = 0x7b0
val dpc = 0x7b1
val dscratch = 0x7b2
val mcycle = 0xf00
val mtime = 0xf01
val minstret = 0xf02
@ -289,8 +292,6 @@ object CSRs {
val marchid = 0xf12
val mimpid = 0xf13
val mhartid = 0xf14
val mtohost = 0x7c0
val mfromhost = 0x7c1
val mreset = 0x7c2
val cycleh = 0xc80
val timeh = 0xc81
@ -302,6 +303,7 @@ object CSRs {
val mstime_deltah = 0x785
val msinstret_deltah = 0x786
val mcycleh = 0xf80
val mtimeh = 0xf81
val minstreth = 0xf82
val all = {
val res = collection.mutable.ArrayBuffer[Int]()
@ -334,7 +336,6 @@ object CSRs {
res += mcause
res += mbadaddr
res += mip
res += mipi
res += mucounteren
res += mscounteren
res += mucycle_delta
@ -343,6 +344,9 @@ object CSRs {
res += mscycle_delta
res += mstime_delta
res += msinstret_delta
res += dcsr
res += dpc
res += dscratch
res += mcycle
res += mtime
res += minstret
@ -351,8 +355,6 @@ object CSRs {
res += marchid
res += mimpid
res += mhartid
res += mtohost
res += mfromhost
res += mreset
res.toArray
}
@ -368,6 +370,7 @@ object CSRs {
res += mstime_deltah
res += msinstret_deltah
res += mcycleh
res += mtimeh
res += minstreth
res.toArray
}

View File

@ -15,6 +15,7 @@ case object FetchWidth extends Field[Int]
case object RetireWidth extends Field[Int]
case object UseVM extends Field[Boolean]
case object UseUser extends Field[Boolean]
case object UseDebug extends Field[Boolean]
case object UseAtomics extends Field[Boolean]
case object UsePerfCounters extends Field[Boolean]
case object FastLoadWord extends Field[Boolean]
@ -34,6 +35,7 @@ trait HasCoreParameters extends HasAddrMapParameters {
val usingVM = p(UseVM)
val usingUser = p(UseUser)
val usingDebug = p(UseDebug)
val usingFPU = p(UseFPU)
val usingAtomics = p(UseAtomics)
val usingFDivSqrt = p(FDivSqrt)
@ -129,6 +131,8 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) {
(if (usingFPU && usingFDivSqrt) Some(new FDivSqrtDecode) else None) ++:
(if (usingRoCC) Some(new RoCCDecode) else None) ++:
(if (xLen > 32) Some(new I64Decode) else None) ++:
(if (usingVM) Some(new SDecode) else None) ++:
(if (usingDebug) Some(new DebugDecode) else None) ++:
Seq(new IDecode)
} flatMap(_.table)

View File

@ -128,7 +128,7 @@ class TLB(implicit p: Parameters) extends TLBModule()(p) {
val do_mprv = io.ptw.status.mprv && !io.req.bits.instruction
val priv = Mux(do_mprv, io.ptw.status.mpp, io.ptw.status.prv)
val priv_s = priv === PRV.S
val priv_uses_vm = priv <= PRV.S
val priv_uses_vm = priv <= PRV.S && !io.ptw.status.debug
val req_xwr = Cat(!r_req.store, r_req.store, !(r_req.instruction || r_req.store))
val ur_bits = ur_array.toBits

View File

@ -10,6 +10,7 @@ import cde.{Parameters, Field}
object Util {
implicit def uintToBitPat(x: UInt): BitPat = BitPat(x)
implicit def intToUInt(x: Int): UInt = UInt(x)
implicit def bigIntToUInt(x: BigInt): UInt = UInt(x)
implicit def booleanToBool(x: Boolean): Bits = Bool(x)
implicit def intSeqToUIntSeq(x: Seq[Int]): Seq[UInt] = x.map(UInt(_))
implicit def seqToVec[T <: Data](x: Seq[T]): Vec[T] = Vec(x)