diff --git a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/DebugModule.hpp b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/DebugModule.hpp index 04e77c2e..66066319 100644 --- a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/DebugModule.hpp +++ b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/DebugModule.hpp @@ -22,7 +22,7 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec::DebugModule BUSY = 0x03, }; - enum AbstractCommandError: std::uint8_t + enum class AbstractCommandError: std::uint8_t { NONE = 0x00, BUSY = 0x01, diff --git a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/AbstractCommandRegister.hpp b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/AbstractCommandRegister.hpp index cbf9eff0..c5a4273e 100644 --- a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/AbstractCommandRegister.hpp +++ b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/AbstractCommandRegister.hpp @@ -9,7 +9,7 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec::DebugModule::Registers { struct AbstractCommandRegister { - enum CommandType: std::uint8_t + enum class CommandType: std::uint8_t { REGISTER_ACCESS = 0x00, QUICK_ACCESS = 0x01, @@ -19,15 +19,12 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec::DebugModule::Registers std::uint32_t control; CommandType commandType; - constexpr AbstractCommandRegister(std::uint32_t control, CommandType commandType) - : control(control) - , commandType(commandType) - {} - - constexpr explicit AbstractCommandRegister(RegisterValue registerValue) - : control(static_cast(registerValue & 0x00FFFFFF)) - , commandType(static_cast((registerValue >> 24) & 0xFF)) - {} + static constexpr AbstractCommandRegister fromValue(RegisterValue value) { + return { + .control = static_cast(value & 0x00FFFFFF), + .commandType = static_cast((value >> 24) & 0xFF), + }; + } [[nodiscard]] constexpr RegisterValue value() const { assert(this->control <= 0x00FFFFFF); diff --git a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/AbstractControlStatusRegister.hpp b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/AbstractControlStatusRegister.hpp index a6f1e638..56cd8b4d 100644 --- a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/AbstractControlStatusRegister.hpp +++ b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/AbstractControlStatusRegister.hpp @@ -8,27 +8,29 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec::DebugModule::Registers { struct AbstractControlStatusRegister { - std::uint8_t dataCount:4; - AbstractCommandError commandError:3; - bool relaxedPrivilege:1; - bool busy:1; - std::uint8_t programBufferSize:5; + std::uint8_t dataCount = 0; + AbstractCommandError commandError = AbstractCommandError::NONE; + bool relaxedPrivilege = false; + bool busy = false; + std::uint8_t programBufferSize = 0; - constexpr explicit AbstractControlStatusRegister(RegisterValue registerValue) - : dataCount(static_cast(registerValue & 0x0F)) - , commandError(static_cast((registerValue >> 8) & 0x07)) - , relaxedPrivilege(static_cast(registerValue & (0x01 << 11))) - , busy(static_cast(registerValue & (0x01 << 12))) - , programBufferSize(static_cast((registerValue >> 24) & 0x1F)) - {} + static constexpr AbstractControlStatusRegister fromValue(RegisterValue value) { + return { + .dataCount = static_cast(value & 0x0F), + .commandError = static_cast((value >> 8) & 0x07), + .relaxedPrivilege = static_cast(value & (0x01 << 11)), + .busy = static_cast(value & (0x01 << 12)), + .programBufferSize = static_cast((value >> 24) & 0x1F), + }; + } [[nodiscard]] constexpr RegisterValue value() const { return RegisterValue{0} - | static_cast(this->dataCount) + | static_cast(this->dataCount & 0x0F) | static_cast(this->commandError) << 8 | static_cast(this->relaxedPrivilege) << 11 | static_cast(this->busy) << 12 - | static_cast(this->programBufferSize) << 24 + | static_cast(this->programBufferSize & 0x1F) << 24 ; } diff --git a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/ControlRegister.hpp b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/ControlRegister.hpp index c4f430e5..a1cef1ba 100644 --- a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/ControlRegister.hpp +++ b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/ControlRegister.hpp @@ -9,43 +9,50 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec::DebugModule::Registers { struct ControlRegister { - enum HartSelectionMode: std::uint8_t + enum class HartSelectionMode: std::uint8_t { SINGLE = 0x00, MULTI = 0x01, }; - bool debugModuleActive:1 = false; - bool ndmReset:1 = false; - bool clearResetHaltRequest:1 = false; - bool setResetHaltRequest:1 = false; - bool clearKeepAlive:1 = false; - bool setKeepAlive:1 = false; + bool debugModuleActive = false; + bool ndmReset = false; + bool clearResetHaltRequest = false; + bool setResetHaltRequest = false; + bool clearKeepAlive = false; + bool setKeepAlive = false; HartIndex selectedHartIndex = 0; - HartSelectionMode hartSelectionMode:1 = HartSelectionMode::SINGLE; - bool acknowledgeUnavailableHarts:1 = false; - bool acknowledgeHaveReset:1 = false; - bool hartReset:1 = false; - bool resumeRequest:1 = false; - bool haltRequest:1 = false; + HartSelectionMode hartSelectionMode = HartSelectionMode::SINGLE; + bool acknowledgeUnavailableHarts = false; + bool acknowledgeHaveReset = false; + bool hartReset = false; + bool resumeRequest = false; + bool haltRequest = false; - ControlRegister() = default; - - constexpr explicit ControlRegister(RegisterValue registerValue) - : debugModuleActive(static_cast(registerValue & 0x01)) - , ndmReset(static_cast(registerValue & (0x01 << 1))) - , clearResetHaltRequest(static_cast(registerValue & (0x01 << 2))) - , setResetHaltRequest(static_cast(registerValue & (0x01 << 3))) - , clearKeepAlive(static_cast(registerValue & (0x01 << 4))) - , setKeepAlive(static_cast(registerValue & (0x01 << 5))) - , selectedHartIndex((((registerValue >> 6) & 0x3FF) << 10) | ((registerValue >> 16) & 0x3FF)) - , hartSelectionMode(static_cast(registerValue & (0x01 << 26))) - , acknowledgeUnavailableHarts(static_cast(registerValue & (0x01 << 27))) - , acknowledgeHaveReset(static_cast(registerValue & (0x01 << 28))) - , hartReset(static_cast(registerValue & (0x01 << 29))) - , resumeRequest(static_cast(registerValue & (0x01 << 30))) - , haltRequest(static_cast(registerValue & static_cast(0x01 << 31))) - {} + /** + * These `fromValue()` functions cannot be constructors because we'd lose designated initialisation (as the + * structs would no longer be aggregates - structs with user-defined constructors cannot be aggregates). + * + * @param value + * @return + */ + static constexpr auto fromValue(RegisterValue value) { + return ControlRegister{ + .debugModuleActive = static_cast(value & 0x01), + .ndmReset = static_cast(value & (0x01 << 1)), + .clearResetHaltRequest = static_cast(value & (0x01 << 2)), + .setResetHaltRequest = static_cast(value & (0x01 << 3)), + .clearKeepAlive = static_cast(value & (0x01 << 4)), + .setKeepAlive = static_cast(value & (0x01 << 5)), + .selectedHartIndex = (((value >> 6) & 0x3FF) << 10) | ((value >> 16) & 0x3FF), + .hartSelectionMode = static_cast(value & (0x01 << 26)), + .acknowledgeUnavailableHarts = static_cast(value & (0x01 << 27)), + .acknowledgeHaveReset = static_cast(value & (0x01 << 28)), + .hartReset = static_cast(value & (0x01 << 29)), + .resumeRequest = static_cast(value & (0x01 << 30)), + .haltRequest = static_cast(value & static_cast(0x01 << 31)), + }; + } [[nodiscard]] constexpr RegisterValue value() const { assert(this->selectedHartIndex <= 0xFFFFF); diff --git a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/MemoryAccessControlField.hpp b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/MemoryAccessControlField.hpp index dd1b80af..5ac19d01 100644 --- a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/MemoryAccessControlField.hpp +++ b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/MemoryAccessControlField.hpp @@ -17,29 +17,19 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec::DebugModule::Registers SIZE_128 = 0x04, }; - bool write:1; - bool postIncrement:1; - MemorySize size:3; - bool virtualAddress:1; + bool write = false; + bool postIncrement = false; + MemorySize size = MemorySize::SIZE_8; + bool virtualAddress = false; - constexpr MemoryAccessControlField( - bool write, - bool postIncrement, - MemorySize size, - bool virtualAddress - ) - : write(write) - , postIncrement(postIncrement) - , size(size) - , virtualAddress(virtualAddress) - {} - - constexpr explicit MemoryAccessControlField(std::uint32_t controlValue) - : write(static_cast(controlValue & (0x01 << 16))) - , postIncrement(static_cast(controlValue & (0x01 << 19))) - , size(static_cast((controlValue >> 20) & 0x07)) - , virtualAddress(static_cast(controlValue & (0x01 << 23))) - {} + static constexpr auto fromValue(std::uint32_t value) { + return MemoryAccessControlField{ + .write = static_cast(value & (0x01 << 16)), + .postIncrement = static_cast(value & (0x01 << 19)), + .size = static_cast((value >> 20) & 0x07), + .virtualAddress = static_cast(value & (0x01 << 23)), + }; + } [[nodiscard]] constexpr std::uint32_t value() const { return std::uint32_t{0} diff --git a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/RegisterAccessControlField.hpp b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/RegisterAccessControlField.hpp index 7e824ce4..32a89886 100644 --- a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/RegisterAccessControlField.hpp +++ b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/RegisterAccessControlField.hpp @@ -15,37 +15,23 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec::DebugModule::Registers SIZE_128 = 0x04, }; - RegisterNumber registerNumber; - bool write:1; - bool transfer:1; - bool postExecute:1; - bool postIncrement:1; - RegisterSize size:3; + RegisterNumber registerNumber = 0; + bool write = false; + bool transfer = false; + bool postExecute = false; + bool postIncrement = false; + RegisterSize size = RegisterSize::SIZE_32; - RegisterAccessControlField( - RegisterNumber registerNumber, - bool write, - bool transfer, - bool postExecute, - bool postIncrement, - RegisterSize size - ) - : registerNumber(registerNumber) - , write(write) - , transfer(transfer) - , postExecute(postExecute) - , postIncrement(postIncrement) - , size(size) - {} - - constexpr explicit RegisterAccessControlField(std::uint32_t controlValue) - : registerNumber(static_cast(controlValue & 0xFFFF)) - , write(static_cast(controlValue & (0x01 << 16))) - , transfer(static_cast(controlValue & (0x01 << 17))) - , postExecute(static_cast(controlValue & (0x01 << 18))) - , postIncrement(static_cast(controlValue & (0x01 << 19))) - , size(static_cast((controlValue >> 20) & 0x07)) - {} + static constexpr auto fromValue(std::uint32_t value) { + return RegisterAccessControlField{ + .registerNumber = static_cast(value & 0xFFFF), + .write = static_cast(value & (0x01 << 16)), + .transfer = static_cast(value & (0x01 << 17)), + .postExecute = static_cast(value & (0x01 << 18)), + .postIncrement = static_cast(value & (0x01 << 19)), + .size = static_cast((value >> 20) & 0x07), + }; + } [[nodiscard]] constexpr std::uint32_t value() const { return std::uint32_t{0} diff --git a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/StatusRegister.hpp b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/StatusRegister.hpp index 62b399a5..72f0649d 100644 --- a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/StatusRegister.hpp +++ b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugModule/Registers/StatusRegister.hpp @@ -8,53 +8,55 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec::DebugModule::Registers { struct StatusRegister { - std::uint8_t version:4; - bool validConfigStructurePointer:1; - bool supportsResetHalt:1; - bool authBusy:1; - bool authenticated:1; - bool anyHalted:1; - bool allHalted:1; - bool anyRunning:1; - bool allRunning:1; - bool anyUnavailable:1; - bool allUnavailable:1; - bool anyNonExistent:1; - bool allNonExistent:1; - bool anyResumeAcknowledge:1; - bool allResumeAcknowledge:1; - bool anyHaveReset:1; - bool allHaveReset:1; - bool implicitBreak:1; - bool stickyUnavailableBits:1; - bool ndmResetPending:1; + std::uint8_t version = 0; + bool validConfigStructurePointer = false; + bool supportsResetHalt = false; + bool authBusy = false; + bool authenticated = false; + bool anyHalted = false; + bool allHalted = false; + bool anyRunning = false; + bool allRunning = false; + bool anyUnavailable = false; + bool allUnavailable = false; + bool anyNonExistent = false; + bool allNonExistent = false; + bool anyResumeAcknowledge = false; + bool allResumeAcknowledge = false; + bool anyHaveReset = false; + bool allHaveReset = false; + bool implicitBreak = false; + bool stickyUnavailableBits = false; + bool ndmResetPending = false; - constexpr explicit StatusRegister(RegisterValue registerValue) - : version(static_cast(registerValue & 0x0F)) - , validConfigStructurePointer(static_cast(registerValue & (0x01 << 4))) - , supportsResetHalt(static_cast(registerValue & (0x01 << 5))) - , authBusy(static_cast(registerValue & (0x01 << 6))) - , authenticated(static_cast(registerValue & (0x01 << 7))) - , anyHalted(static_cast(registerValue & (0x01 << 8))) - , allHalted(static_cast(registerValue & (0x01 << 9))) - , anyRunning(static_cast(registerValue & (0x01 << 10))) - , allRunning(static_cast(registerValue & (0x01 << 11))) - , anyUnavailable(static_cast(registerValue & (0x01 << 12))) - , allUnavailable(static_cast(registerValue & (0x01 << 13))) - , anyNonExistent(static_cast(registerValue & (0x01 << 14))) - , allNonExistent(static_cast(registerValue & (0x01 << 15))) - , anyResumeAcknowledge(static_cast(registerValue & (0x01 << 16))) - , allResumeAcknowledge(static_cast(registerValue & (0x01 << 17))) - , anyHaveReset(static_cast(registerValue & (0x01 << 18))) - , allHaveReset(static_cast(registerValue & (0x01 << 19))) - , implicitBreak(static_cast(registerValue & (0x01 << 22))) - , stickyUnavailableBits(static_cast(registerValue & (0x01 << 23))) - , ndmResetPending(static_cast(registerValue & (0x01 << 24))) - {} + static constexpr StatusRegister fromValue(RegisterValue value) { + return { + .version = static_cast(value & 0x0F), + .validConfigStructurePointer = static_cast(value & (0x01 << 4)), + .supportsResetHalt = static_cast(value & (0x01 << 5)), + .authBusy = static_cast(value & (0x01 << 6)), + .authenticated = static_cast(value & (0x01 << 7)), + .anyHalted = static_cast(value & (0x01 << 8)), + .allHalted = static_cast(value & (0x01 << 9)), + .anyRunning = static_cast(value & (0x01 << 10)), + .allRunning = static_cast(value & (0x01 << 11)), + .anyUnavailable = static_cast(value & (0x01 << 12)), + .allUnavailable = static_cast(value & (0x01 << 13)), + .anyNonExistent = static_cast(value & (0x01 << 14)), + .allNonExistent = static_cast(value & (0x01 << 15)), + .anyResumeAcknowledge = static_cast(value & (0x01 << 16)), + .allResumeAcknowledge = static_cast(value & (0x01 << 17)), + .anyHaveReset = static_cast(value & (0x01 << 18)), + .allHaveReset = static_cast(value & (0x01 << 19)), + .implicitBreak = static_cast(value & (0x01 << 22)), + .stickyUnavailableBits = static_cast(value & (0x01 << 23)), + .ndmResetPending = static_cast(value & (0x01 << 24)), + }; + } [[nodiscard]] constexpr RegisterValue value() const { return RegisterValue{0} - | static_cast(this->version) + | static_cast(this->version & 0x0F) | static_cast(this->validConfigStructurePointer) << 4 | static_cast(this->supportsResetHalt) << 5 | static_cast(this->authBusy) << 6 diff --git a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugTranslator.cpp b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugTranslator.cpp index f2863406..7766364a 100644 --- a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugTranslator.cpp +++ b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugTranslator.cpp @@ -62,7 +62,6 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec void DebugTranslator::init() { // No pre-activation initialisation required. - return; } void DebugTranslator::activate() { @@ -126,18 +125,19 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec } void DebugTranslator::stop() { - auto controlRegister = ControlRegister{}; - controlRegister.debugModuleActive = true; - controlRegister.selectedHartIndex = this->selectedHartIndex; - controlRegister.haltRequest = true; + auto controlRegister = ControlRegister{ + .debugModuleActive = true, + .selectedHartIndex = this->selectedHartIndex, + .haltRequest = true, + }; this->writeDebugModuleControlRegister(controlRegister); auto statusRegister = this->readDebugModuleStatusRegister(); for ( - auto attempts = 1; + auto attempts = 0; !statusRegister.allHalted - && (DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY * attempts) < this->config.targetResponseTimeout; + && (DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY * attempts) <= this->config.targetResponseTimeout; ++attempts ) { std::this_thread::sleep_for(DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY); @@ -153,18 +153,19 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec } void DebugTranslator::run() { - auto controlRegister = ControlRegister{}; - controlRegister.debugModuleActive = true; - controlRegister.selectedHartIndex = this->selectedHartIndex; - controlRegister.resumeRequest = true; + auto controlRegister = ControlRegister{ + .debugModuleActive = true, + .selectedHartIndex = this->selectedHartIndex, + .resumeRequest = true, + }; this->writeDebugModuleControlRegister(controlRegister); auto statusRegister = this->readDebugModuleStatusRegister(); for ( - auto attempts = 1; + auto attempts = 0; !statusRegister.allResumeAcknowledge - && (DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY * attempts) < this->config.targetResponseTimeout; + && (DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY * attempts) <= this->config.targetResponseTimeout; ++attempts ) { std::this_thread::sleep_for(DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY); @@ -175,6 +176,8 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec this->writeDebugModuleControlRegister(controlRegister); if (!statusRegister.allResumeAcknowledge) { + Logger::debug("Failed to resume target execution - stopping target"); + this->stop(); throw Exceptions::Exception{"Target took too long to acknowledge resume request"}; } } @@ -185,10 +188,11 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec this->writeDebugControlStatusRegister(debugControlStatusRegister); - auto controlRegister = ControlRegister{}; - controlRegister.debugModuleActive = true; - controlRegister.selectedHartIndex = this->selectedHartIndex; - controlRegister.resumeRequest = true; + auto controlRegister = ControlRegister{ + .debugModuleActive = true, + .selectedHartIndex = this->selectedHartIndex, + .resumeRequest = true, + }; this->writeDebugModuleControlRegister(controlRegister); @@ -200,12 +204,13 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec } void DebugTranslator::reset() { - auto controlRegister = ControlRegister{}; - controlRegister.debugModuleActive = true; - controlRegister.selectedHartIndex = this->selectedHartIndex; - controlRegister.setResetHaltRequest = true; - controlRegister.haltRequest = true; - controlRegister.ndmReset = true; + auto controlRegister = ControlRegister{ + .debugModuleActive = true, + .ndmReset = true, + .setResetHaltRequest = true, + .selectedHartIndex = this->selectedHartIndex, + .haltRequest = true, + }; this->writeDebugModuleControlRegister(controlRegister); @@ -214,22 +219,21 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec auto statusRegister = this->readDebugModuleStatusRegister(); for ( - auto attempts = 1; + auto attempts = 0; !statusRegister.allHaveReset - && (DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY * attempts) < this->config.targetResponseTimeout; + && (DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY * attempts) <= this->config.targetResponseTimeout; ++attempts ) { std::this_thread::sleep_for(DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY); statusRegister = this->readDebugModuleStatusRegister(); } - controlRegister = ControlRegister{}; - controlRegister.debugModuleActive = true; - controlRegister.selectedHartIndex = this->selectedHartIndex; - controlRegister.clearResetHaltRequest = true; - controlRegister.acknowledgeHaveReset = true; - - this->writeDebugModuleControlRegister(controlRegister); + this->writeDebugModuleControlRegister(ControlRegister{ + .debugModuleActive = true, + .clearResetHaltRequest = true, + .selectedHartIndex = this->selectedHartIndex, + .acknowledgeHaveReset = true, + }); if (!statusRegister.allHaveReset) { throw Exceptions::Exception{"Target took too long to reset"}; @@ -258,7 +262,7 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec const auto& triggerDescriptor = triggerDescriptorOpt->get(); Logger::debug( - "Installing hardware BP at address " + Services::StringService::toHex(address) + " with trigger index " + "Installing hardware BP at address 0x" + Services::StringService::toHex(address) + " with trigger index " + std::to_string(triggerDescriptor.index) ); @@ -270,16 +274,18 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec TriggerModule::Registers::TriggerSelect{triggerDescriptor.index}.value() ); - auto matchControlRegister = MatchControl{}; - matchControlRegister.execute = true; - matchControlRegister.enabledInUserMode = true; - matchControlRegister.enabledInSupervisorMode = true; - matchControlRegister.enabledInMachineMode = true; - matchControlRegister.action = TriggerModule::TriggerAction::ENTER_DEBUG_MODE; - matchControlRegister.accessSize = MatchControl::AccessSize::ANY; - matchControlRegister.compareValueType = MatchControl::CompareValueType::ADDRESS; - - this->writeCpuRegister(CpuRegisterNumber::TRIGGER_DATA_1, matchControlRegister.value()); + this->writeCpuRegister( + CpuRegisterNumber::TRIGGER_DATA_1, + MatchControl{ + .execute = true, + .enabledInUserMode = true, + .enabledInSupervisorMode = true, + .enabledInMachineMode = true, + .action = TriggerModule::TriggerAction::ENTER_DEBUG_MODE, + .accessSize = MatchControl::AccessSize::ANY, + .compareValueType = MatchControl::CompareValueType::ADDRESS, + }.value() + ); this->writeCpuRegister(CpuRegisterNumber::TRIGGER_DATA_2, address); this->allocatedTriggerIndices.emplace(triggerDescriptor.index); @@ -305,7 +311,7 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec void DebugTranslator::clearAllHardwareBreakpoints() { // To ensure that any untracked breakpoints are cleared, we clear all triggers on the target. - for (const auto [triggerIndex, triggerDescriptor] : this->triggerDescriptorsByIndex) { + for (const auto& [triggerIndex, triggerDescriptor] : this->triggerDescriptorsByIndex) { this->clearTrigger(triggerDescriptor); } @@ -386,13 +392,11 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec this->dtmInterface.writeDebugModuleRegister(RegisterAddress::ABSTRACT_DATA_1, startAddress); constexpr auto command = AbstractCommandRegister{ - MemoryAccessControlField{ - false, - true, - MemoryAccessControlField::MemorySize::SIZE_32, - false + .control = MemoryAccessControlField{ + .postIncrement = true, + .size = MemoryAccessControlField::MemorySize::SIZE_32, }.value(), - AbstractCommandRegister::CommandType::MEMORY_ACCESS + .commandType = AbstractCommandRegister::CommandType::MEMORY_ACCESS }; for (auto address = startAddress; address <= (startAddress + bytes - 1); address += 4) { @@ -460,13 +464,12 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec this->dtmInterface.writeDebugModuleRegister(RegisterAddress::ABSTRACT_DATA_1, startAddress); constexpr auto command = AbstractCommandRegister{ - MemoryAccessControlField{ - true, - true, - MemoryAccessControlField::MemorySize::SIZE_32, - false + .control = MemoryAccessControlField{ + .write = true, + .postIncrement = true, + .size = MemoryAccessControlField::MemorySize::SIZE_32, }.value(), - AbstractCommandRegister::CommandType::MEMORY_ACCESS + .commandType = AbstractCommandRegister::CommandType::MEMORY_ACCESS }; for (TargetMemoryAddress offset = 0; offset < buffer.size(); offset += 4) { @@ -491,11 +494,10 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec * We can obtain the maximum hart index by setting all of the hartsel bits in the control register and then * read the value back. */ - auto controlRegister = ControlRegister{}; - controlRegister.debugModuleActive = true; - controlRegister.selectedHartIndex = 0xFFFFF; + this->writeDebugModuleControlRegister( + ControlRegister{.debugModuleActive = true, .selectedHartIndex = 0xFFFFF} + ); - this->writeDebugModuleControlRegister(controlRegister); const auto maxHartIndex = this->readDebugModuleControlRegister().selectedHartIndex; for (auto hartIndex = DebugModule::HartIndex{0}; hartIndex <= maxHartIndex; ++hartIndex) { @@ -503,11 +505,9 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec * We can't just assume that everything between 0 and the maximum hart index are valid hart indices. We * have to test each index until we find one that is non-existent. */ - auto controlRegister = ControlRegister{}; - controlRegister.debugModuleActive = true; - controlRegister.selectedHartIndex = hartIndex; - - this->writeDebugModuleControlRegister(controlRegister); + this->writeDebugModuleControlRegister( + ControlRegister{.debugModuleActive = true, .selectedHartIndex = hartIndex} + ); /* * It's worth noting that some RISC-V targets **do not** set the non-existent flags. I'm not sure why. @@ -544,7 +544,7 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec if (writeSelectError != DebugModule::AbstractCommandError::NONE) { throw Exceptions::Exception{ "Failed to write to TRIGGER_SELECT register - abstract command error: 0x" - + Services::StringService::toHex(writeSelectError) + + Services::StringService::toHex(static_cast(writeSelectError)) }; } @@ -552,9 +552,9 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec break; } - const auto infoReg = TriggerModule::Registers::TriggerInfo{ + const auto infoReg = TriggerModule::Registers::TriggerInfo::fromValue( this->readCpuRegister(CpuRegisterNumber::TRIGGER_INFO) - }; + ); if (infoReg.info == 0x01) { // Trigger doesn't exist @@ -564,9 +564,9 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec auto supportedTypes = infoReg.getSupportedTriggerTypes(); if (supportedTypes.empty()) { // The trigger info register has no trigger type info. Try the data1 register. - const auto data1Reg = TriggerModule::Registers::TriggerData1{ + const auto data1Reg = TriggerModule::Registers::TriggerData1::fromValue( this->readCpuRegister(CpuRegisterNumber::TRIGGER_DATA_1) - }; + ); const auto triggerType = data1Reg.getType(); if (!triggerType.has_value()) { @@ -584,37 +584,40 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec } ControlRegister DebugTranslator::readDebugModuleControlRegister() { - return ControlRegister{this->dtmInterface.readDebugModuleRegister(RegisterAddress::CONTROL_REGISTER)}; + return ControlRegister::fromValue( + this->dtmInterface.readDebugModuleRegister(RegisterAddress::CONTROL_REGISTER) + ); } StatusRegister DebugTranslator::readDebugModuleStatusRegister() { - return StatusRegister{this->dtmInterface.readDebugModuleRegister(RegisterAddress::STATUS_REGISTER)}; + return StatusRegister::fromValue(this->dtmInterface.readDebugModuleRegister(RegisterAddress::STATUS_REGISTER)); } AbstractControlStatusRegister DebugTranslator::readDebugModuleAbstractControlStatusRegister() { - return AbstractControlStatusRegister{ + return AbstractControlStatusRegister::fromValue( this->dtmInterface.readDebugModuleRegister(RegisterAddress::ABSTRACT_CONTROL_STATUS_REGISTER) - }; + ); } DebugControlStatusRegister DebugTranslator::readDebugControlStatusRegister() { - return DebugControlStatusRegister{ + return DebugControlStatusRegister::fromValue( this->readCpuRegister(static_cast(CpuRegisterNumber::DEBUG_CONTROL_STATUS_REGISTER)) - }; + ); } void DebugTranslator::enableDebugModule() { - auto controlRegister = ControlRegister{}; - controlRegister.debugModuleActive = true; - controlRegister.selectedHartIndex = this->selectedHartIndex; + auto controlRegister = ControlRegister{ + .debugModuleActive = true, + .selectedHartIndex = this->selectedHartIndex + }; this->writeDebugModuleControlRegister(controlRegister); controlRegister = this->readDebugModuleControlRegister(); for ( - auto attempts = 1; + auto attempts = 0; !controlRegister.debugModuleActive - && (DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY * attempts) < this->config.targetResponseTimeout; + && (DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY * attempts) <= this->config.targetResponseTimeout; ++attempts ) { std::this_thread::sleep_for(DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY); @@ -627,17 +630,16 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec } void DebugTranslator::disableDebugModule() { - auto controlRegister = ControlRegister{}; - controlRegister.debugModuleActive = false; - controlRegister.selectedHartIndex = this->selectedHartIndex; + this->writeDebugModuleControlRegister( + ControlRegister{.debugModuleActive = false, .selectedHartIndex = this->selectedHartIndex} + ); - this->writeDebugModuleControlRegister(controlRegister); - controlRegister = this->readDebugModuleControlRegister(); + auto controlRegister = this->readDebugModuleControlRegister(); for ( - auto attempts = 1; + auto attempts = 0; controlRegister.debugModuleActive - && (DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY * attempts) < this->config.targetResponseTimeout; + && (DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY * attempts) <= this->config.targetResponseTimeout; ++attempts ) { std::this_thread::sleep_for(DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY); @@ -655,15 +657,12 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec using DebugModule::Registers::RegisterAccessControlField; const auto commandError = this->tryExecuteAbstractCommand(AbstractCommandRegister{ - RegisterAccessControlField{ - number, - false, - true, - false, - false, - RegisterAccessControlField::RegisterSize::SIZE_32 + .control = RegisterAccessControlField{ + .registerNumber = number, + .transfer = true, + .size= RegisterAccessControlField::RegisterSize::SIZE_32 }.value(), - AbstractCommandRegister::CommandType::REGISTER_ACCESS + .commandType = AbstractCommandRegister::CommandType::REGISTER_ACCESS }); if (commandError != DebugModule::AbstractCommandError::NONE) { @@ -685,7 +684,8 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec 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()) + + ") - abstract command error: 0x" + + Services::StringService::toHex(static_cast(result.error())) }; } @@ -704,15 +704,13 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec this->dtmInterface.writeDebugModuleRegister(RegisterAddress::ABSTRACT_DATA_0, value); return this->tryExecuteAbstractCommand(AbstractCommandRegister{ - RegisterAccessControlField{ - number, - true, - true, - false, - false, - RegisterAccessControlField::RegisterSize::SIZE_32 + .control = RegisterAccessControlField{ + .registerNumber = number, + .write = true, + .transfer = true, + .size = RegisterAccessControlField::RegisterSize::SIZE_32 }.value(), - AbstractCommandRegister::CommandType::REGISTER_ACCESS + .commandType = AbstractCommandRegister::CommandType::REGISTER_ACCESS }); } @@ -728,7 +726,8 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec 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) + + ") - abstract command error: 0x" + + Services::StringService::toHex(static_cast(commandError)) }; } } @@ -762,9 +761,9 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec } for ( - auto attempts = 1; + auto attempts = 0; abstractStatusRegister.busy - && (DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY * attempts) < this->config.targetResponseTimeout; + && (DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY * attempts) <= this->config.targetResponseTimeout; ++attempts ) { std::this_thread::sleep_for(DebugTranslator::DEBUG_MODULE_RESPONSE_DELAY); @@ -784,7 +783,8 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec 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) + "Failed to execute abstract command - error: 0x" + + Services::StringService::toHex(static_cast(commandError)) }; } } diff --git a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugTranslatorConfig.cpp b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugTranslatorConfig.cpp index cd166fd3..4084005c 100644 --- a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugTranslatorConfig.cpp +++ b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/DebugTranslatorConfig.cpp @@ -1,11 +1,13 @@ #include "DebugTranslatorConfig.hpp" +#include + namespace DebugToolDrivers::Protocols::RiscVDebugSpec { DebugTranslatorConfig::DebugTranslatorConfig(const YAML::Node& configNode) { if (configNode["targetResponseTimeout"]) { this->targetResponseTimeout = std::chrono::microseconds{ - configNode["targetResponseTimeout"].as(this->targetResponseTimeout.count()) + configNode["targetResponseTimeout"].as(this->targetResponseTimeout.count()) }; } } diff --git a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/Registers/DebugControlStatusRegister.hpp b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/Registers/DebugControlStatusRegister.hpp index 05ec272c..5fa94048 100644 --- a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/Registers/DebugControlStatusRegister.hpp +++ b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/Registers/DebugControlStatusRegister.hpp @@ -18,41 +18,41 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec::Registers GROUP = 0x06, }; - PrivilegeMode privilegeMode:2; - bool step:1 = false; - bool nmiPending:1 = false; - bool mprvEnabled:1 = false; - DebugModeCause debugModeCause:3; - bool stopTime:1 = false; - bool stopCount:1 = false; - bool stepInterruptsEnabled:1 = false; - bool breakUMode:1 = false; - bool breakSMode:1 = false; - bool breakMMode:1 = false; - bool breakVUMode:1 = false; - bool breakVSMode:1 = false; - std::uint8_t debugVersion:4 = 0; + PrivilegeMode privilegeMode = PrivilegeMode::USER; + bool step = false; + bool nmiPending = false; + bool mprvEnabled = false; + DebugModeCause debugModeCause = DebugModeCause::BREAK; + bool stopTime = false; + bool stopCount = false; + bool stepInterruptsEnabled = false; + bool breakUMode = false; + bool breakSMode = false; + bool breakMMode = false; + bool breakVUMode = false; + bool breakVSMode = false; + std::uint8_t debugVersion = 0; - DebugControlStatusRegister() = default; + static constexpr auto fromValue(RegisterValue value) { + return DebugControlStatusRegister{ + .privilegeMode = static_cast(value & 0x03), + .step = static_cast(value & (0x01 << 2)), + .nmiPending = static_cast(value & (0x01 << 3)), + .mprvEnabled = static_cast(value & (0x01 << 4)), + .debugModeCause = static_cast((value >> 6) & 0x07), + .stopTime = static_cast(value & (0x01 << 9)), + .stopCount = static_cast(value & (0x01 << 10)), + .stepInterruptsEnabled = static_cast(value & (0x01 << 11)), + .breakUMode = static_cast(value & (0x01 << 12)), + .breakSMode = static_cast(value & (0x01 << 13)), + .breakMMode = static_cast(value & (0x01 << 15)), + .breakVUMode = static_cast(value & (0x01 << 16)), + .breakVSMode = static_cast(value & (0x01 << 17)), + .debugVersion = static_cast((value >> 28) & 0x0F) + }; + } - constexpr explicit DebugControlStatusRegister(RegisterValue registerValue) - : privilegeMode(static_cast(registerValue & 0x03)) - , step(static_cast(registerValue & (0x01 << 2))) - , nmiPending(static_cast(registerValue & (0x01 << 3))) - , mprvEnabled(static_cast(registerValue & (0x01 << 4))) - , debugModeCause(static_cast((registerValue >> 6) & 0x07)) - , stopTime(static_cast(registerValue & (0x01 << 9))) - , stopCount(static_cast(registerValue & (0x01 << 10))) - , stepInterruptsEnabled(static_cast(registerValue & (0x01 << 11))) - , breakUMode(static_cast(registerValue & (0x01 << 12))) - , breakSMode(static_cast(registerValue & (0x01 << 13))) - , breakMMode(static_cast(registerValue & (0x01 << 15))) - , breakVUMode(static_cast(registerValue & (0x01 << 16))) - , breakVSMode(static_cast(registerValue & (0x01 << 17))) - , debugVersion(static_cast(registerValue >> 28) & 0x0F) - {} - - constexpr RegisterValue value() const { + [[nodiscard]] constexpr RegisterValue value() const { return RegisterValue{0} | static_cast(this->privilegeMode) | static_cast(this->step) << 2 @@ -67,7 +67,7 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec::Registers | static_cast(this->breakMMode) << 15 | static_cast(this->breakVUMode) << 16 | static_cast(this->breakVSMode) << 17 - | static_cast(this->debugVersion) << 28 + | static_cast(this->debugVersion & 0x0F) << 28 ; } }; diff --git a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/RiscVGeneric.hpp b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/RiscVGeneric.hpp index acaf102e..cab4d4a2 100644 --- a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/RiscVGeneric.hpp +++ b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/RiscVGeneric.hpp @@ -9,8 +9,8 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec enum class PrivilegeMode: std::uint8_t { - U_MODE = 0x00, - S_MODE = 0x01, - M_MODE = 0x03, + USER = 0x00, + SUPERVISOR = 0x01, + MACHINE = 0x03, }; } diff --git a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/TriggerModule/Registers/MatchControl.hpp b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/TriggerModule/Registers/MatchControl.hpp index 15fb5790..43606b41 100644 --- a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/TriggerModule/Registers/MatchControl.hpp +++ b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/TriggerModule/Registers/MatchControl.hpp @@ -37,71 +37,39 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec::TriggerModule::Registers DATA = 0x01, }; - bool load:1 = false; - bool store:1 = false; - bool execute:1 = false; - bool enabledInUserMode:1 = false; - bool enabledInSupervisorMode:1 = false; - bool enabledInMachineMode:1 = false; - MatchMode matchMode:4 = MatchMode::EQUAL; - bool chain:1 = false; // TODO: Consider making this an enum - TriggerAction action:4 = TriggerAction::ENTER_DEBUG_MODE; + bool load = false; + bool store = false; + bool execute = false; + bool enabledInUserMode = false; + bool enabledInSupervisorMode = false; + bool enabledInMachineMode = false; + MatchMode matchMode = MatchMode::EQUAL; + bool chain = false; // TODO: Consider making this an enum + TriggerAction action = TriggerAction::RAISE_BREAKPOINT_EXCEPTION; AccessSize accessSize = AccessSize::ANY; - bool timing:1 = false; // TODO: Consider making this an enum - CompareValueType compareValueType:1 = CompareValueType::ADDRESS; - bool hit:1 = false; + bool timing = false; // TODO: Consider making this an enum + CompareValueType compareValueType = CompareValueType::ADDRESS; + bool hit = false; - MatchControl() = default; - - constexpr explicit MatchControl( - bool load, - bool store, - bool execute, - bool enabledInUserMode, - bool enabledInSupervisorMode, - bool enabledInMachineMode, - MatchMode matchMode, - bool chain, - TriggerAction action, - AccessSize accessSize, - bool timing, - CompareValueType compareValueType, - bool hit - ) - : load(load) - , store(store) - , execute(execute) - , enabledInUserMode(enabledInUserMode) - , enabledInSupervisorMode(enabledInSupervisorMode) - , enabledInMachineMode(enabledInMachineMode) - , matchMode(matchMode) - , chain(chain) - , action(action) - , accessSize(accessSize) - , timing(timing) - , compareValueType(compareValueType) - , hit(hit) - {} - - constexpr explicit MatchControl(RegisterValue registerValue) - : load(static_cast(registerValue & 0x01)) - , store(static_cast(registerValue & (0x01 << 1))) - , execute(static_cast(registerValue & (0x01 << 2))) - , enabledInUserMode(static_cast(registerValue & (0x01 << 3))) - , enabledInSupervisorMode(static_cast(registerValue & (0x01 << 4))) - , enabledInMachineMode(static_cast(registerValue & (0x01 << 6))) - , matchMode(static_cast((registerValue >> 7) & 0x0F)) - , chain(static_cast(registerValue & (0x01 << 11))) - , action(static_cast((registerValue >> 12) & 0x0F)) - , accessSize( - static_cast( - (((registerValue >> 21) & 0x03) << 2) | ((registerValue >> 16) & 0x03) - ) - ) - , timing(static_cast(registerValue & (0x01 << 18))) - , compareValueType(static_cast((registerValue >> 19) & 0x01)) - , hit(static_cast(registerValue & (0x01 << 20))) - {} + static constexpr auto fromValue(RegisterValue value) { + return MatchControl{ + .load = static_cast(value & 0x01), + .store = static_cast(value & (0x01 << 1)), + .execute = static_cast(value & (0x01 << 2)), + .enabledInUserMode = static_cast(value & (0x01 << 3)), + .enabledInSupervisorMode = static_cast(value & (0x01 << 4)), + .enabledInMachineMode = static_cast(value & (0x01 << 6)), + .matchMode = static_cast((value >> 7) & 0x0F), + .chain = static_cast(value & (0x01 << 11)), + .action = static_cast((value >> 12) & 0x0F), + .accessSize = static_cast( + (((value >> 21) & 0x03) << 2) | ((value >> 16) & 0x03) + ), + .timing = static_cast(value & (0x01 << 18)), + .compareValueType = static_cast((value >> 19) & 0x01), + .hit = static_cast(value & (0x01 << 20)), + }; + } [[nodiscard]] constexpr RegisterValue value() const { return RegisterValue{0} diff --git a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/TriggerModule/Registers/TriggerData1.hpp b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/TriggerModule/Registers/TriggerData1.hpp index 48314c93..aea98911 100644 --- a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/TriggerModule/Registers/TriggerData1.hpp +++ b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/TriggerModule/Registers/TriggerData1.hpp @@ -9,27 +9,27 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec::TriggerModule::Registers { struct TriggerData1 { - std::uint32_t data:27; - bool debugModeOnly:1; - std::uint8_t type:4; + std::uint32_t data; + bool debugModeOnly; + std::uint8_t type; - TriggerData1() = default; - - constexpr explicit TriggerData1(RegisterValue registerValue) - : data(registerValue & 0x07FFFFFF) - , debugModeOnly(static_cast(registerValue & (0x01 << 27))) - , type(static_cast(registerValue >> 28) & 0x0F) - {} + static constexpr auto fromValue(RegisterValue value) { + return TriggerData1{ + .data = value & 0x07FFFFFF, + .debugModeOnly = static_cast(value & (0x01 << 27)), + .type = static_cast((value >> 28) & 0x0F), + }; + } [[nodiscard]] constexpr RegisterValue value() const { return RegisterValue{0} - | static_cast(this->data) + | static_cast(this->data & 0x07FFFFFF) | static_cast(this->debugModeOnly) << 27 - | static_cast(this->type) << 28 + | static_cast(this->type & 0x0F) << 28 ; } - std::optional getType() const { + [[nodiscard]] std::optional getType() const { return (this->type >= 0x01 && this->type <= 0x07) ? std::optional{static_cast(this->type)} : std::nullopt; diff --git a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/TriggerModule/Registers/TriggerInfo.hpp b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/TriggerModule/Registers/TriggerInfo.hpp index a9488835..6b82340a 100644 --- a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/TriggerModule/Registers/TriggerInfo.hpp +++ b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/TriggerModule/Registers/TriggerInfo.hpp @@ -13,10 +13,12 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec::TriggerModule::Registers std::uint16_t info; std::uint8_t version; - constexpr explicit TriggerInfo(RegisterValue registerValue) - : info(registerValue & 0xFFFF) - , version(static_cast(registerValue >> 24)) - {} + static constexpr auto fromValue(RegisterValue value) { + return TriggerInfo{ + .info = static_cast(value & 0xFFFF), + .version = static_cast(value >> 24), + }; + } [[nodiscard]] constexpr RegisterValue value() const { return RegisterValue{0} @@ -25,7 +27,7 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec::TriggerModule::Registers ; } - std::set getSupportedTriggerTypes() const { + [[nodiscard]] std::set getSupportedTriggerTypes() const { auto output = std::set{}; static constexpr auto types = std::to_array({ diff --git a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/TriggerModule/Registers/TriggerSelect.hpp b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/TriggerModule/Registers/TriggerSelect.hpp index 57a98d75..d90b1876 100644 --- a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/TriggerModule/Registers/TriggerSelect.hpp +++ b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/TriggerModule/Registers/TriggerSelect.hpp @@ -6,6 +6,9 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec::TriggerModule::Registers { + /** + * TODO: Given the single, full width bit field, is this struct really necessary? Review. + */ struct TriggerSelect { TriggerIndex index; diff --git a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/TriggerModule/TriggerModule.hpp b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/TriggerModule/TriggerModule.hpp index 71d13e76..781d74fd 100644 --- a/src/DebugToolDrivers/Protocols/RiscVDebugSpec/TriggerModule/TriggerModule.hpp +++ b/src/DebugToolDrivers/Protocols/RiscVDebugSpec/TriggerModule/TriggerModule.hpp @@ -22,6 +22,7 @@ namespace DebugToolDrivers::Protocols::RiscVDebugSpec::TriggerModule enum class TriggerAction: std::uint8_t { + RAISE_BREAKPOINT_EXCEPTION = 0x00, ENTER_DEBUG_MODE = 0x01, }; }