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
This commit is contained in:
Ron Dreslinski 2006-10-13 15:47:05 -04:00
parent eddbb6801f
commit a17afb1649
10 changed files with 99 additions and 46 deletions

View file

@ -256,7 +256,7 @@ class DmaDevice : public PioDevice
virtual ~DmaDevice(); virtual ~DmaDevice();
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data) 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) void dmaRead(Addr addr, int size, Event *event, uint8_t *data = NULL)
{ dmaPort->dmaAction(Packet::ReadReq, addr, size, event, data); } { dmaPort->dmaAction(Packet::ReadReq, addr, size, event, data); }

View file

@ -153,6 +153,7 @@ Bridge::BridgePort::trySend()
DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n", DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n",
buf->origSrc, pkt->getDest(), pkt->getAddr()); buf->origSrc, pkt->getDest(), pkt->getAddr());
pkt->flags &= ~SNOOP_COMMIT; //CLear it if it was set
if (sendTiming(pkt)) { if (sendTiming(pkt)) {
// send successful // send successful
sendQueue.pop_front(); sendQueue.pop_front();

View file

@ -44,7 +44,6 @@ BaseCache::CachePort::CachePort(const std::string &_name, BaseCache *_cache,
: Port(_name), cache(_cache), isCpuSide(_isCpuSide) : Port(_name), cache(_cache), isCpuSide(_isCpuSide)
{ {
blocked = false; blocked = false;
cshrRetry = NULL;
waitingOnRetry = false; waitingOnRetry = false;
//Start ports at null if more than one is created we should panic //Start ports at null if more than one is created we should panic
//cpuSidePort = NULL; //cpuSidePort = NULL;
@ -195,20 +194,20 @@ BaseCache::CachePort::recvRetry()
} }
else else
{ {
assert(cshrRetry); assert(cache->doSlaveRequest());
//pkt = cache->getCoherencePacket(); //pkt = cache->getCoherencePacket();
//We save the packet, no reordering on CSHRS //We save the packet, no reordering on CSHRS
pkt = cshrRetry; pkt = cache->getCoherencePacket();
MSHR* cshr = (MSHR*)pkt->senderState;
bool success = sendTiming(pkt); bool success = sendTiming(pkt);
cache->sendCoherenceResult(pkt, cshr, success);
waitingOnRetry = !success; waitingOnRetry = !success;
if (success) if (success && cache->doSlaveRequest())
{ {
if (cache->doSlaveRequest()) { DPRINTF(CachePort, "%s has more requests\n", name());
//Still more to issue, rerequest in 1 cycle //Still more to issue, rerequest in 1 cycle
BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this); BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this);
reqCpu->schedule(curTick + 1); reqCpu->schedule(curTick + 1);
}
cshrRetry = NULL;
} }
} }
if (waitingOnRetry) DPRINTF(CachePort, "%s STILL Waiting on retry\n", name()); if (waitingOnRetry) DPRINTF(CachePort, "%s STILL Waiting on retry\n", name());
@ -294,10 +293,12 @@ BaseCache::CacheEvent::process()
pkt->getAddr(), success ? "succesful" : "unsuccesful"); pkt->getAddr(), success ? "succesful" : "unsuccesful");
cachePort->cache->sendResult(pkt, mshr, success); cachePort->cache->sendResult(pkt, mshr, success);
cachePort->waitingOnRetry = !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()) 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 //Still more to issue, rerequest in 1 cycle
pkt = NULL; pkt = NULL;
this->schedule(curTick+1); this->schedule(curTick+1);
@ -306,27 +307,21 @@ BaseCache::CacheEvent::process()
else else
{ {
//CSHR //CSHR
if (!cachePort->cshrRetry) { assert(cachePort->cache->doSlaveRequest());
assert(cachePort->cache->doSlaveRequest()); pkt = cachePort->cache->getCoherencePacket();
pkt = cachePort->cache->getCoherencePacket(); MSHR* cshr = (MSHR*) pkt->senderState;
}
else {
pkt = cachePort->cshrRetry;
}
bool success = cachePort->sendTiming(pkt); bool success = cachePort->sendTiming(pkt);
if (!success) { cachePort->cache->sendResult(pkt, cshr, success);
//Need to send on a retry cachePort->waitingOnRetry = !success;
cachePort->cshrRetry = pkt; if (cachePort->waitingOnRetry)
cachePort->waitingOnRetry = true; DPRINTF(CachePort, "%s now waiting on a retry\n", cachePort->name());
} if (success && cachePort->cache->doSlaveRequest())
else
{ {
cachePort->cshrRetry = NULL; DPRINTF(CachePort, "%s still more CSHR requests to send\n",
if (cachePort->cache->doSlaveRequest()) { cachePort->name());
//Still more to issue, rerequest in 1 cycle //Still more to issue, rerequest in 1 cycle
pkt = NULL; pkt = NULL;
this->schedule(curTick+1); this->schedule(curTick+1);
}
} }
} }
return; return;

View file

@ -116,7 +116,6 @@ class BaseCache : public MemObject
std::list<Packet *> drainList; std::list<Packet *> drainList;
Packet *cshrRetry;
}; };
struct CacheEvent : public Event struct CacheEvent : public Event
@ -188,6 +187,12 @@ class BaseCache : public MemObject
fatal("No implementation"); 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. * Bit vector of the blocking reasons for the access path.
* @sa #BlockedCause * @sa #BlockedCause
@ -489,10 +494,13 @@ class BaseCache : public MemObject
*/ */
void setSlaveRequest(RequestCause cause, Tick time) 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; uint8_t flag = 1<<cause;
slaveRequests |= flag; slaveRequests |= flag;
assert("Implement\n" && 0);
// si->pktuest(time);
} }
/** /**

View file

@ -178,6 +178,13 @@ class Cache : public BaseCache
*/ */
virtual void sendResult(Packet * &pkt, MSHR* mshr, bool success); 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. * Handles a response (cache line fill/write ack) from the bus.
* @param pkt The request being responded to. * @param pkt The request being responded to.

View file

@ -304,6 +304,7 @@ Cache<TagStore,Buffering,Coherence>::handleResponse(Packet * &pkt)
{ {
BlkType *blk = NULL; BlkType *blk = NULL;
if (pkt->senderState) { if (pkt->senderState) {
((MSHR*)pkt->senderState)->pkt = pkt;
if (pkt->result == Packet::Nacked) { if (pkt->result == Packet::Nacked) {
//pkt->reinitFromRequest(); //pkt->reinitFromRequest();
warn("NACKs from devices not connected to the same bus not implemented\n"); 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(); 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> template<class TagStore, class Buffering, class Coherence>
void void

View file

@ -94,6 +94,18 @@ class SimpleCoherence
return NULL; return NULL;
} }
/**
* 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. * Return the proper state given the current state and the bus response.
* @param pkt The bus response. * @param pkt The bus response.

View file

@ -43,20 +43,30 @@ UniCoherence::UniCoherence()
Packet * Packet *
UniCoherence::getPacket() UniCoherence::getPacket()
{ {
bool unblock = cshrs.isFull();
Packet* pkt = cshrs.getReq(); 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; 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. * @todo add support for returning slave requests, not doing them here.
*/ */

View file

@ -108,12 +108,20 @@ class UniCoherence
else else
return BlkValid | BlkWritable; return BlkValid | BlkWritable;
} }
/** /**
* Return outstanding invalidate to forward. * Return outstanding invalidate to forward.
* @return The next invalidate to forward to lower levels of cache. * @return The next invalidate to forward to lower levels of cache.
*/ */
Packet * getPacket(); 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. * Handle snooped bus requests.
* @param pkt The snooped bus request. * @param pkt The snooped bus request.

View file

@ -202,7 +202,9 @@ class Packet
HardPFResp = IsRead | IsResponse | IsHWPrefetch HardPFResp = IsRead | IsResponse | IsHWPrefetch
| NeedsResponse | HasData, | NeedsResponse | HasData,
InvalidateReq = IsInvalidate | IsRequest, InvalidateReq = IsInvalidate | IsRequest,
WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest | HasData, WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest
| HasData | NeedsResponse,
WriteInvalidateResp = IsWrite | IsInvalidate | IsRequest | NeedsResponse,
UpgradeReq = IsInvalidate | IsRequest | IsUpgrade, UpgradeReq = IsInvalidate | IsRequest | IsUpgrade,
ReadExReq = IsRead | IsInvalidate | IsRequest | NeedsResponse, ReadExReq = IsRead | IsInvalidate | IsRequest | NeedsResponse,
ReadExResp = IsRead | IsInvalidate | IsResponse ReadExResp = IsRead | IsInvalidate | IsResponse