changeset 03e09db82c80 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=03e09db82c80
description:
        MEM: Make the bus default port yet another port

        This patch removes the idiosyncratic nature of the default bus port
        and makes it yet another port in the list of interfaces. Rather than
        having a specific pointer to the default port we merely track the
        identifier of this port. This change makes future port diversification
        easier and overall cleans up the bus code.

diffstat:

 src/mem/bus.cc |  97 +++++++++++++++++----------------------------------------
 src/mem/bus.hh |  63 ++----------------------------------
 2 files changed, 35 insertions(+), 125 deletions(-)

diffs (truncated from 337 to 300 lines):

diff -r cd48e2802644 -r 03e09db82c80 src/mem/bus.cc
--- a/src/mem/bus.cc    Tue Jan 17 12:55:09 2012 -0600
+++ b/src/mem/bus.cc    Tue Jan 17 12:55:09 2012 -0600
@@ -38,6 +38,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Authors: Ali Saidi
+ *          Andreas Hansson
  */
 
 /**
@@ -45,9 +46,6 @@
  * Definition of a bus object.
  */
 
-#include <algorithm>
-#include <limits>
-
 #include "base/misc.hh"
 #include "base/trace.hh"
 #include "debug/Bus.hh"
@@ -58,8 +56,7 @@
 Bus::Bus(const BusParams *p)
     : MemObject(p), busId(p->bus_id), clock(p->clock),
       headerCycles(p->header_cycles), width(p->width), tickNextIdle(0),
-      drainEvent(NULL), busIdle(this), inRetry(false), maxId(0),
-      defaultPort(NULL),
+      drainEvent(NULL), busIdle(this), inRetry(false), defaultPortId(-1),
       useDefaultRange(p->use_default_range), defaultBlockSize(p->block_size),
       cachedBlockSize(0), cachedBlockSizeValid(false)
 {
@@ -70,28 +67,25 @@
         fatal("Bus clock period must be positive\n");
     if (headerCycles <= 0)
         fatal("Number of header cycles must be positive\n");
-    clearBusCache();
     clearPortCache();
 }
 
 Port *
 Bus::getPort(const std::string &if_name, int idx)
 {
+    std::string portName;
+    int id = interfaces.size();
     if (if_name == "default") {
-        if (defaultPort == NULL) {
-            defaultPort = new BusPort(csprintf("%s-default",name()), this,
-                                      defaultId);
-            cachedBlockSizeValid = false;
-            return defaultPort;
+        if (defaultPortId == -1) {
+            defaultPortId = id;
+            portName = csprintf("%s-default", name());
         } else
-            fatal("Default port already set\n");
+            fatal("Default port already set on %s\n", name());
+    } else {
+        portName = csprintf("%s-p%d", name(), id);
     }
-    int id;
-    // if_name ignored?  forced to be empty?
-    id = maxId++;
-    assert(maxId < std::numeric_limits<typeof(maxId)>::max());
-    BusPort *bp = new BusPort(csprintf("%s-p%d", name(), id), this, id);
-    interfaces[id] = bp;
+    BusPort *bp = new BusPort(portName, this, id);
+    interfaces.push_back(bp);
     cachedBlockSizeValid = false;
     return bp;
 }
@@ -99,16 +93,16 @@
 void
 Bus::init()
 {
-    m5::hash_map<short,BusPort*>::iterator intIter;
+    std::vector<BusPort*>::iterator intIter;
 
     // iterate over our interfaces and determine which of our neighbours
     // are snooping and add them as snoopers
     for (intIter = interfaces.begin(); intIter != interfaces.end();
          intIter++) {
-        if (intIter->second->getPeer()->isSnooping()) {
+        if ((*intIter)->getPeer()->isSnooping()) {
             DPRINTF(BusAddrRanges, "Adding snooping neighbour %s\n",
-                    intIter->second->getPeer()->name());
-            snoopPorts.push_back(intIter->second);
+                    (*intIter)->getPeer()->name());
+            snoopPorts.push_back(*intIter);
         }
     }
 }
@@ -188,16 +182,7 @@
 {
     short src = pkt->getSrc();
 
-    BusPort *src_port;
-    if (src == defaultId)
-        src_port = defaultPort;
-    else {
-        src_port = checkBusCache(src);
-        if (src_port == NULL) {
-            src_port = interfaces[src];
-            updateBusCache(src, src_port);
-        }
-    }
+    BusPort *src_port = interfaces[src];
 
     // If the bus is busy, or other devices are in line ahead of the current
     // one, put this device on the retry list.
@@ -223,8 +208,7 @@
 
     if (dest == Packet::Broadcast) {
         dest_port_id = findPort(pkt->getAddr());
-        dest_port = (dest_port_id == defaultId) ?
-            defaultPort : interfaces[dest_port_id];
+        dest_port = interfaces[dest_port_id];
         SnoopIter s_end = snoopPorts.end();
         for (SnoopIter s_iter = snoopPorts.begin(); s_iter != s_end; s_iter++) 
{
             BusPort *p = *s_iter;
@@ -235,20 +219,10 @@
             }
         }
     } else {
-        assert(dest < maxId);
+        assert(dest < interfaces.size());
         assert(dest != src); // catch infinite loops
         dest_port_id = dest;
-        if (dest_port_id == defaultId)
-            dest_port = defaultPort;
-        else {
-            dest_port = checkBusCache(dest);
-            if (dest_port == NULL) {
-                dest_port = interfaces[dest_port_id];
-            // updateBusCache(dest_port_id, dest_port);
-            }
-        }
-        dest_port = (dest_port_id == defaultId) ?
-            defaultPort : interfaces[dest_port_id];
+        dest_port = interfaces[dest_port_id];
     }
 
     if (dest_port_id == src) {
@@ -346,7 +320,7 @@
         for (AddrRangeIter i = defaultRange.begin(); i != a_end; i++) {
             if (*i == addr) {
                 DPRINTF(Bus, "  found addr %#llx on default\n", addr);
-                return defaultId;
+                return defaultPortId;
             }
         }
 
@@ -355,7 +329,7 @@
 
     DPRINTF(Bus, "Unable to find destination for addr %#llx, "
             "will use default port\n", addr);
-    return defaultId;
+    return defaultPortId;
 }
 
 
@@ -379,16 +353,7 @@
     int orig_src = pkt->getSrc();
 
     int target_port_id = findPort(pkt->getAddr());
-    BusPort *target_port;
-    if (target_port_id == defaultId)
-        target_port = defaultPort;
-    else {
-      target_port = checkBusCache(target_port_id);
-      if (target_port == NULL) {
-          target_port = interfaces[target_port_id];
-          updateBusCache(target_port_id, target_port);
-      }
-    }
+    BusPort *target_port = interfaces[target_port_id];
 
     SnoopIter s_end = snoopPorts.end();
     for (SnoopIter s_iter = snoopPorts.begin(); s_iter != s_end; s_iter++) {
@@ -444,7 +409,7 @@
     assert(pkt->getDest() == Packet::Broadcast);
 
     int port_id = findPort(pkt->getAddr());
-    Port *port = (port_id == defaultId) ? defaultPort : interfaces[port_id];
+    Port *port = interfaces[port_id];
     // The packet may be changed by another bus on snoops, restore the
     // id after each
     int src_id = pkt->getSrc();
@@ -491,11 +456,11 @@
     DPRINTF(BusAddrRanges, "received RangeChange from device id %d\n", id);
 
     clearPortCache();
-    if (id == defaultId) {
+    if (id == defaultPortId) {
         defaultRange.clear();
         // Only try to update these ranges if the user set a default responder.
         if (useDefaultRange) {
-            AddrRangeList ranges = defaultPort->getPeer()->getAddrRanges();
+            AddrRangeList ranges = interfaces[id]->getPeer()->getAddrRanges();
             for(iter = ranges.begin(); iter != ranges.end(); iter++) {
                 defaultRange.push_back(*iter);
                 DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for default 
range\n",
@@ -504,7 +469,7 @@
         }
     } else {
 
-        assert((id < maxId && id >= 0) || id == defaultId);
+        assert(id < interfaces.size() && id >= 0);
         BusPort *port = interfaces[id];
 
         // Clean out any previously existent ids
@@ -533,14 +498,12 @@
 
     // tell all our peers that our address range has changed.
     // Don't tell the device that caused this change, it already knows
-    m5::hash_map<short,BusPort*>::iterator intIter;
+    std::vector<BusPort*>::const_iterator intIter;
 
     for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++)
-        if (intIter->first != id)
-            intIter->second->sendRangeChange();
+        if ((*intIter)->getId() != id)
+            (*intIter)->sendRangeChange();
 
-    if (id != defaultId && defaultPort)
-        defaultPort->sendRangeChange();
     inRecvRangeChange.erase(id);
 }
 
diff -r cd48e2802644 -r 03e09db82c80 src/mem/bus.hh
--- a/src/mem/bus.hh    Tue Jan 17 12:55:09 2012 -0600
+++ b/src/mem/bus.hh    Tue Jan 17 12:55:09 2012 -0600
@@ -39,6 +39,7 @@
  *
  * Authors: Ron Dreslinski
  *          Ali Saidi
+ *          Andreas Hansson
  */
 
 /**
@@ -91,7 +92,7 @@
         void onRetryList(bool newVal)
         { _onRetryList = newVal; }
 
-        int getId() { return id; }
+        int getId() const { return id; }
 
         /**
          * Determine if this port should be considered a snooper. This
@@ -167,9 +168,6 @@
 
     Event * drainEvent;
 
-
-    static const int defaultId = -3; //Make it unique from Broadcast
-
     typedef range_map<Addr,int>::iterator PortIter;
     range_map<Addr, int> portMap;
 
@@ -297,12 +295,9 @@
     bool inRetry;
     std::set<int> inRecvRangeChange;
 
-    /** max number of bus ids we've handed out so far */
-    short maxId;
-
-    /** An array of pointers to the peer port interfaces
+    /** An ordered vector of pointers to the peer port interfaces
         connected to this bus.*/
-    m5::hash_map<short,BusPort*> interfaces;
+    std::vector<BusPort*> interfaces;
 
     /** An array of pointers to ports that retry should be called on because 
the
      * original send failed for whatever reason.*/
@@ -331,7 +326,7 @@
     }
 
     /** Port that handles requests that don't match any of the interfaces.*/
-    BusPort *defaultPort;
+    short defaultPortId;
 
     /** If true, use address range provided by default device.  Any
        address not handled by another port and not in default device's
@@ -343,54 +338,6 @@
     unsigned cachedBlockSize;
     bool cachedBlockSizeValid;
 
-   // Cache for the peer port interfaces
-    struct BusCache {
-        bool  valid;
-        short id;
-        BusPort  *port;
-    };
-
-    BusCache busCache[3];
-
-    // Checks the peer port interfaces cache for the port id and returns
-    // a pointer to the matching port
-    inline BusPort* checkBusCache(short id) {
-        if (busCache[0].valid && id == busCache[0].id) {
-            return busCache[0].port;
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to