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");
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();
Logger::warning("Erasing program memory, in preparation for programming");
// We don't erase a specific address range - we just erase the entire program memory.
// We don't erase a specific address range - we just erase the entire segment
targetControllerService.eraseMemory(
gdbTargetDescriptor.systemAddressSpaceDescriptor,
gdbTargetDescriptor.programMemorySegmentDescriptor
segmentDescriptor
);
debugSession.connection.writePacket(OkResponsePacket{});

View File

@@ -6,10 +6,10 @@
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:
EraseChip()
EraseProgramMemory()
: Command(0x02)
{
this->payload = {

View File

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

View File

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

View File

@@ -57,6 +57,11 @@ namespace DebugToolDrivers::Wch
this->targetConfig
}
)
, programSegmentDescriptor(
this->targetDescriptionFile.getSystemAddressSpaceDescriptor().getMemorySegmentDescriptor(
"internal_program_memory"
)
)
, flashProgramOpcodes(
WchLinkDebugInterface::getFlashProgramOpcodes(
this->targetDescriptionFile.getProperty("wch_link_interface", "programming_opcode_key").value
@@ -352,11 +357,11 @@ namespace DebugToolDrivers::Wch
const TargetAddressSpaceDescriptor& addressSpaceDescriptor,
const TargetMemorySegmentDescriptor& memorySegmentDescriptor
) {
if (memorySegmentDescriptor.type == TargetMemorySegmentType::FLASH) {
return this->eraseFlashMemory();
if (memorySegmentDescriptor == this->programSegmentDescriptor) {
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() {
@@ -471,10 +476,6 @@ namespace DebugToolDrivers::Wch
this->softwareBreakpointRegistry.remove(softwareBreakpoint);
}
void WchLinkDebugInterface::eraseFlashMemory() {
this->wchLinkInterface.eraseChip();
}
std::span<const unsigned char> WchLinkDebugInterface::getFlashProgramOpcodes(const std::string& key) {
if (key == "op1") {
return FlashProgramOpcodes::FLASH_OP1;

View File

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