summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mem/bus.cc7
-rw-r--r--src/mem/cache/base_cache.cc32
2 files changed, 25 insertions, 14 deletions
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index 75ffed0d2..b11b6de58 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -320,7 +320,7 @@ Bus::functionalSnoop(Packet *pkt)
{
std::vector<int> ports = findSnoopPorts(pkt->getAddr(), pkt->getSrc());
- while (!ports.empty())
+ while (!ports.empty() && pkt->result != Packet::Success)
{
interfaces[ports.back()]->sendFunctional(pkt);
ports.pop_back();
@@ -367,7 +367,10 @@ Bus::recvFunctional(Packet *pkt)
pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
assert(pkt->getDest() == Packet::Broadcast);
functionalSnoop(pkt);
- findPort(pkt->getAddr(), pkt->getSrc())->sendFunctional(pkt);
+
+ // If the snooping found what we were looking for, we're done.
+ if (pkt->result != Packet::Success)
+ findPort(pkt->getAddr(), pkt->getSrc())->sendFunctional(pkt);
}
/** Function called by the port when the bus is receiving a status change.*/
diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc
index 4a4a81f73..3f7a52fab 100644
--- a/src/mem/cache/base_cache.cc
+++ b/src/mem/cache/base_cache.cc
@@ -189,7 +189,6 @@ BaseCache::CachePort::recvRetry()
{
DPRINTF(CachePort, "%s has more requests\n", name());
//Still more to issue, rerequest in 1 cycle
- pkt = NULL;
BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this);
reqCpu->schedule(curTick + 1);
}
@@ -202,12 +201,13 @@ BaseCache::CachePort::recvRetry()
pkt = cshrRetry;
bool success = sendTiming(pkt);
waitingOnRetry = !success;
- if (success && cache->doSlaveRequest())
+ if (success)
{
- //Still more to issue, rerequest in 1 cycle
- pkt = NULL;
- BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this);
- reqCpu->schedule(curTick + 1);
+ if (cache->doSlaveRequest()) {
+ //Still more to issue, rerequest in 1 cycle
+ BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this);
+ reqCpu->schedule(curTick + 1);
+ }
cshrRetry = NULL;
}
}
@@ -305,20 +305,28 @@ BaseCache::CacheEvent::process()
}
else
{
- assert(cachePort->cache->doSlaveRequest());
//CSHR
- pkt = cachePort->cache->getCoherencePacket();
+ if (!cachePort->cshrRetry) {
+ assert(cachePort->cache->doSlaveRequest());
+ pkt = cachePort->cache->getCoherencePacket();
+ }
+ else {
+ pkt = cachePort->cshrRetry;
+ }
bool success = cachePort->sendTiming(pkt);
if (!success) {
//Need to send on a retry
cachePort->cshrRetry = pkt;
cachePort->waitingOnRetry = true;
}
- else if (cachePort->cache->doSlaveRequest())
+ else
{
- //Still more to issue, rerequest in 1 cycle
- pkt = NULL;
- this->schedule(curTick+1);
+ cachePort->cshrRetry = NULL;
+ if (cachePort->cache->doSlaveRequest()) {
+ //Still more to issue, rerequest in 1 cycle
+ pkt = NULL;
+ this->schedule(curTick+1);
+ }
}
}
return;