diff --git a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugTranslator.cpp b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugTranslator.cpp index db528986..1c18a0ef 100644 --- a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugTranslator.cpp +++ b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugTranslator.cpp @@ -505,10 +505,12 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec } } - RegisterValue DebugTranslator::readCpuRegister(RegisterNumber number) { + Expected DebugTranslator::tryReadCpuRegister( + RegisterNumber number + ) { using DebugModule::Registers::RegisterAccessControlField; - this->executeAbstractCommand(AbstractCommandRegister{ + const auto commandError = this->tryExecuteAbstractCommand(AbstractCommandRegister{ RegisterAccessControlField{ number, false, @@ -520,14 +522,44 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec AbstractCommandRegister::CommandType::REGISTER_ACCESS }); + if (commandError != DebugModule::AbstractCommandError::NONE) { + return commandError; + } + return this->dtmInterface.readDebugModuleRegister(RegisterAddress::ABSTRACT_DATA_0); } - void DebugTranslator::writeCpuRegister(RegisterNumber number, RegisterValue value) { + Expected DebugTranslator::tryReadCpuRegister( + Registers::CpuRegisterNumber number + ) { + return this->tryReadCpuRegister(static_cast(number)); + } + + RegisterValue DebugTranslator::readCpuRegister(RegisterNumber number) { + const auto result = this->tryReadCpuRegister(number); + + if (!result.hasValue()) { + throw Exceptions::Exception{ + "Failed to read CPU register (number: 0x" + Services::StringService::toHex(number) + + ") - abstract command error: 0x" + Services::StringService::toHex(result.error()) + }; + } + + return result.value(); + } + + RegisterValue DebugTranslator::readCpuRegister(Registers::CpuRegisterNumber number) { + return this->readCpuRegister(static_cast(number)); + } + + DebugModule::AbstractCommandError DebugTranslator::tryWriteCpuRegister( + RegisterNumber number, + RegisterValue value + ) { using DebugModule::Registers::RegisterAccessControlField; this->dtmInterface.writeDebugModuleRegister(RegisterAddress::ABSTRACT_DATA_0, value); - this->executeAbstractCommand(AbstractCommandRegister{ + return this->tryExecuteAbstractCommand(AbstractCommandRegister{ RegisterAccessControlField{ number, true, @@ -540,6 +572,27 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec }); } + DebugModule::AbstractCommandError DebugTranslator::tryWriteCpuRegister( + Registers::CpuRegisterNumber number, + RegisterValue value + ) { + return this->tryWriteCpuRegister(static_cast(number), value); + } + + void DebugTranslator::writeCpuRegister(RegisterNumber number, RegisterValue value) { + const auto commandError = this->tryWriteCpuRegister(number, value); + if (commandError != DebugModule::AbstractCommandError::NONE) { + throw Exceptions::Exception{ + "Failed to write to CPU register (number: 0x" + Services::StringService::toHex(number) + + ") - abstract command error: 0x" + Services::StringService::toHex(commandError) + }; + } + } + + void DebugTranslator::writeCpuRegister(Registers::CpuRegisterNumber number, RegisterValue value) { + this->writeCpuRegister(static_cast(number), value); + } + void DebugTranslator::writeDebugModuleControlRegister(const ControlRegister& controlRegister) { this->dtmInterface.writeDebugModuleRegister(RegisterAddress::CONTROL_REGISTER, controlRegister.value()); } @@ -551,7 +604,7 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec ); } - void DebugTranslator::executeAbstractCommand( + DebugModule::AbstractCommandError DebugTranslator::tryExecuteAbstractCommand( const DebugModule::Registers::AbstractCommandRegister& abstractCommandRegister ) { this->dtmInterface.writeDebugModuleRegister( @@ -560,11 +613,8 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec ); auto abstractStatusRegister = this->readDebugModuleAbstractControlStatusRegister(); - if (abstractStatusRegister.commandError != AbstractControlStatusRegister::CommandError::NONE) { - throw Exceptions::Exception{ - "Failed to execute abstract command - error: " - + Services::StringService::toHex(abstractStatusRegister.commandError) - }; + if (abstractStatusRegister.commandError != DebugModule::AbstractCommandError::NONE) { + return abstractStatusRegister.commandError; } constexpr auto maxAttempts = 10; @@ -576,6 +626,19 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec if (abstractStatusRegister.busy) { throw Exceptions::Exception{"Abstract command took too long to execute"}; } + + return abstractStatusRegister.commandError; + } + + void DebugTranslator::executeAbstractCommand( + const DebugModule::Registers::AbstractCommandRegister& abstractCommandRegister + ) { + const auto commandError = this->tryExecuteAbstractCommand(abstractCommandRegister); + if (commandError != DebugModule::AbstractCommandError::NONE) { + throw Exceptions::Exception{ + "Failed to execute abstract command - error: 0x" + Services::StringService::toHex(commandError) + }; + } } TargetMemoryAddress DebugTranslator::alignMemoryAddress(TargetMemoryAddress address, TargetMemoryAddress alignTo) { diff --git a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugTranslator.hpp b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugTranslator.hpp index 3be608d7..9b012d06 100644 --- a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugTranslator.hpp +++ b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugTranslator.hpp @@ -20,6 +20,9 @@ #include "DebugModule/Registers/AbstractControlStatusRegister.hpp" #include "DebugModule/Registers/AbstractCommandRegister.hpp" + +#include "src/Helpers/Expected.hpp" + namespace DebugToolDrivers::Protocols::RiscVDebugSpec { /** @@ -92,12 +95,24 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec void enableDebugModule(); void disableDebugModule(); + Expected tryReadCpuRegister(RegisterNumber number); + Expected tryReadCpuRegister( + Registers::CpuRegisterNumber number + ); RegisterValue readCpuRegister(RegisterNumber number); + RegisterValue readCpuRegister(Registers::CpuRegisterNumber number); + + DebugModule::AbstractCommandError tryWriteCpuRegister(RegisterNumber number, RegisterValue value); + DebugModule::AbstractCommandError tryWriteCpuRegister(Registers::CpuRegisterNumber number, RegisterValue value); void writeCpuRegister(RegisterNumber number, RegisterValue value); + void writeCpuRegister(Registers::CpuRegisterNumber number, RegisterValue value); void writeDebugModuleControlRegister(const DebugModule::Registers::ControlRegister& controlRegister); void writeDebugControlStatusRegister(const Registers::DebugControlStatusRegister& controlRegister); + DebugModule::AbstractCommandError tryExecuteAbstractCommand( + const DebugModule::Registers::AbstractCommandRegister& abstractCommandRegister + ); void executeAbstractCommand(const DebugModule::Registers::AbstractCommandRegister& abstractCommandRegister); Targets::TargetMemoryAddress alignMemoryAddress(