mem: Always use SenderState for response routing in RubyPort
authorAndreas Hansson <andreas.hansson@arm.com>
Thu, 22 Jan 2015 10:01:24 +0000 (05:01 -0500)
committerAndreas Hansson <andreas.hansson@arm.com>
Thu, 22 Jan 2015 10:01:24 +0000 (05:01 -0500)
This patch aligns how the response routing is done in the RubyPort,
using the SenderState for both memory and I/O accesses. Before this
patch, only the I/O used the SenderState, whereas the memory accesses
relied on the src field in the packet. With this patch we shift to
using SenderState in both cases, thus not relying on the src field any
longer.

src/mem/ruby/system/RubyPort.cc
src/mem/ruby/system/Sequencer.cc

index 3abdecf3da8af3b33d6bd3cb06b2fa332d174515..66e59144f89cab691aa58fa750b079a4f5593bbf 100644 (file)
@@ -180,11 +180,6 @@ bool RubyPort::MemMasterPort::recvTimingResp(PacketPtr pkt)
     // got a response from a device
     assert(pkt->isResponse());
 
-    // In FS mode, ruby memory will receive pio responses from devices
-    // and it must forward these responses back to the particular CPU.
-    DPRINTF(RubyPort,  "Pio response for address %#x, going to %d\n",
-            pkt->getAddr(), pkt->getDest());
-
     // First we must retrieve the request port from the sender State
     RubyPort::SenderState *senderState =
         safe_cast<RubyPort::SenderState *>(pkt->popSenderState());
@@ -192,6 +187,11 @@ bool RubyPort::MemMasterPort::recvTimingResp(PacketPtr pkt)
     assert(port != NULL);
     delete senderState;
 
+    // In FS mode, ruby memory will receive pio responses from devices
+    // and it must forward these responses back to the particular CPU.
+    DPRINTF(RubyPort,  "Pio response for address %#x, going to %s\n",
+            pkt->getAddr(), port->name());
+
     // attempt to send the response in the next cycle
     port->schedTimingResp(pkt, curTick() + g_system_ptr->clockPeriod());
 
@@ -246,9 +246,6 @@ RubyPort::MemSlavePort::recvTimingReq(PacketPtr pkt)
         return true;
     }
 
-    // Save the port id to be used later to route the response
-    pkt->setSrc(id);
-
     assert(Address(pkt->getAddr()).getOffset() + pkt->getSize() <=
            RubySystem::getBlockSizeBytes());
 
@@ -259,6 +256,10 @@ RubyPort::MemSlavePort::recvTimingReq(PacketPtr pkt)
     // Otherwise, we need to tell the port to retry at a later point
     // and return false.
     if (requestStatus == RequestStatus_Issued) {
+        // Save the port in the sender state object to be used later to
+        // route the response
+        pkt->pushSenderState(new SenderState(this));
+
         DPRINTF(RubyPort, "Request %s 0x%x issued\n", pkt->cmdString(),
                 pkt->getAddr());
         return true;
@@ -343,11 +344,14 @@ RubyPort::ruby_hit_callback(PacketPtr pkt)
     assert(system->isMemAddr(pkt->getAddr()));
     assert(pkt->isRequest());
 
-    // As it has not yet been turned around, the source field tells us
-    // which port it came from.
-    assert(pkt->getSrc() < slave_ports.size());
+    // First we must retrieve the request port from the sender State
+    RubyPort::SenderState *senderState =
+        safe_cast<RubyPort::SenderState *>(pkt->popSenderState());
+    MemSlavePort *port = senderState->port;
+    assert(port != NULL);
+    delete senderState;
 
-    slave_ports[pkt->getSrc()]->hitCallback(pkt);
+    port->hitCallback(pkt);
 
     //
     // If we had to stall the MemSlavePorts, wake them up because the sequencer
index ef1b9676b35082f97d445488ae38322023a186c4..dbf35019957185736a3cb830d5aee8c3d7f27944 100644 (file)
@@ -547,6 +547,8 @@ Sequencer::hitCallback(SequencerRequest* srequest, DataBlock& data,
     // subBlock with the recieved data.  The tester will later access
     // this state.
     if (m_usingRubyTester) {
+        DPRINTF(RubySequencer, "hitCallback %s 0x%x using RubyTester\n",
+                pkt->cmdString(), pkt->getAddr());
         RubyTester::SenderState* testerSenderState =
             pkt->findNextSenderState<RubyTester::SenderState>();
         assert(testerSenderState);