summaryrefslogtreecommitdiff
path: root/src/mem/cache
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/cache')
-rw-r--r--src/mem/cache/base.hh2
-rw-r--r--src/mem/cache/cache.hh8
-rw-r--r--src/mem/cache/cache_impl.hh60
3 files changed, 46 insertions, 24 deletions
diff --git a/src/mem/cache/base.hh b/src/mem/cache/base.hh
index 47cbaf7a0..b24e595b7 100644
--- a/src/mem/cache/base.hh
+++ b/src/mem/cache/base.hh
@@ -142,7 +142,7 @@ class BaseCache : public MemObject
* @param when time to send the response
*/
void respond(PacketPtr pkt, Tick time) {
- queue.schedSendTiming(pkt, time);
+ queue.schedSendTiming(pkt, time, true);
}
protected:
diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh
index e745529a7..a774a356c 100644
--- a/src/mem/cache/cache.hh
+++ b/src/mem/cache/cache.hh
@@ -90,6 +90,8 @@ class Cache : public BaseCache
protected:
+ virtual bool recvTimingSnoop(PacketPtr pkt);
+
virtual bool recvTiming(PacketPtr pkt);
virtual Tick recvAtomic(PacketPtr pkt);
@@ -152,11 +154,13 @@ class Cache : public BaseCache
protected:
+ virtual bool recvTimingSnoop(PacketPtr pkt);
+
virtual bool recvTiming(PacketPtr pkt);
- virtual Tick recvAtomic(PacketPtr pkt);
+ virtual Tick recvAtomicSnoop(PacketPtr pkt);
- virtual void recvFunctional(PacketPtr pkt);
+ virtual void recvFunctionalSnoop(PacketPtr pkt);
virtual unsigned deviceBlockSize() const
{ return cache->getBlockSize(); }
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index 3525e0777..fa6f6c860 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -785,7 +785,7 @@ Cache<TagStore>::functionalAccess(PacketPtr pkt, bool fromCpuSide)
} else if (forwardSnoops && cpuSidePort->getMasterPort().isSnooping()) {
// if it came from the memory side, it must be a snoop request
// and we should only forward it if we are forwarding snoops
- cpuSidePort->sendFunctional(pkt);
+ cpuSidePort->sendFunctionalSnoop(pkt);
}
}
}
@@ -1178,24 +1178,23 @@ Cache<TagStore>::handleSnoop(PacketPtr pkt, BlkType *blk,
// rewritten to be relative to cpu-side bus (if any)
bool alreadyResponded = pkt->memInhibitAsserted();
if (is_timing) {
- Packet *snoopPkt = new Packet(pkt, true); // clear flags
- snoopPkt->setExpressSnoop();
- snoopPkt->senderState = new ForwardResponseRecord(pkt, this);
- cpuSidePort->sendTiming(snoopPkt);
- if (snoopPkt->memInhibitAsserted()) {
+ Packet snoopPkt(pkt, true); // clear flags
+ snoopPkt.setExpressSnoop();
+ snoopPkt.senderState = new ForwardResponseRecord(pkt, this);
+ cpuSidePort->sendTimingSnoop(&snoopPkt);
+ if (snoopPkt.memInhibitAsserted()) {
// cache-to-cache response from some upper cache
assert(!alreadyResponded);
pkt->assertMemInhibit();
} else {
- delete snoopPkt->senderState;
+ delete snoopPkt.senderState;
}
- if (snoopPkt->sharedAsserted()) {
+ if (snoopPkt.sharedAsserted()) {
pkt->assertShared();
}
- delete snoopPkt;
} else {
- int origSrc = pkt->getSrc();
- cpuSidePort->sendAtomic(pkt);
+ Packet::NodeID origSrc = pkt->getSrc();
+ cpuSidePort->sendAtomicSnoop(pkt);
if (!alreadyResponded && pkt->memInhibitAsserted()) {
// cache-to-cache response from some upper cache:
// forward response to original requester
@@ -1335,6 +1334,16 @@ Cache<TagStore>::snoopTiming(PacketPtr pkt)
handleSnoop(pkt, blk, true, false, false);
}
+template<class TagStore>
+bool
+Cache<TagStore>::CpuSidePort::recvTimingSnoop(PacketPtr pkt)
+{
+ // Express snoop responses from master to slave, e.g., from L1 to L2
+ assert(pkt->isResponse());
+
+ cache->timingAccess(pkt);
+ return true;
+}
template<class TagStore>
Tick
@@ -1483,7 +1492,7 @@ Cache<TagStore>::getTimingPacket()
PacketPtr snoop_pkt = new Packet(tgt_pkt, true);
snoop_pkt->setExpressSnoop();
snoop_pkt->senderState = mshr;
- cpuSidePort->sendTiming(snoop_pkt);
+ cpuSidePort->sendTimingSnoop(snoop_pkt);
if (snoop_pkt->memInhibitAsserted()) {
markInService(mshr, snoop_pkt);
@@ -1550,8 +1559,9 @@ template<class TagStore>
bool
Cache<TagStore>::CpuSidePort::recvTiming(PacketPtr pkt)
{
- // illegal to block responses... can lead to deadlock
- if (pkt->isRequest() && !pkt->memInhibitAsserted() && blocked) {
+ assert(pkt->isRequest());
+ // always let inhibited requests through even if blocked
+ if (!pkt->memInhibitAsserted() && blocked) {
DPRINTF(Cache,"Scheduling a retry while blocked\n");
mustSendRetry = true;
return false;
@@ -1603,17 +1613,25 @@ Cache<TagStore>::MemSidePort::recvTiming(PacketPtr pkt)
if (pkt->wasNacked())
panic("Need to implement cache resending nacked packets!\n");
- if (pkt->isResponse()) {
- cache->handleResponse(pkt);
- } else {
- cache->snoopTiming(pkt);
- }
+ assert(pkt->isResponse());
+ cache->handleResponse(pkt);
+ return true;
+}
+
+// Express snooping requests to memside port
+template<class TagStore>
+bool
+Cache<TagStore>::MemSidePort::recvTimingSnoop(PacketPtr pkt)
+{
+ // handle snooping requests
+ assert(pkt->isRequest());
+ cache->snoopTiming(pkt);
return true;
}
template<class TagStore>
Tick
-Cache<TagStore>::MemSidePort::recvAtomic(PacketPtr pkt)
+Cache<TagStore>::MemSidePort::recvAtomicSnoop(PacketPtr pkt)
{
assert(pkt->isRequest());
// atomic snoop
@@ -1622,7 +1640,7 @@ Cache<TagStore>::MemSidePort::recvAtomic(PacketPtr pkt)
template<class TagStore>
void
-Cache<TagStore>::MemSidePort::recvFunctional(PacketPtr pkt)
+Cache<TagStore>::MemSidePort::recvFunctionalSnoop(PacketPtr pkt)
{
assert(pkt->isRequest());
// functional snoop (note that in contrast to atomic we don't have