2022-03-24 19:06:09 +00:00
|
|
|
#include "TargetDescriptor.hpp"
|
2021-08-07 17:22:59 +01:00
|
|
|
|
2022-03-25 00:19:32 +00:00
|
|
|
#include <numeric>
|
|
|
|
|
|
2021-08-07 17:22:59 +01:00
|
|
|
#include "src/Exceptions/Exception.hpp"
|
2022-03-24 19:06:09 +00:00
|
|
|
#include "src/Logger/Logger.hpp"
|
2021-08-07 17:22:59 +01:00
|
|
|
|
2022-03-31 16:05:39 +01:00
|
|
|
namespace Bloom::DebugServer::Gdb::AvrGdb
|
2022-02-05 15:32:08 +00:00
|
|
|
{
|
|
|
|
|
using Bloom::Targets::TargetRegisterDescriptor;
|
|
|
|
|
using Bloom::Targets::TargetRegisterType;
|
2021-08-07 17:22:59 +01:00
|
|
|
|
2022-03-24 19:06:09 +00:00
|
|
|
using Bloom::Exceptions::Exception;
|
|
|
|
|
|
|
|
|
|
TargetDescriptor::TargetDescriptor(const Bloom::Targets::TargetDescriptor& targetDescriptor)
|
2022-08-30 02:04:35 +01:00
|
|
|
: DebugServer::Gdb::TargetDescriptor(
|
|
|
|
|
targetDescriptor,
|
|
|
|
|
{
|
|
|
|
|
{Targets::TargetMemoryType::FLASH, 0},
|
|
|
|
|
{Targets::TargetMemoryType::RAM, 0x00800000U},
|
2022-12-08 21:18:04 +00:00
|
|
|
{Targets::TargetMemoryType::EEPROM, 0x00810000U},
|
2023-05-21 21:08:25 +01:00
|
|
|
},
|
|
|
|
|
{},
|
|
|
|
|
{},
|
|
|
|
|
{}
|
2022-08-30 02:04:35 +01:00
|
|
|
)
|
2022-03-24 19:06:09 +00:00
|
|
|
{
|
2022-02-05 15:32:08 +00:00
|
|
|
this->loadRegisterMappings();
|
2022-03-24 19:06:09 +00:00
|
|
|
}
|
|
|
|
|
|
2023-05-21 21:08:25 +01:00
|
|
|
void TargetDescriptor::loadRegisterMappings() {
|
|
|
|
|
const auto generalPurposeTargetRegisterDescriptorIds = this->targetDescriptor.registerDescriptorIdsForType(
|
|
|
|
|
TargetRegisterType::GENERAL_PURPOSE_REGISTER
|
2022-12-03 22:16:21 +00:00
|
|
|
);
|
2021-12-28 01:16:21 +00:00
|
|
|
|
2023-05-21 21:08:25 +01:00
|
|
|
const auto statusTargetRegisterDescriptorIds = this->targetDescriptor.registerDescriptorIdsForType(
|
|
|
|
|
TargetRegisterType::STATUS_REGISTER
|
|
|
|
|
);
|
2022-03-24 19:06:09 +00:00
|
|
|
|
2023-05-21 21:08:25 +01:00
|
|
|
const auto stackPointerTargetRegisterDescriptorIds = this->targetDescriptor.registerDescriptorIdsForType(
|
|
|
|
|
TargetRegisterType::STACK_POINTER
|
2022-12-03 22:16:21 +00:00
|
|
|
);
|
2021-08-07 17:22:59 +01:00
|
|
|
|
2023-05-21 21:08:25 +01:00
|
|
|
if (generalPurposeTargetRegisterDescriptorIds.size() != 32) {
|
|
|
|
|
throw Exception("Unexpected general purpose register count");
|
|
|
|
|
}
|
2022-03-25 00:14:32 +00:00
|
|
|
|
2023-05-21 21:08:25 +01:00
|
|
|
if (statusTargetRegisterDescriptorIds.empty()) {
|
2022-02-05 15:32:08 +00:00
|
|
|
throw Exception("Missing status register descriptor");
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-21 21:08:25 +01:00
|
|
|
if (stackPointerTargetRegisterDescriptorIds.empty()) {
|
2022-02-05 15:32:08 +00:00
|
|
|
throw Exception("Missing stack pointer register descriptor");
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-25 00:14:32 +00:00
|
|
|
/*
|
2023-05-21 21:08:25 +01:00
|
|
|
* For AVR targets, GDB defines 35 registers in total:
|
2022-03-25 00:14:32 +00:00
|
|
|
*
|
2023-05-21 21:08:25 +01:00
|
|
|
* - Register ID 0 through 31 are general purpose registers
|
|
|
|
|
* - Register ID 32 is the status register (SREG)
|
|
|
|
|
* - Register ID 33 is the stack pointer register
|
|
|
|
|
* - Register ID 34 is the program counter
|
2022-02-05 15:32:08 +00:00
|
|
|
*
|
2023-05-21 21:08:25 +01:00
|
|
|
* For AVR targets, we don't have a target register descriptor for the program counter, so we don't map that
|
|
|
|
|
* GDB register ID (34) to anything here. Instead, the register command packet handlers (ReadRegisters,
|
|
|
|
|
* WriteRegister, etc) will handle any operations involving that GDB register.
|
2022-02-05 15:32:08 +00:00
|
|
|
*/
|
|
|
|
|
|
2022-03-25 00:19:32 +00:00
|
|
|
// General purpose registers
|
2023-05-21 21:08:25 +01:00
|
|
|
GdbRegisterId gdbRegisterId = 0;
|
|
|
|
|
for (const auto descriptorId : generalPurposeTargetRegisterDescriptorIds) {
|
|
|
|
|
auto gdbRegisterDescriptor = RegisterDescriptor(
|
|
|
|
|
gdbRegisterId,
|
|
|
|
|
1,
|
|
|
|
|
"General Purpose Register " + std::to_string(gdbRegisterId)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
this->gdbRegisterIdsByTargetRegisterDescriptorId.emplace(descriptorId, gdbRegisterDescriptor.id);
|
|
|
|
|
this->targetRegisterDescriptorIdsByGdbRegisterId.emplace(gdbRegisterDescriptor.id, descriptorId);
|
|
|
|
|
|
|
|
|
|
this->gdbRegisterDescriptorsById.emplace(gdbRegisterDescriptor.id, std::move(gdbRegisterDescriptor));
|
|
|
|
|
|
|
|
|
|
gdbRegisterId++;
|
2022-02-05 15:32:08 +00:00
|
|
|
}
|
2021-08-07 17:22:59 +01:00
|
|
|
|
2023-05-21 21:08:25 +01:00
|
|
|
const auto& statusTargetRegisterDescriptor = this->targetDescriptor.registerDescriptorsById.at(
|
|
|
|
|
*(statusTargetRegisterDescriptorIds.begin())
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
auto statusGdbRegisterDescriptor = RegisterDescriptor(
|
|
|
|
|
TargetDescriptor::STATUS_GDB_REGISTER_ID,
|
2022-02-05 15:32:08 +00:00
|
|
|
1,
|
|
|
|
|
"Status Register"
|
|
|
|
|
);
|
2021-08-07 17:22:59 +01:00
|
|
|
|
2023-05-21 21:08:25 +01:00
|
|
|
if (statusTargetRegisterDescriptor.size > statusGdbRegisterDescriptor.size) {
|
|
|
|
|
throw Exception("AVR8 status target register size exceeds the GDB register size.");
|
|
|
|
|
}
|
2021-08-07 18:09:12 +01:00
|
|
|
|
2023-05-21 21:08:25 +01:00
|
|
|
this->gdbRegisterIdsByTargetRegisterDescriptorId.emplace(
|
|
|
|
|
statusTargetRegisterDescriptor.id,
|
|
|
|
|
statusGdbRegisterDescriptor.id
|
|
|
|
|
);
|
|
|
|
|
this->targetRegisterDescriptorIdsByGdbRegisterId.emplace(
|
|
|
|
|
statusGdbRegisterDescriptor.id,
|
|
|
|
|
statusTargetRegisterDescriptor.id
|
2022-02-05 15:32:08 +00:00
|
|
|
);
|
|
|
|
|
|
2023-05-21 21:08:25 +01:00
|
|
|
this->gdbRegisterDescriptorsById.emplace(
|
|
|
|
|
statusGdbRegisterDescriptor.id,
|
|
|
|
|
std::move(statusGdbRegisterDescriptor)
|
2022-02-05 15:32:08 +00:00
|
|
|
);
|
2021-08-07 17:22:59 +01:00
|
|
|
|
2023-05-21 21:08:25 +01:00
|
|
|
const auto& stackPointerTargetRegisterDescriptor = this->targetDescriptor.registerDescriptorsById.at(
|
|
|
|
|
*(stackPointerTargetRegisterDescriptorIds.begin())
|
|
|
|
|
);
|
2022-02-05 15:32:08 +00:00
|
|
|
|
2023-05-21 21:08:25 +01:00
|
|
|
auto stackPointerGdbRegisterDescriptor = RegisterDescriptor(
|
|
|
|
|
TargetDescriptor::STACK_POINTER_GDB_REGISTER_ID,
|
|
|
|
|
2,
|
|
|
|
|
"Stack Pointer Register"
|
|
|
|
|
);
|
2021-12-28 01:16:21 +00:00
|
|
|
|
2023-05-21 21:08:25 +01:00
|
|
|
if (stackPointerTargetRegisterDescriptor.size > stackPointerGdbRegisterDescriptor.size) {
|
2022-02-05 15:32:08 +00:00
|
|
|
throw Exception("AVR8 stack pointer target register size exceeds the GDB register size.");
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-21 21:08:25 +01:00
|
|
|
this->gdbRegisterIdsByTargetRegisterDescriptorId.emplace(
|
|
|
|
|
stackPointerTargetRegisterDescriptor.id,
|
|
|
|
|
stackPointerGdbRegisterDescriptor.id
|
|
|
|
|
);
|
|
|
|
|
this->targetRegisterDescriptorIdsByGdbRegisterId.emplace(
|
|
|
|
|
stackPointerGdbRegisterDescriptor.id,
|
|
|
|
|
stackPointerTargetRegisterDescriptor.id
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
this->gdbRegisterDescriptorsById.emplace(
|
|
|
|
|
stackPointerGdbRegisterDescriptor.id,
|
|
|
|
|
std::move(stackPointerGdbRegisterDescriptor)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* We acknowledge the GDB program counter register here, but we don't map it to any target register descriptors.
|
|
|
|
|
*
|
|
|
|
|
* This is because we can't access the program counter on AVR targets in the same way we do with other
|
|
|
|
|
* registers. We don't have a register descriptor for the program counter. We have to treat it as a special
|
|
|
|
|
* case in the register access command packet handlers. See CommandPackets::ReadRegister,
|
|
|
|
|
* CommandPackets::WriteRegister, etc for more.
|
|
|
|
|
*/
|
|
|
|
|
auto programCounterGdbRegisterDescriptor = RegisterDescriptor(
|
|
|
|
|
TargetDescriptor::PROGRAM_COUNTER_GDB_REGISTER_ID,
|
|
|
|
|
4,
|
|
|
|
|
"Program Counter"
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
this->gdbRegisterDescriptorsById.emplace(
|
|
|
|
|
programCounterGdbRegisterDescriptor.id,
|
|
|
|
|
std::move(programCounterGdbRegisterDescriptor)
|
|
|
|
|
);
|
2021-12-28 01:16:21 +00:00
|
|
|
}
|
2021-08-07 17:22:59 +01:00
|
|
|
}
|