summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mem/cache/base_cache.cc1
-rw-r--r--src/mem/cache/base_cache.hh31
-rw-r--r--src/mem/cache/cache.hh26
-rw-r--r--src/mem/cache/cache_impl.hh56
-rw-r--r--src/mem/cache/miss/mshr.hh24
-rw-r--r--src/mem/cache/miss/mshr_queue.cc10
6 files changed, 53 insertions, 95 deletions
diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc
index 8b476e100..1f5182574 100644
--- a/src/mem/cache/base_cache.cc
+++ b/src/mem/cache/base_cache.cc
@@ -54,6 +54,7 @@ BaseCache::BaseCache(const std::string &name, Params &params)
writeBuffer(params.numWriteBuffers, params.numMSHRs+1000,
MSHRQueue_WriteBuffer),
blkSize(params.blkSize),
+ hitLatency(params.hitLatency),
numTarget(params.numTargets),
blocked(0),
noTargetMSHR(NULL),
diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh
index 10fd3289c..27134b2ad 100644
--- a/src/mem/cache/base_cache.hh
+++ b/src/mem/cache/base_cache.hh
@@ -195,6 +195,11 @@ class BaseCache : public MemObject
/** Block size of this cache */
const int blkSize;
+ /**
+ * The latency of a hit in this device.
+ */
+ int hitLatency;
+
/** The number of targets for each MSHR. */
const int numTarget;
@@ -464,15 +469,10 @@ class BaseCache : public MemObject
if (blocked == 0) {
blocked_causes[cause]++;
blockedCycle = curTick;
+ cpuSidePort->setBlocked();
}
- int old_state = blocked;
- if (!(blocked & flag)) {
- //Wasn't already blocked for this cause
- blocked |= flag;
- DPRINTF(Cache,"Blocking for cause %s\n", cause);
- if (!old_state)
- cpuSidePort->setBlocked();
- }
+ blocked |= flag;
+ DPRINTF(Cache,"Blocking for cause %d, mask=%d\n", cause, blocked);
}
/**
@@ -485,16 +485,11 @@ class BaseCache : public MemObject
void clearBlocked(BlockedCause cause)
{
uint8_t flag = 1 << cause;
- DPRINTF(Cache,"Unblocking for cause %s, causes left=%i\n",
- cause, blocked);
- if (blocked & flag)
- {
- blocked &= ~flag;
- if (!isBlocked()) {
- blocked_cycles[cause] += curTick - blockedCycle;
- DPRINTF(Cache,"Unblocking from all causes\n");
- cpuSidePort->clearBlocked();
- }
+ blocked &= ~flag;
+ DPRINTF(Cache,"Unblocking for cause %d, mask=%d\n", cause, blocked);
+ if (blocked == 0) {
+ blocked_cycles[cause] += curTick - blockedCycle;
+ cpuSidePort->clearBlocked();
}
}
diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh
index 06fce1a71..a93b761ec 100644
--- a/src/mem/cache/cache.hh
+++ b/src/mem/cache/cache.hh
@@ -137,23 +137,6 @@ class Cache : public BaseCache
BasePrefetcher *prefetcher;
/**
- * The clock ratio of the outgoing bus.
- * Used for calculating critical word first.
- */
- int busRatio;
-
- /**
- * The bus width in bytes of the outgoing bus.
- * Used for calculating critical word first.
- */
- int busWidth;
-
- /**
- * The latency of a hit in this device.
- */
- int hitLatency;
-
- /**
* Can this cache should allocate a block on a line-sized write miss.
*/
const bool doFastWrites;
@@ -304,15 +287,6 @@ class Cache : public BaseCache
void squash(int threadNum);
/**
- * Allocate a new MSHR or write buffer to handle a miss.
- * @param pkt The access that missed.
- * @param time The time to continue processing the miss.
- * @param isFill Whether to fetch & allocate a block
- * or just forward the request.
- */
- MSHR *allocateBuffer(PacketPtr pkt, Tick time, bool requestBus);
-
- /**
* Selects a outstanding request to service.
* @return The request to service, NULL if none found.
*/
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index 81fcb4158..0649b5061 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -150,27 +150,6 @@ Cache<TagStore,Coherence>::cmpAndSwap(BlkType *blk, PacketPtr pkt)
template<class TagStore, class Coherence>
-MSHR *
-Cache<TagStore,Coherence>::allocateBuffer(PacketPtr pkt, Tick time,
- bool requestBus)
-{
- MSHRQueue *mq = NULL;
-
- if (pkt->isWrite() && !pkt->isRead()) {
- /**
- * @todo Add write merging here.
- */
- mq = &writeBuffer;
- } else {
- mq = &mshrQueue;
- }
-
- return allocateBufferInternal(mq, pkt->getAddr(), pkt->getSize(),
- pkt, time, requestBus);
-}
-
-
-template<class TagStore, class Coherence>
void
Cache<TagStore,Coherence>::markInService(MSHR *mshr)
{
@@ -438,6 +417,8 @@ Cache<TagStore,Coherence>::getBusPacket(PacketPtr cpu_pkt, BlkType *blk,
return NULL;
}
+ assert(cpu_pkt->needsResponse());
+
MemCmd cmd;
const bool useUpgrades = true;
if (blkValid && useUpgrades) {
@@ -1043,23 +1024,34 @@ Cache<TagStore,Coherence>::getTimingPacket()
return NULL;
}
- BlkType *blk = tags->findBlock(mshr->addr);
-
// use request from 1st target
PacketPtr tgt_pkt = mshr->getTarget()->pkt;
- PacketPtr pkt = getBusPacket(tgt_pkt, blk, mshr->needsExclusive);
+ PacketPtr pkt = NULL;
- mshr->isCacheFill = (pkt != NULL);
-
- if (pkt == NULL) {
- // make copy of current packet to forward
- pkt = new Packet(tgt_pkt);
- pkt->allocate();
- if (pkt->isWrite()) {
- pkt->setData(tgt_pkt->getPtr<uint8_t>());
+ if (mshr->isSimpleForward()) {
+ // no response expected, just forward packet as it is
+ assert(tags->findBlock(mshr->addr) == NULL);
+ pkt = tgt_pkt;
+ } else {
+ BlkType *blk = tags->findBlock(mshr->addr);
+ pkt = getBusPacket(tgt_pkt, blk, mshr->needsExclusive);
+
+ mshr->isCacheFill = (pkt != NULL);
+
+ if (pkt == NULL) {
+ // not a cache block request, but a response is expected
+ assert(!mshr->isSimpleForward());
+ // make copy of current packet to forward, keep current
+ // copy for response handling
+ pkt = new Packet(tgt_pkt);
+ pkt->allocate();
+ if (pkt->isWrite()) {
+ pkt->setData(tgt_pkt->getPtr<uint8_t>());
+ }
}
}
+ assert(pkt != NULL);
pkt->senderState = mshr;
return pkt;
}
diff --git a/src/mem/cache/miss/mshr.hh b/src/mem/cache/miss/mshr.hh
index 47f6a819b..195438e46 100644
--- a/src/mem/cache/miss/mshr.hh
+++ b/src/mem/cache/miss/mshr.hh
@@ -164,28 +164,19 @@ public:
* Returns the current number of allocated targets.
* @return The current number of allocated targets.
*/
- int getNumTargets()
- {
- return ntargets;
- }
+ int getNumTargets() { return ntargets; }
/**
* Returns a pointer to the target list.
* @return a pointer to the target list.
*/
- TargetList* getTargetList()
- {
- return &targets;
- }
+ TargetList* getTargetList() { return &targets; }
/**
* Returns a reference to the first target.
* @return A pointer to the first target.
*/
- Target *getTarget()
- {
- return &targets.front();
- }
+ Target *getTarget() { return &targets.front(); }
/**
* Pop first target.
@@ -200,9 +191,14 @@ public:
* Returns true if there are targets left.
* @return true if there are targets
*/
- bool hasTargets()
+ bool hasTargets() { return !targets.empty(); }
+
+ bool isSimpleForward()
{
- return !targets.empty();
+ if (getNumTargets() != 1)
+ return false;
+ Target *tgt = getTarget();
+ return tgt->isCpuSide() && !tgt->pkt->needsResponse();
}
/**
diff --git a/src/mem/cache/miss/mshr_queue.cc b/src/mem/cache/miss/mshr_queue.cc
index 6b030a865..3407e2588 100644
--- a/src/mem/cache/miss/mshr_queue.cc
+++ b/src/mem/cache/miss/mshr_queue.cc
@@ -158,14 +158,14 @@ MSHRQueue::moveToFront(MSHR *mshr)
void
MSHRQueue::markInService(MSHR *mshr)
{
- //assert(mshr == pendingList.front());
-#if 0
- if (!mshr->pkt->needsResponse() && !(mshr->pkt->cmd == MemCmd::UpgradeReq)) {
- assert(mshr->getNumTargets() == 0);
+ if (mshr->isSimpleForward()) {
+ // we just forwarded the request packet & don't expect a
+ // response, so get rid of it
+ assert(mshr->getNumTargets() == 1);
+ mshr->popTarget();
deallocate(mshr);
return;
}
-#endif
mshr->inService = true;
pendingList.erase(mshr->readyIter);
//mshr->readyIter = NULL;