summaryrefslogtreecommitdiff
path: root/src/mem
diff options
context:
space:
mode:
authorRon Dreslinski <rdreslin@umich.edu>2006-10-05 23:28:03 -0400
committerRon Dreslinski <rdreslin@umich.edu>2006-10-05 23:28:03 -0400
commit212c5aefb580375417d357d821255c67a8d90fdf (patch)
treeb4295efc66b5ee924035d948b00bd5127f2a5ffa /src/mem
parent45f881a4ced25105267799432c0f526400f0ba9e (diff)
downloadgem5-212c5aefb580375417d357d821255c67a8d90fdf.tar.xz
Fixes for functional accesses to use the snoop path.
And small other tweaks to snooping coherence. src/mem/cache/base_cache.hh: Make timing response at the time of send. src/mem/cache/cache.hh: src/mem/cache/cache_impl.hh: Update probe interface to be bi-directional for functional accesses src/mem/packet.hh: Add the function to create an atomic response to a given request --HG-- extra : convert_revision : 04075a117cf30a7df16e6d3ce485543cc77d4ca6
Diffstat (limited to 'src/mem')
-rw-r--r--src/mem/cache/base_cache.hh2
-rw-r--r--src/mem/cache/cache.hh4
-rw-r--r--src/mem/cache/cache_impl.hh58
-rw-r--r--src/mem/packet.hh14
4 files changed, 44 insertions, 34 deletions
diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh
index 49999dcb4..19cfe1335 100644
--- a/src/mem/cache/base_cache.hh
+++ b/src/mem/cache/base_cache.hh
@@ -515,8 +515,6 @@ class BaseCache : public MemObject
*/
void respond(Packet *pkt, Tick time)
{
- pkt->makeTimingResponse();
- pkt->result = Packet::Success;
CacheEvent *reqCpu = new CacheEvent(cpuSidePort, pkt);
reqCpu->schedule(time);
}
diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh
index 989b8743e..4b8870c95 100644
--- a/src/mem/cache/cache.hh
+++ b/src/mem/cache/cache.hh
@@ -251,7 +251,7 @@ class Cache : public BaseCache
* request.
* @return The estimated completion time.
*/
- Tick probe(Packet * &pkt, bool update);
+ Tick probe(Packet * &pkt, bool update, CachePort * otherSidePort);
/**
* Snoop for the provided request in the cache and return the estimated
@@ -262,7 +262,7 @@ class Cache : public BaseCache
* request.
* @return The estimated completion time.
*/
- Tick snoopProbe(Packet * &pkt, bool update);
+ Tick snoopProbe(Packet * &pkt);
};
#endif // __CACHE_HH__
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index bea495f9f..228cd2d73 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -99,7 +99,7 @@ doAtomicAccess(Packet *pkt, bool isCpuSide)
pkt->req->setScResult(1);
}
- probe(pkt, true);
+ probe(pkt, true, NULL);
//TEMP ALWAYS SUCCES FOR NOW
pkt->result = Packet::Success;
}
@@ -108,7 +108,7 @@ doAtomicAccess(Packet *pkt, bool isCpuSide)
if (pkt->isResponse())
handleResponse(pkt);
else
- snoopProbe(pkt, true);
+ snoopProbe(pkt);
}
//Fix this timing info
return hitLatency;
@@ -129,16 +129,13 @@ doFunctionalAccess(Packet *pkt, bool isCpuSide)
assert("Can't handle LL/SC on functional path\n");
}
- probe(pkt, false);
+ probe(pkt, false, memSidePort);
//TEMP ALWAYS SUCCESFUL FOR NOW
pkt->result = Packet::Success;
}
else
{
- if (pkt->isResponse())
- handleResponse(pkt);
- else
- snoopProbe(pkt, false);
+ probe(pkt, false, cpuSidePort);
}
}
@@ -251,7 +248,7 @@ Cache<TagStore,Buffering,Coherence>::access(PacketPtr &pkt)
pkt->getAddr() & ~((Addr)blkSize - 1), pkt->req->getPC());
if (blk) {
// Hit
- hits[pkt->cmdToIndex()][pkt->req->getThreadNum()]++;
+ hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++;
// clear dirty bit if write through
if (pkt->needsResponse())
respond(pkt, curTick+lat);
@@ -261,7 +258,7 @@ Cache<TagStore,Buffering,Coherence>::access(PacketPtr &pkt)
// Miss
if (!pkt->req->isUncacheable()) {
- misses[pkt->cmdToIndex()][pkt->req->getThreadNum()]++;
+ misses[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++;
/** @todo Move miss count code into BaseCache */
if (missCount) {
--missCount;
@@ -282,7 +279,7 @@ Cache<TagStore,Buffering,Coherence>::getPacket()
Packet * pkt = missQueue->getPacket();
if (pkt) {
if (!pkt->req->isUncacheable()) {
- if (pkt->cmd == Packet::HardPFReq) misses[Packet::HardPFReq][pkt->req->getThreadNum()]++;
+ if (pkt->cmd == Packet::HardPFReq) misses[Packet::HardPFReq][0/*pkt->req->getThreadNum()*/]++;
BlkType *blk = tags->findBlock(pkt);
Packet::Command cmd = coherence->getBusCmd(pkt->cmd,
(blk)? blk->status : 0);
@@ -326,7 +323,7 @@ Cache<TagStore,Buffering,Coherence>::handleResponse(Packet * &pkt)
PacketList writebacks;
blk = tags->handleFill(blk, (MSHR*)pkt->senderState,
coherence->getNewState(pkt,old_state),
- writebacks);
+ writebacks, pkt);
while (!writebacks.empty()) {
missQueue->doWriteback(writebacks.front());
}
@@ -384,7 +381,6 @@ template<class TagStore, class Buffering, class Coherence>
void
Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
{
- DPRINTF(Cache, "SNOOPING");
Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
BlkType *blk = tags->findBlock(pkt);
MSHR *mshr = missQueue->findMSHR(blk_addr);
@@ -502,7 +498,7 @@ Cache<TagStore,Buffering,Coherence>::invalidateBlk(Addr addr)
*/
template<class TagStore, class Buffering, class Coherence>
Tick
-Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update)
+Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update, CachePort* otherSidePort)
{
// MemDebug::cacheProbe(pkt);
if (!pkt->req->isUncacheable()) {
@@ -533,7 +529,8 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update)
missQueue->findWrites(blk_addr, writes);
if (!update) {
- memSidePort->sendFunctional(pkt);
+ otherSidePort->sendFunctional(pkt);
+
// Check for data in MSHR and writebuffer.
if (mshr) {
warn("Found outstanding miss on an non-update probe");
@@ -628,12 +625,15 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update)
lat = memSidePort->sendAtomic(busPkt);
+ //Be sure to flip the response to a request for coherence
+ busPkt->makeAtomicResponse();
+
/* if (!(busPkt->flags & SATISFIED)) {
// blocked at a higher level, just return
return 0;
}
-*/ misses[pkt->cmdToIndex()][pkt->req->getThreadNum()]++;
+*/ misses[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++;
CacheBlk::State old_state = (blk) ? blk->status : 0;
tags->handleFill(blk, busPkt,
@@ -658,10 +658,10 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update)
}
if (update) {
- hits[pkt->cmdToIndex()][pkt->req->getThreadNum()]++;
+ hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++;
} else if (pkt->isWrite()) {
// Still need to change data in all locations.
- return memSidePort->sendAtomic(pkt);
+ return otherSidePort->sendAtomic(pkt);
}
return curTick + lat;
}
@@ -671,18 +671,18 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update)
template<class TagStore, class Buffering, class Coherence>
Tick
-Cache<TagStore,Buffering,Coherence>::snoopProbe(PacketPtr &pkt, bool update)
+Cache<TagStore,Buffering,Coherence>::snoopProbe(PacketPtr &pkt)
{
- Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
- BlkType *blk = tags->findBlock(pkt);
- MSHR *mshr = missQueue->findMSHR(blk_addr);
- CacheBlk::State new_state = 0;
- bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state);
- if (satisfy) {
- tags->handleSnoop(blk, new_state, pkt);
- return hitLatency;
- }
- tags->handleSnoop(blk, new_state);
- return 0;
+ Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
+ BlkType *blk = tags->findBlock(pkt);
+ MSHR *mshr = missQueue->findMSHR(blk_addr);
+ CacheBlk::State new_state = 0;
+ bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state);
+ if (satisfy) {
+ tags->handleSnoop(blk, new_state, pkt);
+ return hitLatency;
+ }
+ tags->handleSnoop(blk, new_state);
+ return 0;
}
diff --git a/src/mem/packet.hh b/src/mem/packet.hh
index c7d28010c..be9bf5f57 100644
--- a/src/mem/packet.hh
+++ b/src/mem/packet.hh
@@ -312,7 +312,7 @@ class Packet
* for returning as a response to that request. Used for timing
* accesses only. For atomic and functional accesses, the
* request packet is always implicitly passed back *without*
- * modifying the command or destination fields, so this function
+ * modifying the destination fields, so this function
* should not be called. */
void makeTimingResponse() {
assert(needsResponse());
@@ -325,6 +325,18 @@ class Packet
srcValid = false;
}
+ /** Take a request packet and modify it in place to be suitable
+ * for returning as a response to that request.
+ */
+ void makeAtomicResponse() {
+ assert(needsResponse());
+ assert(isRequest());
+ int icmd = (int)cmd;
+ icmd &= ~(IsRequest);
+ icmd |= IsResponse;
+ cmd = (Command)icmd;
+ }
+
/** Take a request packet that has been returned as NACKED and modify it so
* that it can be sent out again. Only packets that need a response can be
* NACKED, so verify that that is true. */