Updated AvrGdbRsp debug server to use the provided register descriptors, instead of creating them
This commit is contained in:
@@ -96,6 +96,7 @@ add_executable(Bloom
|
|||||||
build/resources/TargetDescriptionFiles/AVR/Mapping.json
|
build/resources/TargetDescriptionFiles/AVR/Mapping.json
|
||||||
|
|
||||||
src/DebugServers/GdbRsp/GdbRspDebugServer.cpp
|
src/DebugServers/GdbRsp/GdbRspDebugServer.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
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ void DebugServer::startup() {
|
|||||||
std::bind(&DebugServer::onShutdownDebugServerEvent, this, std::placeholders::_1)
|
std::bind(&DebugServer::onShutdownDebugServerEvent, this, std::placeholders::_1)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this->targetDescriptor = this->targetControllerConsole.getTargetDescriptor();
|
||||||
|
|
||||||
this->init();
|
this->init();
|
||||||
this->setThreadStateAndEmitEvent(ThreadState::READY);
|
this->setThreadStateAndEmitEvent(ThreadState::READY);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "src/Exceptions/DebugServerInterrupted.hpp"
|
#include "src/Exceptions/DebugServerInterrupted.hpp"
|
||||||
#include "src/ApplicationConfig.hpp"
|
#include "src/ApplicationConfig.hpp"
|
||||||
#include "src/Helpers/Thread.hpp"
|
#include "src/Helpers/Thread.hpp"
|
||||||
|
#include "src/Targets/TargetDescriptor.hpp"
|
||||||
#include "src/Targets/TargetRegister.hpp"
|
#include "src/Targets/TargetRegister.hpp"
|
||||||
#include "src/Targets/TargetBreakpoint.hpp"
|
#include "src/Targets/TargetBreakpoint.hpp"
|
||||||
|
|
||||||
@@ -82,6 +83,8 @@ namespace Bloom::DebugServers
|
|||||||
EnvironmentConfig environmentConfig;
|
EnvironmentConfig environmentConfig;
|
||||||
DebugServerConfig debugServerConfig;
|
DebugServerConfig debugServerConfig;
|
||||||
|
|
||||||
|
Targets::TargetDescriptor targetDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called on startup of the DebugServer thread. Derived classes should implement any initialisation work here.
|
* Called on startup of the DebugServer thread. Derived classes should implement any initialisation work here.
|
||||||
*/
|
*/
|
||||||
|
|||||||
58
src/DebugServers/GdbRsp/AvrGdbRsp/AvrGdbRsp.cpp
Normal file
58
src/DebugServers/GdbRsp/AvrGdbRsp/AvrGdbRsp.cpp
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#include "AvrGdbRsp.hpp"
|
||||||
|
|
||||||
|
#include "src/Exceptions/Exception.hpp"
|
||||||
|
|
||||||
|
using namespace Bloom::DebugServers::Gdb;
|
||||||
|
using namespace Bloom::Exceptions;
|
||||||
|
|
||||||
|
using Bloom::Targets::TargetRegisterDescriptor;
|
||||||
|
using Bloom::Targets::TargetRegisterType;
|
||||||
|
|
||||||
|
void AvrGdbRsp::loadRegisterNumberToDescriptorMapping() {
|
||||||
|
auto& registerDescriptorsByType = this->targetDescriptor.registerDescriptorsByType;
|
||||||
|
if (!registerDescriptorsByType.contains(TargetRegisterType::STATUS_REGISTER)) {
|
||||||
|
throw Exception("Missing status register descriptor");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!registerDescriptorsByType.contains(TargetRegisterType::STACK_POINTER)) {
|
||||||
|
throw Exception("Missing stack pointer register descriptor");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!registerDescriptorsByType.contains(TargetRegisterType::PROGRAM_COUNTER)) {
|
||||||
|
throw Exception("Missing program counter register descriptor");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!registerDescriptorsByType.contains(TargetRegisterType::GENERAL_PURPOSE_REGISTER)
|
||||||
|
|| registerDescriptorsByType.at(TargetRegisterType::GENERAL_PURPOSE_REGISTER).size() != 32) {
|
||||||
|
throw Exception("Unexpected general purpose register count");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& gpRegisterDescriptors = registerDescriptorsByType.at(TargetRegisterType::GENERAL_PURPOSE_REGISTER);
|
||||||
|
for (const auto& gpRegisterDescriptor : gpRegisterDescriptors) {
|
||||||
|
this->registerNumberToDescriptorMapping.insert(std::pair(
|
||||||
|
static_cast<GdbRegisterNumber>(gpRegisterDescriptor.id.value()),
|
||||||
|
gpRegisterDescriptor
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
this->registerNumberToDescriptorMapping.insert(std::pair(
|
||||||
|
static_cast<GdbRegisterNumber>(32),
|
||||||
|
registerDescriptorsByType.at(TargetRegisterType::STATUS_REGISTER).front()
|
||||||
|
));
|
||||||
|
|
||||||
|
this->registerNumberToDescriptorMapping.insert(std::pair(
|
||||||
|
static_cast<GdbRegisterNumber>(33),
|
||||||
|
registerDescriptorsByType.at(TargetRegisterType::STACK_POINTER).front()
|
||||||
|
));
|
||||||
|
|
||||||
|
this->registerNumberToDescriptorMapping.insert(std::pair(
|
||||||
|
static_cast<GdbRegisterNumber>(34),
|
||||||
|
registerDescriptorsByType.at(TargetRegisterType::PROGRAM_COUNTER).front()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AvrGdbRsp::init() {
|
||||||
|
this->loadRegisterNumberToDescriptorMapping();
|
||||||
|
|
||||||
|
GdbRspDebugServer::init();
|
||||||
|
}
|
||||||
@@ -32,6 +32,8 @@ namespace Bloom::DebugServers::Gdb
|
|||||||
*/
|
*/
|
||||||
unsigned int gdbInternalMemoryMask = 0xFE0000u;
|
unsigned int gdbInternalMemoryMask = 0xFE0000u;
|
||||||
|
|
||||||
|
BiMap<GdbRegisterNumber, Targets::TargetRegisterDescriptor> registerNumberToDescriptorMapping = {};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* For AVR targets, avr-gdb defines 35 registers in total:
|
* For AVR targets, avr-gdb defines 35 registers in total:
|
||||||
@@ -45,51 +47,12 @@ namespace Bloom::DebugServers::Gdb
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
BiMap<GdbRegisterNumber, Targets::TargetRegisterDescriptor> getRegisterNumberToDescriptorMapping() override {
|
const BiMap<GdbRegisterNumber,Targets::TargetRegisterDescriptor>& getRegisterNumberToDescriptorMapping() override {
|
||||||
using Targets::TargetRegisterDescriptor;
|
return this->registerNumberToDescriptorMapping;
|
||||||
using Targets::TargetRegisterType;
|
|
||||||
|
|
||||||
static BiMap<GdbRegisterNumber, TargetRegisterDescriptor> mapping = {
|
|
||||||
{0, TargetRegisterDescriptor(0, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{1, TargetRegisterDescriptor(1, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{2, TargetRegisterDescriptor(2, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{3, TargetRegisterDescriptor(3, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{4, TargetRegisterDescriptor(4, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{5, TargetRegisterDescriptor(5, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{6, TargetRegisterDescriptor(6, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{7, TargetRegisterDescriptor(7, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{8, TargetRegisterDescriptor(8, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{9, TargetRegisterDescriptor(9, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{10, TargetRegisterDescriptor(10, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{11, TargetRegisterDescriptor(11, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{12, TargetRegisterDescriptor(12, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{13, TargetRegisterDescriptor(13, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{14, TargetRegisterDescriptor(14, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{15, TargetRegisterDescriptor(15, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{16, TargetRegisterDescriptor(16, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{17, TargetRegisterDescriptor(17, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{18, TargetRegisterDescriptor(18, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{19, TargetRegisterDescriptor(19, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{20, TargetRegisterDescriptor(20, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{21, TargetRegisterDescriptor(21, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{22, TargetRegisterDescriptor(22, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{23, TargetRegisterDescriptor(23, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{24, TargetRegisterDescriptor(24, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{25, TargetRegisterDescriptor(25, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{26, TargetRegisterDescriptor(26, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{27, TargetRegisterDescriptor(27, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{28, TargetRegisterDescriptor(28, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{29, TargetRegisterDescriptor(29, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{30, TargetRegisterDescriptor(30, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{31, TargetRegisterDescriptor(31, TargetRegisterType::GENERAL_PURPOSE_REGISTER)},
|
|
||||||
{32, TargetRegisterDescriptor(TargetRegisterType::STATUS_REGISTER)},
|
|
||||||
{33, TargetRegisterDescriptor(TargetRegisterType::STACK_POINTER)},
|
|
||||||
{34, TargetRegisterDescriptor(TargetRegisterType::PROGRAM_COUNTER)},
|
|
||||||
};
|
|
||||||
|
|
||||||
return mapping;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void loadRegisterNumberToDescriptorMapping();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* avr-gdb uses the most significant 15 bits in memory addresses to indicate the type of memory being
|
* avr-gdb uses the most significant 15 bits in memory addresses to indicate the type of memory being
|
||||||
* addressed.
|
* addressed.
|
||||||
@@ -115,6 +78,8 @@ namespace Bloom::DebugServers::Gdb
|
|||||||
return address & this->gdbInternalMemoryMask ? (address & ~(this->gdbInternalMemoryMask)) : address;
|
return address & this->gdbInternalMemoryMask ? (address & ~(this->gdbInternalMemoryMask)) : address;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void init() override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AvrGdbRsp(EventManager& eventManager): GdbRspDebugServer(eventManager) {};
|
explicit AvrGdbRsp(EventManager& eventManager): GdbRspDebugServer(eventManager) {};
|
||||||
|
|
||||||
|
|||||||
@@ -67,5 +67,13 @@ namespace Bloom
|
|||||||
std::unordered_map<TypeA, TypeB> getMap() {
|
std::unordered_map<TypeA, TypeB> getMap() {
|
||||||
return this->map;
|
return this->map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void insert(const std::pair<TypeA, TypeB>& pair) {
|
||||||
|
auto insertResultPair = this->map.insert(pair);
|
||||||
|
this->flippedMap.insert(std::pair<TypeB, typename std::unordered_map<TypeA, TypeB>::iterator>(
|
||||||
|
pair.second,
|
||||||
|
insertResultPair.first
|
||||||
|
));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user