mem: Merge ranges that are part of the conf table
authorAndreas Hansson <andreas.hansson@arm.com>
Mon, 7 Jan 2013 18:05:38 +0000 (13:05 -0500)
committerAndreas Hansson <andreas.hansson@arm.com>
Mon, 7 Jan 2013 18:05:38 +0000 (13:05 -0500)
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.

src/mem/physical.cc
src/mem/physical.hh

index 140e2b1c05d058fdff10f5a4d8ec1d85d981003d..df106d8cce7308cb07544db7f20c5e97861c0d3c 100644 (file)
@@ -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;
 }
 
index 10edeb18fb515de01fb989d25a1687c9a0b79171..02fefb47886dc30e9760d1f3862012c082922468 100644 (file)
@@ -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
      */