summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2015-11-06 03:26:35 -0500
committerAndreas Hansson <andreas.hansson@arm.com>2015-11-06 03:26:35 -0500
commit8bc925e36d0e5de7e70a6d5bf2b1824649932599 (patch)
tree8ffddb6d34d4c574e9d43b75c5be804a1d0d328e
parent8e55d51aaa71d71c7058e8ee15c89d3482991ba2 (diff)
downloadgem5-8bc925e36d0e5de7e70a6d5bf2b1824649932599.tar.xz
mem: Align rules for sinking inhibited packets at the slave
This patch aligns how the memory-system slaves, i.e. the various memory controllers and the bridge, identify and deal with sinking of inhibited packets that are only useful within the coherent part of the memory system. In the future we could shift the onus to the crossbar, and add a parameter "is_point_of_coherence" that would allow it to sink the aforementioned packets.
-rw-r--r--src/mem/bridge.cc21
-rw-r--r--src/mem/bridge.hh6
-rw-r--r--src/mem/dram_ctrl.cc6
-rw-r--r--src/mem/dramsim2.cc12
-rw-r--r--src/mem/simple_mem.cc10
5 files changed, 35 insertions, 20 deletions
diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc
index ecaf6de04..855f39de3 100644
--- a/src/mem/bridge.cc
+++ b/src/mem/bridge.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2013 ARM Limited
+ * Copyright (c) 2011-2013, 2015 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -150,8 +150,20 @@ Bridge::BridgeSlavePort::recvTimingReq(PacketPtr pkt)
DPRINTF(Bridge, "recvTimingReq: %s addr 0x%x\n",
pkt->cmdString(), pkt->getAddr());
- // we should not see a timing request if we are already in a retry
- assert(!retryReq);
+ // sink inhibited packets without further action, also discard any
+ // packet that is not a read or a write
+ if (pkt->memInhibitAsserted() ||
+ !(pkt->isWrite() || pkt->isRead())) {
+ assert(!pkt->needsResponse());
+ pendingDelete.reset(pkt);
+ return true;
+ }
+
+ // we should not get a new request after committing to retry the
+ // current one, but unfortunately the CPU violates this rule, so
+ // simply ignore it for now
+ if (retryReq)
+ return false;
DPRINTF(Bridge, "Response queue size: %d outresp: %d\n",
transmitList.size(), outstandingResponses);
@@ -162,8 +174,7 @@ Bridge::BridgeSlavePort::recvTimingReq(PacketPtr pkt)
retryReq = true;
} else {
// look at the response queue if we expect to see a response
- bool expects_response = pkt->needsResponse() &&
- !pkt->memInhibitAsserted();
+ bool expects_response = pkt->needsResponse();
if (expects_response) {
if (respQueueFull()) {
DPRINTF(Bridge, "Response queue full\n");
diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh
index 6aebe5204..ad3585997 100644
--- a/src/mem/bridge.hh
+++ b/src/mem/bridge.hh
@@ -136,6 +136,12 @@ class Bridge : public MemObject
unsigned int respQueueLimit;
/**
+ * Upstream caches need this packet until true is returned, so
+ * hold it for deletion until a subsequent call
+ */
+ std::unique_ptr<Packet> pendingDelete;
+
+ /**
* Is this side blocked from accepting new response packets.
*
* @return true if the reserved space has reached the set limit
diff --git a/src/mem/dram_ctrl.cc b/src/mem/dram_ctrl.cc
index 4bd83f761..abf570910 100644
--- a/src/mem/dram_ctrl.cc
+++ b/src/mem/dram_ctrl.cc
@@ -590,10 +590,8 @@ DRAMCtrl::recvTimingReq(PacketPtr pkt)
DPRINTF(DRAM, "recvTimingReq: request %s addr %lld size %d\n",
pkt->cmdString(), pkt->getAddr(), pkt->getSize());
- // simply drop inhibited packets and clean evictions
- if (pkt->memInhibitAsserted() ||
- pkt->cmd == MemCmd::CleanEvict) {
- DPRINTF(DRAM, "Inhibited packet or clean evict -- Dropping it now\n");
+ // sink inhibited packets without further action
+ if (pkt->memInhibitAsserted()) {
pendingDelete.reset(pkt);
return true;
}
diff --git a/src/mem/dramsim2.cc b/src/mem/dramsim2.cc
index cd0f45b23..58227e06a 100644
--- a/src/mem/dramsim2.cc
+++ b/src/mem/dramsim2.cc
@@ -175,16 +175,18 @@ DRAMSim2::recvFunctional(PacketPtr pkt)
bool
DRAMSim2::recvTimingReq(PacketPtr pkt)
{
- // we should never see a new request while in retry
- assert(!retryReq);
-
+ // sink inhibited packets without further action
if (pkt->memInhibitAsserted()) {
- // snooper will supply based on copy of packet
- // still target's responsibility to delete packet
pendingDelete.reset(pkt);
return true;
}
+ // we should not get a new request after committing to retry the
+ // current one, but unfortunately the CPU violates this rule, so
+ // simply ignore it for now
+ if (retryReq)
+ return false;
+
// if we cannot accept we need to send a retry once progress can
// be made
bool can_accept = nbrOutstanding() < wrapper.queueSize();
diff --git a/src/mem/simple_mem.cc b/src/mem/simple_mem.cc
index 7e350feb6..639ccbe31 100644
--- a/src/mem/simple_mem.cc
+++ b/src/mem/simple_mem.cc
@@ -97,17 +97,15 @@ SimpleMemory::recvFunctional(PacketPtr pkt)
bool
SimpleMemory::recvTimingReq(PacketPtr pkt)
{
+ // sink inhibited packets without further action
if (pkt->memInhibitAsserted()) {
- // snooper will supply based on copy of packet
- // still target's responsibility to delete packet
pendingDelete.reset(pkt);
return true;
}
- // we should never get a new request after committing to retry the
- // current one, the bus violates the rule as it simply sends a
- // retry to the next one waiting on the retry list, so simply
- // ignore it
+ // we should not get a new request after committing to retry the
+ // current one, but unfortunately the CPU violates this rule, so
+ // simply ignore it for now
if (retryReq)
return false;