RISC-V abstract commands

This commit is contained in:
Nav
2023-11-23 15:21:46 +00:00
parent 776ce3c44d
commit 522187382a
5 changed files with 134 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
#pragma once
#include <cstdint>
#include <cassert>
#include "src/Targets/RiscV/DebugModule/DebugModule.hpp"
namespace Targets::RiscV::DebugModule::Registers
{
struct AbstractCommandRegister
{
enum CommandType: std::uint8_t
{
REGISTER_ACCESS = 0x00,
QUICK_ACCESS = 0x01,
MEMORY_ACCESS = 0x02,
};
std::uint32_t control = 0;
CommandType commandType = CommandType::REGISTER_ACCESS;
AbstractCommandRegister() = default;
constexpr explicit AbstractCommandRegister(RegisterValue registerValue)
: control(static_cast<std::uint32_t>(registerValue & 0x00FFFFFF))
, commandType(static_cast<CommandType>((registerValue >> 24) & 0xFF))
{}
constexpr RegisterValue value() const {
assert(this->control <= 0x00FFFFFF);
return RegisterValue{0}
| static_cast<RegisterValue>(this->control & 0x00FFFFFF)
| static_cast<RegisterValue>(this->commandType) << 24
;
}
};
}

View File

@@ -0,0 +1,53 @@
#pragma once
#include <cstdint>
#include "src/Targets/RiscV/DebugModule/DebugModule.hpp"
namespace Targets::RiscV::DebugModule::Registers
{
struct AbstractControlStatusRegister
{
enum CommandError: std::uint8_t
{
NONE = 0x00,
BUSY = 0x01,
NOT_SUPPORTED = 0x02,
EXCEPTION = 0x03,
HALT_RESUME = 0x04,
BUS = 0x05,
OTHER = 0x07,
};
std::uint8_t dataCount:4 = 0;
CommandError commandError:3 = CommandError::NONE;
bool relaxedPrivilege:1 = false;
bool busy:1 = false;
std::uint8_t programBufferSize:5 = 0;
AbstractControlStatusRegister() = default;
constexpr explicit AbstractControlStatusRegister(RegisterValue registerValue)
: dataCount(static_cast<std::uint8_t>(registerValue & 0x0F))
, commandError(static_cast<CommandError>((registerValue >> 8) & 0x07))
, relaxedPrivilege(static_cast<bool>(registerValue & (0x01 << 11)))
, busy(static_cast<bool>(registerValue & (0x01 << 12)))
, programBufferSize(static_cast<std::uint8_t>((registerValue >> 24) & 0x1F))
{}
constexpr RegisterValue value() const {
return RegisterValue{0}
| static_cast<RegisterValue>(this->dataCount)
| static_cast<RegisterValue>(this->commandError) << 8
| static_cast<RegisterValue>(this->relaxedPrivilege) << 11
| static_cast<RegisterValue>(this->busy) << 12
| static_cast<RegisterValue>(this->programBufferSize) << 24
;
}
constexpr void clearCommandError() {
// Setting all of the bits will clear the field
this->commandError = CommandError::OTHER;
}
};
}

View File

@@ -6,7 +6,10 @@ namespace Targets::RiscV::DebugModule::Registers
{
enum RegisterAddresses: std::uint8_t
{
ABSTRACT_DATA_0 = 0x04,
CONTROL_REGISTER = 0x10,
STATUS_REGISTER = 0x11,
ABSTRACT_CONTROL_STATUS_REGISTER = 0x16,
ABSTRACT_COMMAND_REGISTER = 0x17,
};
}

View File

@@ -15,6 +15,8 @@ namespace Targets::RiscV
using DebugModule::Registers::RegisterAddresses;
using DebugModule::Registers::ControlRegister;
using DebugModule::Registers::StatusRegister;
using DebugModule::Registers::AbstractControlStatusRegister;
using DebugModule::Registers::AbstractCommandRegister;
RiscV::RiscV(const TargetConfig& targetConfig)
: name("CH32X035C8T6") // TODO: TDF
@@ -278,10 +280,43 @@ namespace Targets::RiscV
return StatusRegister(this->riscVDebugInterface->readDebugModuleRegister(RegisterAddresses::STATUS_REGISTER));
}
AbstractControlStatusRegister RiscV::readDebugModuleAbstractControlStatusRegister() {
return AbstractControlStatusRegister(
this->riscVDebugInterface->readDebugModuleRegister(RegisterAddresses::ABSTRACT_CONTROL_STATUS_REGISTER)
);
}
void RiscV::writeDebugModuleControlRegister(const DebugModule::Registers::ControlRegister &controlRegister) {
this->riscVDebugInterface->writeDebugModuleRegister(
RegisterAddresses::CONTROL_REGISTER,
controlRegister.value()
);
}
void RiscV::executeAbstractCommand(
const DebugModule::Registers::AbstractCommandRegister& abstractCommandRegister
) {
this->riscVDebugInterface->writeDebugModuleRegister(
RegisterAddresses::ABSTRACT_COMMAND_REGISTER,
abstractCommandRegister.value()
);
auto abstractStatusRegister = this->readDebugModuleAbstractControlStatusRegister();
if (abstractStatusRegister.commandError != AbstractControlStatusRegister::CommandError::NONE) {
throw Exceptions::Exception(
"Failed to execute abstract command - error: "
+ Services::StringService::toHex(abstractStatusRegister.commandError)
);
}
constexpr auto maxAttempts = 10;
for (auto attempts = 1; abstractStatusRegister.busy && attempts <= maxAttempts; ++attempts) {
std::this_thread::sleep_for(std::chrono::microseconds(10));
abstractStatusRegister = this->readDebugModuleAbstractControlStatusRegister();
}
if (abstractStatusRegister.busy) {
throw Exceptions::Exception("Abstract command took too long to execute");
}
}
}

View File

@@ -11,6 +11,8 @@
#include "src/Targets/RiscV/DebugModule/DebugModule.hpp"
#include "src/Targets/RiscV/DebugModule/Registers/ControlRegister.hpp"
#include "src/Targets/RiscV/DebugModule/Registers/StatusRegister.hpp"
#include "src/Targets/RiscV/DebugModule/Registers/AbstractControlStatusRegister.hpp"
#include "src/Targets/RiscV/DebugModule/Registers/AbstractCommandRegister.hpp"
namespace Targets::RiscV
{
@@ -99,7 +101,10 @@ namespace Targets::RiscV
DebugModule::Registers::ControlRegister readDebugModuleControlRegister();
DebugModule::Registers::StatusRegister readDebugModuleStatusRegister();
DebugModule::Registers::AbstractControlStatusRegister readDebugModuleAbstractControlStatusRegister();
void writeDebugModuleControlRegister(const DebugModule::Registers::ControlRegister &controlRegister);
void executeAbstractCommand(const DebugModule::Registers::AbstractCommandRegister& abstractCommandRegister);
};
}