summaryrefslogtreecommitdiff
path: root/src/mem
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2013-01-07 13:05:38 -0500
committerAndreas Hansson <andreas.hansson@arm.com>2013-01-07 13:05:38 -0500
commit18b147acef164dcc7faa3a6c184c913a2bbb93fa (patch)
tree66e55c920e7c4a1eaddd082d65d5851aedc81742 /src/mem
parentb8c2fa6ba9850d079574ca6d7c91b93dcd3aacb8 (diff)
downloadgem5-18b147acef164dcc7faa3a6c184c913a2bbb93fa.tar.xz
mem: Merge ranges that are part of the conf table
This patch adds basic merging of address ranges when determining which address ranges should be reported in the configuration table. By performing this merging it is possible to distribute an address range across many memory channels (controllers). This is essential to enable address interleaving.
Diffstat (limited to 'src/mem')
-rw-r--r--src/mem/physical.cc29
-rw-r--r--src/mem/physical.hh4
2 files changed, 28 insertions, 5 deletions
diff --git a/src/mem/physical.cc b/src/mem/physical.cc
index 140e2b1c0..df106d8cc 100644
--- a/src/mem/physical.cc
+++ b/src/mem/physical.cc
@@ -203,13 +203,34 @@ PhysicalMemory::getConfAddrRanges() const
// this could be done once in the constructor, but since it is unlikely to
// be called more than once the iteration should not be a problem
AddrRangeList ranges;
- for (vector<AbstractMemory*>::const_iterator m = memories.begin();
- m != memories.end(); ++m) {
- if ((*m)->isConfReported()) {
- ranges.push_back((*m)->getAddrRange());
+ vector<AddrRange> intlv_ranges;
+ for (AddrRangeMap<AbstractMemory*>::const_iterator r = addrMap.begin();
+ r != addrMap.end(); ++r) {
+ if (r->second->isConfReported()) {
+ // 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)) {
+ ranges.push_back(AddrRange(intlv_ranges));
+ intlv_ranges.clear();
+ }
+ intlv_ranges.push_back(r->first);
+ } else {
+ // keep the current range
+ ranges.push_back(r->first);
+ }
}
}
+ // if there is still interleaved ranges waiting to be merged,
+ // go ahead and do it
+ if (!intlv_ranges.empty()) {
+ ranges.push_back(AddrRange(intlv_ranges));
+ }
+
return ranges;
}
diff --git a/src/mem/physical.hh b/src/mem/physical.hh
index 10edeb18f..02fefb478 100644
--- a/src/mem/physical.hh
+++ b/src/mem/physical.hh
@@ -135,7 +135,9 @@ class PhysicalMemory : public Serializable
/**
* Get the memory ranges for all memories that are to be reported
- * to the configuration table.
+ * to the configuration table. The ranges are merged before they
+ * are returned such that any interleaved ranges appear as a
+ * single range.
*
* @return All configuration table memory ranges
*/