/*
- * 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
* Andreas Hansson
*/
+#include "base/trace.hh"
#include "debug/CommMonitor.hh"
#include "mem/comm_monitor.hh"
#include "sim/stats.hh"
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*
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;
}
}
-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;
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
// 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
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
// If it needs a response increment number of outstanding read
// requests
- if (!stats.disableOutstandingHists && needsResponse) {
+ if (!stats.disableOutstandingHists && expects_response) {
++stats.outstandingReadReqs;
}
}
stats.timeOfLastReq = curTick();
}
- } else if (successful && isWrite) {
+ } else if (successful && is_write) {
DPRINTF(CommMonitor, "Forwarded write request\n");
// Same as for reads
stats.writeAddrDist.sample(addr & writeAddrMask);
}
- if (!stats.disableOutstandingHists && needsResponse) {
+ if (!stats.disableOutstandingHists && expects_response) {
++stats.outstandingWriteReqs;
}
// 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
// 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) {
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) {
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