diff options
author | Ron Dreslinski <rdreslin@umich.edu> | 2006-10-13 15:47:05 -0400 |
---|---|---|
committer | Ron Dreslinski <rdreslin@umich.edu> | 2006-10-13 15:47:05 -0400 |
commit | a17afb1649e26c248dc4a61e4a0ef6671785e992 (patch) | |
tree | af88a388d554563222a2612c938a1b8bdc1f2544 | |
parent | eddbb6801f6f9666d81cb5491b4ceedd3955f996 (diff) | |
download | gem5-a17afb1649e26c248dc4a61e4a0ef6671785e992.tar.xz |
Fix for DMA's in FS caches.
Fix CSHR's for flow control.
Fix for Bus Bridges reusing packets (clean flags up)
Now both timing/atomic caches with MOESI in UP fail at same point.
src/dev/io_device.hh:
DMA's should send WriteInvalidates
src/mem/bridge.cc:
Reusing packet, clean flags in the packet set by bus.
src/mem/cache/base_cache.cc:
src/mem/cache/base_cache.hh:
src/mem/cache/cache.hh:
src/mem/cache/cache_impl.hh:
src/mem/cache/coherence/simple_coherence.hh:
src/mem/cache/coherence/uni_coherence.cc:
src/mem/cache/coherence/uni_coherence.hh:
Fix CSHR's for flow control.
src/mem/packet.hh:
Make a writeInvalidateResp, since the DMA expects responses to it's writes
--HG--
extra : convert_revision : 59fd6658bcc0d076f4b143169caca946472a86cd
-rw-r--r-- | src/dev/io_device.hh | 2 | ||||
-rw-r--r-- | src/mem/bridge.cc | 1 | ||||
-rw-r--r-- | src/mem/cache/base_cache.cc | 57 | ||||
-rw-r--r-- | src/mem/cache/base_cache.hh | 14 | ||||
-rw-r--r-- | src/mem/cache/cache.hh | 7 | ||||
-rw-r--r-- | src/mem/cache/cache_impl.hh | 10 | ||||
-rw-r--r-- | src/mem/cache/coherence/simple_coherence.hh | 12 | ||||
-rw-r--r-- | src/mem/cache/coherence/uni_coherence.cc | 30 | ||||
-rw-r--r-- | src/mem/cache/coherence/uni_coherence.hh | 8 | ||||
-rw-r--r-- | src/mem/packet.hh | 4 |
10 files changed, 99 insertions, 46 deletions
diff --git a/src/dev/io_device.hh b/src/dev/io_device.hh index df4f494cb..24e822a40 100644 --- a/src/dev/io_device.hh +++ b/src/dev/io_device.hh @@ -256,7 +256,7 @@ class DmaDevice : public PioDevice virtual ~DmaDevice(); void dmaWrite(Addr addr, int size, Event *event, uint8_t *data) - { dmaPort->dmaAction(Packet::WriteReq, addr, size, event, data) ; } + { dmaPort->dmaAction(Packet::WriteInvalidateReq, addr, size, event, data) ; } void dmaRead(Addr addr, int size, Event *event, uint8_t *data = NULL) { dmaPort->dmaAction(Packet::ReadReq, addr, size, event, data); } diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc index 9c14e7ee2..b181dd583 100644 --- a/src/mem/bridge.cc +++ b/src/mem/bridge.cc @@ -153,6 +153,7 @@ Bridge::BridgePort::trySend() DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n", buf->origSrc, pkt->getDest(), pkt->getAddr()); + pkt->flags &= ~SNOOP_COMMIT; //CLear it if it was set if (sendTiming(pkt)) { // send successful sendQueue.pop_front(); diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc index 3f7a52fab..938bd8786 100644 --- a/src/mem/cache/base_cache.cc +++ b/src/mem/cache/base_cache.cc @@ -44,7 +44,6 @@ BaseCache::CachePort::CachePort(const std::string &_name, BaseCache *_cache, : Port(_name), cache(_cache), isCpuSide(_isCpuSide) { blocked = false; - cshrRetry = NULL; waitingOnRetry = false; //Start ports at null if more than one is created we should panic //cpuSidePort = NULL; @@ -195,20 +194,20 @@ BaseCache::CachePort::recvRetry() } else { - assert(cshrRetry); + assert(cache->doSlaveRequest()); //pkt = cache->getCoherencePacket(); //We save the packet, no reordering on CSHRS - pkt = cshrRetry; + pkt = cache->getCoherencePacket(); + MSHR* cshr = (MSHR*)pkt->senderState; bool success = sendTiming(pkt); + cache->sendCoherenceResult(pkt, cshr, success); waitingOnRetry = !success; - if (success) + if (success && cache->doSlaveRequest()) { - if (cache->doSlaveRequest()) { - //Still more to issue, rerequest in 1 cycle - BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this); - reqCpu->schedule(curTick + 1); - } - cshrRetry = NULL; + DPRINTF(CachePort, "%s has more requests\n", name()); + //Still more to issue, rerequest in 1 cycle + BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this); + reqCpu->schedule(curTick + 1); } } if (waitingOnRetry) DPRINTF(CachePort, "%s STILL Waiting on retry\n", name()); @@ -294,10 +293,12 @@ BaseCache::CacheEvent::process() pkt->getAddr(), success ? "succesful" : "unsuccesful"); cachePort->cache->sendResult(pkt, mshr, success); cachePort->waitingOnRetry = !success; - if (cachePort->waitingOnRetry) DPRINTF(CachePort, "%s now waiting on a retry\n", cachePort->name()); + if (cachePort->waitingOnRetry) + DPRINTF(CachePort, "%s now waiting on a retry\n", cachePort->name()); if (success && cachePort->cache->doMasterRequest()) { - DPRINTF(CachePort, "%s still more MSHR requests to send\n", cachePort->name()); + DPRINTF(CachePort, "%s still more MSHR requests to send\n", + cachePort->name()); //Still more to issue, rerequest in 1 cycle pkt = NULL; this->schedule(curTick+1); @@ -306,27 +307,21 @@ BaseCache::CacheEvent::process() else { //CSHR - if (!cachePort->cshrRetry) { - assert(cachePort->cache->doSlaveRequest()); - pkt = cachePort->cache->getCoherencePacket(); - } - else { - pkt = cachePort->cshrRetry; - } + assert(cachePort->cache->doSlaveRequest()); + pkt = cachePort->cache->getCoherencePacket(); + MSHR* cshr = (MSHR*) pkt->senderState; bool success = cachePort->sendTiming(pkt); - if (!success) { - //Need to send on a retry - cachePort->cshrRetry = pkt; - cachePort->waitingOnRetry = true; - } - else + cachePort->cache->sendResult(pkt, cshr, success); + cachePort->waitingOnRetry = !success; + if (cachePort->waitingOnRetry) + DPRINTF(CachePort, "%s now waiting on a retry\n", cachePort->name()); + if (success && cachePort->cache->doSlaveRequest()) { - cachePort->cshrRetry = NULL; - if (cachePort->cache->doSlaveRequest()) { - //Still more to issue, rerequest in 1 cycle - pkt = NULL; - this->schedule(curTick+1); - } + DPRINTF(CachePort, "%s still more CSHR requests to send\n", + cachePort->name()); + //Still more to issue, rerequest in 1 cycle + pkt = NULL; + this->schedule(curTick+1); } } return; diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh index 455e13d9c..7a9e57430 100644 --- a/src/mem/cache/base_cache.hh +++ b/src/mem/cache/base_cache.hh @@ -116,7 +116,6 @@ class BaseCache : public MemObject std::list<Packet *> drainList; - Packet *cshrRetry; }; struct CacheEvent : public Event @@ -188,6 +187,12 @@ class BaseCache : public MemObject fatal("No implementation"); } + virtual void sendCoherenceResult(Packet* &pkt, MSHR* mshr, bool success) + { + + fatal("No implementation"); + } + /** * Bit vector of the blocking reasons for the access path. * @sa #BlockedCause @@ -489,10 +494,13 @@ class BaseCache : public MemObject */ void setSlaveRequest(RequestCause cause, Tick time) { + if (!doSlaveRequest() && !cpuSidePort->waitingOnRetry) + { + BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(cpuSidePort); + reqCpu->schedule(time); + } uint8_t flag = 1<<cause; slaveRequests |= flag; - assert("Implement\n" && 0); -// si->pktuest(time); } /** diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh index 41b270030..7024ce58a 100644 --- a/src/mem/cache/cache.hh +++ b/src/mem/cache/cache.hh @@ -179,6 +179,13 @@ class Cache : public BaseCache virtual void sendResult(Packet * &pkt, MSHR* mshr, bool success); /** + * Was the CSHR request was sent successfully? + * @param pkt The request. + * @param success True if the request was sent successfully. + */ + virtual void sendCoherenceResult(Packet * &pkt, MSHR* cshr, bool success); + + /** * Handles a response (cache line fill/write ack) from the bus. * @param pkt The request being responded to. */ diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 9db79b843..00f93328e 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -304,6 +304,7 @@ Cache<TagStore,Buffering,Coherence>::handleResponse(Packet * &pkt) { BlkType *blk = NULL; if (pkt->senderState) { + ((MSHR*)pkt->senderState)->pkt = pkt; if (pkt->result == Packet::Nacked) { //pkt->reinitFromRequest(); warn("NACKs from devices not connected to the same bus not implemented\n"); @@ -379,6 +380,15 @@ Cache<TagStore,Buffering,Coherence>::getCoherencePacket() return coherence->getPacket(); } +template<class TagStore, class Buffering, class Coherence> +void +Cache<TagStore,Buffering,Coherence>::sendCoherenceResult(Packet* &pkt, + MSHR *cshr, + bool success) +{ + coherence->sendResult(pkt, cshr, success); +} + template<class TagStore, class Buffering, class Coherence> void diff --git a/src/mem/cache/coherence/simple_coherence.hh b/src/mem/cache/coherence/simple_coherence.hh index 71d8f36f4..a356b3ecc 100644 --- a/src/mem/cache/coherence/simple_coherence.hh +++ b/src/mem/cache/coherence/simple_coherence.hh @@ -95,6 +95,18 @@ class SimpleCoherence } /** + * Was the CSHR request was sent successfully? + * @param pkt The request. + * @param success True if the request was sent successfully. + */ + void sendResult(Packet * &pkt, MSHR* cshr, bool success) + { + //Don't do coherence + return; + } + + + /** * Return the proper state given the current state and the bus response. * @param pkt The bus response. * @param current The current block state. diff --git a/src/mem/cache/coherence/uni_coherence.cc b/src/mem/cache/coherence/uni_coherence.cc index 0efe393f9..751de4801 100644 --- a/src/mem/cache/coherence/uni_coherence.cc +++ b/src/mem/cache/coherence/uni_coherence.cc @@ -43,20 +43,30 @@ UniCoherence::UniCoherence() Packet * UniCoherence::getPacket() { - bool unblock = cshrs.isFull(); Packet* pkt = cshrs.getReq(); - cshrs.markInService((MSHR*)pkt->senderState); - if (!cshrs.havePending()) { - cache->clearSlaveRequest(Request_Coherence); - } - if (unblock) { - //since CSHRs are always used as buffers, should always get rid of one - assert(!cshrs.isFull()); - cache->clearBlocked(Blocked_Coherence); - } return pkt; } +void +UniCoherence::sendResult(Packet * &pkt, MSHR* cshr, bool success) +{ + if (success) + { + bool unblock = cshrs.isFull(); + cshrs.markInService(cshr); + if (!cshrs.havePending()) { + cache->clearSlaveRequest(Request_Coherence); + } + cshrs.deallocate(cshr); + if (unblock) { + //since CSHRs are always used as buffers, should always get rid of one + assert(!cshrs.isFull()); + cache->clearBlocked(Blocked_Coherence); + } + } +} + + /** * @todo add support for returning slave requests, not doing them here. */ diff --git a/src/mem/cache/coherence/uni_coherence.hh b/src/mem/cache/coherence/uni_coherence.hh index 27b6c7fb5..60da7a36e 100644 --- a/src/mem/cache/coherence/uni_coherence.hh +++ b/src/mem/cache/coherence/uni_coherence.hh @@ -108,6 +108,7 @@ class UniCoherence else return BlkValid | BlkWritable; } + /** * Return outstanding invalidate to forward. * @return The next invalidate to forward to lower levels of cache. @@ -115,6 +116,13 @@ class UniCoherence Packet * getPacket(); /** + * Was the CSHR request was sent successfully? + * @param pkt The request. + * @param success True if the request was sent successfully. + */ + void sendResult(Packet * &pkt, MSHR* cshr, bool success); + + /** * Handle snooped bus requests. * @param pkt The snooped bus request. * @param blk The cache block corresponding to the request, if any. diff --git a/src/mem/packet.hh b/src/mem/packet.hh index 48b32ec47..319a4e534 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -202,7 +202,9 @@ class Packet HardPFResp = IsRead | IsResponse | IsHWPrefetch | NeedsResponse | HasData, InvalidateReq = IsInvalidate | IsRequest, - WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest | HasData, + WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest + | HasData | NeedsResponse, + WriteInvalidateResp = IsWrite | IsInvalidate | IsRequest | NeedsResponse, UpgradeReq = IsInvalidate | IsRequest | IsUpgrade, ReadExReq = IsRead | IsInvalidate | IsRequest | NeedsResponse, ReadExResp = IsRead | IsInvalidate | IsResponse |