From f4b30dbdf6bd6be202e42908598cb54962542fe7 Mon Sep 17 00:00:00 2001 From: Nav Date: Fri, 8 Dec 2023 23:04:04 +0000 Subject: [PATCH] Added `RiscVProgramInterface` for RISC-V debug tools that are unable to program RISC-V targets via the debug interface --- src/DebugToolDrivers/DebugTool.hpp | 18 +++++++++++++++ .../RiscV/RiscVProgramInterface.hpp | 23 +++++++++++++++++++ src/Targets/RiscV/RiscV.cpp | 5 ++++ src/Targets/RiscV/RiscV.hpp | 2 ++ 4 files changed, 48 insertions(+) create mode 100644 src/DebugToolDrivers/TargetInterfaces/RiscV/RiscVProgramInterface.hpp diff --git a/src/DebugToolDrivers/DebugTool.hpp b/src/DebugToolDrivers/DebugTool.hpp index 221f7c39..cead69ee 100644 --- a/src/DebugToolDrivers/DebugTool.hpp +++ b/src/DebugToolDrivers/DebugTool.hpp @@ -9,6 +9,7 @@ #include "src/Targets/Microchip/AVR/AVR8/TargetParameters.hpp" #include "TargetInterfaces/RiscV/RiscVDebugInterface.hpp" +#include "TargetInterfaces/RiscV/RiscVProgramInterface.hpp" #include "src/Targets/TargetRegister.hpp" @@ -113,6 +114,23 @@ public: return nullptr; } + /** + * Some debug tools are unable to program RISC-V targets via the RISC-V debug interface. Such tools must provide + * an implementation of the RiscVProgramInterface, which will allow them to implement flash memory writing as a + * separate function, independent of the debug interface. + * + * The RISC-V target driver will forward all flash memory writes to the RiscVProgramInterface returned by this + * member function. If nullptr is returned, the driver will fall back to the RiscVDebugInterface for flash memory + * writes. + * + * Note: the caller of this function will not manage the lifetime of the returned instance. + * + * @return + */ + virtual DebugToolDrivers::TargetInterfaces::RiscV::RiscVProgramInterface* getRiscVProgramInterface() { + return nullptr; + } + [[nodiscard]] bool isInitialised() const { return this->initialised; } diff --git a/src/DebugToolDrivers/TargetInterfaces/RiscV/RiscVProgramInterface.hpp b/src/DebugToolDrivers/TargetInterfaces/RiscV/RiscVProgramInterface.hpp new file mode 100644 index 00000000..976b52cd --- /dev/null +++ b/src/DebugToolDrivers/TargetInterfaces/RiscV/RiscVProgramInterface.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include + +#include "src/Targets/TargetMemory.hpp" + +namespace DebugToolDrivers::TargetInterfaces::RiscV +{ + class RiscVProgramInterface + { + public: + /** + * Should write to the target's FLASH memory. + * + * @param startAddress + * @param buffer + */ + virtual void writeFlashMemory( + Targets::TargetMemoryAddress startAddress, + const Targets::TargetMemoryBuffer& buffer + ) = 0; + }; +} diff --git a/src/Targets/RiscV/RiscV.cpp b/src/Targets/RiscV/RiscV.cpp index c5b94c45..4d7c5856 100644 --- a/src/Targets/RiscV/RiscV.cpp +++ b/src/Targets/RiscV/RiscV.cpp @@ -51,6 +51,7 @@ namespace Targets::RiscV void RiscV::setDebugTool(DebugTool* debugTool) { this->riscVDebugInterface = debugTool->getRiscVDebugInterface(); + this->riscVProgramInterface = debugTool->getRiscVProgramInterface(); } void RiscV::activate() { @@ -395,6 +396,10 @@ namespace Targets::RiscV return this->writeMemory(memoryType, alignedStartAddress, alignedBuffer); } + if (memoryType == TargetMemoryType::FLASH && this->riscVProgramInterface != nullptr) { + return this->riscVProgramInterface->writeFlashMemory(startAddress, buffer); + } + this->riscVDebugInterface->writeDebugModuleRegister(RegisterAddress::ABSTRACT_DATA_1, startAddress); auto command = AbstractCommandRegister(); diff --git a/src/Targets/RiscV/RiscV.hpp b/src/Targets/RiscV/RiscV.hpp index e4d34c16..5af469c7 100644 --- a/src/Targets/RiscV/RiscV.hpp +++ b/src/Targets/RiscV/RiscV.hpp @@ -8,6 +8,7 @@ #include "src/DebugToolDrivers/DebugTool.hpp" #include "src/DebugToolDrivers/TargetInterfaces/RiscV/RiscVDebugInterface.hpp" +#include "src/DebugToolDrivers/TargetInterfaces/RiscV/RiscVProgramInterface.hpp" #include "src/Targets/RiscV/RiscVGeneric.hpp" #include "src/Targets/RiscV/Registers/RegisterNumbers.hpp" @@ -104,6 +105,7 @@ namespace Targets::RiscV RiscVRegisterDescriptor stackPointerRegisterDescriptor; DebugToolDrivers::TargetInterfaces::RiscV::RiscVDebugInterface* riscVDebugInterface = nullptr; + DebugToolDrivers::TargetInterfaces::RiscV::RiscVProgramInterface* riscVProgramInterface = nullptr; std::set hartIndices; DebugModule::HartIndex selectedHartIndex = 0;