WCH RISC-V software breakpoints, and a few other bits of refactoring/tidying

This commit is contained in:
Nav
2024-12-05 23:09:01 +00:00
parent 966244a01a
commit 33ed399337
55 changed files with 1530 additions and 686 deletions

View File

@@ -25,8 +25,10 @@ namespace Targets::Microchip::Avr8
Avr8::Avr8(const TargetConfig& targetConfig, TargetDescriptionFile&& targetDescriptionFile)
: targetConfig(Avr8TargetConfig{targetConfig})
, targetDescriptionFile(std::move(targetDescriptionFile))
, programAddressSpaceDescriptor(this->targetDescriptionFile.getProgramAddressSpaceDescriptor())
, dataAddressSpaceDescriptor(this->targetDescriptionFile.getDataAddressSpaceDescriptor())
, fuseAddressSpaceDescriptor(this->targetDescriptionFile.getFuseAddressSpaceDescriptor())
, programMemorySegmentDescriptor(this->targetDescriptionFile.getProgramMemorySegmentDescriptor())
, ramMemorySegmentDescriptor(this->targetDescriptionFile.getRamMemorySegmentDescriptor())
, ioMemorySegmentDescriptor(this->targetDescriptionFile.getIoMemorySegmentDescriptor())
, fuseMemorySegmentDescriptor(this->targetDescriptionFile.getFuseMemorySegmentDescriptor())
@@ -234,7 +236,6 @@ namespace Targets::Microchip::Avr8
}
this->stop();
this->clearAllBreakpoints();
if (
this->targetConfig.physicalInterface == TargetPhysicalInterface::JTAG
@@ -357,24 +358,30 @@ namespace Targets::Microchip::Avr8
this->avr8DebugInterface->reset();
}
void Avr8::setSoftwareBreakpoint(TargetMemoryAddress address) {
this->avr8DebugInterface->setSoftwareBreakpoint(address);
void Avr8::setProgramBreakpoint(const TargetProgramBreakpoint& breakpoint) {
if (breakpoint.addressSpaceDescriptor != this->programAddressSpaceDescriptor) {
throw Exception{"Unexpected address space descriptor"};
}
if (breakpoint.type == TargetProgramBreakpoint::Type::HARDWARE) {
this->avr8DebugInterface->setHardwareBreakpoint(breakpoint.address);
} else {
this->avr8DebugInterface->setSoftwareBreakpoint(breakpoint.address);
}
}
void Avr8::removeSoftwareBreakpoint(TargetMemoryAddress address) {
this->avr8DebugInterface->clearSoftwareBreakpoint(address);
}
void Avr8::removeProgramBreakpoint(const TargetProgramBreakpoint& breakpoint) {
if (breakpoint.addressSpaceDescriptor != this->programAddressSpaceDescriptor) {
throw Exception{"Unexpected address space descriptor"};
}
void Avr8::setHardwareBreakpoint(TargetMemoryAddress address) {
this->avr8DebugInterface->setHardwareBreakpoint(address);
}
if (breakpoint.type == TargetProgramBreakpoint::Type::HARDWARE) {
this->avr8DebugInterface->clearHardwareBreakpoint(breakpoint.address);
void Avr8::removeHardwareBreakpoint(TargetMemoryAddress address) {
this->avr8DebugInterface->clearHardwareBreakpoint(address);
}
void Avr8::clearAllBreakpoints() {
this->avr8DebugInterface->clearAllBreakpoints();
} else {
this->avr8DebugInterface->clearSoftwareBreakpoint(breakpoint.address);
}
}
TargetRegisterDescriptorAndValuePairs Avr8::readRegisters(const Targets::TargetRegisterDescriptors& descriptors) {
@@ -795,19 +802,19 @@ namespace Targets::Microchip::Avr8
}
BreakpointResources Avr8::getBreakpointResources() {
auto maxHardwareBreakpoints = std::uint16_t{0};
auto hardwareBreakpoints = std::uint32_t{0};
switch (this->targetConfig.physicalInterface) {
case TargetPhysicalInterface::JTAG: {
maxHardwareBreakpoints = this->family == Family::XMEGA ? 2 : 3;
hardwareBreakpoints = this->family == Family::XMEGA ? 2 : 3;
break;
}
case TargetPhysicalInterface::PDI: {
maxHardwareBreakpoints = 2;
hardwareBreakpoints = 2;
break;
}
case TargetPhysicalInterface::UPDI: {
maxHardwareBreakpoints = 1;
hardwareBreakpoints = 1;
break;
}
default: {
@@ -816,11 +823,15 @@ namespace Targets::Microchip::Avr8
}
return BreakpointResources{
maxHardwareBreakpoints,
std::nullopt,
hardwareBreakpoints,
/*
* AVR targets have unlimited SW breakpoints, so we just use the program memory size divided by the
* breakpoint ("BREAK") opcode (byte) size, to determine the limit.
*/
this->programMemorySegmentDescriptor.size() / 2,
std::min(
static_cast<std::uint16_t>(this->targetConfig.reserveSteppingBreakpoint.value_or(true) ? 1 : 0),
maxHardwareBreakpoints
static_cast<std::uint32_t>(this->targetConfig.reserveSteppingBreakpoint.value_or(true) ? 1 : 0),
hardwareBreakpoints
)
};
}

View File

@@ -63,12 +63,8 @@ namespace Targets::Microchip::Avr8
void step() override;
void reset() override;
void setSoftwareBreakpoint(TargetMemoryAddress address) override;
void removeSoftwareBreakpoint(TargetMemoryAddress address) override;
void setHardwareBreakpoint(TargetMemoryAddress address) override;
void removeHardwareBreakpoint(TargetMemoryAddress address) override;
void clearAllBreakpoints() override;
void setProgramBreakpoint(const TargetProgramBreakpoint& breakpoint) override;
void removeProgramBreakpoint(const TargetProgramBreakpoint& breakpoint) override;
TargetRegisterDescriptorAndValuePairs readRegisters(const TargetRegisterDescriptors& descriptors) override;
void writeRegisters(const TargetRegisterDescriptorAndValuePairs& registers) override;
@@ -122,9 +118,11 @@ namespace Targets::Microchip::Avr8
Avr8TargetConfig targetConfig;
TargetDescriptionFile targetDescriptionFile;
TargetAddressSpaceDescriptor programAddressSpaceDescriptor;
TargetAddressSpaceDescriptor dataAddressSpaceDescriptor;
TargetAddressSpaceDescriptor fuseAddressSpaceDescriptor;
TargetMemorySegmentDescriptor programMemorySegmentDescriptor;
TargetMemorySegmentDescriptor ramMemorySegmentDescriptor;
TargetMemorySegmentDescriptor ioMemorySegmentDescriptor;
TargetMemorySegmentDescriptor fuseMemorySegmentDescriptor;

View File

@@ -133,6 +133,10 @@ namespace Targets::Microchip::Avr8
return this->getLockbitAddressSpace().getMemorySegment("lockbits");
}
TargetAddressSpaceDescriptor TargetDescriptionFile::getProgramAddressSpaceDescriptor() const {
return this->targetAddressSpaceDescriptorFromAddressSpace(this->getProgramAddressSpace());
}
TargetAddressSpaceDescriptor TargetDescriptionFile::getDataAddressSpaceDescriptor() const {
return this->targetAddressSpaceDescriptorFromAddressSpace(this->getDataAddressSpace());
}
@@ -141,6 +145,13 @@ namespace Targets::Microchip::Avr8
return this->targetAddressSpaceDescriptorFromAddressSpace(this->getFuseAddressSpace());
}
TargetMemorySegmentDescriptor TargetDescriptionFile::getProgramMemorySegmentDescriptor() const {
return this->targetMemorySegmentDescriptorFromMemorySegment(
this->getProgramMemorySegment(),
this->getProgramAddressSpace()
);
}
TargetMemorySegmentDescriptor TargetDescriptionFile::getRamMemorySegmentDescriptor() const {
return this->targetMemorySegmentDescriptorFromMemorySegment(
this->getRamMemorySegment(),

View File

@@ -61,9 +61,11 @@ namespace Targets::Microchip::Avr8
[[nodiscard]] const TargetDescription::MemorySegment& getFuseMemorySegment() const;
[[nodiscard]] const TargetDescription::MemorySegment& getLockbitMemorySegment() const;
[[nodiscard]] TargetAddressSpaceDescriptor getProgramAddressSpaceDescriptor() const;
[[nodiscard]] TargetAddressSpaceDescriptor getDataAddressSpaceDescriptor() const;
[[nodiscard]] TargetAddressSpaceDescriptor getFuseAddressSpaceDescriptor() const;
[[nodiscard]] TargetMemorySegmentDescriptor getProgramMemorySegmentDescriptor() const;
[[nodiscard]] TargetMemorySegmentDescriptor getRamMemorySegmentDescriptor() const;
[[nodiscard]] TargetMemorySegmentDescriptor getFuseMemorySegmentDescriptor() const;
[[nodiscard]] TargetMemorySegmentDescriptor getIoMemorySegmentDescriptor() const;