RISC-V abstract commands
This commit is contained in:
@@ -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
|
||||
;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user