From 47e92157f7b7dbb2cb4ee3dd2d329bc3f6943475 Mon Sep 17 00:00:00 2001 From: Nav Date: Sat, 16 Mar 2024 00:06:53 +0000 Subject: [PATCH] Added target address space and memory segment descriptor structs --- src/Targets/TargetAddressSpaceDescriptor.hpp | 69 +++++++++++++++++++ .../TargetDescriptionFile.cpp | 50 ++++++++++++++ .../TargetDescriptionFile.hpp | 12 ++++ src/Targets/TargetMemorySegmentDescriptor.hpp | 43 ++++++++++++ 4 files changed, 174 insertions(+) create mode 100644 src/Targets/TargetAddressSpaceDescriptor.hpp create mode 100644 src/Targets/TargetMemorySegmentDescriptor.hpp diff --git a/src/Targets/TargetAddressSpaceDescriptor.hpp b/src/Targets/TargetAddressSpaceDescriptor.hpp new file mode 100644 index 00000000..fe279c1e --- /dev/null +++ b/src/Targets/TargetAddressSpaceDescriptor.hpp @@ -0,0 +1,69 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "TargetMemory.hpp" +#include "TargetMemorySegmentDescriptor.hpp" +#include "src/Exceptions/InternalFatalErrorException.hpp" + +namespace Targets +{ + using TargetAddressSpaceDescriptorId = std::uint8_t; + + struct TargetAddressSpaceDescriptor + { + public: + const TargetAddressSpaceDescriptorId id; + std::string key; + TargetMemoryAddress startAddress; + TargetMemorySize size; + TargetMemoryEndianness endianness; + std::map segmentDescriptorsByKey; + + TargetAddressSpaceDescriptor( + const std::string& key, + TargetMemoryAddress startAddress, + TargetMemorySize size, + TargetMemoryEndianness endianness, + const std::map& segmentDescriptorsByKey + ) + : id(++(TargetAddressSpaceDescriptor::lastAddressSpaceDescriptorId)) + , key(key) + , startAddress(startAddress) + , size(size) + , endianness(endianness) + , segmentDescriptorsByKey(segmentDescriptorsByKey) + {}; + + std::optional> tryGetMemorySegmentDescriptor( + const std::string& key + ) const { + const auto segmentIt = this->segmentDescriptorsByKey.find(key); + + if (segmentIt == this->segmentDescriptorsByKey.end()) { + return std::nullopt; + } + + return std::cref(segmentIt->second); + } + + const TargetMemorySegmentDescriptor& getMemorySegmentDescriptor(const std::string& key) const { + const auto segment = this->tryGetMemorySegmentDescriptor(key); + if (!segment.has_value()) { + throw Exceptions::InternalFatalErrorException( + "Failed to get memory segment descriptor \"" + key + "\" from address space \"" + this->key + + "\" - segment not found" + ); + } + + return segment->get(); + } + + private: + static inline std::atomic lastAddressSpaceDescriptorId = 0; + }; +} diff --git a/src/Targets/TargetDescription/TargetDescriptionFile.cpp b/src/Targets/TargetDescription/TargetDescriptionFile.cpp index 7bd040a4..93b6ac3b 100644 --- a/src/Targets/TargetDescription/TargetDescriptionFile.cpp +++ b/src/Targets/TargetDescription/TargetDescriptionFile.cpp @@ -159,6 +159,20 @@ namespace Targets::TargetDescription return peripheral->get(); } + std::map< + TargetAddressSpaceDescriptorId, + TargetAddressSpaceDescriptor + > TargetDescriptionFile::targetAddressSpaceDescriptorsById() const { + auto output = std::map(); + + for (const auto& [key, addressSpace] : this->addressSpacesByKey) { + auto descriptor = this->targetAddressSpaceDescriptorFromAddressSpace(addressSpace); + output.emplace(descriptor.id, std::move(descriptor)); + } + + return output; + } + void TargetDescriptionFile::init(const std::string& xmlFilePath) { auto file = QFile(QString::fromStdString(xmlFilePath)); if (!file.exists()) { @@ -675,4 +689,40 @@ namespace Targets::TargetDescription TargetDescriptionFile::getAttribute(xmlElement, "package") ); } + + TargetAddressSpaceDescriptor TargetDescriptionFile::targetAddressSpaceDescriptorFromAddressSpace( + const AddressSpace& addressSpace + ) { + auto output = TargetAddressSpaceDescriptor( + addressSpace.key, + addressSpace.startAddress, + addressSpace.size, + addressSpace.endianness.value_or(TargetMemoryEndianness::LITTLE), + {} + ); + + for (const auto& [key, memorySegment] : addressSpace.memorySegmentsByKey) { + output.segmentDescriptorsByKey.emplace( + key, + TargetDescriptionFile::targetMemorySegmentDescriptorFromMemorySegment(memorySegment) + ); + } + + return output; + } + + TargetMemorySegmentDescriptor TargetDescriptionFile::targetMemorySegmentDescriptorFromMemorySegment( + const MemorySegment& memorySegment + ) { + return TargetMemorySegmentDescriptor( + memorySegment.key, + memorySegment.name, + memorySegment.type, + memorySegment.startAddress, + memorySegment.size, + memorySegment.access, + memorySegment.access, + memorySegment.pageSize + ); + } } diff --git a/src/Targets/TargetDescription/TargetDescriptionFile.hpp b/src/Targets/TargetDescription/TargetDescriptionFile.hpp index 77691622..a8581434 100644 --- a/src/Targets/TargetDescription/TargetDescriptionFile.hpp +++ b/src/Targets/TargetDescription/TargetDescriptionFile.hpp @@ -26,6 +26,8 @@ #include "Variant.hpp" #include "src/Targets/TargetFamily.hpp" +#include "src/Targets/TargetAddressSpaceDescriptor.hpp" +#include "src/Targets/TargetMemorySegmentDescriptor.hpp" #include "src/Targets/TargetPhysicalInterface.hpp" namespace Targets::TargetDescription @@ -103,6 +105,8 @@ namespace Targets::TargetDescription ) const; [[nodiscard]] const Peripheral& getPeripheral(std::string_view key) const; + std::map targetAddressSpaceDescriptorsById() const; + protected: std::map deviceAttributesByName; std::map> propertyGroupsByKey; @@ -147,5 +151,13 @@ namespace Targets::TargetDescription static Pinout pinoutFromXml(const QDomElement& xmlElement); static Pin pinFromXml(const QDomElement& xmlElement); static Variant variantFromXml(const QDomElement& xmlElement); + + static TargetAddressSpaceDescriptor targetAddressSpaceDescriptorFromAddressSpace( + const AddressSpace& addressSpace + ); + + static TargetMemorySegmentDescriptor targetMemorySegmentDescriptorFromMemorySegment( + const MemorySegment& memorySegment + ); }; } diff --git a/src/Targets/TargetMemorySegmentDescriptor.hpp b/src/Targets/TargetMemorySegmentDescriptor.hpp new file mode 100644 index 00000000..00e99aa6 --- /dev/null +++ b/src/Targets/TargetMemorySegmentDescriptor.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include +#include + +#include "TargetMemory.hpp" +#include "TargetMemorySegmentType.hpp" + +namespace Targets +{ + struct TargetMemorySegmentDescriptor + { + public: + std::string key; + std::string name; + TargetMemorySegmentType type; + TargetMemoryAddress startAddress; + TargetMemorySize size; + TargetMemoryAccess debugModeAccess; + TargetMemoryAccess programmingModeAccess; + std::optional pageSize; + + TargetMemorySegmentDescriptor( + const std::string& key, + const std::string& name, + TargetMemorySegmentType type, + TargetMemoryAddress startAddress, + TargetMemorySize size, + const TargetMemoryAccess& debugModeAccess, + const TargetMemoryAccess& programmingModeAccess, + std::optional pageSize + ) + : key(key) + , name(name) + , type(type) + , startAddress(startAddress) + , size(size) + , debugModeAccess(debugModeAccess) + , programmingModeAccess(programmingModeAccess) + , pageSize(pageSize) + {}; + }; +}