2022-03-24 19:06:09 +00:00
|
|
|
#include "TargetDescriptor.hpp"
|
2021-08-07 17:22:59 +01:00
|
|
|
|
|
|
|
|
#include "src/Exceptions/Exception.hpp"
|
|
|
|
|
|
2023-08-13 15:47:51 +01:00
|
|
|
namespace DebugServer::Gdb::AvrGdb
|
2022-02-05 15:32:08 +00:00
|
|
|
{
|
2023-08-13 15:47:51 +01:00
|
|
|
using Targets::TargetRegisterDescriptor;
|
|
|
|
|
using Targets::TargetRegisterType;
|
2021-08-07 17:22:59 +01:00
|
|
|
|
2023-08-13 15:47:51 +01:00
|
|
|
using Exceptions::Exception;
|
2022-03-24 19:06:09 +00:00
|
|
|
|
2023-08-13 15:47:51 +01:00
|
|
|
TargetDescriptor::TargetDescriptor(const Targets::TargetDescriptor& targetDescriptor)
|
2024-07-23 21:14:22 +01:00
|
|
|
: programAddressSpaceDescriptor(targetDescriptor.getAddressSpaceDescriptor("prog"))
|
|
|
|
|
, eepromAddressSpaceDescriptor(targetDescriptor.getFirstAddressSpaceDescriptorContainingMemorySegment("internal_eeprom"))
|
|
|
|
|
, sramAddressSpaceDescriptor(targetDescriptor.getAddressSpaceDescriptor("data"))
|
|
|
|
|
, gpRegistersAddressSpaceDescriptor(targetDescriptor.getFirstAddressSpaceDescriptorContainingMemorySegment("gp_registers"))
|
|
|
|
|
, programMemorySegmentDescriptor(this->programAddressSpaceDescriptor.getMemorySegmentDescriptor("internal_program_memory"))
|
|
|
|
|
, eepromMemorySegmentDescriptor(this->eepromAddressSpaceDescriptor.getMemorySegmentDescriptor("internal_eeprom"))
|
|
|
|
|
, sramMemorySegmentDescriptor(this->sramAddressSpaceDescriptor.getMemorySegmentDescriptor("internal_ram"))
|
|
|
|
|
, gpRegistersMemorySegmentDescriptor(this->gpRegistersAddressSpaceDescriptor.getMemorySegmentDescriptor("gp_registers"))
|
|
|
|
|
, cpuGpPeripheralDescriptor(targetDescriptor.getPeripheralDescriptor("cpu_gpr"))
|
|
|
|
|
, cpuGpRegisterGroupDescriptor(this->cpuGpPeripheralDescriptor.getRegisterGroupDescriptor("gpr"))
|
2022-03-24 19:06:09 +00:00
|
|
|
{
|
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)
|
2024-07-23 21:14:22 +01:00
|
|
|
* - Register ID 33 is the stack pointer register (SP)
|
|
|
|
|
* - Register ID 34 is the program counter (PC)
|
2022-02-05 15:32:08 +00:00
|
|
|
*/
|
|
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
// Create the GDB register descriptors and populate the mappings for the general purpose registers (ID 0->31)
|
|
|
|
|
for (const auto& [key, descriptor] : this->cpuGpRegisterGroupDescriptor.registerDescriptorsByKey) {
|
|
|
|
|
if (descriptor.type != TargetRegisterType::GENERAL_PURPOSE_REGISTER) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2023-05-21 21:08:25 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
const auto gdbRegisterId = static_cast<GdbRegisterId>(
|
|
|
|
|
descriptor.startAddress - this->gpRegistersMemorySegmentDescriptor.addressRange.startAddress
|
|
|
|
|
);
|
2023-05-21 21:08:25 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
this->gdbRegisterDescriptorsById.emplace(gdbRegisterId, RegisterDescriptor{gdbRegisterId, 1});
|
|
|
|
|
this->targetRegisterDescriptorsByGdbId.emplace(gdbRegisterId, &descriptor);
|
2022-02-05 15:32:08 +00:00
|
|
|
}
|
2021-08-07 17:22:59 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
this->gdbRegisterDescriptorsById.emplace(
|
|
|
|
|
TargetDescriptor::STATUS_GDB_REGISTER_ID,
|
|
|
|
|
RegisterDescriptor{TargetDescriptor::STATUS_GDB_REGISTER_ID, 1}
|
2023-05-21 21:08:25 +01:00
|
|
|
);
|
2024-07-23 21:14:22 +01:00
|
|
|
this->targetRegisterDescriptorsByGdbId.emplace(
|
2023-05-21 21:08:25 +01:00
|
|
|
TargetDescriptor::STATUS_GDB_REGISTER_ID,
|
2024-07-23 21:14:22 +01:00
|
|
|
&(targetDescriptor.getPeripheralDescriptor("cpu").getRegisterGroupDescriptor("cpu")
|
|
|
|
|
.getRegisterDescriptor("sreg"))
|
2022-02-05 15:32:08 +00:00
|
|
|
);
|
2021-08-07 17:22:59 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
/*
|
|
|
|
|
* We don't map the SP and PC GDB register IDs to target register descriptors because of inconsistencies.
|
|
|
|
|
* The register command handlers will deal with these registers separately. See CommandPackets::ReadRegister,
|
|
|
|
|
* CommandPackets::WriteRegister, etc for more.
|
|
|
|
|
*/
|
|
|
|
|
this->gdbRegisterDescriptorsById.emplace(
|
|
|
|
|
TargetDescriptor::STACK_POINTER_GDB_REGISTER_ID,
|
|
|
|
|
RegisterDescriptor{TargetDescriptor::STACK_POINTER_GDB_REGISTER_ID, 2}
|
2022-02-05 15:32:08 +00:00
|
|
|
);
|
|
|
|
|
|
2023-05-21 21:08:25 +01:00
|
|
|
this->gdbRegisterDescriptorsById.emplace(
|
2024-07-23 21:14:22 +01:00
|
|
|
TargetDescriptor::PROGRAM_COUNTER_GDB_REGISTER_ID,
|
|
|
|
|
RegisterDescriptor{TargetDescriptor::PROGRAM_COUNTER_GDB_REGISTER_ID, 4}
|
2022-02-05 15:32:08 +00:00
|
|
|
);
|
2024-07-23 21:14:22 +01:00
|
|
|
}
|
2021-08-07 17:22:59 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
const Targets::TargetAddressSpaceDescriptor& TargetDescriptor::addressSpaceDescriptorFromGdbAddress(
|
|
|
|
|
GdbMemoryAddress address
|
|
|
|
|
) const {
|
|
|
|
|
if ((address & TargetDescriptor::EEPROM_ADDRESS_MASK) == TargetDescriptor::EEPROM_ADDRESS_MASK) {
|
|
|
|
|
return this->eepromAddressSpaceDescriptor;
|
|
|
|
|
}
|
2022-02-05 15:32:08 +00:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
if ((address & TargetDescriptor::SRAM_ADDRESS_MASK) == TargetDescriptor::SRAM_ADDRESS_MASK) {
|
|
|
|
|
return this->sramAddressSpaceDescriptor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return this->programAddressSpaceDescriptor;
|
|
|
|
|
}
|
2021-12-28 01:16:21 +00:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
Targets::TargetMemoryAddress TargetDescriptor::translateGdbAddress(GdbMemoryAddress address) const {
|
|
|
|
|
if ((address & TargetDescriptor::EEPROM_ADDRESS_MASK) == TargetDescriptor::EEPROM_ADDRESS_MASK) {
|
|
|
|
|
// GDB sends EEPROM addresses in relative form - convert them to absolute form.
|
|
|
|
|
return this->eepromMemorySegmentDescriptor.addressRange.startAddress
|
|
|
|
|
+ (address & ~(TargetDescriptor::EEPROM_ADDRESS_MASK));
|
2022-02-05 15:32:08 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
if ((address & TargetDescriptor::SRAM_ADDRESS_MASK) == TargetDescriptor::SRAM_ADDRESS_MASK) {
|
|
|
|
|
return address & ~(TargetDescriptor::SRAM_ADDRESS_MASK);
|
|
|
|
|
}
|
2023-05-21 21:08:25 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
return address;
|
|
|
|
|
}
|
2023-05-21 21:08:25 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
GdbMemoryAddress TargetDescriptor::translateTargetMemoryAddress(
|
|
|
|
|
Targets::TargetMemoryAddress address,
|
|
|
|
|
const Targets::TargetAddressSpaceDescriptor& addressSpaceDescriptor,
|
|
|
|
|
const Targets::TargetMemorySegmentDescriptor& memorySegmentDescriptor
|
|
|
|
|
) const {
|
|
|
|
|
if (memorySegmentDescriptor.type == Targets::TargetMemorySegmentType::FLASH) {
|
|
|
|
|
return address;
|
|
|
|
|
}
|
2023-05-21 21:08:25 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
if (memorySegmentDescriptor.type == Targets::TargetMemorySegmentType::EEPROM) {
|
|
|
|
|
// GDB expects EEPROM addresses in relative form
|
|
|
|
|
return (address - memorySegmentDescriptor.addressRange.startAddress)
|
|
|
|
|
| TargetDescriptor::EEPROM_ADDRESS_MASK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// We assume everything else is SRAM
|
|
|
|
|
return address | TargetDescriptor::SRAM_ADDRESS_MASK;
|
2021-12-28 01:16:21 +00:00
|
|
|
}
|
2021-08-07 17:22:59 +01:00
|
|
|
}
|