ruby: handle llsc accesses through CacheEntry, not CacheMemory
[gem5.git] / src / mem / comm_monitor.cc
index 5db6f5e9a04d573ba472b04b7bd9d8349200413f..beb7fe32c08eb3c5f681eeb273f2d07edbc638e6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 ARM Limited
+ * Copyright (c) 2012-2013, 2015 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
  *          Andreas Hansson
  */
 
-#include "base/callback.hh"
-#include "base/output.hh"
 #include "base/trace.hh"
 #include "debug/CommMonitor.hh"
 #include "mem/comm_monitor.hh"
-#include "proto/packet.pb.h"
 #include "sim/stats.hh"
 
 CommMonitor::CommMonitor(Params* params)
@@ -52,46 +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),
-      traceStream(NULL)
+      stats(params)
 {
-    // If we are using a trace file, then open the file,
-    if (params->trace_file != "") {
-        // If the trace file is not specified as an absolute path,
-        // append the current simulation output directory
-        std::string filename = simout.resolve(params->trace_file);
-        traceStream = new ProtoOutputStream(filename);
-
-        // Create a protobuf message for the header and write it to
-        // the stream
-        Message::PacketHeader header_msg;
-        header_msg.set_obj_id(name());
-        header_msg.set_tick_freq(SimClock::Frequency);
-        traceStream->write(header_msg);
-
-        // Register a callback to compensate for the destructor not
-        // being called. The callback forces the stream to flush and
-        // closes the output file.
-        Callback* cb = new MakeCallback<CommMonitor,
-            &CommMonitor::closeStreams>(this);
-        registerExitCallback(cb);
-    }
-
-    // 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);
-}
-
-void
-CommMonitor::closeStreams()
-{
-    if (traceStream != NULL)
-        delete traceStream;
+            "Created monitor %s with sample period %d ticks (%f ms)\n",
+            name(), samplePeriodTicks, samplePeriod * 1E3);
 }
 
 CommMonitor*
@@ -108,6 +73,13 @@ CommMonitor::init()
         fatal("Communication monitor is not connected on both sides.\n");
 }
 
+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)
 {
@@ -143,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
@@ -160,13 +137,13 @@ CommMonitor::recvTimingReq(PacketPtr pkt)
 
     // Store relevant fields of packet, because packet may be modified
     // or even deleted when sendTiming() is called.
-    bool is_read = pkt->isRead();
-    bool is_write = pkt->isWrite();
-    int cmd = pkt->cmdToIndex();
-    Request::FlagsType req_flags = pkt->req->getFlags();
-    unsigned size = pkt->getSize();
-    Addr addr = pkt->getAddr();
-    bool expects_response = pkt->needsResponse() && !pkt->memInhibitAsserted();
+    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
@@ -185,18 +162,15 @@ CommMonitor::recvTimingReq(PacketPtr pkt)
         delete pkt->popSenderState();
     }
 
-    if (successful && traceStream != NULL) {
-        // Create a protobuf message representing the
-        // packet. Currently we do not preserve the flags in the
-        // trace.
-        Message::Packet pkt_msg;
-        pkt_msg.set_tick(curTick());
-        pkt_msg.set_cmd(cmd);
-        pkt_msg.set_flags(req_flags);
-        pkt_msg.set_addr(addr);
-        pkt_msg.set_size(size);
-
-        traceStream->write(pkt_msg);
+    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 && is_read) {
@@ -324,6 +298,11 @@ CommMonitor::recvTimingResp(PacketPtr pkt)
         }
     }
 
+    if (successful) {
+        assert(pkt->isResponse());
+        ppPktResp->notify(pkt);
+    }
+
     if (successful && is_read) {
         // Decrement number of outstanding read requests
         DPRINTF(CommMonitor, "Received read response\n");
@@ -386,15 +365,15 @@ CommMonitor::getAddrRanges() const
 }
 
 void
-CommMonitor::recvRetryMaster()
+CommMonitor::recvReqRetry()
 {
-    slavePort.sendRetry();
+    slavePort.sendRetryReq();
 }
 
 void
-CommMonitor::recvRetrySlave()
+CommMonitor::recvRespRetry()
 {
-    masterPort.sendRetry();
+    masterPort.sendRetryResp();
 }
 
 void