/*
+ * Copyright (c) 2012 ARM Limited
+ * All rights reserved.
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
#include <string>
-#include "mem/cache/base.hh"
#include "base/intmath.hh"
+#include "debug/Cache.hh"
+#include "debug/CacheRepl.hh"
+#include "mem/cache/tags/cacheset.hh"
#include "mem/cache/tags/lru.hh"
+#include "mem/cache/base.hh"
#include "sim/core.hh"
-#include "cacheset.hh"
using namespace std;
sets = new CacheSet[numSets];
blks = new BlkType[numSets * assoc];
// allocate data storage in one big chunk
- dataBlks = new uint8_t[numSets*assoc*blkSize];
+ numBlocks = numSets * assoc;
+ dataBlks = new uint8_t[numBlocks * blkSize];
unsigned blkIndex = 0; // index into blks array
for (unsigned i = 0; i < numSets; ++i) {
++blkIndex;
// invalidate new cache block
- blk->status = 0;
+ blk->invalidate();
//EGH Fix Me : do we need to initialize blk?
}
LRU::BlkType*
-LRU::accessBlock(Addr addr, int &lat, int context_src)
+LRU::accessBlock(Addr addr, Cycles &lat, int master_id)
{
Addr tag = extractTag(addr);
unsigned set = extractSet(addr);
sets[set].moveToHead(blk);
DPRINTF(CacheRepl, "set %x: moving blk %x to MRU\n",
set, regenerateBlkAddr(tag, set));
- if (blk->whenReady > curTick
- && blk->whenReady - curTick > hitLatency) {
- lat = blk->whenReady - curTick;
+ if (blk->whenReady > curTick()
+ && cache->ticksToCycles(blk->whenReady - curTick()) > hitLatency) {
+ lat = cache->ticksToCycles(blk->whenReady - curTick());
}
blk->refCount += 1;
}
unsigned set = extractSet(addr);
// grab a replacement candidate
BlkType *blk = sets[set].blks[assoc-1];
- if (blk->isValid()) {
- replacements[0]++;
- totalRefs += blk->refCount;
- ++sampledRefs;
- blk->refCount = 0;
+ if (blk->isValid()) {
DPRINTF(CacheRepl, "set %x: selecting blk %x for replacement\n",
set, regenerateBlkAddr(blk->tag, set));
}
}
void
-LRU::insertBlock(Addr addr, BlkType *blk, int context_src)
+LRU::insertBlock(Addr addr, BlkType *blk, int master_id)
{
if (!blk->isTouched) {
tagsInUse++;
blk->isTouched = true;
if (!warmedUp && tagsInUse.value() >= warmupBound) {
warmedUp = true;
- warmupCycle = curTick;
+ warmupCycle = curTick();
}
}
+ // If we're replacing a block that was previously valid update
+ // stats for it. This can't be done in findBlock() because a
+ // found block might not actually be replaced there if the
+ // coherence protocol says it can't be.
+ if (blk->isValid()) {
+ replacements[0]++;
+ totalRefs += blk->refCount;
+ ++sampledRefs;
+ blk->refCount = 0;
+
+ // deal with evicted block
+ assert(blk->srcMasterId < cache->system->maxMasters());
+ occupancies[blk->srcMasterId]--;
+
+ blk->invalidate();
+ }
+
+ blk->isTouched = true;
// Set tag for new block. Caller is responsible for setting status.
blk->tag = extractTag(addr);
+ // deal with what we are bringing in
+ assert(master_id < cache->system->maxMasters());
+ occupancies[master_id]++;
+ blk->srcMasterId = master_id;
+
unsigned set = extractSet(addr);
sets[set].moveToHead(blk);
}
void
-LRU::invalidateBlk(BlkType *blk)
+LRU::invalidate(BlkType *blk)
+{
+ assert(blk);
+ assert(blk->isValid());
+ tagsInUse--;
+ assert(blk->srcMasterId < cache->system->maxMasters());
+ occupancies[blk->srcMasterId]--;
+ blk->srcMasterId = Request::invldMasterId;
+
+ // should be evicted before valid blocks
+ unsigned set = blk->set;
+ sets[set].moveToTail(blk);
+}
+
+void
+LRU::clearLocks()
{
- if (blk) {
- blk->status = 0;
- blk->isTouched = false;
- blk->clearLoadLocks();
- tagsInUse--;
+ for (int i = 0; i < numBlocks; i++){
+ blks[i].clearLoadLocks();
+ }
+}
+
+std::string
+LRU::print() const {
+ std::string cache_state;
+ for (unsigned i = 0; i < numSets; ++i) {
+ // link in the data blocks
+ for (unsigned j = 0; j < assoc; ++j) {
+ BlkType *blk = sets[i].blks[j];
+ if (blk->isValid())
+ cache_state += csprintf("\tset: %d block: %d %s\n", i, j,
+ blk->print());
+ }
}
+ if (cache_state.empty())
+ cache_state = "no valid tags\n";
+ return cache_state;
}
void