diff --git a/src/Targets/Microchip/AVR/AVR8/TargetDescription/TargetDescriptionFile.cpp b/src/Targets/Microchip/AVR/AVR8/TargetDescription/TargetDescriptionFile.cpp index 3034faf2..80fdcc23 100644 --- a/src/Targets/Microchip/AVR/AVR8/TargetDescription/TargetDescriptionFile.cpp +++ b/src/Targets/Microchip/AVR/AVR8/TargetDescription/TargetDescriptionFile.cpp @@ -12,6 +12,11 @@ using namespace Bloom::Targets::Microchip::Avr::Avr8Bit; using namespace Bloom::Targets::Microchip::Avr; using namespace Bloom::Exceptions; +using Bloom::Targets::TargetDescription::RegisterGroup; +using Bloom::Targets::TargetDescription::MemorySegment; +using Bloom::Targets::TargetDescription::MemorySegmentType; +using Bloom::Targets::TargetDescription::Register; + TargetDescriptionFile::TargetDescriptionFile( const TargetSignature& targetSignature, std::optional targetName @@ -147,3 +152,357 @@ Family TargetDescriptionFile::getFamily() const { return familyNameToEnums.at(familyName); } + +std::optional 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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; +} diff --git a/src/Targets/Microchip/AVR/AVR8/TargetDescription/TargetDescriptionFile.hpp b/src/Targets/Microchip/AVR/AVR8/TargetDescription/TargetDescriptionFile.hpp index f2dc6148..c757b0e3 100644 --- a/src/Targets/Microchip/AVR/AVR8/TargetDescription/TargetDescriptionFile.hpp +++ b/src/Targets/Microchip/AVR/AVR8/TargetDescription/TargetDescriptionFile.hpp @@ -71,5 +71,26 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit::TargetDescription * @return */ Family getFamily() const; + + std::optional getFlashMemorySegment() const; + std::optional getRamMemorySegment() const; + std::optional getRegisterMemorySegment() const; + std::optional getEepromMemorySegment() const; + std::optional getFirstBootSectionMemorySegment() const; + std::optional getCpuRegisterGroup() const; + std::optional getBootLoadRegisterGroup() const; + std::optional getEepromRegisterGroup() const; + std::optional getStatusRegister() const; + std::optional getStackPointerRegister() const; + std::optional getStackPointerHighRegister() const; + std::optional getStackPointerLowRegister() const; + std::optional getOscillatorCalibrationRegister() const; + std::optional getSpmcsRegister() const; + std::optional getSpmcRegister() const; + std::optional getEepromAddressRegister() const; + std::optional getEepromAddressLowRegister() const; + std::optional getEepromAddressHighRegister() const; + std::optional getEepromDataRegister() const; + std::optional getEepromControlRegister() const; }; } diff --git a/src/Targets/TargetDescription/TargetDescriptionFile.cpp b/src/Targets/TargetDescription/TargetDescriptionFile.cpp index 6cb56a8d..4e1a52df 100644 --- a/src/Targets/TargetDescription/TargetDescriptionFile.cpp +++ b/src/Targets/TargetDescription/TargetDescriptionFile.cpp @@ -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& 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& 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& 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 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 TargetDescriptionFile::getAddressSpacesMappe return output; } -std::optional 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 TargetDescriptionFile::getVariants() const { std::vector output; diff --git a/src/Targets/TargetDescription/TargetDescriptionFile.hpp b/src/Targets/TargetDescription/TargetDescriptionFile.hpp index eae2ba06..ad853d58 100644 --- a/src/Targets/TargetDescription/TargetDescriptionFile.hpp +++ b/src/Targets/TargetDescription/TargetDescriptionFile.hpp @@ -10,8 +10,6 @@ #include "Module.hpp" #include "Variant.hpp" #include "Pinout.hpp" -#include "src/Targets/Microchip/AVR/TargetSignature.hpp" -#include "src/Targets/Microchip/AVR/AVR8/Family.hpp" namespace Bloom::Targets::TargetDescription { @@ -48,25 +46,36 @@ namespace Bloom::Targets::TargetDescription mutable std::optional> cachedPinoutByNameMapping; /** - * Constructs an AddressSpace object from an XML element (in the form of a QDomElement), taken from a target - * description file. + * Constructs an AddressSpace object from an XML element. * * @param xmlElement * @return */ - AddressSpace generateAddressSpaceFromXml(const QDomElement& xmlElement) const; + static AddressSpace generateAddressSpaceFromXml(const QDomElement& xmlElement); /** - * Constructs a MemorySegment from an XML element (in the form of a QDomElement) taken from a target - * description file. + * Constructs a MemorySegment object from an XML element. * * @param xmlElement * @return */ - MemorySegment generateMemorySegmentFromXml(const QDomElement& xmlElement) const; - RegisterGroup generateRegisterGroupFromXml(const QDomElement& xmlElement) const; + static MemorySegment generateMemorySegmentFromXml(const QDomElement& xmlElement); - Register generateRegisterFromXml(const QDomElement& xmlElement) const; + /** + * Constructs a RegisterGroup object from an XML element. + * + * @param xmlElement + * @return + */ + static RegisterGroup generateRegisterGroupFromXml(const QDomElement& xmlElement); + + /** + * Constructs a Register object from an XML element. + * + * @param xmlElement + * @return + */ + static Register generateRegisterFromXml(const QDomElement& xmlElement); public: TargetDescriptionFile() = default; @@ -77,7 +86,7 @@ namespace Bloom::Targets::TargetDescription * * @param xmlFilePath */ - TargetDescriptionFile(const QString& xmlFilePath) { + explicit TargetDescriptionFile(const QString& xmlFilePath) { this->init(xmlFilePath); } @@ -86,14 +95,19 @@ namespace Bloom::Targets::TargetDescription * * @param xml */ - TargetDescriptionFile(const QDomDocument& xml) { + explicit TargetDescriptionFile(const QDomDocument& xml) { this->init(xml); } + /** + * Extracts target name. + * + * @return + */ std::string getTargetName() const; /** - * Extracts all address spaces for the AVR8 target, from the target description XML. + * Extracts all address spaces for the target. * * Will return a mapping of the extracted address spaces, mapped by id. * @@ -101,31 +115,40 @@ namespace Bloom::Targets::TargetDescription */ std::map getAddressSpacesMappedById() const; + /** + * Extracts all property groups and returns a mapping of them, with the property group name being the key. + * + * @return + */ const std::map& getPropertyGroupsMappedByName() const; + + /** + * Extracts all modules and returns a mapping of them, with the module name being the key. + * + * @return + */ const std::map& getModulesMappedByName() const; + + /** + * Extracts all peripheral modules and returns a mapping of this, with the peripheral module name being + * the key. + * + * @return + */ const std::map& getPeripheralModulesMappedByName() const; - std::optional getFlashMemorySegment() const; - std::optional getRamMemorySegment() const; - std::optional getRegisterMemorySegment() const; - std::optional getEepromMemorySegment() const; - std::optional getFirstBootSectionMemorySegment() const; - std::optional getCpuRegisterGroup() const; - std::optional getBootLoadRegisterGroup() const; - std::optional getEepromRegisterGroup() const; - std::optional getStatusRegister() const; - std::optional getStackPointerRegister() const; - std::optional getStackPointerHighRegister() const; - std::optional getStackPointerLowRegister() const; - std::optional getOscillatorCalibrationRegister() const; - std::optional getSpmcsRegister() const; - std::optional getSpmcRegister() const; - std::optional getEepromAddressRegister() const; - std::optional getEepromAddressLowRegister() const; - std::optional getEepromAddressHighRegister() const; - std::optional getEepromDataRegister() const; - std::optional getEepromControlRegister() const; + /** + * Extracts all variants. + * + * @return + */ std::vector getVariants() const; + + /** + * Extracts all pinouts and returns a mapping of them, with the pinout name being the key. + * + * @return + */ const std::map& getPinoutsMappedByName() const; }; }