This commit is contained in:
Nav
2023-11-23 12:59:36 +00:00
parent c1c9a0ceeb
commit 776ce3c44d
4 changed files with 38 additions and 25 deletions

View File

@@ -67,7 +67,7 @@ namespace TargetController
this->startup();
this->setThreadStateAndEmitEvent(ThreadState::READY);
Logger::debug("TargetController ready and waiting for commands");
Logger::debug("TargetController ready");
while (this->getThreadState() == ThreadState::READY) {
this->fireTargetEvents();

View File

@@ -1,6 +1,7 @@
#pragma once
#include <cstdint>
#include <cassert>
#include "src/Targets/RiscV/DebugModule/DebugModule.hpp"
@@ -47,6 +48,8 @@ namespace Targets::RiscV::DebugModule::Registers
{}
constexpr RegisterValue value() const {
assert(this->selectedHartIndex <= 0xFFFFF);
return RegisterValue{0}
| static_cast<RegisterValue>(this->debugModuleActive)
| static_cast<RegisterValue>(this->ndmReset) << 1

View File

@@ -6,6 +6,7 @@
#include "DebugModule/Registers/RegisterAddresses.hpp"
#include "src/Exceptions/Exception.hpp"
#include "src/TargetController/Exceptions/TargetOperationFailure.hpp"
#include "src/Logger/Logger.hpp"
@@ -30,7 +31,12 @@ namespace Targets::RiscV
void RiscV::activate() {
this->riscVDebugInterface->activate({});
this->discoverHartIndices();
this->hartIndices = this->discoverHartIndices();
if (this->hartIndices.empty()) {
throw Exceptions::TargetOperationFailure("Failed to discover a single RISC-V hart");
}
Logger::debug("Discovered RISC-V harts: " + std::to_string(this->hartIndices.size()));
/*
@@ -82,18 +88,18 @@ namespace Targets::RiscV
controlRegister.selectedHartIndex = this->selectedHartIndex;
controlRegister.resumeRequest = true;
this->writeControlRegister(controlRegister);
this->writeDebugModuleControlRegister(controlRegister);
constexpr auto maxAttempts = 10;
auto statusRegister = this->readStatusRegister();
auto statusRegister = this->readDebugModuleStatusRegister();
for (auto attempts = 1; !statusRegister.allResumeAcknowledge && attempts <= maxAttempts; ++attempts) {
std::this_thread::sleep_for(std::chrono::microseconds(10));
statusRegister = this->readStatusRegister();
statusRegister = this->readDebugModuleStatusRegister();
}
controlRegister.resumeRequest = false;
this->writeControlRegister(controlRegister);
this->writeDebugModuleControlRegister(controlRegister);
if (!statusRegister.allResumeAcknowledge) {
throw Exceptions::Exception("Target took too long to acknowledge resume request");
@@ -106,18 +112,18 @@ namespace Targets::RiscV
controlRegister.selectedHartIndex = this->selectedHartIndex;
controlRegister.haltRequest = true;
this->writeControlRegister(controlRegister);
this->writeDebugModuleControlRegister(controlRegister);
constexpr auto maxAttempts = 10;
auto statusRegister = this->readStatusRegister();
auto statusRegister = this->readDebugModuleStatusRegister();
for (auto attempts = 1; !statusRegister.allHalted && attempts <= maxAttempts; ++attempts) {
std::this_thread::sleep_for(std::chrono::microseconds(10));
statusRegister = this->readStatusRegister();
statusRegister = this->readDebugModuleStatusRegister();
}
controlRegister.haltRequest = false;
this->writeControlRegister(controlRegister);
this->writeDebugModuleControlRegister(controlRegister);
if (!statusRegister.allHalted) {
throw Exceptions::Exception("Target took too long to halt selected harts");
@@ -182,7 +188,7 @@ namespace Targets::RiscV
}
TargetState RiscV::getState() {
return this->readStatusRegister().anyRunning ? TargetState::RUNNING : TargetState::STOPPED;
return this->readDebugModuleStatusRegister().anyRunning ? TargetState::RUNNING : TargetState::STOPPED;
}
TargetMemoryAddress RiscV::getProgramCounter() {
@@ -220,7 +226,9 @@ namespace Targets::RiscV
return false;
}
void RiscV::discoverHartIndices() {
std::set<DebugModule::HartIndex> RiscV::discoverHartIndices() {
auto hartIndices = std::set<DebugModule::HartIndex>();
/*
* We can obtain the maximum hart index by setting all of the hartsel bits in the control register and then
* reading the value back.
@@ -229,8 +237,8 @@ namespace Targets::RiscV
controlRegister.debugModuleActive = true;
controlRegister.selectedHartIndex = 0xFFFFF;
this->writeControlRegister(controlRegister);
controlRegister = this->readControlRegister();
this->writeDebugModuleControlRegister(controlRegister);
controlRegister = this->readDebugModuleControlRegister();
for (DebugModule::HartIndex hartIndex = 0; hartIndex <= controlRegister.selectedHartIndex; ++hartIndex) {
/*
@@ -241,34 +249,36 @@ namespace Targets::RiscV
controlRegister.debugModuleActive = true;
controlRegister.selectedHartIndex = hartIndex;
this->writeControlRegister(controlRegister);
this->writeDebugModuleControlRegister(controlRegister);
/*
* It's worth noting that some RISC-V targets **do not** set the non-existent flags. I'm not sure why.
* Have they just hardwired hartsel to 0 because they only support a single hart, preventing the selection
* Has hartsel been hardwired to 0 because they only support a single hart, preventing the selection
* of non-existent harts?
*
* Relying on the maximum hart index seems to be all we can do in this case.
*/
if (this->readStatusRegister().anyNonExistent) {
if (this->readDebugModuleStatusRegister().anyNonExistent) {
break;
}
this->hartIndices.insert(hartIndex);
}
hartIndices.insert(hartIndex);
}
ControlRegister RiscV::readControlRegister() {
return hartIndices;
}
ControlRegister RiscV::readDebugModuleControlRegister() {
return ControlRegister(
this->riscVDebugInterface->readDebugModuleRegister(RegisterAddresses::CONTROL_REGISTER)
);
}
StatusRegister RiscV::readStatusRegister() {
StatusRegister RiscV::readDebugModuleStatusRegister() {
return StatusRegister(this->riscVDebugInterface->readDebugModuleRegister(RegisterAddresses::STATUS_REGISTER));
}
void RiscV::writeControlRegister(const ControlRegister& controlRegister) {
void RiscV::writeDebugModuleControlRegister(const DebugModule::Registers::ControlRegister &controlRegister) {
this->riscVDebugInterface->writeDebugModuleRegister(
RegisterAddresses::CONTROL_REGISTER,
controlRegister.value()

View File

@@ -95,11 +95,11 @@ namespace Targets::RiscV
std::set<DebugModule::HartIndex> hartIndices;
DebugModule::HartIndex selectedHartIndex = 0;
void discoverHartIndices();
std::set<DebugModule::HartIndex> discoverHartIndices();
DebugModule::Registers::ControlRegister readControlRegister();
DebugModule::Registers::StatusRegister readStatusRegister();
DebugModule::Registers::ControlRegister readDebugModuleControlRegister();
DebugModule::Registers::StatusRegister readDebugModuleStatusRegister();
void writeControlRegister(const DebugModule::Registers::ControlRegister& controlRegister);
void writeDebugModuleControlRegister(const DebugModule::Registers::ControlRegister &controlRegister);
};
}