From 01396afcec68358ec0394758285891cd9bb16003 Mon Sep 17 00:00:00 2001 From: Nav Date: Thu, 24 Mar 2022 19:06:09 +0000 Subject: [PATCH] Renamed AvrGdbRsp directory to AvrGdb and moved target register functions to new GDB target descriptor class --- CMakeLists.txt | 4 +- src/Application.hpp | 2 +- src/DebugServers/GdbRsp/AvrGdb/AvrGdbRsp.cpp | 17 +++ src/DebugServers/GdbRsp/AvrGdb/AvrGdbRsp.hpp | 51 ++++++++ .../TargetDescriptor.cpp} | 65 +++++----- .../GdbRsp/AvrGdb/TargetDescriptor.hpp | 51 ++++++++ .../GdbRsp/AvrGdbRsp/AvrGdbRsp.hpp | 112 ------------------ 7 files changed, 156 insertions(+), 146 deletions(-) create mode 100644 src/DebugServers/GdbRsp/AvrGdb/AvrGdbRsp.cpp create mode 100644 src/DebugServers/GdbRsp/AvrGdb/AvrGdbRsp.hpp rename src/DebugServers/GdbRsp/{AvrGdbRsp/AvrGdbRsp.cpp => AvrGdb/TargetDescriptor.cpp} (88%) create mode 100644 src/DebugServers/GdbRsp/AvrGdb/TargetDescriptor.hpp delete mode 100644 src/DebugServers/GdbRsp/AvrGdbRsp/AvrGdbRsp.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b2b4f23..3a6d6a43 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -127,7 +127,6 @@ add_executable(Bloom src/DebugServers/DebugServer.cpp src/DebugServers/GdbRsp/GdbRspDebugServer.cpp src/DebugServers/GdbRsp/GdbDebugServerConfig.cpp - src/DebugServers/GdbRsp/AvrGdbRsp/AvrGdbRsp.cpp src/DebugServers/GdbRsp/Connection.cpp src/DebugServers/GdbRsp/CommandPackets/CommandPacket.cpp src/DebugServers/GdbRsp/CommandPackets/CommandPacketFactory.cpp @@ -143,6 +142,9 @@ add_executable(Bloom src/DebugServers/GdbRsp/CommandPackets/RemoveBreakpoint.cpp src/DebugServers/GdbRsp/ResponsePackets/SupportedFeaturesResponse.cpp + # AVR GDB Server + src/DebugServers/GdbRsp/AvrGdb/AvrGdbRsp.cpp + src/DebugServers/GdbRsp/AvrGdb/TargetDescriptor.cpp # Insight src/Insight/Insight.cpp src/Insight/InsightWorker/InsightWorker.cpp diff --git a/src/Application.hpp b/src/Application.hpp index f44d2009..8cf5bb59 100644 --- a/src/Application.hpp +++ b/src/Application.hpp @@ -10,7 +10,7 @@ #include "src/Helpers/Thread.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/SignalHandler/SignalHandler.hpp" diff --git a/src/DebugServers/GdbRsp/AvrGdb/AvrGdbRsp.cpp b/src/DebugServers/GdbRsp/AvrGdb/AvrGdbRsp.cpp new file mode 100644 index 00000000..bd7f803c --- /dev/null +++ b/src/DebugServers/GdbRsp/AvrGdb/AvrGdbRsp.cpp @@ -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); + } +} diff --git a/src/DebugServers/GdbRsp/AvrGdb/AvrGdbRsp.hpp b/src/DebugServers/GdbRsp/AvrGdb/AvrGdbRsp.hpp new file mode 100644 index 00000000..7f2e8f62 --- /dev/null +++ b/src/DebugServers/GdbRsp/AvrGdb/AvrGdbRsp.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include + +#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; + }; +} diff --git a/src/DebugServers/GdbRsp/AvrGdbRsp/AvrGdbRsp.cpp b/src/DebugServers/GdbRsp/AvrGdb/TargetDescriptor.cpp similarity index 88% rename from src/DebugServers/GdbRsp/AvrGdbRsp/AvrGdbRsp.cpp rename to src/DebugServers/GdbRsp/AvrGdb/TargetDescriptor.cpp index 164dff7e..fdd97cfc 100644 --- a/src/DebugServers/GdbRsp/AvrGdbRsp/AvrGdbRsp.cpp +++ b/src/DebugServers/GdbRsp/AvrGdb/TargetDescriptor.cpp @@ -1,21 +1,46 @@ -#include "AvrGdbRsp.hpp" +#include "TargetDescriptor.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::TargetRegisterType; - void AvrGdbRsp::init() { - this->loadRegisterMappings(); + using Bloom::Exceptions::Exception; - GdbRspDebugServer::init(); + TargetDescriptor::TargetDescriptor(const Bloom::Targets::TargetDescriptor& targetDescriptor) + : DebugServers::Gdb::TargetDescriptor(targetDescriptor) + { + this->loadRegisterMappings(); } - void AvrGdbRsp::loadRegisterMappings() { + std::optional 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; if (!registerDescriptorsByType.contains(TargetRegisterType::STATUS_REGISTER)) { 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."); } } - - std::optional 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."); - } } diff --git a/src/DebugServers/GdbRsp/AvrGdb/TargetDescriptor.hpp b/src/DebugServers/GdbRsp/AvrGdb/TargetDescriptor.hpp new file mode 100644 index 00000000..b56cbd32 --- /dev/null +++ b/src/DebugServers/GdbRsp/AvrGdb/TargetDescriptor.hpp @@ -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 registerDescriptorsByGdbNumber = {}; + BiMap 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 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(); + }; +} diff --git a/src/DebugServers/GdbRsp/AvrGdbRsp/AvrGdbRsp.hpp b/src/DebugServers/GdbRsp/AvrGdbRsp/AvrGdbRsp.hpp deleted file mode 100644 index 5a1e686a..00000000 --- a/src/DebugServers/GdbRsp/AvrGdbRsp/AvrGdbRsp.hpp +++ /dev/null @@ -1,112 +0,0 @@ -#pragma once - -#include - -#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& getRegisterNumberToDescriptorMapping() override { - return this->registerDescriptorsByGdbNumber; - }; - - std::optional 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 registerDescriptorsByGdbNumber = {}; - BiMap 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; - }; -}