Blocked_NoTargets,
Blocked_NoWBBuffers,
Blocked_Coherence,
- Blocked_Copy,
NUM_BLOCKED_CAUSES
};
Request_PF
};
+class MSHR;
/**
* A basic cache interface. Implements some common functions for speed.
*/
bool isCpuSide;
+ bool waitingOnRetry;
+
std::list<Packet *> drainList;
+
};
struct CacheEvent : public Event
if (status == Port::RangeChange){
if (!isCpuSide) {
cpuSidePort->sendStatusChange(Port::RangeChange);
- if (topLevelCache && !snoopRangesSent) {
+ if (!snoopRangesSent) {
snoopRangesSent = true;
memSidePort->sendStatusChange(Port::RangeChange);
}
memSidePort->sendStatusChange(Port::RangeChange);
}
}
- else if (status == Port::SnoopSquash) {
- assert(snoopPhase2);
- snoopPhase2 = false;
- }
}
virtual Packet *getPacket()
fatal("No implementation");
}
- virtual void sendResult(Packet* &pkt, bool success)
+ virtual void sendResult(Packet* &pkt, MSHR* mshr, bool success)
+ {
+
+ fatal("No implementation");
+ }
+
+ virtual void sendCoherenceResult(Packet* &pkt, MSHR* mshr, bool success)
{
fatal("No implementation");
protected:
- /** True if this cache is connected to the CPU. */
- bool topLevelCache;
-
-
- /** True if we are now in phase 2 of the snoop process. */
- bool snoopPhase2;
-
/** Stores time the cache blocked for statistics. */
Tick blockedCycle;
*/
BaseCache(const std::string &name, Params ¶ms)
: MemObject(name), blocked(0), blockedSnoop(0), masterRequests(0),
- slaveRequests(0), topLevelCache(false), blkSize(params.blkSize),
+ slaveRequests(0), blkSize(params.blkSize),
missCount(params.maxMisses)
{
//Start ports at null if more than one is created we should panic
return blkSize;
}
- /**
- * Returns true if this cache is connect to the CPU.
- * @return True if this is a L1 cache.
- */
- bool isTopLevel()
- {
- return topLevelCache;
- }
-
/**
* Returns true if the cache is blocked for accesses.
*/
blocked_causes[cause]++;
blockedCycle = curTick;
}
+ int old_state = blocked;
if (!(blocked & flag)) {
//Wasn't already blocked for this cause
blocked |= flag;
DPRINTF(Cache,"Blocking for cause %s\n", cause);
- cpuSidePort->setBlocked();
+ if (!old_state)
+ cpuSidePort->setBlocked();
}
}
void setBlockedForSnoop(BlockedCause cause)
{
uint8_t flag = 1 << cause;
- if (!(blocked & flag)) {
+ uint8_t old_state = blockedSnoop;
+ if (!(blockedSnoop & flag)) {
//Wasn't already blocked for this cause
blockedSnoop |= flag;
- memSidePort->setBlocked();
+ if (!old_state)
+ memSidePort->setBlocked();
}
}
*/
void setMasterRequest(RequestCause cause, Tick time)
{
- if (!doMasterRequest())
+ if (!doMasterRequest() && !memSidePort->waitingOnRetry)
{
BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(memSidePort);
reqCpu->schedule(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;
slaveRequests |= flag;
- assert("Implement\n" && 0);
-// si->pktuest(time);
}
/**
*/
void respond(Packet *pkt, Tick time)
{
- CacheEvent *reqCpu = new CacheEvent(cpuSidePort, pkt);
- reqCpu->schedule(time);
+ if (pkt->needsResponse()) {
+ CacheEvent *reqCpu = new CacheEvent(cpuSidePort, pkt);
+ reqCpu->schedule(time);
+ }
+ else {
+ if (pkt->cmd != Packet::UpgradeReq)
+ {
+ delete pkt->req;
+ delete pkt;
+ }
+ }
}
/**
if (!pkt->req->isUncacheable()) {
missLatency[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/] += time - pkt->time;
}
- CacheEvent *reqCpu = new CacheEvent(cpuSidePort, pkt);
- reqCpu->schedule(time);
+ if (pkt->needsResponse()) {
+ CacheEvent *reqCpu = new CacheEvent(cpuSidePort, pkt);
+ reqCpu->schedule(time);
+ }
+ else {
+ if (pkt->cmd != Packet::UpgradeReq)
+ {
+ delete pkt->req;
+ delete pkt;
+ }
+ }
}
/**
*/
void respondToSnoop(Packet *pkt, Tick time)
{
-// assert("Implement\n" && 0);
-// mi->respond(pkt,curTick + hitLatency);
+ assert (pkt->needsResponse());
CacheEvent *reqMem = new CacheEvent(memSidePort, pkt);
reqMem->schedule(time);
}
{
//This is where snoops get updated
AddrRangeList dummy;
- if (!topLevelCache)
- {
- cpuSidePort->getPeerAddressRanges(dummy, snoop);
- }
- else
- {
- snoop.push_back(RangeSize(0,-1));
- }
-
+ cpuSidePort->getPeerAddressRanges(dummy, snoop);
return;
}
}