1
0

debug: Use flags for resume instead of program buffer. Untested.

This commit is contained in:
Megan Wachs 2017-04-07 09:54:51 -07:00 committed by Andrew Waterman
parent d361e9e343
commit 22c6f728c3
3 changed files with 57 additions and 30 deletions

View File

@ -10,7 +10,9 @@
// Region of memory where each hart has 1 // Region of memory where each hart has 1
// byte to read. // byte to read.
#define OK_GO 0x400 #define FLAGS 0x400
#define FLAG_GO 0
#define FLAG_RESUME 1
.option norvc .option norvc
.global entry .global entry
@ -18,7 +20,7 @@
// Entry location on ebreak, Halt, or Breakpoint // Entry location on ebreak, Halt, or Breakpoint
// It is the same for all harts. They branch when // 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: entry:
jal zero, _entry jal zero, _entry
@ -36,12 +38,17 @@ _entry:
// We continue to let the hart know that we are halted in order that // 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. // 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 // 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: entry_loop:
csrr s0, CSR_MHARTID csrr s0, CSR_MHARTID
sw s0, HALTED(zero) sw s0, HALTED(zero)
lb s0, OK_GO(s0) // 1 byte flag per hart. Only one hart advances here. lbu s0, FLAGS(s0) // 1 byte flag per hart. Only one hart advances here.
bne zero, s0, going 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 jal zero, entry_loop
_exception: _exception:
@ -50,16 +57,14 @@ _exception:
going: going:
csrr s0, CSR_DSCRATCH // Restore s0 here 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 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 // Debug Mode will flush the I-Cache. We need that so that the
// remainder of the variable instructions will be what Debug Module // remainder of the variable instructions will be what Debug Module
// intends. // intends.
_resume: _resume:
csrw CSR_DSCRATCH, s0 // Save s0 to allow signaling MHARTID
csrr s0, CSR_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 csrr s0, CSR_DSCRATCH // Restore s0
dret dret

View File

@ -52,7 +52,7 @@ object DsbRegAddrs{
def RESUMING = 0x108 def RESUMING = 0x108
def EXCEPTION = 0x10C def EXCEPTION = 0x10C
def GO = 0x400 def FLAGS = 0x400
def ROMBASE = 0x800 def ROMBASE = 0x800
def RESUME = 0x804 def RESUME = 0x804
@ -479,6 +479,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
//-------------------------------------------------------------- //--------------------------------------------------------------
val haltedBitRegs = RegInit(Vec.fill(nComponents){false.B}) val haltedBitRegs = RegInit(Vec.fill(nComponents){false.B})
val resumeReqRegs = RegInit(Vec.fill(nComponents){false.B})
// --- regmapper outputs // --- regmapper outputs
@ -537,6 +538,9 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
DMSTATUSRdData.anyrunning := true.B DMSTATUSRdData.anyrunning := true.B
} }
DMSTATUSRdData.allresumeack := ~resumeReqRegs(selectedHartReg)
DMSTATUSRdData.anyresumeack := ~resumeReqRegs(selectedHartReg)
//TODO //TODO
DMSTATUSRdData.cfgstrvalid := false.B DMSTATUSRdData.cfgstrvalid := false.B
@ -685,7 +689,9 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
for (component <- 0 until nComponents) { for (component <- 0 until nComponents) {
when (~io.dmactive) { when (~io.dmactive) {
haltedBitRegs(component) := false.B haltedBitRegs(component) := false.B
resumeReqRegs(component) := false.B
}.otherwise { }.otherwise {
// Hart Halt Notification Logic
when (hartHaltedWrEn) { when (hartHaltedWrEn) {
when (cfg.hartIdToHartSel(hartHaltedId) === component.U) { when (cfg.hartIdToHartSel(hartHaltedId) === component.U) {
haltedBitRegs(component) := true.B haltedBitRegs(component) := true.B
@ -695,6 +701,19 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
haltedBitRegs(component) := false.B 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 goProgramBuffer = Wire(init = false.B)
val goResume = Wire(init = false.B)
val goAbstract = Wire(init = false.B) val goAbstract = Wire(init = false.B)
val whereToReg = Reg(UInt(32.W)) val whereToReg = Reg(UInt(32.W))
@ -736,17 +754,11 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
jalAbstract.setImm(ABSTRACT - WHERETO) jalAbstract.setImm(ABSTRACT - WHERETO)
jalProgBuf.rd := 0.U 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) { when (~io.dmactive) {
whereToReg := 0.U whereToReg := 0.U
}.otherwise{ }.otherwise{
when (goProgramBuffer) { when (goProgramBuffer) {
whereToReg := jalProgBuf.asUInt() whereToReg := jalProgBuf.asUInt()
}.elsewhen (goResume) {
whereToReg := jalResume.asUInt()
}.elsewhen (goAbstract) { }.elsewhen (goAbstract) {
whereToReg := jalAbstract.asUInt() whereToReg := jalAbstract.asUInt()
} }
@ -757,7 +769,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
when (~io.dmactive){ when (~io.dmactive){
goReg := false.B goReg := false.B
}.otherwise { }.otherwise {
when (goProgramBuffer | goResume | goAbstract) { when (goProgramBuffer | goAbstract) {
goReg := true.B goReg := true.B
}.elsewhen (hartGoingWrEn){ }.elsewhen (hartGoingWrEn){
assert(hartGoingId === 0.U, "Unexpected 'GOING' hart.")//Chisel3 #540 %x, expected %x", hartGoingId, 0.U) 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), 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."); "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 // Abstract Command Decoding & Generation
@ -870,7 +892,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
// These sections are read-only. // These sections are read-only.
ROMBASE -> DebugRomContents().map(x => RegField.r(8, (x & 0xFF).U(8.W))), 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)), WHERETO -> Seq(RegField.r(32, whereToReg)),
ABSTRACT -> abstractGeneratedMem.map(x => RegField.r(32, x)) ABSTRACT -> abstractGeneratedMem.map(x => RegField.r(32, x))
) )
@ -940,9 +962,8 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
when (wrAccessRegisterCommand || regAccessRegisterCommand) { when (wrAccessRegisterCommand || regAccessRegisterCommand) {
ctrlStateNxt := CtrlState(CheckGenerate) ctrlStateNxt := CtrlState(CheckGenerate)
}.elsewhen(io.innerCtrl.fire() && io.innerCtrl.bits.resumereq) {
goResume := 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

View File

@ -5,13 +5,14 @@ package uncore.devices
object DebugRomContents { object DebugRomContents {
def apply() : Array[Byte] = { Array ( 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, 0x0f, 0x00, 0xf0, 0x0f, 0x73, 0x10, 0x24, 0x7b, 0x73, 0x24, 0x40, 0xf1,
0x23, 0x20, 0x80, 0x10, 0x03, 0x04, 0x04, 0x40, 0x63, 0x18, 0x80, 0x00, 0x23, 0x20, 0x80, 0x10, 0x03, 0x44, 0x04, 0x40, 0x13, 0x74, 0x14, 0x00,
0x6f, 0xf0, 0x1f, 0xff, 0x23, 0x26, 0x00, 0x10, 0x73, 0x00, 0x10, 0x00, 0x63, 0x10, 0x04, 0x02, 0x73, 0x24, 0x40, 0xf1, 0x03, 0x44, 0x04, 0x40,
0x73, 0x24, 0x20, 0x7b, 0x23, 0x22, 0x00, 0x10, 0x67, 0x00, 0x00, 0x30, 0x13, 0x74, 0x24, 0x00, 0xe3, 0x18, 0x04, 0xfc, 0x6f, 0xf0, 0xdf, 0xfd,
0x73, 0x10, 0x24, 0x7b, 0x73, 0x24, 0x40, 0xf1, 0x23, 0x24, 0x80, 0x10, 0x23, 0x26, 0x00, 0x10, 0x73, 0x00, 0x10, 0x00, 0x73, 0x24, 0x20, 0x7b,
0x73, 0x24, 0x20, 0x7b, 0x73, 0x00, 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) } ).map(_.toByte) }
} }