Fixes to get single level uni-coherence to work.

Now to try L2 caches in FS.

src/mem/cache/base_cache.hh:
    Fix uni-coherence for atomic accesses in coherence protocol access to port
src/mem/cache/cache_impl.hh:
    Properly handle uni-coherence
src/mem/cache/coherence/simple_coherence.hh:
    Properly forward invalidates (not done for MSI+ protocols (assumed top level for now)
src/mem/cache/coherence/uni_coherence.cc:
src/mem/cache/coherence/uni_coherence.hh:
    Properly forward invalidates in atomic/timing uni-coherence

--HG--
extra : convert_revision : f0f11315e8e7f32c19d92287f6f9c27b079c96f7
This commit is contained in:
Ron Dreslinski
2006-10-19 20:02:57 -04:00
parent 9cf063eb8e
commit e34e564f79
5 changed files with 61 additions and 30 deletions

View File

@@ -128,8 +128,10 @@ class BaseCache : public MemObject
const char *description();
};
protected:
public: //Made public so coherence can get at it.
CachePort *cpuSidePort;
protected:
CachePort *memSidePort;
bool snoopRangesSent;

View File

@@ -373,10 +373,15 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
//Revisit this for multi level coherence
return;
}
//Send a timing (true) invalidate up if the protocol calls for it
coherence->propogateInvalidate(pkt, true);
Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
BlkType *blk = tags->findBlock(pkt);
MSHR *mshr = missQueue->findMSHR(blk_addr);
if (coherence->hasProtocol()) { //@todo Move this into handle bus req
if (coherence->hasProtocol() || pkt->isInvalidate()) {
//@todo Move this into handle bus req
//If we find an mshr, and it is in service, we need to NACK or
//invalidate
if (mshr) {
@@ -626,6 +631,7 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update,
}
}
return 0;
} else if (!blk) {
// update the cache state and statistics
if (mshr || !writes.empty()){
@@ -713,24 +719,27 @@ template<class TagStore, class Buffering, class Coherence>
Tick
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) {
DPRINTF(Cache, "Cache snooped a %s request for addr %x and "
"now supplying data, new state is %i\n",
pkt->cmdString(), blk_addr, new_state);
//Send a atomic (false) invalidate up if the protocol calls for it
coherence->propogateInvalidate(pkt, true);
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) {
DPRINTF(Cache, "Cache snooped a %s request for addr %x and "
"now supplying data, new state is %i\n",
pkt->cmdString(), blk_addr, new_state);
tags->handleSnoop(blk, new_state, pkt);
return hitLatency;
}
if (blk)
DPRINTF(Cache, "Cache snooped a %s request for addr %x, "
"new state is %i\n",
}
if (blk)
DPRINTF(Cache, "Cache snooped a %s request for addr %x, "
"new state is %i\n",
pkt->cmdString(), blk_addr, new_state);
tags->handleSnoop(blk, new_state);
return 0;
tags->handleSnoop(blk, new_state);
return 0;
}

View File

@@ -160,6 +160,12 @@ class SimpleCoherence
bool allowFastWrites() { return false; }
bool hasProtocol() { return true; }
void propogateInvalidate(Packet *pkt, bool isTiming)
{
//For now we do nothing, asssumes simple coherence is top level of cache
return;
}
};
#endif //__SIMPLE_COHERENCE_HH__

View File

@@ -76,19 +76,31 @@ UniCoherence::handleBusRequest(Packet * &pkt, CacheBlk *blk, MSHR *mshr,
{
new_state = 0;
if (pkt->isInvalidate()) {
DPRINTF(Cache, "snoop inval on blk %x (blk ptr %x)\n",
pkt->getAddr(), blk);
// Forward to other caches
Packet * tmp = new Packet(pkt->req, Packet::InvalidateReq, -1);
cshrs.allocate(tmp);
cache->setSlaveRequest(Request_Coherence, curTick);
if (cshrs.isFull()) {
cache->setBlockedForSnoop(Blocked_Coherence);
}
} else {
if (blk) {
new_state = blk->status;
}
DPRINTF(Cache, "snoop inval on blk %x (blk ptr %x)\n",
pkt->getAddr(), blk);
}
else if (blk) {
new_state = blk->status;
}
return false;
}
void
UniCoherence::propogateInvalidate(Packet *pkt, bool isTiming)
{
if (pkt->isInvalidate()) {
if (isTiming) {
// Forward to other caches
Packet * tmp = new Packet(pkt->req, Packet::InvalidateReq, -1);
cshrs.allocate(tmp);
cache->setSlaveRequest(Request_Coherence, curTick);
if (cshrs.isFull())
cache->setBlockedForSnoop(Blocked_Coherence);
}
else {
Packet * tmp = new Packet(pkt->req, Packet::InvalidateReq, -1);
cache->cpuSidePort->sendAtomic(tmp);
delete tmp;
}
}
}

View File

@@ -139,6 +139,8 @@ class UniCoherence
bool allowFastWrites() { return true; }
bool hasProtocol() { return false; }
void propogateInvalidate(Packet *pkt, bool isTiming);
};
#endif //__UNI_COHERENCE_HH__