ruby: handle llsc accesses through CacheEntry, not CacheMemory
[gem5.git] / src / mem / comm_monitor.cc
index 4255d58ad705fca035ea3d8dea066bb7e6a3ed61..beb7fe32c08eb3c5f681eeb273f2d07edbc638e6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2012-2013, 2015 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -38,6 +38,7 @@
  *          Andreas Hansson
  */
 
+#include "base/trace.hh"
 #include "debug/CommMonitor.hh"
 #include "mem/comm_monitor.hh"
 #include "sim/stats.hh"
@@ -48,16 +49,14 @@ CommMonitor::CommMonitor(Params* params)
       slavePort(name() + "-slave", *this),
       samplePeriodicEvent(this),
       samplePeriodTicks(params->sample_period),
+      samplePeriod(params->sample_period / SimClock::Float::s),
       readAddrMask(params->read_addr_mask),
       writeAddrMask(params->write_addr_mask),
       stats(params)
 {
-    // keep track of the sample period both in ticks and absolute time
-    samplePeriod.setTick(params->sample_period);
-
     DPRINTF(CommMonitor,
-            "Created monitor %s with sample period %d ticks (%f s)\n",
-            name(), samplePeriodTicks, samplePeriod);
+            "Created monitor %s with sample period %d ticks (%f ms)\n",
+            name(), samplePeriodTicks, samplePeriod * 1E3);
 }
 
 CommMonitor*
@@ -74,8 +73,15 @@ CommMonitor::init()
         fatal("Communication monitor is not connected on both sides.\n");
 }
 
-MasterPort&
-CommMonitor::getMasterPort(const std::string& if_name, int idx)
+void
+CommMonitor::regProbePoints()
+{
+    ppPktReq.reset(new ProbePoints::Packet(getProbeManager(), "PktRequest"));
+    ppPktResp.reset(new ProbePoints::Packet(getProbeManager(), "PktResponse"));
+}
+
+BaseMasterPort&
+CommMonitor::getMasterPort(const std::string& if_name, PortID idx)
 {
     if (if_name == "master") {
         return masterPort;
@@ -84,8 +90,8 @@ CommMonitor::getMasterPort(const std::string& if_name, int idx)
     }
 }
 
-SlavePort&
-CommMonitor::getSlavePort(const std::string& if_name, int idx)
+BaseSlavePort&
+CommMonitor::getSlavePort(const std::string& if_name, PortID idx)
 {
     if (if_name == "slave") {
         return slavePort;
@@ -109,7 +115,12 @@ CommMonitor::recvFunctionalSnoop(PacketPtr pkt)
 Tick
 CommMonitor::recvAtomic(PacketPtr pkt)
 {
-    return masterPort.sendAtomic(pkt);
+    ppPktReq->notify(pkt);
+
+    const Tick delay(masterPort.sendAtomic(pkt));
+    assert(pkt->isResponse());
+    ppPktResp->notify(pkt);
+    return delay;
 }
 
 Tick
@@ -126,21 +137,20 @@ CommMonitor::recvTimingReq(PacketPtr pkt)
 
     // Store relevant fields of packet, because packet may be modified
     // or even deleted when sendTiming() is called.
-    bool isRead = pkt->isRead();
-    bool isWrite = pkt->isWrite();
-    unsigned size = pkt->getSize();
-    Addr addr = pkt->getAddr();
-    bool needsResponse = pkt->needsResponse();
-    bool memInhibitAsserted = pkt->memInhibitAsserted();
-    Packet::SenderState* senderState = pkt->senderState;
+    const bool is_read = pkt->isRead();
+    const bool is_write = pkt->isWrite();
+    const MemCmd cmd = pkt->cmd;
+    const unsigned size = pkt->getSize();
+    const Addr addr = pkt->getAddr();
+    const bool expects_response(
+        pkt->needsResponse() && !pkt->memInhibitAsserted());
 
     // If a cache miss is served by a cache, a monitor near the memory
     // would see a request which needs a response, but this response
     // would be inhibited and not come back from the memory. Therefore
     // we additionally have to check the inhibit flag.
-    if (needsResponse && !memInhibitAsserted && !stats.disableLatencyHists) {
-        pkt->senderState = new CommMonitorSenderState(senderState,
-                                                      curTick());
+    if (expects_response && !stats.disableLatencyHists) {
+        pkt->pushSenderState(new CommMonitorSenderState(curTick()));
     }
 
     // Attempt to send the packet (always succeeds for inhibited
@@ -148,12 +158,22 @@ CommMonitor::recvTimingReq(PacketPtr pkt)
     bool successful = masterPort.sendTimingReq(pkt);
 
     // If not successful, restore the sender state
-    if (!successful && needsResponse && !stats.disableLatencyHists) {
-        delete pkt->senderState;
-        pkt->senderState = senderState;
+    if (!successful && expects_response && !stats.disableLatencyHists) {
+        delete pkt->popSenderState();
+    }
+
+    if (successful) {
+        // The receiver might already have modified the packet. We
+        // want to give the probe access to the original packet, which
+        // means we need to fake the original packet by temporarily
+        // restoring the command.
+        const MemCmd response_cmd(pkt->cmd);
+        pkt->cmd = cmd;
+        ppPktReq->notify(pkt);
+        pkt->cmd = response_cmd;
     }
 
-    if (successful && isRead) {
+    if (successful && is_read) {
         DPRINTF(CommMonitor, "Forwarded read request\n");
 
         // Increment number of observed read transactions
@@ -173,7 +193,7 @@ CommMonitor::recvTimingReq(PacketPtr pkt)
 
         // If it needs a response increment number of outstanding read
         // requests
-        if (!stats.disableOutstandingHists && needsResponse) {
+        if (!stats.disableOutstandingHists && expects_response) {
             ++stats.outstandingReadReqs;
         }
 
@@ -190,7 +210,7 @@ CommMonitor::recvTimingReq(PacketPtr pkt)
             }
             stats.timeOfLastReq = curTick();
         }
-    } else if (successful && isWrite) {
+    } else if (successful && is_write) {
         DPRINTF(CommMonitor, "Forwarded write request\n");
 
         // Same as for reads
@@ -213,7 +233,7 @@ CommMonitor::recvTimingReq(PacketPtr pkt)
             stats.writeAddrDist.sample(addr & writeAddrMask);
         }
 
-        if (!stats.disableOutstandingHists && needsResponse) {
+        if (!stats.disableOutstandingHists && expects_response) {
             ++stats.outstandingWriteReqs;
         }
 
@@ -245,20 +265,20 @@ CommMonitor::recvTimingResp(PacketPtr pkt)
 
     // Store relevant fields of packet, because packet may be modified
     // or even deleted when sendTiming() is called.
-    bool isRead = pkt->isRead();
-    bool isWrite = pkt->isWrite();
+    bool is_read = pkt->isRead();
+    bool is_write = pkt->isWrite();
     unsigned size = pkt->getSize();
     Tick latency = 0;
-    CommMonitorSenderState* commReceivedState =
+    CommMonitorSenderState* received_state =
         dynamic_cast<CommMonitorSenderState*>(pkt->senderState);
 
     if (!stats.disableLatencyHists) {
         // Restore initial sender state
-        if (commReceivedState == NULL)
+        if (received_state == NULL)
             panic("Monitor got a response without monitor sender state\n");
 
         // Restore the sate
-        pkt->senderState = commReceivedState->origSenderState;
+        pkt->senderState = received_state->predecessor;
     }
 
     // Attempt to send the packet
@@ -268,17 +288,22 @@ CommMonitor::recvTimingResp(PacketPtr pkt)
         // If packet successfully send, sample value of latency,
         // afterwards delete sender state, otherwise restore state
         if (successful) {
-            latency = curTick() - commReceivedState->transmitTime;
+            latency = curTick() - received_state->transmitTime;
             DPRINTF(CommMonitor, "Latency: %d\n", latency);
-            delete commReceivedState;
+            delete received_state;
         } else {
             // Don't delete anything and let the packet look like we
             // did not touch it
-            pkt->senderState = commReceivedState;
+            pkt->senderState = received_state;
         }
     }
 
-    if (successful && isRead) {
+    if (successful) {
+        assert(pkt->isResponse());
+        ppPktResp->notify(pkt);
+    }
+
+    if (successful && is_read) {
         // Decrement number of outstanding read requests
         DPRINTF(CommMonitor, "Received read response\n");
         if (!stats.disableOutstandingHists) {
@@ -296,7 +321,7 @@ CommMonitor::recvTimingResp(PacketPtr pkt)
             stats.totalReadBytes += size;
         }
 
-    } else if (successful && isWrite) {
+    } else if (successful && is_write) {
         // Decrement number of outstanding write requests
         DPRINTF(CommMonitor, "Received write response\n");
         if (!stats.disableOutstandingHists) {
@@ -328,37 +353,27 @@ CommMonitor::recvTimingSnoopResp(PacketPtr pkt)
 bool
 CommMonitor::isSnooping() const
 {
-    return slavePort.getMasterPort().isSnooping();
-}
-
-unsigned
-CommMonitor::deviceBlockSizeMaster()
-{
-    return slavePort.peerBlockSize();
-}
-
-unsigned
-CommMonitor::deviceBlockSizeSlave()
-{
-    return masterPort.peerBlockSize();
+    // check if the connected master port is snooping
+    return slavePort.isSnooping();
 }
 
 AddrRangeList
-CommMonitor::getAddrRanges()
+CommMonitor::getAddrRanges() const
 {
-    return masterPort.getSlavePort().getAddrRanges();
+    // get the address ranges of the connected slave port
+    return masterPort.getAddrRanges();
 }
 
 void
-CommMonitor::recvRetryMaster()
+CommMonitor::recvReqRetry()
 {
-    slavePort.sendRetry();
+    slavePort.sendRetryReq();
 }
 
 void
-CommMonitor::recvRetrySlave()
+CommMonitor::recvRespRetry()
 {
-    masterPort.sendRetry();
+    masterPort.sendRetryResp();
 }
 
 void