WCH RISC-V software breakpoints, and a few other bits of refactoring/tidying

This commit is contained in:
Nav
2024-12-05 23:09:01 +00:00
parent 966244a01a
commit 33ed399337
55 changed files with 1530 additions and 686 deletions

View File

@@ -110,7 +110,7 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec
if (!this->debugModuleDescriptor.triggerDescriptorsByIndex.empty()) {
// Clear any left-over triggers from the previous debug session
this->clearAllTriggerBreakpoints();
this->clearAllTriggers();
}
this->initDebugControlStatusRegister();
@@ -122,6 +122,8 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec
Logger::debug("Data register count: " + std::to_string(this->debugModuleDescriptor.abstractDataRegisterCount));
Logger::debug("Program buffer size: " + std::to_string(this->debugModuleDescriptor.programBufferSize));
this->clearProgramBuffer();
if (this->debugModuleDescriptor.abstractDataRegisterCount > 0) {
if (this->debugModuleDescriptor.programBufferSize >= 3) {
this->debugModuleDescriptor.memoryAccessStrategies.insert(MemoryAccessStrategy::PROGRAM_BUFFER);
@@ -299,15 +301,20 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec
void DebugTranslator::insertTriggerBreakpoint(TargetMemoryAddress address) {
using TriggerModule::TriggerType;
const auto triggerDescriptorOpt = this->getAvailableTrigger();
// We may already have a trigger for this address. If so, reuse it.
const auto preexistingTriggerIndexIt = this->triggerIndicesByBreakpointAddress.find(address);
auto triggerDescriptorOpt = preexistingTriggerIndexIt != this->triggerIndicesByBreakpointAddress.end()
? std::cref(this->debugModuleDescriptor.triggerDescriptorsByIndex.at(preexistingTriggerIndexIt->second))
: this->getAvailableTrigger();
if (!triggerDescriptorOpt.has_value()) {
throw Exceptions::TargetOperationFailure{"Insufficient resources - no available trigger"};
}
const auto& triggerDescriptor = triggerDescriptorOpt->get();
Logger::debug(
"Installing hardware BP at address 0x" + Services::StringService::toHex(address) + " with trigger index "
+ std::to_string(triggerDescriptor.index)
"Installing RISC-V trigger for program address 0x" + Services::StringService::toHex(address)
+ " with trigger index " + std::to_string(triggerDescriptor.index)
);
if (triggerDescriptor.supportedTypes.contains(TriggerType::MATCH_CONTROL)) {
@@ -353,7 +360,7 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec
this->allocatedTriggerIndices.erase(triggerDescriptor.index);
}
void DebugTranslator::clearAllTriggerBreakpoints() {
void DebugTranslator::clearAllTriggers() {
// To ensure that any untracked breakpoints are cleared, we clear all triggers on the target.
for (const auto& [triggerIndex, triggerDescriptor] : this->debugModuleDescriptor.triggerDescriptorsByIndex) {
this->clearTrigger(triggerDescriptor);
@@ -505,6 +512,42 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec
throw Exceptions::InternalFatalErrorException{"Unknown selected memory access strategy"};
}
AbstractCommandError DebugTranslator::readAndClearAbstractCommandError() {
const auto commandError = this->readDebugModuleAbstractControlStatusRegister().commandError;
if (commandError != AbstractCommandError::NONE) {
this->clearAbstractCommandError();
}
return commandError;
}
void DebugTranslator::clearProgramBuffer() {
if (this->debugModuleDescriptor.programBufferSize < 1) {
return;
}
this->writeProgramBuffer(
std::vector<Opcodes::Opcode>(this->debugModuleDescriptor.programBufferSize, Opcodes::Ebreak)
);
}
void DebugTranslator::executeFenceProgram() {
static constexpr auto programOpcodes = std::to_array<Opcodes::Opcode>({
Opcodes::FenceI,
Opcodes::Fence,
Opcodes::Ebreak,
});
if (programOpcodes.size() > this->debugModuleDescriptor.programBufferSize) {
throw Exceptions::TargetOperationFailure{
"Cannot execute fence program via RISC-V debug module program buffer - insufficient program buffer size"
};
}
this->writeProgramBuffer(programOpcodes);
this->readCpuRegister(CpuRegisterNumber::GPR_X8, {.postExecute = true});
}
std::vector<DebugModule::HartIndex> DebugTranslator::discoverHartIndices() {
auto hartIndices = std::vector<DebugModule::HartIndex>{};