mem: Merge interleaved ranges when creating backing store

This patch adds merging of interleaved ranges before creating the
backing stores. The backing stores are always a contigous chunk of the
address space, and with this patch it is possible to have interleaved
memories in the system.
This commit is contained in:
Andreas Hansson 2013-03-01 13:20:21 -05:00
parent cafd38f36c
commit 1a58362e25

View file

@ -99,20 +99,41 @@ PhysicalMemory::PhysicalMemory(const string& _name,
// space to be mapped to backing store, also remember what
// memories constitute the range so we can go and find out if we
// have to init their parts to zero
vector<AddrRange> intlv_ranges;
vector<AbstractMemory*> curr_memories;
for (AddrRangeMap<AbstractMemory*>::const_iterator r = addrMap.begin();
r != addrMap.end(); ++r) {
// simply skip past all memories that are null and hence do
// not need any backing store
if (!r->second->isNull()) {
// this will eventually be extended to support merging of
// interleaved address ranges, and although it might seem
// overly complicated at this point it will all be used
curr_memories.push_back(r->second);
createBackingStore(r->first, curr_memories);
curr_memories.clear();
// if the range is interleaved then save it for now
if (r->first.interleaved()) {
// if we already got interleaved ranges that are not
// part of the same range, then first do a merge
// before we add the new one
if (!intlv_ranges.empty() &&
!intlv_ranges.back().mergesWith(r->first)) {
AddrRange merged_range(intlv_ranges);
createBackingStore(merged_range, curr_memories);
intlv_ranges.clear();
curr_memories.clear();
}
intlv_ranges.push_back(r->first);
curr_memories.push_back(r->second);
} else {
vector<AbstractMemory*> single_memory;
single_memory.push_back(r->second);
createBackingStore(r->first, single_memory);
}
}
}
// if there is still interleaved ranges waiting to be merged, go
// ahead and do it
if (!intlv_ranges.empty()) {
AddrRange merged_range(intlv_ranges);
createBackingStore(merged_range, curr_memories);
}
}
void