#include "TargetDescriptionFile.hpp" #include "src/Services/PathService.hpp" #include "src/Services/StringService.hpp" #include "src/Logger/Logger.hpp" #include "src/Exceptions/Exception.hpp" #include "src/Targets/TargetDescription/Exceptions/TargetDescriptionParsingFailureException.hpp" namespace Targets::Microchip::Avr8 { using Targets::TargetDescription::RegisterGroup; using Targets::TargetDescription::AddressSpace; using Targets::TargetDescription::MemorySegment; using Targets::TargetDescription::Register; using Targets::TargetDescription::Exceptions::InvalidTargetDescriptionDataException; using Targets::TargetRegisterDescriptor; using Services::StringService; TargetDescriptionFile::TargetDescriptionFile(const std::string& xmlFilePath) : Targets::TargetDescription::TargetDescriptionFile(xmlFilePath) {} TargetSignature TargetDescriptionFile::getTargetSignature() const { const auto& signatureGroup = this->getPropertyGroup("signatures"); return { StringService::toUint8(signatureGroup.getProperty("signature0").value, 16), StringService::toUint8(signatureGroup.getProperty("signature1").value, 16), StringService::toUint8(signatureGroup.getProperty("signature2").value, 16) }; } Family TargetDescriptionFile::getAvrFamily() const { static const auto targetFamiliesByName = std::map{ {"MEGA", Family::MEGA}, {"XMEGA", Family::XMEGA}, {"TINY", Family::TINY}, {"DA", Family::DA}, {"DB", Family::DB}, {"DD", Family::DD}, {"EA", Family::EA}, }; const auto familyIt = targetFamiliesByName.find(this->getDeviceAttribute("avr-family")); if (familyIt == targetFamiliesByName.end()) { throw InvalidTargetDescriptionDataException{"Unknown AVR family name in target description file"}; } return familyIt->second; } const TargetDescription::AddressSpace& TargetDescriptionFile::getRegisterFileAddressSpace() const { /* * On some AVRs, the register file is accessible via the data address space. On the newer UPDI and PDI AVRs, * it has a dedicated address space. */ const auto addressSpace = this->tryGetAddressSpace("register_file"); return addressSpace.has_value() ? addressSpace->get() : this->getAddressSpace("data"); } const TargetDescription::AddressSpace& TargetDescriptionFile::getProgramAddressSpace() const { return this->getAddressSpace("prog"); } const TargetDescription::AddressSpace& TargetDescriptionFile::getDataAddressSpace() const { return this->getAddressSpace("data"); } const TargetDescription::AddressSpace& TargetDescriptionFile::getEepromAddressSpace() const { const auto addressSpace = this->tryGetAddressSpace("eeprom"); return addressSpace.has_value() ? addressSpace->get() : this->getAddressSpace("data"); } const TargetDescription::AddressSpace& TargetDescriptionFile::getIoAddressSpace() const { return this->getAddressSpace("data"); } const TargetDescription::AddressSpace& TargetDescriptionFile::getSignatureAddressSpace() const { const auto addressSpace = this->tryGetAddressSpace("signatures"); return addressSpace.has_value() ? addressSpace->get() : this->getAddressSpace("data"); } const TargetDescription::AddressSpace& TargetDescriptionFile::getFuseAddressSpace() const { const auto addressSpace = this->tryGetAddressSpace("fuses"); return addressSpace.has_value() ? addressSpace->get() : this->getAddressSpace("data"); } const TargetDescription::AddressSpace& TargetDescriptionFile::getLockbitAddressSpace() const { const auto addressSpace = this->tryGetAddressSpace("lockbits"); return addressSpace.has_value() ? addressSpace->get() : this->getAddressSpace("data"); } const TargetDescription::MemorySegment& TargetDescriptionFile::getProgramMemorySegment() const { return this->getProgramAddressSpace().getMemorySegment("internal_program_memory"); } const TargetDescription::MemorySegment& TargetDescriptionFile::getRamMemorySegment() const { return this->getDataAddressSpace().getMemorySegment("internal_ram"); } const TargetDescription::MemorySegment& TargetDescriptionFile::getEepromMemorySegment() const { return this->getEepromAddressSpace().getMemorySegment("internal_eeprom"); } const TargetDescription::MemorySegment& TargetDescriptionFile::getIoMemorySegment() const { const auto& addressSpace = this->getIoAddressSpace(); const auto segment = addressSpace.tryGetMemorySegment("io"); return segment.has_value() ? segment->get() : addressSpace.getMemorySegment("mapped_io"); } const TargetDescription::MemorySegment& TargetDescriptionFile::getSignatureMemorySegment() const { return this->getSignatureAddressSpace().getMemorySegment("signatures"); } const TargetDescription::MemorySegment& TargetDescriptionFile::getFuseMemorySegment() const { return this->getFuseAddressSpace().getMemorySegment("fuses"); } const TargetDescription::MemorySegment& TargetDescriptionFile::getLockbitMemorySegment() const { return this->getLockbitAddressSpace().getMemorySegment("lockbits"); } TargetAddressSpaceDescriptor TargetDescriptionFile::getDataAddressSpaceDescriptor() const { return this->targetAddressSpaceDescriptorFromAddressSpace(this->getDataAddressSpace()); } TargetAddressSpaceDescriptor TargetDescriptionFile::getFuseAddressSpaceDescriptor() const { return this->targetAddressSpaceDescriptorFromAddressSpace(this->getFuseAddressSpace()); } TargetMemorySegmentDescriptor TargetDescriptionFile::getRamMemorySegmentDescriptor() const { return this->targetMemorySegmentDescriptorFromMemorySegment( this->getRamMemorySegment(), this->getDataAddressSpace() ); } TargetMemorySegmentDescriptor TargetDescriptionFile::getFuseMemorySegmentDescriptor() const { return this->targetMemorySegmentDescriptorFromMemorySegment( this->getFuseMemorySegment(), this->getFuseAddressSpace() ); } TargetMemorySegmentDescriptor TargetDescriptionFile::getIoMemorySegmentDescriptor() const { return this->targetMemorySegmentDescriptorFromMemorySegment( this->getIoMemorySegment(), this->getIoAddressSpace() ); } TargetPeripheralDescriptor TargetDescriptionFile::getFuseTargetPeripheralDescriptor() const { return this->getTargetPeripheralDescriptor("fuse"); } Pair< TargetRegisterDescriptor, TargetBitFieldDescriptor > TargetDescriptionFile::getFuseRegisterBitFieldDescriptorPair(const std::string& fuseBitFieldKey) const { const auto peripheralDescriptor = this->getFuseTargetPeripheralDescriptor(); const auto pair = peripheralDescriptor.getRegisterGroupDescriptor("fuse").getRegisterBitFieldDescriptorPair( fuseBitFieldKey ); return {pair.first.clone(), pair.second.clone()}; } std::optional TargetDescriptionFile::getFuseEnableStrategy() const { const auto fuseEnabledValueProperty = this->tryGetProperty("programming_info", "fuse_enabled_value"); if (fuseEnabledValueProperty.has_value()) { if (fuseEnabledValueProperty->get().value == "0") { return FuseEnableStrategy::CLEAR; } if (fuseEnabledValueProperty->get().value == "1") { return FuseEnableStrategy::SET; } } return std::nullopt; } }