Merge pull request #825 from freechipsproject/debug_wfi
Debug + WFI Interactions
This commit is contained in:
commit
992b480c74
@ -1 +1 @@
|
|||||||
Subproject commit 7cd1d1057d3bcd040b9e655fd35f57ccc97e075a
|
Subproject commit 75371b4e19435833f80767da691b718c68551f13
|
@ -59,9 +59,7 @@ class DCSR extends Bundle {
|
|||||||
val stopcycle = Bool()
|
val stopcycle = Bool()
|
||||||
val stoptime = Bool()
|
val stoptime = Bool()
|
||||||
val cause = UInt(width = 3)
|
val cause = UInt(width = 3)
|
||||||
// TODO: debugint is not in the Debug Spec v13
|
val zero1 = UInt(width=3)
|
||||||
val debugint = Bool()
|
|
||||||
val zero1 = UInt(width=2)
|
|
||||||
val step = Bool()
|
val step = Bool()
|
||||||
val prv = UInt(width = PRV.SZ)
|
val prv = UInt(width = PRV.SZ)
|
||||||
}
|
}
|
||||||
@ -214,6 +212,7 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
|||||||
reset_dcsr.xdebugver := 1
|
reset_dcsr.xdebugver := 1
|
||||||
reset_dcsr.prv := PRV.M
|
reset_dcsr.prv := PRV.M
|
||||||
val reg_dcsr = Reg(init=reset_dcsr)
|
val reg_dcsr = Reg(init=reset_dcsr)
|
||||||
|
val reg_debugint = Reg(Bool())
|
||||||
|
|
||||||
val (supported_interrupts, delegable_interrupts) = {
|
val (supported_interrupts, delegable_interrupts) = {
|
||||||
val sup = Wire(new MIP)
|
val sup = Wire(new MIP)
|
||||||
@ -312,7 +311,7 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
|||||||
io.pmp := reg_pmp.map(PMP(_))
|
io.pmp := reg_pmp.map(PMP(_))
|
||||||
|
|
||||||
// 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_debugint && !reg_debug) {
|
||||||
io.interrupt := true
|
io.interrupt := true
|
||||||
io.interrupt_cause := UInt(interruptMSB) + CSR.debugIntCause
|
io.interrupt_cause := UInt(interruptMSB) + CSR.debugIntCause
|
||||||
}
|
}
|
||||||
@ -505,8 +504,8 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
|||||||
val exception = insn_call || insn_break || io.exception
|
val exception = insn_call || insn_break || io.exception
|
||||||
assert(PopCount(insn_ret :: insn_call :: insn_break :: io.exception :: Nil) <= 1, "these conditions must be mutually exclusive")
|
assert(PopCount(insn_ret :: insn_call :: insn_break :: io.exception :: Nil) <= 1, "these conditions must be mutually exclusive")
|
||||||
|
|
||||||
when (insn_wfi) { reg_wfi := true }
|
when (insn_wfi && !io.singleStep && !reg_debug) { reg_wfi := true }
|
||||||
when (pending_interrupts.orR || exception) { reg_wfi := false }
|
when (pending_interrupts.orR || exception || reg_debugint) { reg_wfi := false }
|
||||||
assert(!reg_wfi || io.retire === UInt(0))
|
assert(!reg_wfi || io.retire === UInt(0))
|
||||||
|
|
||||||
when (io.retire(0) || exception) { reg_singleStepped := true }
|
when (io.retire(0) || exception) { reg_singleStepped := true }
|
||||||
@ -721,7 +720,7 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
|||||||
reg_mip.mtip := io.interrupts.mtip
|
reg_mip.mtip := io.interrupts.mtip
|
||||||
reg_mip.msip := io.interrupts.msip
|
reg_mip.msip := io.interrupts.msip
|
||||||
reg_mip.meip := io.interrupts.meip
|
reg_mip.meip := io.interrupts.meip
|
||||||
reg_dcsr.debugint := io.interrupts.debug
|
reg_debugint := io.interrupts.debug
|
||||||
|
|
||||||
if (!usingVM) {
|
if (!usingVM) {
|
||||||
reg_mideleg := 0
|
reg_mideleg := 0
|
||||||
|
@ -328,6 +328,8 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod
|
|||||||
when (DMCONTROLWrEn) {
|
when (DMCONTROLWrEn) {
|
||||||
DMCONTROLNxt.ndmreset := DMCONTROLWrData.ndmreset
|
DMCONTROLNxt.ndmreset := DMCONTROLWrData.ndmreset
|
||||||
DMCONTROLNxt.hartsel := DMCONTROLWrData.hartsel
|
DMCONTROLNxt.hartsel := DMCONTROLWrData.hartsel
|
||||||
|
DMCONTROLNxt.haltreq := DMCONTROLWrData.haltreq
|
||||||
|
DMCONTROLNxt.resumereq := DMCONTROLWrData.resumereq
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -934,6 +936,8 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
|
|||||||
val commandWrIsAccessRegister = (COMMANDWrData.cmdtype === DebugAbstractCommandType.AccessRegister.id.U)
|
val commandWrIsAccessRegister = (COMMANDWrData.cmdtype === DebugAbstractCommandType.AccessRegister.id.U)
|
||||||
val commandRegIsAccessRegister = (COMMANDReg.cmdtype === DebugAbstractCommandType.AccessRegister.id.U)
|
val commandRegIsAccessRegister = (COMMANDReg.cmdtype === DebugAbstractCommandType.AccessRegister.id.U)
|
||||||
|
|
||||||
|
val commandWrIsUnsupported = COMMANDWrEn && !commandWrIsAccessRegister;
|
||||||
|
|
||||||
val commandRegIsUnsupported = Wire(init = true.B)
|
val commandRegIsUnsupported = Wire(init = true.B)
|
||||||
val commandRegBadHaltResume = Wire(init = false.B)
|
val commandRegBadHaltResume = Wire(init = false.B)
|
||||||
when (commandRegIsAccessRegister) {
|
when (commandRegIsAccessRegister) {
|
||||||
@ -951,16 +955,20 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
|
|||||||
// -----------------------
|
// -----------------------
|
||||||
|
|
||||||
when (ctrlStateReg === CtrlState(Waiting)){
|
when (ctrlStateReg === CtrlState(Waiting)){
|
||||||
|
|
||||||
when (wrAccessRegisterCommand || regAccessRegisterCommand) {
|
when (wrAccessRegisterCommand || regAccessRegisterCommand) {
|
||||||
ctrlStateNxt := CtrlState(CheckGenerate)
|
ctrlStateNxt := CtrlState(CheckGenerate)
|
||||||
|
}.elsewhen (commandWrIsUnsupported) { // These checks are really on the command type.
|
||||||
|
errorUnsupported := true.B
|
||||||
|
}.elsewhen (autoexec && commandRegIsUnsupported) {
|
||||||
|
errorUnsupported := true.B
|
||||||
}
|
}
|
||||||
}.elsewhen (ctrlStateReg === CtrlState(CheckGenerate)){
|
}.elsewhen (ctrlStateReg === CtrlState(CheckGenerate)){
|
||||||
|
|
||||||
// We use this state to ensure that the COMMAND has been
|
// We use this state to ensure that the COMMAND has been
|
||||||
// registered by the time that we need to use it, to avoid
|
// registered by the time that we need to use it, to avoid
|
||||||
// generating it directly from the COMMANDWrData.
|
// generating it directly from the COMMANDWrData.
|
||||||
|
// This 'commandRegIsUnsupported' is really just checking the
|
||||||
|
// AccessRegisterCommand parameters (regno)
|
||||||
when (commandRegIsUnsupported) {
|
when (commandRegIsUnsupported) {
|
||||||
errorUnsupported := true.B
|
errorUnsupported := true.B
|
||||||
ctrlStateNxt := CtrlState(Waiting)
|
ctrlStateNxt := CtrlState(Waiting)
|
||||||
|
Loading…
Reference in New Issue
Block a user