Add some add'l debug features (#1112)
* debug: Update macros from spec * debug: some corrections in the auto-generated files * debug: update renamed fields * Debug: implement the implicit ebreak option for small program buffers * debug: clean up some unused code and add more require() explanations * debug: make implicit ebreak false * debug: Add the havereset/haveresetack functionality * debug: program buffer can still be 16 even if there is an implicit ebreak
This commit is contained in:
parent
acc8c2bbb3
commit
e7704f46c8
@ -44,8 +44,6 @@ object DsbBusConsts {
|
||||
|
||||
object DsbRegAddrs{
|
||||
|
||||
// These may need to move around to be used by the serial interface.
|
||||
|
||||
// These are used by the ROM.
|
||||
def HALTED = 0x100
|
||||
def GOING = 0x104
|
||||
@ -61,8 +59,14 @@ object DsbRegAddrs{
|
||||
def DATA = 0x380
|
||||
|
||||
// We want DATA to immediately follow PROGBUF so that we can
|
||||
// use them interchangeably.
|
||||
def PROGBUF(cfg:DebugModuleParams) = {DATA - (cfg.nProgramBufferWords * 4)}
|
||||
// use them interchangeably. Leave another slot if there is an
|
||||
// implicit ebreak.
|
||||
def PROGBUF(cfg:DebugModuleParams) = {
|
||||
val tmp = DATA - (cfg.nProgramBufferWords * 4)
|
||||
if (cfg.hasImplicitEbreak) (tmp - 4) else tmp
|
||||
}
|
||||
// This is unused if hasImpEbreak is false, and just points to the end of the PROGBUF.
|
||||
def IMPEBREAK(cfg: DebugModuleParams) = { DATA - 4 }
|
||||
|
||||
// We want abstract to be immediately before PROGBUF
|
||||
// because we auto-generate 2 instructions.
|
||||
@ -108,9 +112,11 @@ import DebugAbstractCommandType._
|
||||
* nProgamBufferWords: Number of 32-bit words for Program Buffer
|
||||
* hasBusMaster: Whethr or not a bus master should be included
|
||||
* The size of the accesses supported by the Bus Master.
|
||||
* nSerialPorts : Number of serial ports to instantiate
|
||||
* supportQuickAccess : Whether or not to support the quick access command.
|
||||
* supportHartArray : Whether or not to implement the hart array register.
|
||||
* hartIdToHartSel: For systems where hart ids are not 1:1 with hartsel, provide the mapping.
|
||||
* hartSelToHartId: Provide inverse mapping of the above
|
||||
* hasImplicitEbreak: There is an additional RO program buffer word containing an ebreak
|
||||
**/
|
||||
|
||||
case class DebugModuleParams (
|
||||
@ -125,27 +131,25 @@ case class DebugModuleParams (
|
||||
hasAccess32 : Boolean = false,
|
||||
hasAccess16 : Boolean = false,
|
||||
hasAccess8 : Boolean = false,
|
||||
nSerialPorts : Int = 0,
|
||||
supportQuickAccess : Boolean = false,
|
||||
supportHartArray : Boolean = false,
|
||||
hartIdToHartSel : (UInt) => UInt = (x:UInt) => x,
|
||||
hartSelToHartId : (UInt) => UInt = (x:UInt) => x
|
||||
hartSelToHartId : (UInt) => UInt = (x:UInt) => x,
|
||||
hasImplicitEbreak : Boolean = false
|
||||
) {
|
||||
|
||||
if (hasBusMaster == false){
|
||||
require (hasAccess128 == false)
|
||||
require (hasAccess64 == false)
|
||||
require (hasAccess32 == false)
|
||||
require (hasAccess16 == false)
|
||||
require (hasAccess8 == false)
|
||||
require (hasAccess128 == false, "No Bus mastering support in Debug Module yet")
|
||||
require (hasAccess64 == false, "No Bus mastering support in Debug Module yet")
|
||||
require (hasAccess32 == false, "No Bus mastering support in Debug Module yet")
|
||||
require (hasAccess16 == false, "No Bus mastering support in Debug Module yet")
|
||||
require (hasAccess8 == false, "No Bus mastering support in Debug Module yet")
|
||||
}
|
||||
|
||||
require (nSerialPorts <= 8)
|
||||
require ((nDMIAddrSize >= 7) && (nDMIAddrSize <= 32), s"Legal DMIAddrSize is 7-32, not ${nDMIAddrSize}")
|
||||
|
||||
require ((nDMIAddrSize >= 7) && (nDMIAddrSize <= 32))
|
||||
|
||||
require ((nAbstractDataWords > 0) && (nAbstractDataWords <= 16))
|
||||
require ((nProgramBufferWords >= 0) && (nProgramBufferWords <= 16))
|
||||
require ((nAbstractDataWords > 0) && (nAbstractDataWords <= 16), s"Legal nAbstractDataWords is 0-16, not ${nAbstractDataWords}")
|
||||
require ((nProgramBufferWords >= 0) && (nProgramBufferWords <= 16), s"Legal nProgramBufferWords is 0-16, not ${nProgramBufferWords}")
|
||||
|
||||
if (supportQuickAccess) {
|
||||
// TODO: Check that quick access requirements are met.
|
||||
@ -201,8 +205,9 @@ class DMIIO(implicit val p: Parameters) extends ParameterizedBundle()(p) {
|
||||
*/
|
||||
|
||||
class DebugInternalBundle ()(implicit val p: Parameters) extends ParameterizedBundle()(p) {
|
||||
val resumereq = Bool()
|
||||
val hartsel = UInt(10.W)
|
||||
val resumereq = Bool()
|
||||
val hartsel = UInt(10.W)
|
||||
val ackhavereset = Bool()
|
||||
}
|
||||
|
||||
/* structure for top-level Debug Module signals which aren't the bus interfaces.
|
||||
@ -324,10 +329,11 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod
|
||||
DMCONTROLNxt := DMCONTROLReset
|
||||
} .otherwise {
|
||||
when (DMCONTROLWrEn) {
|
||||
DMCONTROLNxt.ndmreset := DMCONTROLWrData.ndmreset
|
||||
DMCONTROLNxt.hartsel := DMCONTROLWrData.hartsel
|
||||
DMCONTROLNxt.haltreq := DMCONTROLWrData.haltreq
|
||||
DMCONTROLNxt.resumereq := DMCONTROLWrData.resumereq
|
||||
DMCONTROLNxt.ndmreset := DMCONTROLWrData.ndmreset
|
||||
DMCONTROLNxt.hartsel := DMCONTROLWrData.hartsel
|
||||
DMCONTROLNxt.haltreq := DMCONTROLWrData.haltreq
|
||||
DMCONTROLNxt.resumereq := DMCONTROLWrData.resumereq
|
||||
DMCONTROLNxt.ackhavereset := DMCONTROLWrData.ackhavereset
|
||||
}
|
||||
}
|
||||
|
||||
@ -378,8 +384,9 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod
|
||||
}
|
||||
|
||||
io.innerCtrl.valid := DMCONTROLWrEn
|
||||
io.innerCtrl.bits.hartsel := DMCONTROLWrData.hartsel
|
||||
io.innerCtrl.bits.resumereq := DMCONTROLWrData.resumereq
|
||||
io.innerCtrl.bits.hartsel := DMCONTROLWrData.hartsel
|
||||
io.innerCtrl.bits.resumereq := DMCONTROLWrData.resumereq
|
||||
io.innerCtrl.bits.ackhavereset := DMCONTROLWrData.ackhavereset
|
||||
|
||||
io.ctrl.ndreset := DMCONTROLReg.ndmreset
|
||||
io.ctrl.dmactive := DMCONTROLReg.dmactive
|
||||
@ -461,17 +468,17 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
|
||||
// Sanity Check Configuration For this implementation.
|
||||
//--------------------------------------------------------------
|
||||
|
||||
require (cfg.nSerialPorts == 0)
|
||||
require (cfg.hasBusMaster == false)
|
||||
require (cfg.supportQuickAccess == false)
|
||||
require (cfg.supportHartArray == false)
|
||||
require (cfg.hasBusMaster == false, "No Bus Mastering support yet")
|
||||
require (cfg.supportQuickAccess == false, "No Quick Access support yet")
|
||||
require (cfg.supportHartArray == false, "No Hart Array support yet")
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Register & Wire Declarations (which need to be pre-declared)
|
||||
//--------------------------------------------------------------
|
||||
|
||||
val haltedBitRegs = RegInit(Vec.fill(nComponents){false.B})
|
||||
val resumeReqRegs = RegInit(Vec.fill(nComponents){false.B})
|
||||
val haltedBitRegs = RegInit(Vec.fill(nComponents){false.B})
|
||||
val resumeReqRegs = RegInit(Vec.fill(nComponents){false.B})
|
||||
val haveResetBitRegs = RegInit(Vec.fill(nComponents){true.B})
|
||||
|
||||
// --- regmapper outputs
|
||||
|
||||
@ -512,7 +519,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
|
||||
|
||||
val DMSTATUSRdData = Wire(init = (new DMSTATUSFields()).fromBits(0.U))
|
||||
DMSTATUSRdData.authenticated := true.B // Not implemented
|
||||
DMSTATUSRdData.versionlo := "b10".U
|
||||
DMSTATUSRdData.version := 2.U // Version 0.13
|
||||
|
||||
// Chisel3 Issue #527 , have to do intermediate assignment.
|
||||
val unavailVec = Wire(init = Vec.fill(nComponents){false.B})
|
||||
@ -531,14 +538,24 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
|
||||
DMSTATUSRdData.allrunning := true.B
|
||||
DMSTATUSRdData.anyrunning := true.B
|
||||
}
|
||||
DMSTATUSRdData.allhavereset := haveResetBitRegs(selectedHartReg)
|
||||
DMSTATUSRdData.anyhavereset := haveResetBitRegs(selectedHartReg)
|
||||
|
||||
val resumereq = io.innerCtrl.fire() && io.innerCtrl.bits.resumereq
|
||||
|
||||
when (io.innerCtrl.fire()){
|
||||
when (io.innerCtrl.bits.ackhavereset) {
|
||||
haveResetBitRegs(io.innerCtrl.bits.hartsel) := false.B
|
||||
}
|
||||
}
|
||||
|
||||
DMSTATUSRdData.allresumeack := ~resumeReqRegs(selectedHartReg) && ~resumereq
|
||||
DMSTATUSRdData.anyresumeack := ~resumeReqRegs(selectedHartReg) && ~resumereq
|
||||
|
||||
//TODO
|
||||
DMSTATUSRdData.cfgstrvalid := false.B
|
||||
DMSTATUSRdData.devtreevalid := false.B
|
||||
|
||||
DMSTATUSRdData.impebreak := (cfg.hasImplicitEbreak).B
|
||||
|
||||
//----HARTINFO
|
||||
|
||||
@ -562,8 +579,8 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
|
||||
//----ABSTRACTCS
|
||||
|
||||
val ABSTRACTCSReset = Wire(init = (new ABSTRACTCSFields()).fromBits(0.U))
|
||||
ABSTRACTCSReset.datacount := cfg.nAbstractDataWords.U
|
||||
ABSTRACTCSReset.progsize := cfg.nProgramBufferWords.U
|
||||
ABSTRACTCSReset.datacount := cfg.nAbstractDataWords.U
|
||||
ABSTRACTCSReset.progbufsize := cfg.nProgramBufferWords.U
|
||||
|
||||
val ABSTRACTCSReg = Reg(new ABSTRACTCSFields())
|
||||
val ABSTRACTCSWrDataVal = Wire(init = 0.U(32.W))
|
||||
@ -876,10 +893,11 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
|
||||
PROGBUF(cfg)-> programBufferMem.map(x => RegField(8, x)),
|
||||
|
||||
// These sections are read-only.
|
||||
WHERETO -> Seq(RegField.r(32, jalAbstract.asUInt)),
|
||||
ABSTRACT(cfg)-> abstractGeneratedMem.map{x => RegField.r(32, x)},
|
||||
FLAGS -> flags.map{x => RegField.r(8, x.asUInt())},
|
||||
ROMBASE -> DebugRomContents().map(x => RegField.r(8, (x & 0xFF).U(8.W)))
|
||||
IMPEBREAK(cfg)-> {if (cfg.hasImplicitEbreak) Seq(RegField.r(32, Instructions.EBREAK.value.U)) else Nil},
|
||||
WHERETO -> Seq(RegField.r(32, jalAbstract.asUInt)),
|
||||
ABSTRACT(cfg) -> abstractGeneratedMem.map{x => RegField.r(32, x)},
|
||||
FLAGS -> flags.map{x => RegField.r(8, x.asUInt())},
|
||||
ROMBASE -> DebugRomContents().map(x => RegField.r(8, (x & 0xFF).U(8.W)))
|
||||
|
||||
)
|
||||
|
||||
|
@ -2,7 +2,7 @@ package freechips.rocketchip.devices.debug
|
||||
|
||||
import Chisel._
|
||||
|
||||
// This file was auto-generated from the repository at https://github.com/sifive/riscv-debug-spec.git,
|
||||
// This file was auto-generated from the repository at https://github.com/riscv/riscv-debug-spec.git,
|
||||
// 'make chisel'
|
||||
|
||||
object AC_RegAddrs {
|
||||
@ -29,7 +29,7 @@ class ACCESS_REGISTERFields extends Bundle {
|
||||
val size = UInt(3.W)
|
||||
|
||||
val reserved1 = UInt(1.W)
|
||||
|
||||
|
||||
/* When 1, execute the program in the Program Buffer exactly once
|
||||
after performing the transfer, if any.
|
||||
*/
|
||||
@ -38,6 +38,9 @@ class ACCESS_REGISTERFields extends Bundle {
|
||||
/* 0: Don't do the operation specified by \Fwrite.
|
||||
|
||||
1: Do the operation specified by \Fwrite.
|
||||
|
||||
This bit can be used to just execute the Program Buffer without
|
||||
having to worry about placing valid values into \Fsize or \Fregno.
|
||||
*/
|
||||
val transfer = Bool()
|
||||
|
||||
@ -50,7 +53,10 @@ class ACCESS_REGISTERFields extends Bundle {
|
||||
*/
|
||||
val write = Bool()
|
||||
|
||||
/* Number of the register to access, as described in Table~\ref{tab:regno}.
|
||||
/* Number of the register to access, as described in
|
||||
Table~\ref{tab:regno}.
|
||||
\Rdpc may be used as an alias for PC if this command is
|
||||
supported on a non-halted hart.
|
||||
*/
|
||||
val regno = UInt(16.W)
|
||||
|
||||
|
@ -2,7 +2,7 @@ package freechips.rocketchip.devices.debug
|
||||
|
||||
import Chisel._
|
||||
|
||||
// This file was auto-generated from the repository at https://github.com/sifive/riscv-debug-spec.git,
|
||||
// This file was auto-generated from the repository at https://github.com/riscv/riscv-debug-spec.git,
|
||||
// 'make chisel'
|
||||
|
||||
object DMI_RegAddrs {
|
||||
@ -11,6 +11,14 @@ object DMI_RegAddrs {
|
||||
|
||||
This register reports status for the overall debug module
|
||||
as well as the currently selected harts, as defined in \Fhasel.
|
||||
|
||||
Harts are nonexistent if they will never be part of this system, no
|
||||
matter how long a user waits. Eg. in a simple single-hart system only
|
||||
one hart exists, and all others are nonexistent.
|
||||
|
||||
Harts are unavailable if they might exist/become available at a later
|
||||
time. Eg. in a multi-hart system some might temporarily be powered
|
||||
down, or a system might support hot-swapping harts.
|
||||
*/
|
||||
def DMI_DMSTATUS = 0x11
|
||||
|
||||
@ -52,8 +60,10 @@ object DMI_RegAddrs {
|
||||
def DMI_HAWINDOWSEL = 0x14
|
||||
|
||||
/* This register provides R/W access to a 32-bit portion of the
|
||||
hart array mask register. The position of the window is determined by
|
||||
\Rhawindowsel.
|
||||
hart array mask register.
|
||||
The position of the window is determined by \Rhawindowsel. I.e. bit 0
|
||||
refers to hart $\Rhawindowsel * 32$, while bit 31 refers to hart
|
||||
$\Rhawindowsel * 32 + 31$.
|
||||
*/
|
||||
def DMI_HAWINDOW = 0x15
|
||||
|
||||
@ -82,27 +92,29 @@ object DMI_RegAddrs {
|
||||
*/
|
||||
def DMI_ABSTRACTAUTO = 0x18
|
||||
|
||||
/* The Configuration String is described in the RISC-V Priviledged Specification.
|
||||
When {\tt cfgstrvalid} is set, reading this register returns bits 31:0 of the configuration
|
||||
string address. Reading the other {\tt cfgstraddr} registers returns the upper bits of the
|
||||
address.
|
||||
/* When {\tt devtreevalid} is set, reading this register returns bits 31:0
|
||||
of the Device Tree address. Reading the other {\tt devtreeaddr}
|
||||
registers returns the upper bits of the address.
|
||||
|
||||
When system bus mastering is implemented, this should be the
|
||||
address that should be used with the System Bus Access module. Otherwise,
|
||||
this should be the address that should be used to access the
|
||||
config string when \Fhartsel=0.
|
||||
When system bus mastering is implemented, this must be an
|
||||
address that can be used with the System Bus Access module. Otherwise,
|
||||
this must be an address that can be used to access the
|
||||
Device Tree from the hart with ID 0.
|
||||
|
||||
If {\tt cfgstrvalid} is 0, then the {\tt cfgstraddr} registers
|
||||
If {\tt devtreevalid} is 0, then the {\tt devtreeaddr} registers
|
||||
hold identifier information which is not
|
||||
further specified in this document.
|
||||
|
||||
The Device Tree itself is described in the RISC-V Privileged
|
||||
Specification.
|
||||
*/
|
||||
def DMI_CFGSTRADDR0 = 0x19
|
||||
def DMI_DEVTREEADDR0 = 0x19
|
||||
|
||||
def DMI_CFGSTRADDR1 = 0x1a
|
||||
def DMI_DEVTREEADDR1 = 0x1a
|
||||
|
||||
def DMI_CFGSTRADDR2 = 0x1b
|
||||
def DMI_DEVTREEADDR2 = 0x1b
|
||||
|
||||
def DMI_CFGSTRADDR3 = 0x1c
|
||||
def DMI_DEVTREEADDR3 = 0x1c
|
||||
|
||||
/* Basic read/write registers that may be read or changed by abstract
|
||||
commands.
|
||||
@ -110,6 +122,8 @@ object DMI_RegAddrs {
|
||||
Accessing them while an abstract command is executing causes \Fcmderr
|
||||
to be set.
|
||||
|
||||
Attempts to write them while \Fbusy is set does not change their value.
|
||||
|
||||
The values in these registers may not be preserved after an abstract
|
||||
command is executed. The only guarantees on their contents are the ones
|
||||
offered by the command in question. If the command fails, no
|
||||
@ -121,6 +135,11 @@ object DMI_RegAddrs {
|
||||
|
||||
/* The {\tt progbuf} registers provide read/write access to the optional
|
||||
program buffer.
|
||||
|
||||
Accessing them while an abstract command is executing causes \Fcmderr
|
||||
to be set.
|
||||
|
||||
Attempts to write them while \Fbusy is set does not change their value.
|
||||
*/
|
||||
def DMI_PROGBUF0 = 0x20
|
||||
|
||||
@ -135,41 +154,12 @@ object DMI_RegAddrs {
|
||||
*/
|
||||
def DMI_AUTHDATA = 0x30
|
||||
|
||||
/* If \Fserialcount is 0, this register is not present.
|
||||
*/
|
||||
def DMI_SERCS = 0x34
|
||||
|
||||
/* If \Fserialcount is 0, this register is not present.
|
||||
|
||||
This register provides access to the write data queue of the serial port
|
||||
selected by \Fserial in \Rsercs.
|
||||
|
||||
If the {\tt error} bit is not set and the queue is not full, a write to this register
|
||||
adds the written data to the core-to-debugger queue.
|
||||
Otherwise the {\tt error} bit is set and the write returns error.
|
||||
|
||||
A read to this register returns the last data written.
|
||||
*/
|
||||
def DMI_SERTX = 0x35
|
||||
|
||||
/* If \Fserialcount is 0, this register is not present.
|
||||
|
||||
This register provides access to the read data queues of the serial port
|
||||
selected by \Fserial in \Rsercs.
|
||||
|
||||
If the {\tt error} bit is not set and the queue is not empty, a read from this register reads the
|
||||
oldest entry in the debugger-to-core queue, and removes that entry from the queue.
|
||||
Otherwise the {\tt error} bit is set and the read returns error.
|
||||
*/
|
||||
def DMI_SERRX = 0x36
|
||||
|
||||
def DMI_SBCS = 0x38
|
||||
|
||||
/* If \Fsbasize is 0, then this register is not present.
|
||||
|
||||
When the system bus master is busy,
|
||||
writes to this register will return error
|
||||
and \Fsberror is set.
|
||||
writes to this register will set \Fsberror.
|
||||
|
||||
If \Fsberror is 0 and \Fsbautoread is set then the system bus
|
||||
master will start
|
||||
@ -189,31 +179,31 @@ object DMI_RegAddrs {
|
||||
/* If all of the {\tt sbaccess} bits in \Rsbcs are 0, then this register
|
||||
is not present.
|
||||
|
||||
If \Fsberror isn't 0 then accesses return error, and don't do anything
|
||||
else.
|
||||
Any successful system bus read updates the data in this register, and
|
||||
marks it no longer stale.
|
||||
|
||||
Writes to this register:
|
||||
If \Fsberror isn't 0 then accesses do nothing.
|
||||
|
||||
\begin{steps}{Writes to this register:}
|
||||
\item If the bus master is busy then accesses set \Fsberror, and
|
||||
don't do anything else.
|
||||
\item Start a bus write of {\tt sbdata} to {\tt sbaddress}.
|
||||
\item If \Fsbautoincrement is set, increment {\tt sbaddress}.
|
||||
\end{steps}
|
||||
|
||||
1. If the bus master is busy then accesses set \Fsberror, return error,
|
||||
and don't do anything else.
|
||||
\begin{steps}{Reads from this register:}
|
||||
\item If the register is marked stale, then set \Fsberror and don't
|
||||
do anything else.
|
||||
\item ``Return'' the data.
|
||||
\item Mark the register stale.
|
||||
\item If \Fsbautoincrement is set, increment {\tt sbaddress}.
|
||||
\item If \Fsbautoread is set, start another system bus read.
|
||||
\end{steps}
|
||||
|
||||
2. Update internal data.
|
||||
|
||||
3. Start a bus write of the internal data to the internal address.
|
||||
|
||||
4. If \Fsbautoincrement is set, increment the internal address.
|
||||
|
||||
Reads to this register:
|
||||
|
||||
1. If bits 31:0 of the internal data register haven't been updated
|
||||
since the last time this register was read, then set \Fsberror, return
|
||||
error, and don't do anything else.
|
||||
|
||||
2. ``Return'' the data.
|
||||
|
||||
3. If \Fsbautoincrement is set, increment the internal address.
|
||||
|
||||
4. If \Fsbautoread is set, start another system bus read.
|
||||
Only \Rsbdatazero has this behavior. The other {\tt sbdata} registers
|
||||
have no side effects. On systems that have buses wider than 32 bits, a
|
||||
debugger should access \Rsbdatazero after accessing the other {\tt
|
||||
sbdata} registers.
|
||||
*/
|
||||
def DMI_SBDATA0 = 0x3c
|
||||
|
||||
@ -234,13 +224,47 @@ object DMI_RegAddrs {
|
||||
|
||||
class DMSTATUSFields extends Bundle {
|
||||
|
||||
val reserved0 = UInt(14.W)
|
||||
val reserved0 = UInt(5.W)
|
||||
|
||||
/* This field is 1 when all currently selected harts have acknowledged the previous \Fresumereq.
|
||||
/* Gets set if the Debug Module was accessed incorrectly.
|
||||
|
||||
0 (none): No error.
|
||||
|
||||
1 (badaddr): There was an access to an unimplemented Debug Module
|
||||
address.
|
||||
|
||||
7 (other): An access failed for another reason.
|
||||
*/
|
||||
val dmerr = UInt(3.W)
|
||||
|
||||
val reserved1 = UInt(1.W)
|
||||
|
||||
/* If 1, then there is an implicit {\tt ebreak} instruction at the
|
||||
non-existent word immediately after the Program Buffer. This saves
|
||||
the debugger from having to write the {\tt ebreak} itself, and
|
||||
allows the Program Buffer to be one word smaller.
|
||||
|
||||
This must be 1 when \Fprogbufsize is 1.
|
||||
*/
|
||||
val impebreak = Bool()
|
||||
|
||||
val reserved2 = UInt(2.W)
|
||||
|
||||
/* This field is 1 when all currently selected harts have been reset but the reset has not been acknowledged.
|
||||
*/
|
||||
val allhavereset = Bool()
|
||||
|
||||
/* This field is 1 when any currently selected hart has been reset but the reset has not been acknowledged.
|
||||
*/
|
||||
val anyhavereset = Bool()
|
||||
|
||||
/* This field is 1 when all currently selected harts have acknowledged
|
||||
the previous resume request.
|
||||
*/
|
||||
val allresumeack = Bool()
|
||||
|
||||
/* This field is 1 when any currently selected hart has acknowledged the previous \Fresumereq.
|
||||
/* This field is 1 when any currently selected hart has acknowledged
|
||||
the previous resume request.
|
||||
*/
|
||||
val anyresumeack = Bool()
|
||||
|
||||
@ -293,49 +317,58 @@ class DMSTATUSFields extends Bundle {
|
||||
*/
|
||||
val authbusy = Bool()
|
||||
|
||||
val reserved1 = UInt(1.W)
|
||||
val reserved3 = UInt(1.W)
|
||||
|
||||
val cfgstrvalid = Bool()
|
||||
/* 0: \Rdevtreeaddrzero--\Rdevtreeaddrthree hold information which
|
||||
is not relevant to the Device Tree.
|
||||
|
||||
/* Reserved for future use. Reads as 0.
|
||||
1: \Rdevtreeaddrzero--\Rdevtreeaddrthree registers hold the address of the
|
||||
Device Tree.
|
||||
*/
|
||||
val versionhi = UInt(2.W)
|
||||
val devtreevalid = Bool()
|
||||
|
||||
/* 00: There is no Debug Module present.
|
||||
/* 0: There is no Debug Module present.
|
||||
|
||||
01: There is a Debug Module and it conforms to version 0.11 of this
|
||||
1: There is a Debug Module and it conforms to version 0.11 of this
|
||||
specification.
|
||||
|
||||
10: There is a Debug Module and it conforms to version 0.13 of this
|
||||
2: There is a Debug Module and it conforms to version 0.13 of this
|
||||
specification.
|
||||
|
||||
11: Reserved for future use.
|
||||
15: There is a Debug Module but it does not conform to any
|
||||
available version of this spec.
|
||||
*/
|
||||
val versionlo = UInt(2.W)
|
||||
val version = UInt(4.W)
|
||||
|
||||
}
|
||||
|
||||
class DMCONTROLFields extends Bundle {
|
||||
|
||||
/* Halt request signal for all currently selected harts. When set to 1, the
|
||||
hart will halt if it is not currently halted.
|
||||
Setting both \Fhaltreq and \Fresumereq leads to undefined behavior.
|
||||
/* Writes the halt request bit for all currently selected harts.
|
||||
When set to 1, each selected hart will halt if it is not currently
|
||||
halted.
|
||||
|
||||
Writing 1 or 0 has no effect on a hart which is already halted, but
|
||||
the bit must be cleared to 0 before the hart is resumed.
|
||||
|
||||
Writes apply to the new value of \Fhartsel and \Fhasel.
|
||||
*/
|
||||
val haltreq = Bool()
|
||||
|
||||
/* Resume request signal for all currently selected harts. When set to 1,
|
||||
the hart will resume if it is currently halted.
|
||||
Setting both \Fhaltreq and \Fresumereq leads to undefined behavior.
|
||||
/* Writes the resume request bit for all currently selected harts.
|
||||
When set to 1, each selected hart will resume if it is currently
|
||||
halted.
|
||||
|
||||
The resume request bit is ignored while the halt request bit is
|
||||
set.
|
||||
|
||||
Writes apply to the new value of \Fhartsel and \Fhasel.
|
||||
*/
|
||||
val resumereq = Bool()
|
||||
|
||||
/* This optional bit controls reset to all the currently selected harts.
|
||||
To perform a reset the debugger writes 1, and then writes 0 to
|
||||
deassert the reset signal.
|
||||
/* This optional field writes the reset bit for all the currently
|
||||
selected harts. To perform a reset the debugger writes 1, and then
|
||||
writes 0 to deassert the reset signal.
|
||||
|
||||
If this feature is not implemented, the bit always stays 0, so
|
||||
after writing 1 the debugger can read the register back to see if
|
||||
@ -345,7 +378,14 @@ class DMCONTROLFields extends Bundle {
|
||||
*/
|
||||
val hartreset = Bool()
|
||||
|
||||
val reserved0 = UInt(2.W)
|
||||
/* Writing 1 to this bit clears the {\tt havereset} bits for
|
||||
any selected harts.
|
||||
|
||||
Writes apply to the new value of \Fhartsel and \Fhasel.
|
||||
*/
|
||||
val ackhavereset = Bool()
|
||||
|
||||
val reserved0 = UInt(1.W)
|
||||
|
||||
/* Selects the definition of currently selected harts.
|
||||
|
||||
@ -369,7 +409,11 @@ class DMCONTROLFields extends Bundle {
|
||||
val reserved1 = UInt(14.W)
|
||||
|
||||
/* This bit controls the reset signal from the DM to the rest of the
|
||||
system. To perform a reset the debugger writes 1, and then writes 0
|
||||
system. The signal should reset every part of the system, including
|
||||
every hart, except for the DM and any logic required to access the
|
||||
DM.
|
||||
To perform a system reset the debugger writes 1,
|
||||
and then writes 0
|
||||
to deassert the reset.
|
||||
*/
|
||||
val ndmreset = Bool()
|
||||
@ -386,8 +430,8 @@ class DMCONTROLFields extends Bundle {
|
||||
Debug Module after power up, including the platform's system reset
|
||||
or Debug Transport reset signals.
|
||||
|
||||
A debugger should pulse this bit low to ensure that the Debug
|
||||
Module is fully reset and ready to use.
|
||||
A debugger may pulse this bit low to get the debug module into a
|
||||
known state.
|
||||
|
||||
Implementations may use this bit to aid debugging, for example by
|
||||
preventing the Debug Module from being power gated while debugging
|
||||
@ -431,7 +475,7 @@ class HARTINFOFields extends Bundle {
|
||||
shadowing the {\tt data} registers.
|
||||
|
||||
If \Fdataaccess is 1: Signed address of RAM where the {\tt data}
|
||||
registers are shadowed.
|
||||
registers are shadowed, to be used to access relative to \Rzero.
|
||||
*/
|
||||
val dataaddr = UInt(12.W)
|
||||
|
||||
@ -524,11 +568,8 @@ class ABSTRACTCSFields extends Bundle {
|
||||
val reserved0 = UInt(3.W)
|
||||
|
||||
/* Size of the Program Buffer, in 32-bit words. Valid sizes are 0 - 16.
|
||||
|
||||
TODO: Explain what can be done with each size of the buffer, to suggest
|
||||
why you would want more or less words.
|
||||
*/
|
||||
val progsize = UInt(5.W)
|
||||
val progbufsize = UInt(5.W)
|
||||
|
||||
val reserved1 = UInt(11.W)
|
||||
|
||||
@ -547,8 +588,9 @@ class ABSTRACTCSFields extends Bundle {
|
||||
|
||||
0 (none): No error.
|
||||
|
||||
1 (busy): An abstract command was executing while \Rcommand or one
|
||||
of the {\tt data} registers was accessed.
|
||||
1 (busy): An abstract command was executing while \Rcommand,
|
||||
\Rabstractcs, \Rabstractauto was written, or when one
|
||||
of the {\tt data} or {\tt progbuf} registers was read or written.
|
||||
|
||||
2 (not supported): The requested command is not supported. A
|
||||
command that is not supported while the hart is running may be
|
||||
@ -567,7 +609,7 @@ class ABSTRACTCSFields extends Bundle {
|
||||
val reserved3 = UInt(3.W)
|
||||
|
||||
/* Number of {\tt data} registers that are implemented as part of the
|
||||
abstract command interface. Valid sizes are 0 - 8.
|
||||
abstract command interface. Valid sizes are 0 - 12.
|
||||
*/
|
||||
val datacount = UInt(5.W)
|
||||
|
||||
@ -590,20 +632,20 @@ class COMMANDFields extends Bundle {
|
||||
class ABSTRACTAUTOFields extends Bundle {
|
||||
|
||||
/* When a bit in this field is 1, read or write accesses the corresponding {\tt progbuf} word
|
||||
cause the command in \Rcommand to be executed again.
|
||||
cause the command in \Rcommand to be executed again.
|
||||
*/
|
||||
val autoexecprogbuf = UInt(16.W)
|
||||
|
||||
val reserved0 = UInt(4.W)
|
||||
|
||||
/* When a bit in this field is 1, read or write accesses the corresponding {\tt data} word
|
||||
cause the command in \Rcommand to be executed again.
|
||||
cause the command in \Rcommand to be executed again.
|
||||
*/
|
||||
val autoexecdata = UInt(12.W)
|
||||
|
||||
}
|
||||
|
||||
class CFGSTRADDR0Fields extends Bundle {
|
||||
class DEVTREEADDR0Fields extends Bundle {
|
||||
|
||||
val addr = UInt(32.W)
|
||||
|
||||
@ -627,88 +669,6 @@ class AUTHDATAFields extends Bundle {
|
||||
|
||||
}
|
||||
|
||||
class SERCSFields extends Bundle {
|
||||
|
||||
/* Number of supported serial ports.
|
||||
*/
|
||||
val serialcount = UInt(4.W)
|
||||
|
||||
val reserved0 = UInt(1.W)
|
||||
|
||||
/* Select which serial port is accessed by \Rserrx and \Rsertx.
|
||||
*/
|
||||
val serial = UInt(3.W)
|
||||
|
||||
val error7 = Bool()
|
||||
|
||||
val valid7 = Bool()
|
||||
|
||||
val full7 = Bool()
|
||||
|
||||
val error6 = Bool()
|
||||
|
||||
val valid6 = Bool()
|
||||
|
||||
val full6 = Bool()
|
||||
|
||||
val error5 = Bool()
|
||||
|
||||
val valid5 = Bool()
|
||||
|
||||
val full5 = Bool()
|
||||
|
||||
val error4 = Bool()
|
||||
|
||||
val valid4 = Bool()
|
||||
|
||||
val full4 = Bool()
|
||||
|
||||
val error3 = Bool()
|
||||
|
||||
val valid3 = Bool()
|
||||
|
||||
val full3 = Bool()
|
||||
|
||||
val error2 = Bool()
|
||||
|
||||
val valid2 = Bool()
|
||||
|
||||
val full2 = Bool()
|
||||
|
||||
val error1 = Bool()
|
||||
|
||||
val valid1 = Bool()
|
||||
|
||||
val full1 = Bool()
|
||||
|
||||
/* 1 when the debugger-to-core queue for serial port 0 has
|
||||
over or underflowed. This bit will remain set until it is reset by
|
||||
writing 1 to this bit.
|
||||
*/
|
||||
val error0 = Bool()
|
||||
|
||||
/* 1 when the core-to-debugger queue for serial port 0 is not empty.
|
||||
*/
|
||||
val valid0 = Bool()
|
||||
|
||||
/* 1 when the debugger-to-core queue for serial port 0 is full.
|
||||
*/
|
||||
val full0 = Bool()
|
||||
|
||||
}
|
||||
|
||||
class SERTXFields extends Bundle {
|
||||
|
||||
val data = UInt(32.W)
|
||||
|
||||
}
|
||||
|
||||
class SERRXFields extends Bundle {
|
||||
|
||||
val data = UInt(32.W)
|
||||
|
||||
}
|
||||
|
||||
class SBCSFields extends Bundle {
|
||||
|
||||
val reserved0 = UInt(11.W)
|
||||
@ -731,20 +691,18 @@ class SBCSFields extends Bundle {
|
||||
|
||||
4: 128-bit
|
||||
|
||||
If an unsupported system bus access size is written here,
|
||||
the DM may not perform the access, or may perform the access
|
||||
with any access size.
|
||||
If an unsupported system bus access size is written here, the DM
|
||||
does not perform the access and sberror is set to 3.
|
||||
*/
|
||||
val sbaccess = UInt(3.W)
|
||||
|
||||
/* When 1, the internal address value (used by the system bus master)
|
||||
is incremented by the access size (in bytes) selected in \Fsbaccess
|
||||
after every system bus access.
|
||||
/* When 1, {\tt sbaddress} is incremented by the access size (in
|
||||
bytes) selected in \Fsbaccess after every system bus access.
|
||||
*/
|
||||
val sbautoincrement = Bool()
|
||||
|
||||
/* When 1, every read from \Rsbdatazero automatically triggers a system
|
||||
bus read at the new address.
|
||||
/* When 1, every read from \Rsbdatazero automatically triggers a
|
||||
system bus read at the (possibly auto-incremented) address.
|
||||
*/
|
||||
val sbautoread = Bool()
|
||||
|
||||
@ -762,10 +720,9 @@ class SBCSFields extends Bundle {
|
||||
|
||||
3: There was some other error (eg. alignment).
|
||||
|
||||
4: The system bus master was busy when a one of the
|
||||
4: The system bus master was busy when one of the
|
||||
{\tt sbaddress} or {\tt sbdata} registers was written,
|
||||
or the {\tt sbdata} register was read when it had
|
||||
stale data.
|
||||
or \Rsbdatazero was read when it had stale data.
|
||||
*/
|
||||
val sberror = UInt(3.W)
|
||||
|
||||
@ -798,7 +755,7 @@ class SBCSFields extends Bundle {
|
||||
|
||||
class SBADDRESS0Fields extends Bundle {
|
||||
|
||||
/* Accesses bits 31:0 of the internal address.
|
||||
/* Accesses bits 31:0 of the physical address in {\tt sbaddress}.
|
||||
*/
|
||||
val address = UInt(32.W)
|
||||
|
||||
@ -806,8 +763,8 @@ class SBADDRESS0Fields extends Bundle {
|
||||
|
||||
class SBADDRESS1Fields extends Bundle {
|
||||
|
||||
/* Accesses bits 63:32 of the internal address (if the system address
|
||||
bus is that wide).
|
||||
/* Accesses bits 63:32 of the physical address in {\tt sbaddress} (if
|
||||
the system address bus is that wide).
|
||||
*/
|
||||
val address = UInt(32.W)
|
||||
|
||||
@ -815,8 +772,8 @@ class SBADDRESS1Fields extends Bundle {
|
||||
|
||||
class SBADDRESS2Fields extends Bundle {
|
||||
|
||||
/* Accesses bits 95:64 of the internal address (if the system address
|
||||
bus is that wide).
|
||||
/* Accesses bits 95:64 of the physical address in {\tt sbaddress} (if
|
||||
the system address bus is that wide).
|
||||
*/
|
||||
val address = UInt(32.W)
|
||||
|
||||
@ -824,7 +781,7 @@ class SBADDRESS2Fields extends Bundle {
|
||||
|
||||
class SBDATA0Fields extends Bundle {
|
||||
|
||||
/* Accesses bits 31:0 of the internal data.
|
||||
/* Accesses bits 31:0 of {\tt sbdata}.
|
||||
*/
|
||||
val data = UInt(32.W)
|
||||
|
||||
@ -832,8 +789,8 @@ class SBDATA0Fields extends Bundle {
|
||||
|
||||
class SBDATA1Fields extends Bundle {
|
||||
|
||||
/* Accesses bits 63:32 of the internal data (if the system bus is
|
||||
that wide).
|
||||
/* Accesses bits 63:32 of {\tt sbdata} (if the system bus is that
|
||||
wide).
|
||||
*/
|
||||
val data = UInt(32.W)
|
||||
|
||||
@ -841,8 +798,8 @@ class SBDATA1Fields extends Bundle {
|
||||
|
||||
class SBDATA2Fields extends Bundle {
|
||||
|
||||
/* Accesses bits 95:64 of the internal data (if the system bus is
|
||||
that wide).
|
||||
/* Accesses bits 95:64 of {\tt sbdata} (if the system bus is that
|
||||
wide).
|
||||
*/
|
||||
val data = UInt(32.W)
|
||||
|
||||
@ -850,8 +807,8 @@ class SBDATA2Fields extends Bundle {
|
||||
|
||||
class SBDATA3Fields extends Bundle {
|
||||
|
||||
/* Accesses bits 127:96 of the internal data (if the system bus is
|
||||
that wide).
|
||||
/* Accesses bits 127:96 of {\tt sbdata} (if the system bus is that
|
||||
wide).
|
||||
*/
|
||||
val data = UInt(32.W)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user