Skip to content

Commit

Permalink
[rtemodel, projmgr] Update memory regions header generation
Browse files Browse the repository at this point in the history
  • Loading branch information
grasci-arm authored Sep 6, 2024
1 parent ece195b commit 929dd38
Show file tree
Hide file tree
Showing 14 changed files with 811 additions and 197 deletions.
3 changes: 2 additions & 1 deletion libs/rtemodel/include/RteTarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,8 @@ class RteTarget : public RteItem

void FilterComponents();
std::string GenerateRegionsHeaderContent() const;
std::string GenerateMemoryRegionContent(RteItem* memory, const std::string& id, bool bBoardMemory ) const;
std::string GenerateMemoryRegionContent(const std::vector<RteItem*> memVec, const std::string& id, const std::string& dfp) const;
std::pair<std::string, std::string> GetAccessAttributes(RteItem* mem) const;
bool GenerateRTEComponentsH();
bool GenerateRteHeaderFile(const std::string& headerName, const std::string& content,
bool bRegionsHeader = false, const std::string& directory = EMPTY_STRING);
Expand Down
191 changes: 127 additions & 64 deletions libs/rtemodel/src/RteTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1725,45 +1725,53 @@ std::string RteTarget::GetRegionsHeader() const
return GetDeviceFolder() + "/regions_" + filename + ".h";
}

std::string RteTarget::GenerateMemoryRegionContent(RteItem* memory, const std::string& id, bool bBoardMemory) const
std::pair<std::string, std::string> RteTarget::GetAccessAttributes(RteItem* mem) const
{
return {
string(mem->IsReadAccess() ? "r" : "") +
(mem->IsWriteAccess() ? "w" : "") +
(mem->IsExecuteAccess() ? "x" : ""),
string(mem->IsPeripheralAccess() ? "p" : "") +
(mem->IsSecureAccess() ? "s" : "") +
(mem->IsNonSecureAccess() ? "n" : "") +
(mem->IsCallableAccess() ? "c" : "")
};
}

std::string RteTarget::GenerateMemoryRegionContent(const std::vector<RteItem*> memVec, const std::string& id, const std::string& dfp) const
{
bool bRam = memory->IsWriteAccess();
string name = memory->GetName();
ostringstream oss;
if(bBoardMemory) {
oss << "// <h> " << id << " (is region: " << name << " from BSP)" << RteUtils::LF_STRING;
} else {
oss << "// <h> " << id << " (is region: " << name << " from DFP)" << RteUtils::LF_STRING;
string pack, access, name, start, size;
bool unused = memVec.empty();
if (!unused) {
pack = memVec.front()->GetPackageID() == dfp ? "DFP" : "BSP";
access = GetAccessAttributes(memVec.front()).first;
for (const auto& mem : memVec) {
name += (mem == memVec.front() ? "" : "+") + mem->GetName();
}
start = memVec.front()->GetAttribute("start");
unsigned int decSize = 0;
ostringstream hexSize;
for (const auto& mem : memVec) {
decSize += stoul(mem->GetAttribute("size"), nullptr, 16);
}
hexSize << "0x" << uppercase << setfill('0') << setw(8) << hex << decSize;
size = hexSize.str();
}

string start = memory->GetAttribute("start");
ostringstream oss;
oss << "// <h> " << id << " (" << (unused ? "unused" :
"is " + access + " memory: " + name + " from " + pack) << ")" << RteUtils::LF_STRING;
oss << "// <o> Base address <0x0-0xFFFFFFFF:8>" << RteUtils::LF_STRING;
oss << "// <i> Defines base address of memory region." << RteUtils::LF_STRING;
oss << "// <i> Default: " << start << RteUtils::LF_STRING;
oss << "#define " << id << "_BASE " << start << RteUtils::LF_STRING;

string size = memory->GetAttribute("size");
oss << "// <o> Region size [bytes] <0x0-0xFFFFFFFF:8>" << RteUtils::LF_STRING;
oss << "// <i> Defines size of memory region." << RteUtils::LF_STRING;
oss << "// <i> Default: " << size << RteUtils::LF_STRING;
oss << "#define " << id << "_SIZE " << size << RteUtils::LF_STRING;

int defaultRegion = memory->IsDefault() ? 1 : 0;
oss << "// <q> Default region" << RteUtils::LF_STRING;
oss << "// <i> Enables memory region globally for the application." << RteUtils::LF_STRING;
oss << "#define " << id << "_DEFAULT " << defaultRegion << RteUtils::LF_STRING;

if (bRam) {
int noInit = memory->IsNoInit() ? 1 : 0;
oss << "// <q> No zero initialize" << RteUtils::LF_STRING;
oss << "// <i> Excludes region from zero initialization." << RteUtils::LF_STRING;
oss << "#define " << id << "_NOINIT " << noInit << RteUtils::LF_STRING;
} else {
int startup = memory->IsStartup() ? 1 : 0;
oss << "// <q> Startup" << RteUtils::LF_STRING;
oss << "// <i> Selects region to be used for startup code." << RteUtils::LF_STRING;
oss << "#define " << id << "_STARTUP " << startup << RteUtils::LF_STRING;
oss << "// <i> Defines base address of memory region." << (unused ? "" : " Default: " + start) << RteUtils::LF_STRING;
if (id == "__ROM0") {
oss << "// <i> Contains Startup and Vector Table" << RteUtils::LF_STRING;
}
if (id == "__RAM0") {
oss << "// <i> Contains uninitialized RAM, Stack, and Heap" << RteUtils::LF_STRING;
}
oss << "#define " << id << "_BASE " << (unused ? "0" : start) << RteUtils::LF_STRING;
oss << "// <o> Region size [bytes] <0x0-0xFFFFFFFF:8>" << RteUtils::LF_STRING;
oss << "// <i> Defines size of memory region." << (unused ? "" : " Default: " + size) << RteUtils::LF_STRING;
oss << "#define " << id << "_SIZE " << (unused ? "0" : size) << RteUtils::LF_STRING;
oss << "// </h>" << RteUtils::LF_STRING;
oss << RteUtils::LF_STRING;
return oss.str();
Expand All @@ -1776,31 +1784,72 @@ std::string RteTarget::GenerateRegionsHeaderContent() const
if (!device) {
return EMPTY_STRING;
}
vector<RteItem*> memRO;
vector<RteItem*> memRW;
unsigned int totalRW = 0;
auto& deviceMems = device->GetEffectiveProperties("memory", GetProcessorName());
for (auto mem : deviceMems) {
if (mem->IsWriteAccess()) {
memRW.push_back(mem);
totalRW += stoul(mem->GetAttribute("size"), nullptr, 16);
} else {
memRO.push_back(mem);
}
}
size_t nDeviceRO = memRO.size();
size_t nDeviceRW = memRW.size();

// get memory collections from device and board
Collection<RteDeviceProperty*> deviceMemCollection;
Collection<RteItem*> boardMemCollection;
deviceMemCollection = device->GetEffectiveProperties("memory", GetProcessorName());
RteBoard* board = GetBoard();
if (board) {
Collection<RteItem*> boardMemCollection;
for( auto mem : board->GetMemories(boardMemCollection)) {
if (mem->IsWriteAccess()) {
memRW.push_back(mem);
totalRW += stoul(mem->GetAttribute("size"), nullptr, 16);
} else {
memRO.push_back(mem);
board->GetMemories(boardMemCollection);
}

// init memory regions
unsigned int totalRW = 0;
map<string, vector<RteItem*>> memRO = { {"__ROM0",{}}, {"__ROM1",{}}, {"__ROM2",{}}, {"__ROM3",{}} };
map<string, vector<RteItem*>> memRW = { {"__RAM0",{}}, {"__RAM1",{}}, {"__RAM2",{}}, {"__RAM3",{}} };
vector<RteItem*> notAllocated;
auto init = [&](auto collection) {
for (auto mem : collection) {
if (mem->GetAttributeAsBool("default")) {
if (mem->IsWriteAccess()) {
totalRW += stoul(mem->GetAttribute("size"), nullptr, 16);
}
if (memRW.at("__RAM0").empty() && mem->IsWriteAccess() && mem->GetAttributeAsBool("uninit")) {
memRW.at("__RAM0").push_back(mem);
continue;
}
if (memRO.at("__ROM0").empty() && mem->IsExecuteAccess() && mem->GetAttributeAsBool("startup")) {
memRO.at("__ROM0").push_back(mem);
continue;
}
}
notAllocated.push_back(mem);
}
};
init(deviceMemCollection);
init(boardMemCollection);

// allocate remaining memory regions
for (auto it = notAllocated.begin(); it < notAllocated.end();) {
auto mem = *it;
bool allocated = false;
auto* dst = mem->IsWriteAccess() ? &memRW : mem->IsExecuteAccess() ? &memRO : nullptr;
if (dst && mem->GetAttributeAsBool("default")) {
for (auto& [_, alloc] : *dst) {
if (alloc.empty()) {
// free slot found
alloc.push_back(mem);
allocated = true;
break;
} else {
// search contiguous memory region (same pack, same access)
if ((mem->GetPackageID() == alloc.back()->GetPackageID()) &&
GetAccessAttributes(mem) == GetAccessAttributes(alloc.back()) &&
stoul(mem->GetAttribute("start"), nullptr, 16) == stoul(alloc.back()->GetAttribute("start"), nullptr, 16) +
stoul(alloc.back()->GetAttribute("size"), nullptr, 16)) {
alloc.push_back(mem);
allocated = true;
break;
}
}
}
}
if (allocated) {
it = notAllocated.erase(it);
} else {
it++;
}
}

ostringstream oss;
Expand All @@ -1818,20 +1867,16 @@ std::string RteTarget::GenerateRegionsHeaderContent() const

oss << "// <h> ROM Configuration" << RteUtils::LF_STRING;
oss << "// =======================" << RteUtils::LF_STRING;
for (size_t i = 0; i < memRO.size(); i++) {
RteItem* mem = memRO[i];
string id = string("__ROM") +RteUtils::LongToString(i);
oss << GenerateMemoryRegionContent(mem, id, i >= nDeviceRO);
for (const auto& [id, mem] : memRO) {
oss << GenerateMemoryRegionContent(mem, id, device->GetPackageID());
}
oss << "// </h>" << RteUtils::LF_STRING;
oss << RteUtils::LF_STRING;

oss << "// <h> RAM Configuration" << RteUtils::LF_STRING;
oss << "// =======================" << RteUtils::LF_STRING;
for (size_t i = 0; i < memRW.size(); i++) {
RteItem* mem = memRW[i];
string id = string("__RAM") + RteUtils::LongToString(i);
oss << GenerateMemoryRegionContent(mem, id, i >= nDeviceRW);
for (const auto& [id, mem] : memRW) {
oss << GenerateMemoryRegionContent(mem, id, device->GetPackageID());
}
oss << "// </h>" << RteUtils::LF_STRING;
oss << RteUtils::LF_STRING;
Expand All @@ -1843,6 +1888,24 @@ std::string RteTarget::GenerateRegionsHeaderContent() const
oss << "#define __HEAP_SIZE " << (totalRW >= 6144 ? "0x00000C00" : "0x00000000") << RteUtils::LF_STRING;
oss << "// </h>" << RteUtils::LF_STRING;

if (!notAllocated.empty()) {
oss << RteUtils::LF_STRING << "// <n> Resources that are not allocated to linker regions" << RteUtils::LF_STRING;
size_t maxNameLength = 0;
for (const auto& mem : notAllocated) {
size_t nameLength = mem->GetName().length();
if (nameLength > maxNameLength) {
maxNameLength = nameLength;
}
}
for (const auto& mem : notAllocated) {
oss << "// <i> ";
oss << left << setw(10) << GetAccessAttributes(mem).first + (mem->IsWriteAccess() ? " RAM:" : " ROM:");
oss << left << setw(maxNameLength + 12) << mem->GetName() + " from" + (mem->GetPackageID() == device->GetPackageID() ? " DFP:" : " BSP:");
oss << "BASE: " << mem->GetAttribute("start") << " SIZE: " << mem->GetAttribute("size");
oss << (mem->GetProcessorName().empty() ? "" : " Pname: " + mem->GetProcessorName()) << RteUtils::LF_STRING;
}
}

return oss.str();
}

Expand Down
84 changes: 62 additions & 22 deletions test/projects/RteTestM4/regions_RteTest_ARMCM4_FP_ref.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,82 @@

// <h> ROM Configuration
// =======================
// <h> __ROM0 (is region: FLASH from DFP)
// <h> __ROM0 (is rx memory: FLASH from DFP)
// <o> Base address <0x0-0xFFFFFFFF:8>
// <i> Defines base address of memory region.
// <i> Default: 0x00000000
// <i> Defines base address of memory region. Default: 0x00000000
// <i> Contains Startup and Vector Table
#define __ROM0_BASE 0x00000000
// <o> Region size [bytes] <0x0-0xFFFFFFFF:8>
// <i> Defines size of memory region.
// <i> Default: 0x00040000
// <i> Defines size of memory region. Default: 0x00040000
#define __ROM0_SIZE 0x00040000
// <q> Default region
// <i> Enables memory region globally for the application.
#define __ROM0_DEFAULT 1
// <q> Startup
// <i> Selects region to be used for startup code.
#define __ROM0_STARTUP 1
// </h>

// <h> __ROM1 (unused)
// <o> Base address <0x0-0xFFFFFFFF:8>
// <i> Defines base address of memory region.
#define __ROM1_BASE 0
// <o> Region size [bytes] <0x0-0xFFFFFFFF:8>
// <i> Defines size of memory region.
#define __ROM1_SIZE 0
// </h>

// <h> __ROM2 (unused)
// <o> Base address <0x0-0xFFFFFFFF:8>
// <i> Defines base address of memory region.
#define __ROM2_BASE 0
// <o> Region size [bytes] <0x0-0xFFFFFFFF:8>
// <i> Defines size of memory region.
#define __ROM2_SIZE 0
// </h>

// <h> __ROM3 (unused)
// <o> Base address <0x0-0xFFFFFFFF:8>
// <i> Defines base address of memory region.
#define __ROM3_BASE 0
// <o> Region size [bytes] <0x0-0xFFFFFFFF:8>
// <i> Defines size of memory region.
#define __ROM3_SIZE 0
// </h>

// </h>

// <h> RAM Configuration
// =======================
// <h> __RAM0 (is region: SRAM from DFP)
// <h> __RAM0 (is rwx memory: SRAM from DFP)
// <o> Base address <0x0-0xFFFFFFFF:8>
// <i> Defines base address of memory region.
// <i> Default: 0x20000000
// <i> Defines base address of memory region. Default: 0x20000000
// <i> Contains uninitialized RAM, Stack, and Heap
#define __RAM0_BASE 0x20000000
// <o> Region size [bytes] <0x0-0xFFFFFFFF:8>
// <i> Defines size of memory region.
// <i> Default: 0x00020000
// <i> Defines size of memory region. Default: 0x00020000
#define __RAM0_SIZE 0x00020000
// <q> Default region
// <i> Enables memory region globally for the application.
#define __RAM0_DEFAULT 1
// <q> No zero initialize
// <i> Excludes region from zero initialization.
#define __RAM0_NOINIT 1
// </h>

// <h> __RAM1 (unused)
// <o> Base address <0x0-0xFFFFFFFF:8>
// <i> Defines base address of memory region.
#define __RAM1_BASE 0
// <o> Region size [bytes] <0x0-0xFFFFFFFF:8>
// <i> Defines size of memory region.
#define __RAM1_SIZE 0
// </h>

// <h> __RAM2 (unused)
// <o> Base address <0x0-0xFFFFFFFF:8>
// <i> Defines base address of memory region.
#define __RAM2_BASE 0
// <o> Region size [bytes] <0x0-0xFFFFFFFF:8>
// <i> Defines size of memory region.
#define __RAM2_SIZE 0
// </h>

// <h> __RAM3 (unused)
// <o> Base address <0x0-0xFFFFFFFF:8>
// <i> Defines base address of memory region.
#define __RAM3_BASE 0
// <o> Region size [bytes] <0x0-0xFFFFFFFF:8>
// <i> Defines size of memory region.
#define __RAM3_SIZE 0
// </h>

// </h>
Expand Down
Loading

0 comments on commit 929dd38

Please sign in to comment.