Renamed AvrGdbRsp directory to AvrGdb and moved target register functions to new GDB target descriptor class

This commit is contained in:
Nav
2022-03-24 19:06:09 +00:00
parent 5d58bbde07
commit 01396afcec
7 changed files with 156 additions and 146 deletions

View File

@@ -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

View File

@@ -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"

View 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);
}
}

View 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;
};
}

View File

@@ -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.");
}
} }

View 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();
};
}

View File

@@ -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;
};
}