summaryrefslogtreecommitdiff
path: root/src/mem/cache
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/cache')
-rw-r--r--src/mem/cache/base_cache.cc26
-rw-r--r--src/mem/cache/base_cache.hh41
-rw-r--r--src/mem/cache/cache.hh2
-rw-r--r--src/mem/cache/cache_impl.hh75
-rw-r--r--src/mem/cache/coherence/coherence_protocol.cc2
-rw-r--r--src/mem/cache/miss/blocking_buffer.cc6
-rw-r--r--src/mem/cache/miss/blocking_buffer.hh2
-rw-r--r--src/mem/cache/miss/miss_queue.cc13
-rw-r--r--src/mem/cache/miss/miss_queue.hh2
9 files changed, 97 insertions, 72 deletions
diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc
index d7ccca8c0..c56f48eeb 100644
--- a/src/mem/cache/base_cache.cc
+++ b/src/mem/cache/base_cache.cc
@@ -71,7 +71,7 @@ BaseCache::CachePort::deviceBlockSize()
bool
BaseCache::CachePort::recvTiming(Packet *pkt)
{
- if (blocked)
+ if (pkt->isRequest() && blocked)
{
DPRINTF(Cache,"Scheduling a retry while blocked\n");
mustSendRetry = true;
@@ -105,14 +105,14 @@ BaseCache::CachePort::recvRetry()
drainList.pop_front();
}
}
-
- if (!isCpuSide)
+ else if (!isCpuSide)
{
pkt = cache->getPacket();
+ MSHR* mshr = (MSHR*)pkt->senderState;
bool success = sendTiming(pkt);
DPRINTF(Cache, "Address %x was %s in sending the timing request\n",
pkt->getAddr(), success ? "succesful" : "unsuccesful");
- cache->sendResult(pkt, success);
+ cache->sendResult(pkt, mshr, success);
if (success && cache->doMasterRequest())
{
//Still more to issue, rerequest in 1 cycle
@@ -123,7 +123,9 @@ BaseCache::CachePort::recvRetry()
}
else
{
- pkt = cache->getCoherencePacket();
+ //pkt = cache->getCoherencePacket();
+ //We save the packet, no reordering on CSHRS
+ pkt = cshrRetry;
bool success = sendTiming(pkt);
if (success && cache->doSlaveRequest())
{
@@ -182,10 +184,11 @@ BaseCache::CacheEvent::process()
{
//MSHR
pkt = cachePort->cache->getPacket();
+ MSHR* mshr = (MSHR*) pkt->senderState;
bool success = cachePort->sendTiming(pkt);
DPRINTF(Cache, "Address %x was %s in sending the timing request\n",
pkt->getAddr(), success ? "succesful" : "unsuccesful");
- cachePort->cache->sendResult(pkt, success);
+ cachePort->cache->sendResult(pkt, mshr, success);
if (success && cachePort->cache->doMasterRequest())
{
//Still more to issue, rerequest in 1 cycle
@@ -198,7 +201,11 @@ BaseCache::CacheEvent::process()
//CSHR
pkt = cachePort->cache->getCoherencePacket();
bool success = cachePort->sendTiming(pkt);
- if (success && cachePort->cache->doSlaveRequest())
+ if (!success) {
+ //Need to send on a retry
+ cachePort->cshrRetry = pkt;
+ }
+ else if (cachePort->cache->doSlaveRequest())
{
//Still more to issue, rerequest in 1 cycle
pkt = NULL;
@@ -209,7 +216,10 @@ BaseCache::CacheEvent::process()
}
//Response
//Know the packet to send
- pkt->result = Packet::Success;
+ if (pkt->flags & NACKED_LINE)
+ pkt->result = Packet::Nacked;
+ else
+ pkt->result = Packet::Success;
pkt->makeTimingResponse();
if (!cachePort->drainList.empty()) {
//Already blocked waiting for bus, just append
diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh
index c69fb7fd5..c45f3b71b 100644
--- a/src/mem/cache/base_cache.hh
+++ b/src/mem/cache/base_cache.hh
@@ -72,6 +72,7 @@ enum RequestCause{
Request_PF
};
+class MSHR;
/**
* A basic cache interface. Implements some common functions for speed.
*/
@@ -112,6 +113,8 @@ class BaseCache : public MemObject
bool isCpuSide;
std::list<Packet *> drainList;
+
+ Packet *cshrRetry;
};
struct CacheEvent : public Event
@@ -156,7 +159,7 @@ class BaseCache : public MemObject
if (status == Port::RangeChange){
if (!isCpuSide) {
cpuSidePort->sendStatusChange(Port::RangeChange);
- if (topLevelCache && !snoopRangesSent) {
+ if (!snoopRangesSent) {
snoopRangesSent = true;
memSidePort->sendStatusChange(Port::RangeChange);
}
@@ -165,10 +168,6 @@ class BaseCache : public MemObject
memSidePort->sendStatusChange(Port::RangeChange);
}
}
- else if (status == Port::SnoopSquash) {
- assert(snoopPhase2);
- snoopPhase2 = false;
- }
}
virtual Packet *getPacket()
@@ -181,7 +180,7 @@ class BaseCache : public MemObject
fatal("No implementation");
}
- virtual void sendResult(Packet* &pkt, bool success)
+ virtual void sendResult(Packet* &pkt, MSHR* mshr, bool success)
{
fatal("No implementation");
@@ -215,9 +214,6 @@ class BaseCache : public MemObject
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;
@@ -523,8 +519,10 @@ class BaseCache : public MemObject
*/
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);
+ }
}
/**
@@ -537,8 +535,10 @@ class BaseCache : public MemObject
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);
+ }
}
/**
@@ -549,6 +549,7 @@ class BaseCache : public MemObject
{
// assert("Implement\n" && 0);
// mi->respond(pkt,curTick + hitLatency);
+ assert (pkt->needsResponse());
CacheEvent *reqMem = new CacheEvent(memSidePort, pkt);
reqMem->schedule(time);
}
@@ -570,14 +571,14 @@ class BaseCache : public MemObject
{
//This is where snoops get updated
AddrRangeList dummy;
- if (!topLevelCache)
- {
+// if (!topLevelCache)
+// {
cpuSidePort->getPeerAddressRanges(dummy, snoop);
- }
- else
- {
- snoop.push_back(RangeSize(0,-1));
- }
+// }
+// else
+// {
+// snoop.push_back(RangeSize(0,-1));
+// }
return;
}
diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh
index 4b8870c95..923bf8255 100644
--- a/src/mem/cache/cache.hh
+++ b/src/mem/cache/cache.hh
@@ -175,7 +175,7 @@ class Cache : public BaseCache
* @param pkt The request.
* @param success True if the request was sent successfully.
*/
- virtual void sendResult(Packet * &pkt, bool success);
+ virtual void sendResult(Packet * &pkt, MSHR* mshr, bool success);
/**
* Handles a response (cache line fill/write ack) from the bus.
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index 46f4b0ebe..c3c1c0881 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -60,28 +60,20 @@ doTimingAccess(Packet *pkt, CachePort *cachePort, bool isCpuSide)
{
if (isCpuSide)
{
- if (pkt->isWrite() && (pkt->req->getFlags() & LOCKED)) {
+ if (pkt->isWrite() && (pkt->req->isLocked())) {
pkt->req->setScResult(1);
}
- if (!(pkt->flags & SATISFIED)) {
- access(pkt);
- }
+ access(pkt);
+
}
else
{
if (pkt->isResponse())
handleResponse(pkt);
else {
- //Check if we are in phase1
- if (!snoopPhase2) {
- snoopPhase2 = true;
- }
- else {
- //Check if we should do the snoop
- if (pkt->flags && SNOOP_COMMIT)
- snoop(pkt);
- snoopPhase2 = false;
- }
+ //Check if we should do the snoop
+ if (pkt->flags & SNOOP_COMMIT)
+ snoop(pkt);
}
}
return true;
@@ -95,7 +87,7 @@ doAtomicAccess(Packet *pkt, bool isCpuSide)
if (isCpuSide)
{
//Temporary solution to LL/SC
- if (pkt->isWrite() && (pkt->req->getFlags() & LOCKED)) {
+ if (pkt->isWrite() && (pkt->req->isLocked())) {
pkt->req->setScResult(1);
}
@@ -125,7 +117,7 @@ doFunctionalAccess(Packet *pkt, bool isCpuSide)
pkt->req->setThreadContext(0,0);
//Temporary solution to LL/SC
- if (pkt->isWrite() && (pkt->req->getFlags() & LOCKED)) {
+ if (pkt->isWrite() && (pkt->req->isLocked())) {
assert("Can't handle LL/SC on functional path\n");
}
@@ -211,9 +203,8 @@ Cache<TagStore,Buffering,Coherence>::access(PacketPtr &pkt)
pkt->getAddr() & (((ULL(1))<<48)-1),
pkt->getAddr() & ~((Addr)blkSize - 1));
- //@todo Should this return latency have the hit latency in it?
-// respond(pkt,curTick+lat);
pkt->flags |= SATISFIED;
+ //Invalidates/Upgrades need no response if they get the bus
// return MA_HIT; //@todo, return values
return true;
}
@@ -243,9 +234,9 @@ Cache<TagStore,Buffering,Coherence>::access(PacketPtr &pkt)
missQueue->doWriteback(writebacks.front());
writebacks.pop_front();
}
- DPRINTF(Cache, "%s %x %s blk_addr: %x pc %x\n", pkt->cmdString(),
+ DPRINTF(Cache, "%s %x %s blk_addr: %x\n", pkt->cmdString(),
pkt->getAddr() & (((ULL(1))<<48)-1), (blk) ? "hit" : "miss",
- pkt->getAddr() & ~((Addr)blkSize - 1), pkt->req->getPC());
+ pkt->getAddr() & ~((Addr)blkSize - 1));
if (blk) {
// Hit
hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++;
@@ -294,10 +285,10 @@ Cache<TagStore,Buffering,Coherence>::getPacket()
template<class TagStore, class Buffering, class Coherence>
void
-Cache<TagStore,Buffering,Coherence>::sendResult(PacketPtr &pkt, bool success)
+Cache<TagStore,Buffering,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr, bool success)
{
if (success) {
- missQueue->markInService(pkt);
+ missQueue->markInService(pkt, mshr);
//Temp Hack for UPGRADES
if (pkt->cmd == Packet::UpgradeReq) {
handleResponse(pkt);
@@ -313,6 +304,13 @@ Cache<TagStore,Buffering,Coherence>::handleResponse(Packet * &pkt)
{
BlkType *blk = NULL;
if (pkt->senderState) {
+ if (pkt->result == Packet::Nacked) {
+ pkt->reinitFromRequest();
+ panic("Unimplemented NACK of packet\n");
+ }
+ if (pkt->result == Packet::BadAddress) {
+ //Make the response a Bad address and send it
+ }
// MemDebug::cacheResponse(pkt);
DPRINTF(Cache, "Handling reponse to %x, blk addr: %x\n",pkt->getAddr(),
pkt->getAddr() & (((ULL(1))<<48)-1));
@@ -321,9 +319,11 @@ Cache<TagStore,Buffering,Coherence>::handleResponse(Packet * &pkt)
blk = tags->findBlock(pkt);
CacheBlk::State old_state = (blk) ? blk->status : 0;
PacketList writebacks;
+ CacheBlk::State new_state = coherence->getNewState(pkt,old_state);
+ DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n",
+ pkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state);
blk = tags->handleFill(blk, (MSHR*)pkt->senderState,
- coherence->getNewState(pkt,old_state),
- writebacks, pkt);
+ new_state, writebacks, pkt);
while (!writebacks.empty()) {
missQueue->doWriteback(writebacks.front());
writebacks.pop_front();
@@ -394,9 +394,9 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
//If the outstanding request was an invalidate (upgrade,readex,..)
//Then we need to ACK the request until we get the data
//Also NACK if the outstanding request is not a cachefill (writeback)
+ assert(!(pkt->flags & SATISFIED));
pkt->flags |= SATISFIED;
pkt->flags |= NACKED_LINE;
- assert("Don't detect these on the other side yet\n");
respondToSnoop(pkt, curTick + hitLatency);
return;
}
@@ -410,7 +410,7 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
//@todo Make it so that a read to a pending read can't be exclusive now.
//Set the address so find match works
- assert("Don't have invalidates yet\n");
+ panic("Don't have invalidates yet\n");
invalidatePkt->addrOverride(pkt->getAddr());
//Append the invalidate on
@@ -433,6 +433,7 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
if (pkt->isRead()) {
//Only Upgrades don't get here
//Supply the data
+ assert(!(pkt->flags & SATISFIED));
pkt->flags |= SATISFIED;
//If we are in an exclusive protocol, make it ask again
@@ -451,7 +452,7 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
if (pkt->isInvalidate()) {
//This must be an upgrade or other cache will take ownership
- missQueue->markInService(mshr->pkt);
+ missQueue->markInService(mshr->pkt, mshr);
}
return;
}
@@ -461,10 +462,16 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
CacheBlk::State new_state;
bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state);
if (satisfy) {
+ DPRINTF(Cache, "Cache snooped a %s request and now supplying data,"
+ "new state is %i\n",
+ pkt->cmdString(), new_state);
+
tags->handleSnoop(blk, new_state, pkt);
respondToSnoop(pkt, curTick + hitLatency);
return;
}
+ if (blk) DPRINTF(Cache, "Cache snooped a %s request, new state is %i\n",
+ pkt->cmdString(), new_state);
tags->handleSnoop(blk, new_state);
}
@@ -610,7 +617,7 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update, CachePort
// update the cache state and statistics
if (mshr || !writes.empty()){
// Can't handle it, return pktuest unsatisfied.
- return 0;
+ panic("Atomic access ran into outstanding MSHR's or WB's!");
}
if (!pkt->req->isUncacheable()) {
// Fetch the cache block to fill
@@ -627,7 +634,9 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update, CachePort
lat = memSidePort->sendAtomic(busPkt);
//Be sure to flip the response to a request for coherence
- busPkt->makeAtomicResponse();
+ if (busPkt->needsResponse()) {
+ busPkt->makeAtomicResponse();
+ }
/* if (!(busPkt->flags & SATISFIED)) {
// blocked at a higher level, just return
@@ -662,7 +671,7 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update, CachePort
hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++;
} else if (pkt->isWrite()) {
// Still need to change data in all locations.
- return otherSidePort->sendAtomic(pkt);
+ otherSidePort->sendFunctional(pkt);
}
return curTick + lat;
}
@@ -680,9 +689,15 @@ Cache<TagStore,Buffering,Coherence>::snoopProbe(PacketPtr &pkt)
CacheBlk::State new_state = 0;
bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state);
if (satisfy) {
+ DPRINTF(Cache, "Cache snooped a %s request and now supplying data,"
+ "new state is %i\n",
+ pkt->cmdString(), new_state);
+
tags->handleSnoop(blk, new_state, pkt);
return hitLatency;
}
+ if (blk) DPRINTF(Cache, "Cache snooped a %s request, new state is %i\n",
+ pkt->cmdString(), new_state);
tags->handleSnoop(blk, new_state);
return 0;
}
diff --git a/src/mem/cache/coherence/coherence_protocol.cc b/src/mem/cache/coherence/coherence_protocol.cc
index bcf3ce9c5..e28dda3dc 100644
--- a/src/mem/cache/coherence/coherence_protocol.cc
+++ b/src/mem/cache/coherence/coherence_protocol.cc
@@ -271,7 +271,7 @@ CoherenceProtocol::CoherenceProtocol(const string &name,
}
Packet::Command writeToSharedCmd = doUpgrades ? Packet::UpgradeReq : Packet::ReadExReq;
- Packet::Command writeToSharedResp = doUpgrades ? Packet::UpgradeResp : Packet::ReadExResp;
+ Packet::Command writeToSharedResp = doUpgrades ? Packet::UpgradeReq : Packet::ReadExResp;
//@todo add in hardware prefetch to this list
if (protocol == "msi") {
diff --git a/src/mem/cache/miss/blocking_buffer.cc b/src/mem/cache/miss/blocking_buffer.cc
index 7a6ea9133..f7aacff89 100644
--- a/src/mem/cache/miss/blocking_buffer.cc
+++ b/src/mem/cache/miss/blocking_buffer.cc
@@ -123,12 +123,12 @@ BlockingBuffer::restoreOrigCmd(Packet * &pkt)
}
void
-BlockingBuffer::markInService(Packet * &pkt)
+BlockingBuffer::markInService(Packet * &pkt, MSHR* mshr)
{
if (!pkt->isCacheFill() && pkt->isWrite()) {
// Forwarding a write/ writeback, don't need to change
// the command
- assert((MSHR*)pkt->senderState == &wb);
+ assert(mshr == &wb);
cache->clearMasterRequest(Request_WB);
if (!pkt->needsResponse()) {
assert(wb.getNumTargets() == 0);
@@ -138,7 +138,7 @@ BlockingBuffer::markInService(Packet * &pkt)
wb.inService = true;
}
} else {
- assert((MSHR*)pkt->senderState == &miss);
+ assert(mshr == &miss);
cache->clearMasterRequest(Request_MSHR);
if (!pkt->needsResponse()) {
assert(miss.getNumTargets() == 0);
diff --git a/src/mem/cache/miss/blocking_buffer.hh b/src/mem/cache/miss/blocking_buffer.hh
index 641d5a798..f7069696c 100644
--- a/src/mem/cache/miss/blocking_buffer.hh
+++ b/src/mem/cache/miss/blocking_buffer.hh
@@ -152,7 +152,7 @@ public:
* are successfully sent.
* @param pkt The request that was sent on the bus.
*/
- void markInService(Packet * &pkt);
+ void markInService(Packet * &pkt, MSHR* mshr);
/**
* Frees the resources of the pktuest and unblock the cache.
diff --git a/src/mem/cache/miss/miss_queue.cc b/src/mem/cache/miss/miss_queue.cc
index 273b6587f..bdb7a39c8 100644
--- a/src/mem/cache/miss/miss_queue.cc
+++ b/src/mem/cache/miss/miss_queue.cc
@@ -372,7 +372,7 @@ MissQueue::allocateMiss(Packet * &pkt, int size, Tick time)
MSHR*
MissQueue::allocateWrite(Packet * &pkt, int size, Tick time)
{
- MSHR* mshr = wb.allocate(pkt,blkSize);
+ MSHR* mshr = wb.allocate(pkt,size);
mshr->order = order++;
//REMOVING COMPRESSION FOR NOW
@@ -446,7 +446,7 @@ MissQueue::handleMiss(Packet * &pkt, int blkSize, Tick time)
/**
* @todo Add write merging here.
*/
- mshr = allocateWrite(pkt, blkSize, time);
+ mshr = allocateWrite(pkt, pkt->getSize(), time);
return;
}
@@ -526,9 +526,8 @@ MissQueue::restoreOrigCmd(Packet * &pkt)
}
void
-MissQueue::markInService(Packet * &pkt)
+MissQueue::markInService(Packet * &pkt, MSHR* mshr)
{
- assert(pkt->senderState != 0);
bool unblock = false;
BlockedCause cause = NUM_BLOCKED_CAUSES;
@@ -540,7 +539,7 @@ MissQueue::markInService(Packet * &pkt)
// Forwarding a write/ writeback, don't need to change
// the command
unblock = wb.isFull();
- wb.markInService((MSHR*)pkt->senderState);
+ wb.markInService(mshr);
if (!wb.havePending()){
cache->clearMasterRequest(Request_WB);
}
@@ -551,11 +550,11 @@ MissQueue::markInService(Packet * &pkt)
}
} else {
unblock = mq.isFull();
- mq.markInService((MSHR*)pkt->senderState);
+ mq.markInService(mshr);
if (!mq.havePending()){
cache->clearMasterRequest(Request_MSHR);
}
- if (((MSHR*)(pkt->senderState))->originalCmd == Packet::HardPFReq) {
+ if (mshr->originalCmd == Packet::HardPFReq) {
DPRINTF(HWPrefetch, "%s:Marking a HW_PF in service\n",
cache->name());
//Also clear pending if need be
diff --git a/src/mem/cache/miss/miss_queue.hh b/src/mem/cache/miss/miss_queue.hh
index 505d1f90c..179638d2b 100644
--- a/src/mem/cache/miss/miss_queue.hh
+++ b/src/mem/cache/miss/miss_queue.hh
@@ -256,7 +256,7 @@ class MissQueue
* are successfully sent.
* @param pkt The request that was sent on the bus.
*/
- void markInService(Packet * &pkt);
+ void markInService(Packet * &pkt, MSHR* mshr);
/**
* Collect statistics and free resources of a satisfied pktuest.