debug: Use flags for resume instead of program buffer. Untested.
This commit is contained in:
parent
d361e9e343
commit
22c6f728c3
@ -10,7 +10,9 @@
|
||||
|
||||
// Region of memory where each hart has 1
|
||||
// byte to read.
|
||||
#define OK_GO 0x400
|
||||
#define FLAGS 0x400
|
||||
#define FLAG_GO 0
|
||||
#define FLAG_RESUME 1
|
||||
|
||||
.option norvc
|
||||
.global entry
|
||||
@ -18,7 +20,7 @@
|
||||
|
||||
// Entry location on ebreak, Halt, or Breakpoint
|
||||
// It is the same for all harts. They branch when
|
||||
// their specific OK_GO bit is set.
|
||||
// their GO or RESUME bit is set.
|
||||
|
||||
entry:
|
||||
jal zero, _entry
|
||||
@ -36,12 +38,17 @@ _entry:
|
||||
// We continue to let the hart know that we are halted in order that
|
||||
// a DM which was reset is still made aware that a hart is halted.
|
||||
// We keep checking both whether there is something the debugger wants
|
||||
// us to do, or whether we should not be halted anymore.
|
||||
// us to do, or whether we should resume.
|
||||
entry_loop:
|
||||
csrr s0, CSR_MHARTID
|
||||
sw s0, HALTED(zero)
|
||||
lb s0, OK_GO(s0) // 1 byte flag per hart. Only one hart advances here.
|
||||
bne zero, s0, going
|
||||
lbu s0, FLAGS(s0) // 1 byte flag per hart. Only one hart advances here.
|
||||
andi s0, s0, (1 << FLAG_GO)
|
||||
bnez s0, going
|
||||
csrr s0, CSR_MHARTID
|
||||
lbu s0, FLAGS(s0) // multiple harts can resume here
|
||||
andi s0, s0, (1 << FLAG_RESUME)
|
||||
bnez s0, resume
|
||||
jal zero, entry_loop
|
||||
|
||||
_exception:
|
||||
@ -50,16 +57,14 @@ _exception:
|
||||
|
||||
going:
|
||||
csrr s0, CSR_DSCRATCH // Restore s0 here
|
||||
sw zero, GOING(zero) // When debug module sees this write, the OK_GO flag is reset.
|
||||
sw zero, GOING(zero) // When debug module sees this write, the GO flag is reset.
|
||||
jalr zero, zero, %lo(whereto) // Rocket-Chip has a specific hack which is that jalr in
|
||||
// Debug Mode will flush the I-Cache. We need that so that the
|
||||
// remainder of the variable instructions will be what Debug Module
|
||||
// intends.
|
||||
|
||||
_resume:
|
||||
csrw CSR_DSCRATCH, s0 // Save s0 to allow signaling MHARTID
|
||||
csrr s0, CSR_MHARTID
|
||||
sw s0, RESUMING(zero) // Let the Debug Module know you're not halted anymore.
|
||||
sw s0, RESUMING(zero) // When Debug Module sees this write, the RESUME flag is reset.
|
||||
csrr s0, CSR_DSCRATCH // Restore s0
|
||||
dret
|
||||
|
||||
|
@ -52,7 +52,7 @@ object DsbRegAddrs{
|
||||
def RESUMING = 0x108
|
||||
def EXCEPTION = 0x10C
|
||||
|
||||
def GO = 0x400
|
||||
def FLAGS = 0x400
|
||||
|
||||
def ROMBASE = 0x800
|
||||
def RESUME = 0x804
|
||||
@ -479,6 +479,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
|
||||
//--------------------------------------------------------------
|
||||
|
||||
val haltedBitRegs = RegInit(Vec.fill(nComponents){false.B})
|
||||
val resumeReqRegs = RegInit(Vec.fill(nComponents){false.B})
|
||||
|
||||
// --- regmapper outputs
|
||||
|
||||
@ -537,6 +538,9 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
|
||||
DMSTATUSRdData.anyrunning := true.B
|
||||
}
|
||||
|
||||
DMSTATUSRdData.allresumeack := ~resumeReqRegs(selectedHartReg)
|
||||
DMSTATUSRdData.anyresumeack := ~resumeReqRegs(selectedHartReg)
|
||||
|
||||
//TODO
|
||||
DMSTATUSRdData.cfgstrvalid := false.B
|
||||
|
||||
@ -685,7 +689,9 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
|
||||
for (component <- 0 until nComponents) {
|
||||
when (~io.dmactive) {
|
||||
haltedBitRegs(component) := false.B
|
||||
resumeReqRegs(component) := false.B
|
||||
}.otherwise {
|
||||
// Hart Halt Notification Logic
|
||||
when (hartHaltedWrEn) {
|
||||
when (cfg.hartIdToHartSel(hartHaltedId) === component.U) {
|
||||
haltedBitRegs(component) := true.B
|
||||
@ -695,6 +701,19 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
|
||||
haltedBitRegs(component) := false.B
|
||||
}
|
||||
}
|
||||
|
||||
// Hart Resume Req Logic
|
||||
// If you request a hart to resume at the same moment
|
||||
// it actually does resume, then the request wins.
|
||||
// So don't try to write resumereq more than once
|
||||
when (hartResumingWrEn) {
|
||||
when (cfg.hartIdToHartSel(hartResumingId) === component.U) {
|
||||
resumeReqRegs(component) := false.B
|
||||
}
|
||||
}
|
||||
when(io.innerCtrl.fire() && io.innerCtrl.bits.resumereq) {
|
||||
resumeReqRegs(io.innerCtrl.bits.hartsel) := true.B
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -723,7 +742,6 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
|
||||
//--------------------------------------------------------------
|
||||
|
||||
val goProgramBuffer = Wire(init = false.B)
|
||||
val goResume = Wire(init = false.B)
|
||||
val goAbstract = Wire(init = false.B)
|
||||
|
||||
val whereToReg = Reg(UInt(32.W))
|
||||
@ -736,17 +754,11 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
|
||||
jalAbstract.setImm(ABSTRACT - WHERETO)
|
||||
jalProgBuf.rd := 0.U
|
||||
|
||||
val jalResume = Wire(init = (new GeneratedUJ()).fromBits(rocket.Instructions.JAL.value.U))
|
||||
jalResume.setImm(RESUME - WHERETO)
|
||||
jalResume.rd := 0.U
|
||||
|
||||
when (~io.dmactive) {
|
||||
whereToReg := 0.U
|
||||
}.otherwise{
|
||||
when (goProgramBuffer) {
|
||||
whereToReg := jalProgBuf.asUInt()
|
||||
}.elsewhen (goResume) {
|
||||
whereToReg := jalResume.asUInt()
|
||||
}.elsewhen (goAbstract) {
|
||||
whereToReg := jalAbstract.asUInt()
|
||||
}
|
||||
@ -757,7 +769,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
|
||||
when (~io.dmactive){
|
||||
goReg := false.B
|
||||
}.otherwise {
|
||||
when (goProgramBuffer | goResume | goAbstract) {
|
||||
when (goProgramBuffer | goAbstract) {
|
||||
goReg := true.B
|
||||
}.elsewhen (hartGoingWrEn){
|
||||
assert(hartGoingId === 0.U, "Unexpected 'GOING' hart.")//Chisel3 #540 %x, expected %x", hartGoingId, 0.U)
|
||||
@ -765,10 +777,20 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
|
||||
}
|
||||
}
|
||||
|
||||
val goBytes = Wire(init = Vec.fill(1024){0.U(8.W)})
|
||||
class flagBundle extends Bundle {
|
||||
val reserved = UInt(6.W)
|
||||
val resume = Bool()
|
||||
val go = Bool()
|
||||
}
|
||||
|
||||
val flags = Wire(init = Vec.fill(1024){new flagBundle().fromBits(0.U)})
|
||||
assert ((cfg.hartSelToHartId(selectedHartReg) < 1024.U),
|
||||
"HartSel to HartId Mapping is illegal for this Debug Implementation, because HartID must be < 1024 for it to work.");
|
||||
goBytes(cfg.hartSelToHartId(selectedHartReg)) := Cat(0.U(7.W), goReg)
|
||||
flags(cfg.hartSelToHartId(selectedHartReg)).go := goReg
|
||||
for (component <- 0 until nComponents) {
|
||||
val componentSel = Wire(component.U)
|
||||
flags(cfg.hartSelToHartId(componentSel)).resume := resumeReqRegs(component)
|
||||
}
|
||||
|
||||
//----------------------------
|
||||
// Abstract Command Decoding & Generation
|
||||
@ -870,10 +892,10 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
|
||||
|
||||
// These sections are read-only.
|
||||
ROMBASE -> DebugRomContents().map(x => RegField.r(8, (x & 0xFF).U(8.W))),
|
||||
GO -> goBytes.map(x => RegField.r(8, x)),
|
||||
FLAGS -> flags.map{x => RegField.r(8, x.asUInt())},
|
||||
WHERETO -> Seq(RegField.r(32, whereToReg)),
|
||||
ABSTRACT -> abstractGeneratedMem.map(x => RegField.r(32, x))
|
||||
)
|
||||
)
|
||||
|
||||
// Override System Bus accesses with dmactive reset.
|
||||
when (~io.dmactive){
|
||||
@ -940,9 +962,8 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
|
||||
|
||||
when (wrAccessRegisterCommand || regAccessRegisterCommand) {
|
||||
ctrlStateNxt := CtrlState(CheckGenerate)
|
||||
}.elsewhen(io.innerCtrl.fire() && io.innerCtrl.bits.resumereq) {
|
||||
goResume := true.B
|
||||
}
|
||||
|
||||
}.elsewhen (ctrlStateReg === CtrlState(CheckGenerate)){
|
||||
|
||||
// We use this state to ensure that the COMMAND has been
|
||||
|
@ -5,13 +5,14 @@ package uncore.devices
|
||||
object DebugRomContents {
|
||||
|
||||
def apply() : Array[Byte] = { Array (
|
||||
0x6f, 0x00, 0xc0, 0x00, 0x6f, 0x00, 0x80, 0x03, 0x6f, 0x00, 0x00, 0x02,
|
||||
0x6f, 0x00, 0xc0, 0x00, 0x6f, 0x00, 0xc0, 0x04, 0x6f, 0x00, 0x40, 0x03,
|
||||
0x0f, 0x00, 0xf0, 0x0f, 0x73, 0x10, 0x24, 0x7b, 0x73, 0x24, 0x40, 0xf1,
|
||||
0x23, 0x20, 0x80, 0x10, 0x03, 0x04, 0x04, 0x40, 0x63, 0x18, 0x80, 0x00,
|
||||
0x6f, 0xf0, 0x1f, 0xff, 0x23, 0x26, 0x00, 0x10, 0x73, 0x00, 0x10, 0x00,
|
||||
0x73, 0x24, 0x20, 0x7b, 0x23, 0x22, 0x00, 0x10, 0x67, 0x00, 0x00, 0x30,
|
||||
0x73, 0x10, 0x24, 0x7b, 0x73, 0x24, 0x40, 0xf1, 0x23, 0x24, 0x80, 0x10,
|
||||
0x73, 0x24, 0x20, 0x7b, 0x73, 0x00, 0x20, 0x7b
|
||||
0x23, 0x20, 0x80, 0x10, 0x03, 0x44, 0x04, 0x40, 0x13, 0x74, 0x14, 0x00,
|
||||
0x63, 0x10, 0x04, 0x02, 0x73, 0x24, 0x40, 0xf1, 0x03, 0x44, 0x04, 0x40,
|
||||
0x13, 0x74, 0x24, 0x00, 0xe3, 0x18, 0x04, 0xfc, 0x6f, 0xf0, 0xdf, 0xfd,
|
||||
0x23, 0x26, 0x00, 0x10, 0x73, 0x00, 0x10, 0x00, 0x73, 0x24, 0x20, 0x7b,
|
||||
0x23, 0x22, 0x00, 0x10, 0x67, 0x00, 0x00, 0x30, 0x73, 0x24, 0x40, 0xf1,
|
||||
0x23, 0x24, 0x80, 0x10, 0x73, 0x24, 0x20, 0x7b, 0x73, 0x00, 0x20, 0x7b
|
||||
).map(_.toByte) }
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user