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
|
// 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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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) }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user