diff options
Diffstat (limited to 'src/mem/physical.cc')
-rw-r--r-- | src/mem/physical.cc | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/src/mem/physical.cc b/src/mem/physical.cc index df106d8cc..4b7001eb5 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -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 |