mem: Relax packet src/dest check and shift onus to crossbar
authorAndreas Hansson <andreas.hansson@arm.com>
Tue, 2 Dec 2014 11:07:56 +0000 (06:07 -0500)
committerAndreas Hansson <andreas.hansson@arm.com>
Tue, 2 Dec 2014 11:07:56 +0000 (06:07 -0500)
This patch allows objects to get the src/dest of a packet even if it
is not set to a valid port id. This simplifies (ab)using the bridge as
a buffer and latency adapter in situations where the neighbouring
MemObjects are not crossbars.

The checks that were done in the packet are now shifted to the
crossbar where the fields are used to index into the port
arrays. Thus, the carrier of the information is not burdened with
checking, and the crossbar can check not only that the destination is
set, but also that the port index is within limits.

src/mem/bridge.cc
src/mem/coherent_xbar.cc
src/mem/noncoherent_xbar.cc
src/mem/packet.hh

index 085c97b53ef18757675072ddcdb0f79415bedbb7..b26da57e3d10749e014c9b33c7f4901efeddecdc 100644 (file)
@@ -242,9 +242,8 @@ Bridge::BridgeSlavePort::schedTimingResp(PacketPtr pkt, Tick when)
     pkt->setDest(req_state->origSrc);
     delete req_state;
 
-    // the bridge assumes that at least one crossbar has set the
-    // destination field of the packet
-    assert(pkt->isDestValid());
+    // the bridge sets the destination irrespective of it is valid or
+    // not, as it is checked in the crossbar
     DPRINTF(Bridge, "response, new dest %d\n", pkt->getDest());
 
     // If we're about to put this packet at the head of the queue, we
index ce5116de9b747a05dbdf2a55ae2e3f708e101ff7..6ad7b1785d84307df173dea9ae10462f3fa08d45 100644 (file)
@@ -272,6 +272,8 @@ CoherentXBar::recvTimingResp(PacketPtr pkt, PortID master_port_id)
 
     // determine the destination based on what is stored in the packet
     PortID slave_port_id = pkt->getDest();
+    assert(slave_port_id != InvalidPortID);
+    assert(slave_port_id < respLayers.size());
 
     // test if the crossbar should be considered occupied for the
     // current port
@@ -369,6 +371,7 @@ CoherentXBar::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id)
 
     // get the destination from the packet
     PortID dest_port_id = pkt->getDest();
+    assert(dest_port_id != InvalidPortID);
 
     // determine if the response is from a snoop request we
     // created as the result of a normal request (in which case it
@@ -382,6 +385,7 @@ CoherentXBar::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id)
     // is being passed on as a normal response since this is occupying
     // the response layer rather than the snoop response layer
     if (forwardAsSnoop) {
+        assert(dest_port_id < snoopLayers.size());
         if (!snoopLayers[dest_port_id]->tryTiming(src_port)) {
             DPRINTF(CoherentXBar, "recvTimingSnoopResp: src %s %s 0x%x BUSY\n",
                     src_port->name(), pkt->cmdString(), pkt->getAddr());
@@ -390,6 +394,7 @@ CoherentXBar::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id)
     } else {
         // get the master port that mirrors this slave port internally
         MasterPort* snoop_port = snoopRespPorts[slave_port_id];
+        assert(dest_port_id < respLayers.size());
         if (!respLayers[dest_port_id]->tryTiming(snoop_port)) {
             DPRINTF(CoherentXBar, "recvTimingSnoopResp: src %s %s 0x%x BUSY\n",
                     snoop_port->name(), pkt->cmdString(), pkt->getAddr());
index bc51be5a2b25e06a7b325b66c9c13c24f6f56629..476b8314ff71028f85e12c2ab9f0c42d38bc22bb 100644 (file)
@@ -171,6 +171,8 @@ NoncoherentXBar::recvTimingResp(PacketPtr pkt, PortID master_port_id)
 
     // determine the destination based on what is stored in the packet
     PortID slave_port_id = pkt->getDest();
+    assert(slave_port_id != InvalidPortID);
+    assert(slave_port_id < respLayers.size());
 
     // test if the layer should be considered occupied for the current
     // port
index dab1b1b95651fdfee0ecb64452c0f8e5f59ca36c..9320d7886b9e5ed01b44c8f4a72792bafa788461 100644 (file)
@@ -544,15 +544,13 @@ class Packet : public Printable
     bool hadBadAddress() const { return cmd == MemCmd::BadAddressError; }
     void copyError(Packet *pkt) { assert(pkt->isError()); cmd = pkt->cmd; }
 
-    bool isSrcValid() const { return src != InvalidPortID; }
     /// Accessor function to get the source index of the packet.
-    PortID getSrc() const { assert(isSrcValid()); return src; }
+    PortID getSrc() const { return src; }
     /// Accessor function to set the source index of the packet.
     void setSrc(PortID _src) { src = _src; }
 
-    bool isDestValid() const { return dest != InvalidPortID; }
     /// Accessor function for the destination index of the packet.
-    PortID getDest() const { assert(isDestValid()); return dest; }
+    PortID getDest() const { return dest; }
     /// Accessor function to set the destination index of the packet.
     void setDest(PortID _dest) { dest = _dest; }
     /// Reset destination field, e.g. to turn a response into a request again.