Moved AVR8 specific TDF parsing to AVR8 derivation of TDF class.
Also some other small tweaks to TDF function qualifiers Also improved some comments
This commit is contained in:
@@ -37,7 +37,7 @@ std::string TargetDescriptionFile::getTargetName() const {
|
||||
return this->deviceElement.attributes().namedItem("name").nodeValue().toStdString();
|
||||
}
|
||||
|
||||
AddressSpace TargetDescriptionFile::generateAddressSpaceFromXml(const QDomElement& xmlElement) const {
|
||||
AddressSpace TargetDescriptionFile::generateAddressSpaceFromXml(const QDomElement& xmlElement) {
|
||||
if (
|
||||
!xmlElement.hasAttribute("id")
|
||||
|| !xmlElement.hasAttribute("name")
|
||||
@@ -73,7 +73,9 @@ AddressSpace TargetDescriptionFile::generateAddressSpaceFromXml(const QDomElemen
|
||||
auto& memorySegments = addressSpace.memorySegmentsByTypeAndName;
|
||||
for (int segmentIndex = 0; segmentIndex < segmentNodes.count(); segmentIndex++) {
|
||||
try {
|
||||
auto segment = this->generateMemorySegmentFromXml(segmentNodes.item(segmentIndex).toElement());
|
||||
auto segment = TargetDescriptionFile::generateMemorySegmentFromXml(
|
||||
segmentNodes.item(segmentIndex).toElement()
|
||||
);
|
||||
|
||||
if (memorySegments.find(segment.type) == memorySegments.end()) {
|
||||
memorySegments.insert(
|
||||
@@ -94,7 +96,7 @@ AddressSpace TargetDescriptionFile::generateAddressSpaceFromXml(const QDomElemen
|
||||
return addressSpace;
|
||||
}
|
||||
|
||||
MemorySegment TargetDescriptionFile::generateMemorySegmentFromXml(const QDomElement& xmlElement) const {
|
||||
MemorySegment TargetDescriptionFile::generateMemorySegmentFromXml(const QDomElement& xmlElement) {
|
||||
if (
|
||||
!xmlElement.hasAttribute("type")
|
||||
|| !xmlElement.hasAttribute("name")
|
||||
@@ -144,7 +146,7 @@ MemorySegment TargetDescriptionFile::generateMemorySegmentFromXml(const QDomElem
|
||||
return segment;
|
||||
}
|
||||
|
||||
RegisterGroup TargetDescriptionFile::generateRegisterGroupFromXml(const QDomElement& xmlElement) const {
|
||||
RegisterGroup TargetDescriptionFile::generateRegisterGroupFromXml(const QDomElement& xmlElement) {
|
||||
if (!xmlElement.hasAttribute("name")) {
|
||||
throw Exception("Missing register group name attribute");
|
||||
}
|
||||
@@ -164,7 +166,9 @@ RegisterGroup TargetDescriptionFile::generateRegisterGroupFromXml(const QDomElem
|
||||
auto registerNodes = xmlElement.elementsByTagName("register");
|
||||
for (int registerIndex = 0; registerIndex < registerNodes.count(); registerIndex++) {
|
||||
try {
|
||||
auto reg = this->generateRegisterFromXml(registerNodes.item(registerIndex).toElement());
|
||||
auto reg = TargetDescriptionFile::generateRegisterFromXml(
|
||||
registerNodes.item(registerIndex).toElement()
|
||||
);
|
||||
registers.insert(std::pair(reg.name, reg));
|
||||
|
||||
} catch (const Exception& exception) {
|
||||
@@ -176,7 +180,7 @@ RegisterGroup TargetDescriptionFile::generateRegisterGroupFromXml(const QDomElem
|
||||
return registerGroup;
|
||||
}
|
||||
|
||||
Register TargetDescriptionFile::generateRegisterFromXml(const QDomElement& xmlElement) const {
|
||||
Register TargetDescriptionFile::generateRegisterFromXml(const QDomElement& xmlElement) {
|
||||
if (
|
||||
!xmlElement.hasAttribute("name")
|
||||
|| !xmlElement.hasAttribute("offset")
|
||||
@@ -255,7 +259,9 @@ const std::map<std::string, Module>& TargetDescriptionFile::getModulesMappedByNa
|
||||
|
||||
auto registerGroupNodes = moduleElement.elementsByTagName("register-group");
|
||||
for (int registerGroupIndex = 0; registerGroupIndex < registerGroupNodes.count(); registerGroupIndex++) {
|
||||
auto registerGroup = this->generateRegisterGroupFromXml(registerGroupNodes.item(registerGroupIndex).toElement());
|
||||
auto registerGroup = TargetDescriptionFile::generateRegisterGroupFromXml(
|
||||
registerGroupNodes.item(registerGroupIndex).toElement()
|
||||
);
|
||||
|
||||
module.registerGroupsMappedByName.insert(std::pair(registerGroup.name, registerGroup));
|
||||
}
|
||||
@@ -283,7 +289,9 @@ const std::map<std::string, Module>& TargetDescriptionFile::getPeripheralModules
|
||||
|
||||
auto registerGroupNodes = moduleElement.elementsByTagName("register-group");
|
||||
for (int registerGroupIndex = 0; registerGroupIndex < registerGroupNodes.count(); registerGroupIndex++) {
|
||||
auto registerGroup = this->generateRegisterGroupFromXml(registerGroupNodes.item(registerGroupIndex).toElement());
|
||||
auto registerGroup = TargetDescriptionFile::generateRegisterGroupFromXml(
|
||||
registerGroupNodes.item(registerGroupIndex).toElement()
|
||||
);
|
||||
|
||||
module.registerGroupsMappedByName.insert(std::pair(registerGroup.name, registerGroup));
|
||||
}
|
||||
@@ -296,7 +304,9 @@ const std::map<std::string, Module>& TargetDescriptionFile::getPeripheralModules
|
||||
|
||||
auto registerGroupNodes = instanceXml.elementsByTagName("register-group");
|
||||
for (int registerGroupIndex = 0; registerGroupIndex < registerGroupNodes.count(); registerGroupIndex++) {
|
||||
auto registerGroup = this->generateRegisterGroupFromXml(registerGroupNodes.item(registerGroupIndex).toElement());
|
||||
auto registerGroup = TargetDescriptionFile::generateRegisterGroupFromXml(
|
||||
registerGroupNodes.item(registerGroupIndex).toElement()
|
||||
);
|
||||
|
||||
instance.registerGroupsMappedByName.insert(std::pair(registerGroup.name, registerGroup));
|
||||
}
|
||||
@@ -345,7 +355,9 @@ std::map<std::string, AddressSpace> TargetDescriptionFile::getAddressSpacesMappe
|
||||
|
||||
for (int addressSpaceIndex = 0; addressSpaceIndex < addressSpaceNodes.count(); addressSpaceIndex++) {
|
||||
try {
|
||||
auto addressSpace = this->generateAddressSpaceFromXml(addressSpaceNodes.item(addressSpaceIndex).toElement());
|
||||
auto addressSpace = TargetDescriptionFile::generateAddressSpaceFromXml(
|
||||
addressSpaceNodes.item(addressSpaceIndex).toElement()
|
||||
);
|
||||
output.insert(std::pair(addressSpace.id, addressSpace));
|
||||
|
||||
} catch (const Exception& exception) {
|
||||
@@ -356,360 +368,6 @@ std::map<std::string, AddressSpace> TargetDescriptionFile::getAddressSpacesMappe
|
||||
return output;
|
||||
}
|
||||
|
||||
std::optional<MemorySegment> TargetDescriptionFile::getFlashMemorySegment() const {
|
||||
auto addressMapping = this->getAddressSpacesMappedById();
|
||||
auto programAddressSpaceIt = addressMapping.find("prog");
|
||||
|
||||
// Flash memory attributes are typically found in memory segments within the program address space.
|
||||
if (programAddressSpaceIt != addressMapping.end()) {
|
||||
auto& programAddressSpace = programAddressSpaceIt->second;
|
||||
auto& programMemorySegments = programAddressSpace.memorySegmentsByTypeAndName;
|
||||
|
||||
if (programMemorySegments.find(MemorySegmentType::FLASH) != programMemorySegments.end()) {
|
||||
auto& flashMemorySegments = programMemorySegments.find(MemorySegmentType::FLASH)->second;
|
||||
|
||||
/*
|
||||
* In AVR8 TDFs, flash memory segments are typically named "APP_SECTION", "PROGMEM" or "FLASH".
|
||||
*/
|
||||
auto flashSegmentIt = flashMemorySegments.find("app_section") != flashMemorySegments.end() ?
|
||||
flashMemorySegments.find("app_section")
|
||||
: flashMemorySegments.find("progmem") != flashMemorySegments.end()
|
||||
? flashMemorySegments.find("progmem") : flashMemorySegments.find("flash");
|
||||
|
||||
if (flashSegmentIt != flashMemorySegments.end()) {
|
||||
return flashSegmentIt->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<MemorySegment> TargetDescriptionFile::getRamMemorySegment() const {
|
||||
auto addressMapping = this->getAddressSpacesMappedById();
|
||||
|
||||
// Internal RAM ®ister attributes are usually found in the data address space
|
||||
auto dataAddressSpaceIt = addressMapping.find("data");
|
||||
|
||||
if (dataAddressSpaceIt != addressMapping.end()) {
|
||||
auto& dataAddressSpace = dataAddressSpaceIt->second;
|
||||
auto& dataMemorySegments = dataAddressSpace.memorySegmentsByTypeAndName;
|
||||
|
||||
if (dataMemorySegments.find(MemorySegmentType::RAM) != dataMemorySegments.end()) {
|
||||
auto& ramMemorySegments = dataMemorySegments.find(MemorySegmentType::RAM)->second;
|
||||
auto ramMemorySegmentIt = ramMemorySegments.begin();
|
||||
|
||||
if (ramMemorySegmentIt != ramMemorySegments.end()) {
|
||||
return ramMemorySegmentIt->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<MemorySegment> TargetDescriptionFile::getRegisterMemorySegment() const {
|
||||
auto addressMapping = this->getAddressSpacesMappedById();
|
||||
|
||||
// Internal RAM ®ister attributes are usually found in the data address space
|
||||
auto dataAddressSpaceIt = addressMapping.find("data");
|
||||
|
||||
if (dataAddressSpaceIt != addressMapping.end()) {
|
||||
auto& dataAddressSpace = dataAddressSpaceIt->second;
|
||||
auto& dataMemorySegments = dataAddressSpace.memorySegmentsByTypeAndName;
|
||||
|
||||
if (dataMemorySegments.find(MemorySegmentType::REGISTERS) != dataMemorySegments.end()) {
|
||||
auto& registerMemorySegments = dataMemorySegments.find(MemorySegmentType::REGISTERS)->second;
|
||||
auto registerMemorySegmentIt = registerMemorySegments.begin();
|
||||
|
||||
if (registerMemorySegmentIt != registerMemorySegments.end()) {
|
||||
return registerMemorySegmentIt->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<MemorySegment> TargetDescriptionFile::getEepromMemorySegment() const {
|
||||
auto addressMapping = this->getAddressSpacesMappedById();
|
||||
|
||||
if (addressMapping.contains("eeprom")) {
|
||||
auto& eepromAddressSpace = addressMapping.at("eeprom");
|
||||
auto& eepromAddressSpaceSegments = eepromAddressSpace.memorySegmentsByTypeAndName;
|
||||
|
||||
if (eepromAddressSpaceSegments.contains(MemorySegmentType::EEPROM)) {
|
||||
return eepromAddressSpaceSegments.at(MemorySegmentType::EEPROM).begin()->second;
|
||||
}
|
||||
|
||||
} else {
|
||||
// The EEPROM memory segment may be part of the data address space
|
||||
if (addressMapping.contains("data")) {
|
||||
auto dataAddressSpace = addressMapping.at("data");
|
||||
|
||||
if (dataAddressSpace.memorySegmentsByTypeAndName.contains(MemorySegmentType::EEPROM)) {
|
||||
return dataAddressSpace.memorySegmentsByTypeAndName.at(MemorySegmentType::EEPROM).begin()->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<MemorySegment> TargetDescriptionFile::getFirstBootSectionMemorySegment() const {
|
||||
auto addressMapping = this->getAddressSpacesMappedById();
|
||||
auto programAddressSpaceIt = addressMapping.find("prog");
|
||||
|
||||
if (programAddressSpaceIt != addressMapping.end()) {
|
||||
auto& programAddressSpace = programAddressSpaceIt->second;
|
||||
auto& programMemorySegments = programAddressSpace.memorySegmentsByTypeAndName;
|
||||
|
||||
if (programMemorySegments.find(MemorySegmentType::FLASH) != programMemorySegments.end()) {
|
||||
auto& flashMemorySegments = programMemorySegments.find(MemorySegmentType::FLASH)->second;
|
||||
|
||||
if (flashMemorySegments.contains("boot_section_1")) {
|
||||
return flashMemorySegments.at("boot_section_1");
|
||||
|
||||
} else if (flashMemorySegments.contains("boot_section")) {
|
||||
return flashMemorySegments.at("boot_section");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<RegisterGroup> TargetDescriptionFile::getCpuRegisterGroup() const {
|
||||
auto& modulesByName = this->getModulesMappedByName();
|
||||
|
||||
if (modulesByName.find("cpu") != modulesByName.end()) {
|
||||
auto cpuModule = modulesByName.find("cpu")->second;
|
||||
auto cpuRegisterGroupIt = cpuModule.registerGroupsMappedByName.find("cpu");
|
||||
|
||||
if (cpuRegisterGroupIt != cpuModule.registerGroupsMappedByName.end()) {
|
||||
return cpuRegisterGroupIt->second;
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<RegisterGroup> TargetDescriptionFile::getBootLoadRegisterGroup() const {
|
||||
auto& modulesByName = this->getModulesMappedByName();
|
||||
|
||||
if (modulesByName.contains("boot_load")) {
|
||||
auto& bootLoadModule = modulesByName.at("boot_load");
|
||||
auto bootLoadRegisterGroupIt = bootLoadModule.registerGroupsMappedByName.find("boot_load");
|
||||
|
||||
if (bootLoadRegisterGroupIt != bootLoadModule.registerGroupsMappedByName.end()) {
|
||||
return bootLoadRegisterGroupIt->second;
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<RegisterGroup> TargetDescriptionFile::getEepromRegisterGroup() const {
|
||||
auto& modulesByName = this->getModulesMappedByName();
|
||||
|
||||
if (modulesByName.find("eeprom") != modulesByName.end()) {
|
||||
auto eepromModule = modulesByName.find("eeprom")->second;
|
||||
auto eepromRegisterGroupIt = eepromModule.registerGroupsMappedByName.find("eeprom");
|
||||
|
||||
if (eepromRegisterGroupIt != eepromModule.registerGroupsMappedByName.end()) {
|
||||
return eepromRegisterGroupIt->second;
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<Register> TargetDescriptionFile::getStatusRegister() const {
|
||||
auto cpuRegisterGroup = this->getCpuRegisterGroup();
|
||||
|
||||
if (cpuRegisterGroup.has_value()) {
|
||||
auto statusRegisterIt = cpuRegisterGroup->registersMappedByName.find("sreg");
|
||||
|
||||
if (statusRegisterIt != cpuRegisterGroup->registersMappedByName.end()) {
|
||||
return statusRegisterIt->second;
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<Register> TargetDescriptionFile::getStackPointerRegister() const {
|
||||
auto cpuRegisterGroup = this->getCpuRegisterGroup();
|
||||
|
||||
if (cpuRegisterGroup.has_value()) {
|
||||
auto stackPointerRegisterIt = cpuRegisterGroup->registersMappedByName.find("sp");
|
||||
|
||||
if (stackPointerRegisterIt != cpuRegisterGroup->registersMappedByName.end()) {
|
||||
return stackPointerRegisterIt->second;
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<Register> TargetDescriptionFile::getStackPointerHighRegister() const {
|
||||
auto cpuRegisterGroup = this->getCpuRegisterGroup();
|
||||
|
||||
if (cpuRegisterGroup.has_value()) {
|
||||
auto stackPointerHighRegisterIt = cpuRegisterGroup->registersMappedByName.find("sph");
|
||||
|
||||
if (stackPointerHighRegisterIt != cpuRegisterGroup->registersMappedByName.end()) {
|
||||
return stackPointerHighRegisterIt->second;
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<Register> TargetDescriptionFile::getStackPointerLowRegister() const {
|
||||
auto cpuRegisterGroup = this->getCpuRegisterGroup();
|
||||
|
||||
if (cpuRegisterGroup.has_value()) {
|
||||
auto stackPointerLowRegisterIt = cpuRegisterGroup->registersMappedByName.find("spl");
|
||||
|
||||
if (stackPointerLowRegisterIt != cpuRegisterGroup->registersMappedByName.end()) {
|
||||
return stackPointerLowRegisterIt->second;
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<Register> TargetDescriptionFile::getOscillatorCalibrationRegister() const {
|
||||
auto cpuRegisterGroup = this->getCpuRegisterGroup();
|
||||
|
||||
if (cpuRegisterGroup.has_value()) {
|
||||
auto& cpuRegisters = cpuRegisterGroup->registersMappedByName;
|
||||
|
||||
if (cpuRegisters.contains("osccal")) {
|
||||
return cpuRegisters.at("osccal");
|
||||
|
||||
} else if (cpuRegisters.contains("osccal0")) {
|
||||
return cpuRegisters.at("osccal0");
|
||||
|
||||
} else if (cpuRegisters.contains("osccal1")) {
|
||||
return cpuRegisters.at("osccal1");
|
||||
|
||||
} else if (cpuRegisters.contains("fosccal")) {
|
||||
return cpuRegisters.at("fosccal");
|
||||
|
||||
} else if (cpuRegisters.contains("sosccala")) {
|
||||
return cpuRegisters.at("sosccala");
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<Register> TargetDescriptionFile::getSpmcsRegister() const {
|
||||
auto cpuRegisterGroup = this->getCpuRegisterGroup();
|
||||
|
||||
if (cpuRegisterGroup.has_value() && cpuRegisterGroup->registersMappedByName.contains("spmcsr")) {
|
||||
return cpuRegisterGroup->registersMappedByName.at("spmcsr");
|
||||
|
||||
} else {
|
||||
auto bootLoadRegisterGroup = this->getBootLoadRegisterGroup();
|
||||
|
||||
if (bootLoadRegisterGroup.has_value() && bootLoadRegisterGroup->registersMappedByName.contains("spmcsr")) {
|
||||
return bootLoadRegisterGroup->registersMappedByName.at("spmcsr");
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<Register> TargetDescriptionFile::getSpmcRegister() const {
|
||||
auto bootLoadRegisterGroup = this->getBootLoadRegisterGroup();
|
||||
|
||||
if (bootLoadRegisterGroup.has_value() && bootLoadRegisterGroup->registersMappedByName.contains("spmcr")) {
|
||||
return bootLoadRegisterGroup->registersMappedByName.at("spmcr");
|
||||
|
||||
} else {
|
||||
auto cpuRegisterGroup = this->getCpuRegisterGroup();
|
||||
|
||||
if (cpuRegisterGroup.has_value() && cpuRegisterGroup->registersMappedByName.contains("spmcr")) {
|
||||
return cpuRegisterGroup->registersMappedByName.at("spmcr");
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<Register> TargetDescriptionFile::getEepromAddressRegister() const {
|
||||
auto eepromRegisterGroup = this->getEepromRegisterGroup();
|
||||
|
||||
if (eepromRegisterGroup.has_value()) {
|
||||
auto eepromAddressRegisterIt = eepromRegisterGroup->registersMappedByName.find("eear");
|
||||
|
||||
if (eepromAddressRegisterIt != eepromRegisterGroup->registersMappedByName.end()) {
|
||||
return eepromAddressRegisterIt->second;
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<Register> TargetDescriptionFile::getEepromAddressLowRegister() const {
|
||||
auto eepromRegisterGroup = this->getEepromRegisterGroup();
|
||||
|
||||
if (eepromRegisterGroup.has_value()) {
|
||||
auto eepromAddressRegisterIt = eepromRegisterGroup->registersMappedByName.find("eearl");
|
||||
|
||||
if (eepromAddressRegisterIt != eepromRegisterGroup->registersMappedByName.end()) {
|
||||
return eepromAddressRegisterIt->second;
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<Register> TargetDescriptionFile::getEepromAddressHighRegister() const {
|
||||
auto eepromRegisterGroup = this->getEepromRegisterGroup();
|
||||
|
||||
if (eepromRegisterGroup.has_value()) {
|
||||
auto eepromAddressRegisterIt = eepromRegisterGroup->registersMappedByName.find("eearh");
|
||||
|
||||
if (eepromAddressRegisterIt != eepromRegisterGroup->registersMappedByName.end()) {
|
||||
return eepromAddressRegisterIt->second;
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<Register> TargetDescriptionFile::getEepromDataRegister() const {
|
||||
auto eepromRegisterGroup = this->getEepromRegisterGroup();
|
||||
|
||||
if (eepromRegisterGroup.has_value()) {
|
||||
auto eepromDataRegisterIt = eepromRegisterGroup->registersMappedByName.find("eedr");
|
||||
|
||||
if (eepromDataRegisterIt != eepromRegisterGroup->registersMappedByName.end()) {
|
||||
return eepromDataRegisterIt->second;
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<Register> TargetDescriptionFile::getEepromControlRegister() const {
|
||||
auto eepromRegisterGroup = this->getEepromRegisterGroup();
|
||||
|
||||
if (eepromRegisterGroup.has_value()) {
|
||||
auto eepromControlRegisterIt = eepromRegisterGroup->registersMappedByName.find("eecr");
|
||||
|
||||
if (eepromControlRegisterIt != eepromRegisterGroup->registersMappedByName.end()) {
|
||||
return eepromControlRegisterIt->second;
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::vector<Variant> TargetDescriptionFile::getVariants() const {
|
||||
std::vector<Variant> output;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user