WCH-Link erase command doesn't erase the whole chip, as initially thought. It only erases the program memory segment.

The boot segment appears to be left untouched.
This commit is contained in:
Nav
2024-12-13 22:48:20 +00:00
parent a971e92a58
commit 00919e4057
6 changed files with 33 additions and 18 deletions

View File

@@ -45,14 +45,27 @@ namespace DebugServer::Gdb::RiscVGdb::CommandPackets
Logger::info("Handling FlashErase packet"); Logger::info("Handling FlashErase packet");
try { try {
const auto segmentDescriptorOpt = gdbTargetDescriptor.systemAddressSpaceDescriptor.getContainingMemorySegmentDescriptor(
this->startAddress
);
if (!segmentDescriptorOpt.has_value()) {
throw Exception{"Invalid command - no containing memory segment found for the given start address"};
}
const auto& segmentDescriptor = segmentDescriptorOpt->get();
if (!segmentDescriptor.programmingModeAccess.writeable) {
throw Exception{"Memory segment (\"" + segmentDescriptor.name + "\") not writable in programming mode"};
}
Logger::warning("Erasing \"" + segmentDescriptor.name + "\" segment, in preparation for programming");
targetControllerService.enableProgrammingMode(); targetControllerService.enableProgrammingMode();
Logger::warning("Erasing program memory, in preparation for programming"); // We don't erase a specific address range - we just erase the entire segment
// We don't erase a specific address range - we just erase the entire program memory.
targetControllerService.eraseMemory( targetControllerService.eraseMemory(
gdbTargetDescriptor.systemAddressSpaceDescriptor, gdbTargetDescriptor.systemAddressSpaceDescriptor,
gdbTargetDescriptor.programMemorySegmentDescriptor segmentDescriptor
); );
debugSession.connection.writePacket(OkResponsePacket{}); debugSession.connection.writePacket(OkResponsePacket{});

View File

@@ -6,10 +6,10 @@
namespace DebugToolDrivers::Wch::Protocols::WchLink::Commands namespace DebugToolDrivers::Wch::Protocols::WchLink::Commands
{ {
class EraseChip: public Command<std::array<unsigned char, 1>> class EraseProgramMemory: public Command<std::array<unsigned char, 1>>
{ {
public: public:
EraseChip() EraseProgramMemory()
: Command(0x02) : Command(0x02)
{ {
this->payload = { this->payload = {

View File

@@ -16,7 +16,7 @@
#include "Commands/StartRamCodeWrite.hpp" #include "Commands/StartRamCodeWrite.hpp"
#include "Commands/EndRamCodeWrite.hpp" #include "Commands/EndRamCodeWrite.hpp"
#include "Commands/WriteFlash.hpp" #include "Commands/WriteFlash.hpp"
#include "Commands/EraseChip.hpp" #include "Commands/EraseProgramMemory.hpp"
#include "src/Helpers/BiMap.hpp" #include "src/Helpers/BiMap.hpp"
#include "src/Services/StringService.hpp" #include "src/Services/StringService.hpp"
@@ -243,7 +243,7 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
this->sendCommandAndWaitForResponse(Commands::EndProgrammingSession{}); this->sendCommandAndWaitForResponse(Commands::EndProgrammingSession{});
} }
void WchLinkInterface::eraseChip() { void WchLinkInterface::eraseProgramMemory() {
this->sendCommandAndWaitForResponse(Commands::EraseChip{}); this->sendCommandAndWaitForResponse(Commands::EraseProgramMemory{});
} }
} }

View File

@@ -52,7 +52,7 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
Targets::TargetMemorySize blockSize, Targets::TargetMemorySize blockSize,
std::span<const unsigned char> flashProgramOpcodes std::span<const unsigned char> flashProgramOpcodes
); );
void eraseChip(); void eraseProgramMemory();
template <class CommandType> template <class CommandType>
auto sendCommandAndWaitForResponse(const CommandType& command) { auto sendCommandAndWaitForResponse(const CommandType& command) {

View File

@@ -57,6 +57,11 @@ namespace DebugToolDrivers::Wch
this->targetConfig this->targetConfig
} }
) )
, programSegmentDescriptor(
this->targetDescriptionFile.getSystemAddressSpaceDescriptor().getMemorySegmentDescriptor(
"internal_program_memory"
)
)
, flashProgramOpcodes( , flashProgramOpcodes(
WchLinkDebugInterface::getFlashProgramOpcodes( WchLinkDebugInterface::getFlashProgramOpcodes(
this->targetDescriptionFile.getProperty("wch_link_interface", "programming_opcode_key").value this->targetDescriptionFile.getProperty("wch_link_interface", "programming_opcode_key").value
@@ -352,11 +357,11 @@ namespace DebugToolDrivers::Wch
const TargetAddressSpaceDescriptor& addressSpaceDescriptor, const TargetAddressSpaceDescriptor& addressSpaceDescriptor,
const TargetMemorySegmentDescriptor& memorySegmentDescriptor const TargetMemorySegmentDescriptor& memorySegmentDescriptor
) { ) {
if (memorySegmentDescriptor.type == TargetMemorySegmentType::FLASH) { if (memorySegmentDescriptor == this->programSegmentDescriptor) {
return this->eraseFlashMemory(); return this->wchLinkInterface.eraseProgramMemory();
} }
throw Exception{"Erasing non-flash memory not supported in WchLinkDebugInterface"}; // Ignore other (non-program memory) erase requests, for now.
} }
void WchLinkDebugInterface::enableProgrammingMode() { void WchLinkDebugInterface::enableProgrammingMode() {
@@ -471,10 +476,6 @@ namespace DebugToolDrivers::Wch
this->softwareBreakpointRegistry.remove(softwareBreakpoint); this->softwareBreakpointRegistry.remove(softwareBreakpoint);
} }
void WchLinkDebugInterface::eraseFlashMemory() {
this->wchLinkInterface.eraseChip();
}
std::span<const unsigned char> WchLinkDebugInterface::getFlashProgramOpcodes(const std::string& key) { std::span<const unsigned char> WchLinkDebugInterface::getFlashProgramOpcodes(const std::string& key) {
if (key == "op1") { if (key == "op1") {
return FlashProgramOpcodes::FLASH_OP1; return FlashProgramOpcodes::FLASH_OP1;

View File

@@ -89,6 +89,8 @@ namespace DebugToolDrivers::Wch
Protocols::WchLink::WchLinkInterface& wchLinkInterface; Protocols::WchLink::WchLinkInterface& wchLinkInterface;
DebugToolDrivers::Protocols::RiscVDebugSpec::DebugTranslator riscVTranslator; DebugToolDrivers::Protocols::RiscVDebugSpec::DebugTranslator riscVTranslator;
const Targets::TargetMemorySegmentDescriptor& programSegmentDescriptor;
/** /**
* The 'target activation' command returns a payload of 5 bytes. * The 'target activation' command returns a payload of 5 bytes.
* *
@@ -107,7 +109,6 @@ namespace DebugToolDrivers::Wch
void setSoftwareBreakpoint(const Targets::TargetProgramBreakpoint& breakpoint); void setSoftwareBreakpoint(const Targets::TargetProgramBreakpoint& breakpoint);
void clearSoftwareBreakpoint(const Targets::TargetProgramBreakpoint& breakpoint); void clearSoftwareBreakpoint(const Targets::TargetProgramBreakpoint& breakpoint);
void eraseFlashMemory();
static std::span<const unsigned char> getFlashProgramOpcodes(const std::string& key); static std::span<const unsigned char> getFlashProgramOpcodes(const std::string& key);
}; };
} }