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->startup();
this->setThreadStateAndEmitEvent(ThreadState::READY); this->setThreadStateAndEmitEvent(ThreadState::READY);
Logger::debug("TargetController ready and waiting for commands"); Logger::debug("TargetController ready");
while (this->getThreadState() == ThreadState::READY) { while (this->getThreadState() == ThreadState::READY) {
this->fireTargetEvents(); this->fireTargetEvents();

View File

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

View File

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

View File

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