Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow debug module to be at a base address other than 0 #2649

Merged
merged 10 commits into from
Oct 2, 2020

Conversation

ernie-sifive
Copy link
Contributor

Related issue:

Type of change: feature request

Impact: API addition (no impact on existing code)

Development Phase: implementation

Release Notes

A new baseAddress parameter is added to DebugModuleParams. This defaults to 0 but can be changed to another 4K-aligned address in the config.

The dataaddr field of DMI register hartinfo indicates the address of the DATA registers in memory and the debug spec states that these may be accessed using dataaddr offset from x0. When the DM is not at zero, this is no longer true. Therefore, hartinfo is forced to 0, which the debug spec says means it is nonexistent. This will prevent debuggers from attempting to use the program buffer to directly access DATA.

The number of Debug Scratch registers is increased from 1 to 2 when the base address is non-zero. Besides saving s0 to use as a temporary for moving data values, the debug ROM must now save another register which serves as a base pointer for data accesses within the debug module (e.g. FLAGS register).

The debug ROM code is changed to accommodate a non-zero base address. There are now two different debug ROMs since the non-zero version assumes dscratch1 exists and has about 20% more code.

The constructed opcodes in ABSTRACT in Debug.scala are changed to accommodate a non-zero base address when necessary. Basically, DATA(s1) or DATA(s0) is used to load/store registers, depending on which register the abstract command is accessing. s0/s1 is restored to the customer value before ABSTRACT falls through to PROGBUF.

Hardcoded debug vector addresses in CSR.scala now come from DebugModuleKey and reflect baseAddress. The debug vector address computation is done at elaboration.

@aswaterman
Copy link
Member

CSR changes look good. I assume the same debug ROM code copes with either case?

@aswaterman
Copy link
Member

Nevermind, I see, it's different code for the two cases. Makes sense.

@ernie-sifive ernie-sifive merged commit 9699c48 into master Oct 2, 2020
@@ -9,7 +9,7 @@ import chisel3.util._
import freechips.rocketchip.config._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.regmapper._
import freechips.rocketchip.rocket.Instructions
import freechips.rocketchip.rocket.{CSRs, Instructions}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder how much work it would be to move these two helpers to util so that Rocket and Debug can both depend on them, rather than having a circular dependency between these packages?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Instructions.scala file that has these objects looks like it used to be generated from the riscv/riscv-opcodes repository. I ran the chisel generator there, but the result was much different from Instructions.scala, so it's clear the two have diverged at some time in the past. The Spike CSR list used by the Debug ROM code is yet another divergent copy of this info. It makes sense to me to have this info in a foundation like riscv-opcodes and generate all uses from there.

@@ -1579,13 +1643,14 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int, beatBytes: I
val commandWrIsAccessRegister = (COMMANDWrData.cmdtype === DebugAbstractCommandType.AccessRegister.id.U)
val commandRegIsAccessRegister = (COMMANDReg.cmdtype === DebugAbstractCommandType.AccessRegister.id.U)

val commandWrIsUnsupported = COMMANDWrEn && !commandWrIsAccessRegister;
val commandWrIsUnsupported = COMMANDWrEn && !commandWrIsAccessRegister
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a semi-colon?! that must be a @mwachs5 2017 original 😂

@@ -7,6 +7,7 @@ import Chisel._
import Chisel.ImplicitConversions._
import chisel3.withClock
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.devices.debug.DebugModuleKey
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is definitely the dark side of the implicit p pattern; we're going to feel the pain if we ever have more than one debug unit and want them to differ according to any of the parameters used here. I am not really sure how to make it diplomatic though, is the only extant direct wire between the core and debug unit that one interrupt line?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes -- a debug interrupt, a TL slave port from cbus, and a TL master port to fbus. I guess if there is more than one DM in the address space, then the one whose interrupt is attached is the one this Tile will use and the debug exception address should be customized to that one. This PR doesn't add to the problem -- before, it was a hardcoded 0x800 which didn't allow multiple DMs either.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants