summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Dreslinski <rdreslin@umich.edu>2006-10-13 15:47:05 -0400
committerRon Dreslinski <rdreslin@umich.edu>2006-10-13 15:47:05 -0400
commita17afb1649e26c248dc4a61e4a0ef6671785e992 (patch)
treeaf88a388d554563222a2612c938a1b8bdc1f2544
parenteddbb6801f6f9666d81cb5491b4ceedd3955f996 (diff)
downloadgem5-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.hh2
-rw-r--r--src/mem/bridge.cc1
-rw-r--r--src/mem/cache/base_cache.cc57
-rw-r--r--src/mem/cache/base_cache.hh14
-rw-r--r--src/mem/cache/cache.hh7
-rw-r--r--src/mem/cache/cache_impl.hh10
-rw-r--r--src/mem/cache/coherence/simple_coherence.hh12
-rw-r--r--src/mem/cache/coherence/uni_coherence.cc30
-rw-r--r--src/mem/cache/coherence/uni_coherence.hh8
-rw-r--r--src/mem/packet.hh4
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