mem: Use address range to find the destination port in the xbar
authorNikos Nikoleris <nikos.nikoleris@arm.com>
Mon, 4 Jun 2018 15:20:47 +0000 (16:20 +0100)
committerNikos Nikoleris <nikos.nikoleris@arm.com>
Tue, 19 Jun 2018 14:24:25 +0000 (14:24 +0000)
Previously the xbar used the start address to lookup the port map and
determine the right destination of an incoming packet. This change
uses the full address range to correctly determine the right master.

Change-Id: I5118712c43ae65aba64e71bf030bca5c99770bdd
Reviewed-on: https://gem5-review.googlesource.com/11117
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>

src/mem/coherent_xbar.cc
src/mem/noncoherent_xbar.cc
src/mem/xbar.cc
src/mem/xbar.hh

index 872ee5c0df24381edd416477331ca9bbe7a1bbd6..d46f3893f34591499007df691701f5b9fc5b5785 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2017 ARM Limited
+ * Copyright (c) 2011-2018 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -151,8 +151,9 @@ CoherentXBar::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
     // and the cache responding flag should always be the same
     assert(is_express_snoop == cache_responding);
 
-    // determine the destination based on the address
-    PortID master_port_id = findPort(pkt->getAddr());
+    // determine the destination based on the destination address range
+    AddrRange addr_range = RangeSize(pkt->getAddr(), pkt->getSize());
+    PortID master_port_id = findPort(addr_range);
 
     // test if the crossbar should be considered occupied for the current
     // port, and exclude express snoops from the check
@@ -551,7 +552,9 @@ CoherentXBar::recvTimingSnoopReq(PacketPtr pkt, PortID master_port_id)
     // device responsible for the address range something is
     // wrong, hence there is nothing further to do as the packet
     // would be going back to where it came from
-    assert(master_port_id == findPort(pkt->getAddr()));
+    AddrRange addr_range M5_VAR_USED =
+        RangeSize(pkt->getAddr(), pkt->getSize());
+    assert(findPort(addr_range) == master_port_id);
 }
 
 bool
@@ -781,7 +784,8 @@ CoherentXBar::recvAtomic(PacketPtr pkt, PortID slave_port_id)
 
     // even if we had a snoop response, we must continue and also
     // perform the actual request at the destination
-    PortID master_port_id = findPort(pkt->getAddr());
+    AddrRange addr_range = RangeSize(pkt->getAddr(), pkt->getSize());
+    PortID master_port_id = findPort(addr_range);
 
     if (sink_packet) {
         DPRINTF(CoherentXBar, "%s: Not forwarding %s\n", __func__,
@@ -1005,7 +1009,7 @@ CoherentXBar::recvFunctional(PacketPtr pkt, PortID slave_port_id)
             }
         }
 
-        PortID dest_id = findPort(pkt->getAddr());
+        PortID dest_id = findPort(RangeSize(pkt->getAddr(), pkt->getSize()));
 
         masterPorts[dest_id]->sendFunctional(pkt);
     }
index 3ff991fdb72d1d395c90fd63e9a845ea11612fea..7bd04cb3eeb3083cd1ec665bbd30cd34f3efcbcd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 ARM Limited
+ * Copyright (c) 2011-2015, 2018 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -108,7 +108,8 @@ NoncoherentXBar::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
     assert(!pkt->isExpressSnoop());
 
     // determine the destination based on the address
-    PortID master_port_id = findPort(pkt->getAddr());
+    AddrRange addr_range = RangeSize(pkt->getAddr(), pkt->getSize());
+    PortID master_port_id = findPort(addr_range);
 
     // test if the layer should be considered occupied for the current
     // port
@@ -253,7 +254,8 @@ NoncoherentXBar::recvAtomic(PacketPtr pkt, PortID slave_port_id)
     unsigned int pkt_cmd = pkt->cmdToIndex();
 
     // determine the destination port
-    PortID master_port_id = findPort(pkt->getAddr());
+    AddrRange addr_range = RangeSize(pkt->getAddr(), pkt->getSize());
+    PortID master_port_id = findPort(addr_range);
 
     // stats updates for the request
     pktCount[slave_port_id][master_port_id]++;
@@ -303,7 +305,8 @@ NoncoherentXBar::recvFunctional(PacketPtr pkt, PortID slave_port_id)
     }
 
     // determine the destination port
-    PortID dest_id = findPort(pkt->getAddr());
+    AddrRange addr_range = RangeSize(pkt->getAddr(), pkt->getSize());
+    PortID dest_id = findPort(addr_range);
 
     // forward the request to the appropriate destination
     masterPorts[dest_id]->sendFunctional(pkt);
index c3a5c83fe0aabdcb7149d258cf7dbd4d0a93785d..b139cdc9b9dabd2a5b366b7e0007438bb60d4dde 100644 (file)
@@ -321,34 +321,34 @@ BaseXBar::Layer<SrcType,DstType>::recvRetry()
 }
 
 PortID
-BaseXBar::findPort(Addr addr)
+BaseXBar::findPort(AddrRange addr_range)
 {
     // we should never see any address lookups before we've got the
     // ranges of all connected slave modules
     assert(gotAllAddrRanges);
 
     // Check the address map interval tree
-    auto i = portMap.contains(addr);
+    auto i = portMap.contains(addr_range);
     if (i != portMap.end()) {
         return i->second;
     }
 
     // Check if this matches the default range
     if (useDefaultRange) {
-        if (defaultRange.contains(addr)) {
-            DPRINTF(AddrRanges, "  found addr %#llx on default\n",
-                    addr);
+        if (addr_range.isSubset(defaultRange)) {
+            DPRINTF(AddrRanges, "  found addr %s on default\n",
+                    addr_range.to_string());
             return defaultPortID;
         }
     } else if (defaultPortID != InvalidPortID) {
-        DPRINTF(AddrRanges, "Unable to find destination for addr %#llx, "
-                "will use default port\n", addr);
+        DPRINTF(AddrRanges, "Unable to find destination for %s, "
+                "will use default port\n", addr_range.to_string());
         return defaultPortID;
     }
 
     // we should use the range for the default port and it did not
     // match, or the default port is not set
-    fatal("Unable to find destination for addr %#llx on %s\n", addr,
+    fatal("Unable to find destination for %s on %s\n", addr_range.to_string(),
           name());
 }
 
index 2b7e7ed48740a0a57aa598fdeb9b0bc09c8fc6a5..abe2a1096315cc1724610cb82ac185658050631d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 ARM Limited
+ * Copyright (c) 2011-2015, 2018 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -342,13 +342,14 @@ class BaseXBar : public MemObject
      */
     virtual void recvRangeChange(PortID master_port_id);
 
-    /** Find which port connected to this crossbar (if any) should be
-     * given a packet with this address.
+    /**
+     * Find which port connected to this crossbar (if any) should be
+     * given a packet with this address range.
      *
-     * @param addr Address to find port for.
+     * @param addr_range Address range to find port for.
      * @return id of port that the packet should be sent out of.
      */
-    PortID findPort(Addr addr);
+    PortID findPort(AddrRange addr_range);
 
     /**
      * Return the address ranges the crossbar is responsible for.