Renamed AvrGdbRsp directory to AvrGdb and moved target register functions to new GDB target descriptor class
This commit is contained in:
@@ -127,7 +127,6 @@ add_executable(Bloom
|
|||||||
src/DebugServers/DebugServer.cpp
|
src/DebugServers/DebugServer.cpp
|
||||||
src/DebugServers/GdbRsp/GdbRspDebugServer.cpp
|
src/DebugServers/GdbRsp/GdbRspDebugServer.cpp
|
||||||
src/DebugServers/GdbRsp/GdbDebugServerConfig.cpp
|
src/DebugServers/GdbRsp/GdbDebugServerConfig.cpp
|
||||||
src/DebugServers/GdbRsp/AvrGdbRsp/AvrGdbRsp.cpp
|
|
||||||
src/DebugServers/GdbRsp/Connection.cpp
|
src/DebugServers/GdbRsp/Connection.cpp
|
||||||
src/DebugServers/GdbRsp/CommandPackets/CommandPacket.cpp
|
src/DebugServers/GdbRsp/CommandPackets/CommandPacket.cpp
|
||||||
src/DebugServers/GdbRsp/CommandPackets/CommandPacketFactory.cpp
|
src/DebugServers/GdbRsp/CommandPackets/CommandPacketFactory.cpp
|
||||||
@@ -143,6 +142,9 @@ add_executable(Bloom
|
|||||||
src/DebugServers/GdbRsp/CommandPackets/RemoveBreakpoint.cpp
|
src/DebugServers/GdbRsp/CommandPackets/RemoveBreakpoint.cpp
|
||||||
src/DebugServers/GdbRsp/ResponsePackets/SupportedFeaturesResponse.cpp
|
src/DebugServers/GdbRsp/ResponsePackets/SupportedFeaturesResponse.cpp
|
||||||
|
|
||||||
|
# AVR GDB Server
|
||||||
|
src/DebugServers/GdbRsp/AvrGdb/AvrGdbRsp.cpp
|
||||||
|
src/DebugServers/GdbRsp/AvrGdb/TargetDescriptor.cpp
|
||||||
# Insight
|
# Insight
|
||||||
src/Insight/Insight.cpp
|
src/Insight/Insight.cpp
|
||||||
src/Insight/InsightWorker/InsightWorker.cpp
|
src/Insight/InsightWorker/InsightWorker.cpp
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#include "src/Helpers/Thread.hpp"
|
#include "src/Helpers/Thread.hpp"
|
||||||
|
|
||||||
#include "src/TargetController/TargetController.hpp"
|
#include "src/TargetController/TargetController.hpp"
|
||||||
#include "src/DebugServers/GdbRsp/AvrGdbRsp/AvrGdbRsp.hpp"
|
#include "src/DebugServers/GdbRsp/AvrGdb/AvrGdbRsp.hpp"
|
||||||
#include "src/Insight/Insight.hpp"
|
#include "src/Insight/Insight.hpp"
|
||||||
#include "src/SignalHandler/SignalHandler.hpp"
|
#include "src/SignalHandler/SignalHandler.hpp"
|
||||||
|
|
||||||
|
|||||||
17
src/DebugServers/GdbRsp/AvrGdb/AvrGdbRsp.cpp
Normal file
17
src/DebugServers/GdbRsp/AvrGdb/AvrGdbRsp.cpp
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#include "AvrGdbRsp.hpp"
|
||||||
|
|
||||||
|
#include "src/Exceptions/Exception.hpp"
|
||||||
|
|
||||||
|
namespace Bloom::DebugServers::Gdb::AvrGdb
|
||||||
|
{
|
||||||
|
using namespace Bloom::Exceptions;
|
||||||
|
|
||||||
|
using Bloom::Targets::TargetRegisterDescriptor;
|
||||||
|
using Bloom::Targets::TargetRegisterType;
|
||||||
|
|
||||||
|
void AvrGdbRsp::init() {
|
||||||
|
DebugServers::Gdb::GdbRspDebugServer::init();
|
||||||
|
|
||||||
|
this->gdbTargetDescriptor = TargetDescriptor(this->targetDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
51
src/DebugServers/GdbRsp/AvrGdb/AvrGdbRsp.hpp
Normal file
51
src/DebugServers/GdbRsp/AvrGdb/AvrGdbRsp.hpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "TargetDescriptor.hpp"
|
||||||
|
|
||||||
|
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
|
||||||
|
#include "src/DebugServers/GdbRsp/RegisterDescriptor.hpp"
|
||||||
|
#include "src/Helpers/BiMap.hpp"
|
||||||
|
|
||||||
|
namespace Bloom::DebugServers::Gdb::AvrGdb
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The AVR GDB client (avr-gdb) defines a set of parameters relating to AVR targets. These parameters are
|
||||||
|
* hardcoded in the AVR GDB source code. The client expects all compatible GDB RSP servers to be aware of
|
||||||
|
* these parameters.
|
||||||
|
*
|
||||||
|
* An example of these hardcoded parameters is target registers and the order in which they are supplied; AVR GDB
|
||||||
|
* clients expect 35 registers to be accessible via the server. 32 of these registers are general purpose CPU
|
||||||
|
* registers. The GP registers are expected to be followed by the status register (SREG), stack pointer
|
||||||
|
* register (SPH & SPL) and the program counter. These must all be given in a specific order, which is
|
||||||
|
* pre-determined by the AVR GDB client. See AvrGdbRsp::getRegisterNumberToDescriptorMapping() for more.
|
||||||
|
*
|
||||||
|
* For more on this, see the AVR GDB source code at https://github.com/bminor/binutils-gdb/blob/master/gdb/avr-tdep.c
|
||||||
|
*
|
||||||
|
* The AvrGdpRsp class extends the generic GDB RSP debug server and implements these AVR specific parameters.
|
||||||
|
*/
|
||||||
|
class AvrGdbRsp: public GdbRspDebugServer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit AvrGdbRsp(
|
||||||
|
const ProjectConfig& projectConfig,
|
||||||
|
const EnvironmentConfig& environmentConfig,
|
||||||
|
const DebugServerConfig& debugServerConfig
|
||||||
|
): GdbRspDebugServer(projectConfig, environmentConfig, debugServerConfig) {};
|
||||||
|
|
||||||
|
std::string getName() const override {
|
||||||
|
return "AVR GDB Remote Serial Protocol Debug Server";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void init() override;
|
||||||
|
|
||||||
|
const Gdb::TargetDescriptor& getGdbTargetDescriptor() override {
|
||||||
|
return this->gdbTargetDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TargetDescriptor gdbTargetDescriptor;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,21 +1,46 @@
|
|||||||
#include "AvrGdbRsp.hpp"
|
#include "TargetDescriptor.hpp"
|
||||||
|
|
||||||
#include "src/Exceptions/Exception.hpp"
|
#include "src/Exceptions/Exception.hpp"
|
||||||
|
#include "src/Logger/Logger.hpp"
|
||||||
|
|
||||||
namespace Bloom::DebugServers::Gdb
|
namespace Bloom::DebugServers::Gdb::AvrGdb
|
||||||
{
|
{
|
||||||
using namespace Bloom::Exceptions;
|
|
||||||
|
|
||||||
using Bloom::Targets::TargetRegisterDescriptor;
|
using Bloom::Targets::TargetRegisterDescriptor;
|
||||||
using Bloom::Targets::TargetRegisterType;
|
using Bloom::Targets::TargetRegisterType;
|
||||||
|
|
||||||
void AvrGdbRsp::init() {
|
using Bloom::Exceptions::Exception;
|
||||||
this->loadRegisterMappings();
|
|
||||||
|
|
||||||
GdbRspDebugServer::init();
|
TargetDescriptor::TargetDescriptor(const Bloom::Targets::TargetDescriptor& targetDescriptor)
|
||||||
|
: DebugServers::Gdb::TargetDescriptor(targetDescriptor)
|
||||||
|
{
|
||||||
|
this->loadRegisterMappings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvrGdbRsp::loadRegisterMappings() {
|
std::optional<GdbRegisterNumberType> TargetDescriptor::getRegisterNumberFromTargetRegisterDescriptor(
|
||||||
|
const Targets::TargetRegisterDescriptor& registerDescriptor
|
||||||
|
) {
|
||||||
|
return this->targetRegisterDescriptorsByGdbNumber.valueAt(registerDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
const RegisterDescriptor& TargetDescriptor::getRegisterDescriptorFromNumber(GdbRegisterNumberType number) {
|
||||||
|
if (this->registerDescriptorsByGdbNumber.contains(number)) {
|
||||||
|
return this->registerDescriptorsByGdbNumber.at(number);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw Exception("Unknown register from GDB - register number (" + std::to_string(number)
|
||||||
|
+ ") not mapped to any GDB register descriptor.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const TargetRegisterDescriptor& TargetDescriptor::getTargetRegisterDescriptorFromNumber(GdbRegisterNumberType number) {
|
||||||
|
if (this->targetRegisterDescriptorsByGdbNumber.contains(number)) {
|
||||||
|
return this->targetRegisterDescriptorsByGdbNumber.at(number);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw Exception("Unknown register from GDB - register number (" + std::to_string(number)
|
||||||
|
+ ") not mapped to any target register descriptor.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetDescriptor::loadRegisterMappings() {
|
||||||
auto& registerDescriptorsByType = this->targetDescriptor.registerDescriptorsByType;
|
auto& registerDescriptorsByType = this->targetDescriptor.registerDescriptorsByType;
|
||||||
if (!registerDescriptorsByType.contains(TargetRegisterType::STATUS_REGISTER)) {
|
if (!registerDescriptorsByType.contains(TargetRegisterType::STATUS_REGISTER)) {
|
||||||
throw Exception("Missing status register descriptor");
|
throw Exception("Missing status register descriptor");
|
||||||
@@ -121,28 +146,4 @@ namespace Bloom::DebugServers::Gdb
|
|||||||
throw Exception("AVR8 program counter size exceeds the GDB register size.");
|
throw Exception("AVR8 program counter size exceeds the GDB register size.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<GdbRegisterNumberType> AvrGdbRsp::getRegisterNumberFromTargetRegisterDescriptor(
|
|
||||||
const Targets::TargetRegisterDescriptor& registerDescriptor
|
|
||||||
) {
|
|
||||||
return this->targetRegisterDescriptorsByGdbNumber.valueAt(registerDescriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
const RegisterDescriptor& AvrGdbRsp::getRegisterDescriptorFromNumber(GdbRegisterNumberType number) {
|
|
||||||
if (this->registerDescriptorsByGdbNumber.contains(number)) {
|
|
||||||
return this->registerDescriptorsByGdbNumber.at(number);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw Exception("Unknown register from GDB - register number (" + std::to_string(number)
|
|
||||||
+ ") not mapped to any GDB register descriptor.");
|
|
||||||
}
|
|
||||||
|
|
||||||
const TargetRegisterDescriptor& AvrGdbRsp::getTargetRegisterDescriptorFromNumber(GdbRegisterNumberType number) {
|
|
||||||
if (this->targetRegisterDescriptorsByGdbNumber.contains(number)) {
|
|
||||||
return this->targetRegisterDescriptorsByGdbNumber.at(number);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw Exception("Unknown register from GDB - register number (" + std::to_string(number)
|
|
||||||
+ ") not mapped to any target register descriptor.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
51
src/DebugServers/GdbRsp/AvrGdb/TargetDescriptor.hpp
Normal file
51
src/DebugServers/GdbRsp/AvrGdb/TargetDescriptor.hpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "src/DebugServers/GdbRsp/TargetDescriptor.hpp"
|
||||||
|
|
||||||
|
#include "src/Helpers/BiMap.hpp"
|
||||||
|
|
||||||
|
namespace Bloom::DebugServers::Gdb::AvrGdb
|
||||||
|
{
|
||||||
|
class TargetDescriptor: public DebugServers::Gdb::TargetDescriptor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BiMap<GdbRegisterNumberType, RegisterDescriptor> registerDescriptorsByGdbNumber = {};
|
||||||
|
BiMap<GdbRegisterNumberType, Targets::TargetRegisterDescriptor> targetRegisterDescriptorsByGdbNumber = {};
|
||||||
|
|
||||||
|
const Bloom::Targets::TargetDescriptor& targetDescriptor;
|
||||||
|
|
||||||
|
explicit TargetDescriptor(const Bloom::Targets::TargetDescriptor& targetDescriptor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should retrieve the GDB register number, given a target register descriptor. Or std::nullopt if the target
|
||||||
|
* register descriptor isn't mapped to any GDB register.
|
||||||
|
*
|
||||||
|
* @param registerDescriptor
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
std::optional<GdbRegisterNumberType> getRegisterNumberFromTargetRegisterDescriptor(
|
||||||
|
const Targets::TargetRegisterDescriptor& registerDescriptor
|
||||||
|
) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should retrieve the GDB register descriptor for a given GDB register number.
|
||||||
|
*
|
||||||
|
* @param number
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
const RegisterDescriptor& getRegisterDescriptorFromNumber(GdbRegisterNumberType number) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should retrieve the mapped target register descriptor for a given GDB register number.
|
||||||
|
*
|
||||||
|
* @param number
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
const Targets::TargetRegisterDescriptor& getTargetRegisterDescriptorFromNumber(
|
||||||
|
GdbRegisterNumberType number
|
||||||
|
) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void loadRegisterMappings();
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
|
|
||||||
#include "src/DebugServers/GdbRsp/RegisterDescriptor.hpp"
|
|
||||||
#include "src/Helpers/BiMap.hpp"
|
|
||||||
|
|
||||||
namespace Bloom::DebugServers::Gdb
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The AVR GDB client (avr-gdb) defines a set of parameters relating to AVR targets. These parameters are
|
|
||||||
* hardcoded in the AVR GDB source code. The client expects all compatible GDB RSP servers to be aware of
|
|
||||||
* these parameters.
|
|
||||||
*
|
|
||||||
* An example of these hardcoded parameters is target registers and the order in which they are supplied; AVR GDB
|
|
||||||
* clients expect 35 registers to be accessible via the server. 32 of these registers are general purpose CPU
|
|
||||||
* registers. The GP registers are expected to be followed by the status register (SREG), stack pointer
|
|
||||||
* register (SPH & SPL) and the program counter. These must all be given in a specific order, which is
|
|
||||||
* pre-determined by the AVR GDB client. See AvrGdbRsp::getRegisterNumberToDescriptorMapping() for more.
|
|
||||||
*
|
|
||||||
* For more on this, see the AVR GDB source code at https://github.com/bminor/binutils-gdb/blob/master/gdb/avr-tdep.c
|
|
||||||
*
|
|
||||||
* The AvrGdpRsp class extends the generic GDB RSP debug server and implements these AVR specific parameters.
|
|
||||||
*/
|
|
||||||
class AvrGdbRsp: public GdbRspDebugServer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit AvrGdbRsp(
|
|
||||||
const ProjectConfig& projectConfig,
|
|
||||||
const EnvironmentConfig& environmentConfig,
|
|
||||||
const DebugServerConfig& debugServerConfig
|
|
||||||
): GdbRspDebugServer(projectConfig, environmentConfig, debugServerConfig) {};
|
|
||||||
|
|
||||||
std::string getName() const override {
|
|
||||||
return "AVR GDB Remote Serial Protocol Debug Server";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void init() override;
|
|
||||||
|
|
||||||
void loadRegisterMappings();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* avr-gdb uses the most significant 15 bits in memory addresses to indicate the type of memory being
|
|
||||||
* addressed.
|
|
||||||
*
|
|
||||||
* @param address
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
Targets::TargetMemoryType getMemoryTypeFromGdbAddress(std::uint32_t address) override {
|
|
||||||
if (address & this->gdbInternalMemoryMask) {
|
|
||||||
return Targets::TargetMemoryType::RAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Targets::TargetMemoryType::FLASH;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Strips the most significant 15 bits from a GDB memory address.
|
|
||||||
*
|
|
||||||
* @param address
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
std::uint32_t removeMemoryTypeIndicatorFromGdbAddress(std::uint32_t address) override {
|
|
||||||
return address & this->gdbInternalMemoryMask ? (address & ~(this->gdbInternalMemoryMask)) : address;
|
|
||||||
};
|
|
||||||
|
|
||||||
const BiMap<GdbRegisterNumberType, RegisterDescriptor>& getRegisterNumberToDescriptorMapping() override {
|
|
||||||
return this->registerDescriptorsByGdbNumber;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::optional<GdbRegisterNumberType> getRegisterNumberFromTargetRegisterDescriptor(
|
|
||||||
const Targets::TargetRegisterDescriptor& registerDescriptor
|
|
||||||
) override;
|
|
||||||
|
|
||||||
const RegisterDescriptor& getRegisterDescriptorFromNumber(GdbRegisterNumberType number) override;
|
|
||||||
|
|
||||||
const Targets::TargetRegisterDescriptor& getTargetRegisterDescriptorFromNumber(
|
|
||||||
GdbRegisterNumberType number
|
|
||||||
) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/*
|
|
||||||
* For AVR targets, avr-gdb defines 35 registers in total:
|
|
||||||
*
|
|
||||||
* Register number 0 through 31 are general purpose registers
|
|
||||||
* Register number 32 is the status register (SREG)
|
|
||||||
* Register number 33 is the stack pointer register
|
|
||||||
* Register number 34 is the program counter register
|
|
||||||
*
|
|
||||||
* In this class, we maintain two bidirectional mappings:
|
|
||||||
*
|
|
||||||
* - registerDescriptorsByGdbNumber
|
|
||||||
* A mapping of GDB register numbers to GDB register descriptors.
|
|
||||||
*
|
|
||||||
* - targetRegisterDescriptorsByGdbNumber
|
|
||||||
* A mapping of GDB register numbers to target register descriptors.
|
|
||||||
*
|
|
||||||
* The functions above provide an interface for the retrieval of GDB register descriptors and target register
|
|
||||||
* descriptors, by their respective GDB register number.
|
|
||||||
*/
|
|
||||||
BiMap<GdbRegisterNumberType, RegisterDescriptor> registerDescriptorsByGdbNumber = {};
|
|
||||||
BiMap<GdbRegisterNumberType, Targets::TargetRegisterDescriptor> targetRegisterDescriptorsByGdbNumber = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The mask used by the AVR GDB client to encode the memory type into memory addresses.
|
|
||||||
* See AvrGdbRsp::getMemoryTypeFromGdbAddress() for more.
|
|
||||||
*/
|
|
||||||
unsigned int gdbInternalMemoryMask = 0xFE0000U;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user