Support for hardware breakpoints

This commit is contained in:
Nav
2023-09-20 23:37:54 +01:00
parent df5a141089
commit d7b59cac59
24 changed files with 480 additions and 68 deletions

View File

@@ -268,6 +268,7 @@ namespace Targets::Microchip::Avr::Avr8Bit
"Microchip",
this->targetMemoryDescriptorsByType,
this->targetRegisterDescriptorsById,
this->getBreakpointResources(),
{},
Targets::TargetMemoryType::FLASH
);
@@ -304,12 +305,20 @@ namespace Targets::Microchip::Avr::Avr8Bit
this->avr8DebugInterface->reset();
}
void Avr8::setBreakpoint(std::uint32_t address) {
this->avr8DebugInterface->setBreakpoint(address);
void Avr8::setSoftwareBreakpoint(TargetMemoryAddress address) {
this->avr8DebugInterface->setSoftwareBreakpoint(address);
}
void Avr8::removeBreakpoint(std::uint32_t address) {
this->avr8DebugInterface->clearBreakpoint(address);
void Avr8::removeSoftwareBreakpoint(TargetMemoryAddress address) {
this->avr8DebugInterface->clearSoftwareBreakpoint(address);
}
void Avr8::setHardwareBreakpoint(TargetMemoryAddress address) {
this->avr8DebugInterface->setHardwareBreakpoint(address);
}
void Avr8::removeHardwareBreakpoint(TargetMemoryAddress address) {
this->avr8DebugInterface->clearHardwareBreakpoint(address);
}
void Avr8::clearAllBreakpoints() {
@@ -687,6 +696,33 @@ namespace Targets::Microchip::Avr::Avr8Bit
}
}
BreakpointResources Avr8::getBreakpointResources() {
auto maxHardwareBreakpoints = 0;
switch (this->targetConfig.physicalInterface) {
case PhysicalInterface::JTAG: {
maxHardwareBreakpoints = this->family == Family::XMEGA ? 2 : 3;
break;
}
case PhysicalInterface::PDI: {
maxHardwareBreakpoints = 2;
break;
}
case PhysicalInterface::UPDI: {
maxHardwareBreakpoints = 1;
break;
}
default: {
break;
}
}
return BreakpointResources(
maxHardwareBreakpoints,
std::nullopt
);
}
bool Avr8::isFuseEnabled(const FuseBitsDescriptor& descriptor, unsigned char fuseByteValue) const {
const auto programmedValue = static_cast<unsigned char>(
this->fuseEnableStrategy == FuseEnableStrategy::SET

View File

@@ -19,6 +19,7 @@
#include "src/Targets/Microchip/AVR/Fuse.hpp"
#include "src/Targets/TargetRegister.hpp"
#include "src/Targets/TargetBreakpoint.hpp"
#include "TargetDescription/TargetDescriptionFile.hpp"
@@ -58,8 +59,11 @@ namespace Targets::Microchip::Avr::Avr8Bit
void step() override;
void reset() override;
void setBreakpoint(TargetProgramCounter address) override;
void removeBreakpoint(TargetProgramCounter address) override;
void setSoftwareBreakpoint(TargetProgramCounter address) override;
void removeSoftwareBreakpoint(TargetProgramCounter address) override;
void setHardwareBreakpoint(TargetProgramCounter address) override;
void removeHardwareBreakpoint(TargetProgramCounter address) override;
void clearAllBreakpoints() override;
void writeRegisters(TargetRegisters registers) override;
@@ -143,6 +147,8 @@ namespace Targets::Microchip::Avr::Avr8Bit
void loadTargetMemoryDescriptors();
BreakpointResources getBreakpointResources();
/**
* Checks if a particular fuse is enabled in the given fuse byte value. Takes the target's fuse enable strategy
* into account.

View File

@@ -111,18 +111,32 @@ namespace Targets
virtual void reset() = 0;
/**
* Should set a breakpoint on the target, at the given address.
* Should set a software breakpoint on the target, at the given address.
*
* @param address
*/
virtual void setBreakpoint(TargetMemoryAddress address) = 0;
virtual void setSoftwareBreakpoint(TargetMemoryAddress address) = 0;
/**
* Should remove a breakpoint at the given address.
* Should remove a software breakpoint at the given address.
*
* @param address
*/
virtual void removeBreakpoint(TargetMemoryAddress address) = 0;
virtual void removeSoftwareBreakpoint(TargetMemoryAddress address) = 0;
/**
* Should set a hardware breakpoint on the target, at the given address.
*
* @param address
*/
virtual void setHardwareBreakpoint(TargetMemoryAddress address) = 0;
/**
* Should remove a hardware breakpoint at the given address.
*
* @param address
*/
virtual void removeHardwareBreakpoint(TargetMemoryAddress address) = 0;
/**
* Should clear all breakpoints on the target.

View File

@@ -1,12 +1,13 @@
#pragma once
#include <cstdint>
#include <optional>
#include "TargetMemory.hpp"
namespace Targets
{
enum class TargetBreakCause: int
enum class TargetBreakCause: std::uint8_t
{
BREAKPOINT,
UNKNOWN,
@@ -14,12 +15,38 @@ namespace Targets
struct TargetBreakpoint
{
enum class Type: std::uint8_t
{
HARDWARE,
SOFTWARE,
};
/**
* Byte address of the breakpoint.
*/
TargetMemoryAddress address = 0;
Type type = Type::SOFTWARE;
TargetBreakpoint() = default;
explicit TargetBreakpoint(TargetMemoryAddress address): address(address) {};
explicit TargetBreakpoint(TargetMemoryAddress address, Type type = Type::SOFTWARE)
: address(address)
, type(type)
{};
};
struct BreakpointResources
{
std::optional<std::uint16_t> maximumHardwareBreakpoints;
std::optional<std::uint16_t> maximumSoftwareBreakpoints;
BreakpointResources(
std::optional<std::uint16_t> maximumHardwareBreakpoints,
std::optional<std::uint16_t> maximumSoftwareBreakpoints
)
: maximumHardwareBreakpoints(maximumHardwareBreakpoints)
, maximumSoftwareBreakpoints(maximumSoftwareBreakpoints)
{}
};
}

View File

@@ -10,6 +10,7 @@
#include "TargetMemory.hpp"
#include "TargetRegister.hpp"
#include "TargetVariant.hpp"
#include "TargetBreakpoint.hpp"
namespace Targets
{
@@ -20,6 +21,7 @@ namespace Targets
std::string vendorName;
std::map<TargetMemoryType, TargetMemoryDescriptor> memoryDescriptorsByType;
std::map<TargetRegisterDescriptorId, TargetRegisterDescriptor> registerDescriptorsById;
BreakpointResources breakpointResources;
std::vector<TargetVariant> variants;
TargetMemoryType programMemoryType;
@@ -30,6 +32,7 @@ namespace Targets
const std::string& vendorName,
const std::map<TargetMemoryType, TargetMemoryDescriptor>& memoryDescriptorsByType,
const std::map<TargetRegisterDescriptorId, TargetRegisterDescriptor>& registerDescriptorsById,
const BreakpointResources& breakpointResources,
const std::vector<TargetVariant>& variants,
TargetMemoryType programMemoryType
)
@@ -38,6 +41,7 @@ namespace Targets
, vendorName(vendorName)
, memoryDescriptorsByType(memoryDescriptorsByType)
, registerDescriptorsById(registerDescriptorsById)
, breakpointResources(breakpointResources)
, variants(variants)
, programMemoryType(programMemoryType)
{}