-
Notifications
You must be signed in to change notification settings - Fork 925
Add DCSR.MPRVEN support #1882
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
base: master
Are you sure you want to change the base?
Add DCSR.MPRVEN support #1882
Conversation
I've also added tests targeting this feature: riscv-software-src/riscv-tests#599 |
Adds DCSR.MPRVEN bit support, as specified in RISC-V External Debug Support Version 1.0.0-rc4 (https://github.com/riscv/riscv-debug-spec/releases/tag/1.0.0-rc4, see 4.9.1 Debug Control and Status). This bit allows to enable hardware virtual address translation when memory access is initiated by the debugger (see 4.1 Debug Mode, clause 2). This change: * Increases debug specification coverage, allows more detailed testing of external debuggers with Spike. * Decreases the number of required abstract commands to read virtual memory thus improving the user experience. Commit's changes: * Added MPRVEN field to DCSR register * Updated debug_rom.S to turn off MPRVEN while executing ROM To avoid unwanted address translation in while debug_rom.S executed DCSR.MPRVEN bit has to be cleared on entry and restored on exit. Updated version of debug_rom.S does the following: * On _entry: clears DCSR.MPRVEN bit, stores previous DCSR value to S1 and stores previous S1 value to DSCRATCH01 * On _exception: restores S1 value from DSCRATCH01 * On _resume/going: restores S1 and DCSR values Signed-off-by: Farid Khaydari <f.khaydari@syntacore.com>
372448d
to
95af514
Compare
@aswaterman, @rtwfroody, would you kindly take a look? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had thought that not using dscratch1 was a goal of this sample debug ROM, but I'll defer to @rtwfroody
@aswaterman Can you approve the workflows for this change? |
Yep. |
csrw CSR_DSCRATCH1, s1 // Save s1 | ||
csrrci s1, CSR_DCSR, DCSR_MPRVEN // Save DCSR and clear MPRVEN |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This clobbers s1. Now the debugger can't access it anymore.
Also you're going through a bunch of effort here to clear dcsr.mprven while in debug mode, but if you're clearing it then when does the bit actually have an effect?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the use of register s1:
The register s1 is used within the debug ROM to save and restore the DCSR register, specifically to manage the MPRVEN bit. After the debug ROM execution, s1 is restored to its original value, ensuring that the debugger can access it as before. This approach maintains the integrity of s1 for debugger operations.
Clarification on MPRVEN bit management:
The MPRVEN bit is cleared within the debug ROM to prevent unwanted virtual address translations during ROM execution. However, it is crucial that this bit is set when the debugger initiates memory accesses. The debug ROM's role is to ensure a controlled environment, and the MPRVEN bit will have its intended effect when the debugger performs memory operations post-ROM execution.
@@ -64,6 +72,8 @@ _resume: | |||
csrr s0, CSR_MHARTID | |||
sw s0, DEBUG_ROM_RESUMING(zero) // When Debug Module sees this write, the RESUME flag is reset. | |||
csrr s0, CSR_DSCRATCH0 // Restore s0 | |||
csrw CSR_DCSR, s1 // Restore DSCR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How can the debugger set bits in dcsr if here you overwrite it with a previously saved value? The debugger has to be able to set bits like ebreakm and step.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your feedback! I understand your concern about the debugger's ability to set bits like ebreakm and step in the DCSR register.
As I understand, the debugger modifies the DCSR only in whereto section (section for progbuf and abstract commands code). And we clear MPRVEN only inside of debug ROM which is not intersect with whereto. This means that restoring the entire DCSR register (including MPRVEN) should not interfere with the debugger's ability to set other bits like ebreakm and step during normal operation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But additional dscratch2 may be needed to support this when base address of debug is not ZERO. @fk-sc @rtwfroody
In Rocket-chip: https://github.com/chipsalliance/rocket-chip/blob/f517abbf41abb65cea37421d3559f9739efd00a9/scripts/debug_rom/debug_rom_nonzero.S#L51C7-L51C29
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wissygh this is not the case for spike
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wissygh just to elaborate. This patch does not mean that dscratch2 becomes unusable in any way. Whether or not dscratch register is used is an implementation detail specific to the design/implementation.
This change allows us to implement support for hw address translation in spike (do note that this not only updates the ROM image - it has some changes in the codebase of the simulator). This change is required to test relevant support in riscv-openocd. It has nothing to do with rocket-chip or other designs.
@rtwfroody would you kindly take a look again? |
@rtwfroody ping) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. I've read over this again and now it makes sense to me. Sorry for not reading more closely the first time around. Thanks for your explanations.
@aswaterman could you please consider merging this? I already have tests for OpenOCD in riscv_tests repository that depend on this patch: pr599 There are some concerns from @wissygh that indicate that this may break compatibility (I'm not sure that there was one, to be fair) with rocket-chip project for some configurations of their designs. This compatibility was never intended to be in the scope of this MR, though. If this is an issue - someone could try to address this in a subsequent commit. I can participate too if there is a request for it. |
What concerns me is whether Spike will continue to increase its use of dscratchX if similar issues arise in the future. Additionally, Spike is considered an important reference when designing the microarchitecture. What I'm trying to say is, is there a better way to solve this problem? |
The thing is that this patch extends existing functionality. The fact that the new ROM becomes incompatible with some older rocket-chip design is a direct consequence of that (we introduce a new micro architectural feature that should be taken into account).
I don't think that we require to increase the number of dsccrach registers in future. It could be possible to avoid it. However, I don't think that we can reduce the number of used scratch registers in this specific case.
Given the summary above I don't think there is. However, if in future we need to take into account some new issue - it should be possible to implement a solution that won't require more scratch registers. |
I share @wissygh's concern but don't have a great solution. But one improvement I'd recommend is to use |
I think you can avoid using dscratch1 by duplicating some code. You'd write something like:
Thinking of this more, the comment says we disable mprven to avoid address translation when fetching code from the debug_rom. What about fetching code while mprven is set? E.g. the few instructions before you disable mprven, and the fetching of instructions orchestrated pointed at by whereto? |
Avoiding use of dscratch1 by restructuring the code would be an improvement, IMO. |
I noticed that when |
When running OpenOCD with Spike, the simulator ignores writes to dcsr.mprven (it behaves like it hardwired to zero). Consequently, hardware-assisted virtual-to-physical address translation doesn't work properly, and "virtual" address accesses directly map to physical memory. OpenOCD’s automated mprven toggling thus has no effect in this environment. The patch corrects this behavior by allowing Spike to honor dcsr.mprven writes, enabling proper translation. This is the reason this MR exists. @wissygh |
Yes, therefore I believe that Spike only needs to add support for the implementation of |
As soon as we add support for mprven we have to update debug rom because the debug rom itself performs memory accesses and expects these memory accesses to avoid memory translation |
@rtwfroody, I will try to implement your idea. If successful, I’ll create a separate PR. For now, I’ll use the temporary Regarding your concerns about instruction fetch: the RISC-V Privileged Specification (section 3.1.6.3, Memory Privilege in mstatus Register) states that MPRV should not affect instruction address translation. I’ve double-checked Spike’s implementation, and it behaves correctly. |
@wissygh, are you okay with the approach suggested by @aswaterman? |
I would strongly prefer to wait until you've gotten @rtwfroody's scheme working, rather than using the |
What I want to express here is that if the |
OK! |
Aside from that there is also "abstract memory access" command mechanism that does not use progbuf at all (just FYI). |
Adds DCSR.MPRVEN bit support, as specified in RISC-V External Debug Support Version 1.0.0-rc4 (https://github.com/riscv/riscv-debug-spec/releases/tag/1.0.0-rc4, see 4.9.1 Debug Control and Status).
This bit allows to enable hardware virtual address translation when memory access is initiated by the debugger (see 4.1 Debug Mode, clause 2).
This change:
Commit's changes:
To avoid unwanted address translation while debug_rom.S executed DCSR.MPRVEN bit has to be cleared on entry and restored on exit.
Updated version of debug_rom.S does the following: