diff options
author | Andreas Hansson <andreas.hansson@arm.com> | 2013-03-01 13:20:21 -0500 |
---|---|---|
committer | Andreas Hansson <andreas.hansson@arm.com> | 2013-03-01 13:20:21 -0500 |
commit | 1a58362e25839417047847c7e150a89287a3de7d (patch) | |
tree | 0d444b2131bb093d9884bddc5f3e24b6621e16cb | |
parent | cafd38f36c4d71c3f3d6efaf0023aec2cfc51b32 (diff) | |
download | gem5-1a58362e25839417047847c7e150a89287a3de7d.tar.xz |
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.
-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 |