#include <string>
-#include "mem/cache/base_cache.hh"
+#include "mem/cache/base.hh"
#include "base/intmath.hh"
#include "mem/cache/tags/lru.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
using namespace std;
LRUBlk*
-CacheSet::findBlk(int asid, Addr tag) const
+CacheSet::findBlk(Addr tag) const
{
for (int i = 0; i < assoc; ++i) {
if (blks[i]->tag == tag && blks[i]->isValid()) {
// allocate data storage in one big chunk
dataBlks = new uint8_t[numSets*assoc*blkSize];
- blkIndex = 0; // index into blks array
+ blkIndex = 0; // index into blks array
for (i = 0; i < numSets; ++i) {
sets[i].assoc = assoc;
// table; won't matter because the block is invalid
blk->tag = j;
blk->whenReady = 0;
- blk->req->asid = -1;
blk->isTouched = false;
blk->size = blkSize;
sets[i].blks[j]=blk;
// probe cache for presence of given block.
bool
-LRU::probe(int asid, Addr addr) const
+LRU::probe(Addr addr) const
{
// return(findBlock(Read, addr, asid) != 0);
Addr tag = extractTag(addr);
unsigned myset = extractSet(addr);
- LRUBlk *blk = sets[myset].findBlk(asid, tag);
+ LRUBlk *blk = sets[myset].findBlk(tag);
- return (blk != NULL); // true if in cache
+ return (blk != NULL); // true if in cache
}
LRUBlk*
-LRU::findBlock(Addr addr, int asid, int &lat)
+LRU::findBlock(Addr addr, int &lat)
{
Addr tag = extractTag(addr);
unsigned set = extractSet(addr);
- LRUBlk *blk = sets[set].findBlk(asid, tag);
+ LRUBlk *blk = sets[set].findBlk(tag);
lat = hitLatency;
if (blk != NULL) {
// move this block to head of the MRU list
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;
return blk;
}
-LRUBlk*
-LRU::findBlock(Packet * &pkt, int &lat)
-{
- Addr addr = pkt->paddr;
- int asid = pkt->req->asid;
-
- Addr tag = extractTag(addr);
- unsigned set = extractSet(addr);
- LRUBlk *blk = sets[set].findBlk(asid, tag);
- lat = hitLatency;
- if (blk != NULL) {
- // move this block to head of the MRU list
- sets[set].moveToHead(blk);
- if (blk->whenReady > curTick
- && blk->whenReady - curTick > hitLatency) {
- lat = blk->whenReady - curTick;
- }
- blk->refCount += 1;
- }
-
- return blk;
-}
LRUBlk*
-LRU::findBlock(Addr addr, int asid) const
+LRU::findBlock(Addr addr) const
{
Addr tag = extractTag(addr);
unsigned set = extractSet(addr);
- LRUBlk *blk = sets[set].findBlk(asid, tag);
+ LRUBlk *blk = sets[set].findBlk(tag);
return blk;
}
LRUBlk*
-LRU::findReplacement(Packet * &pkt, PacketList* &writebacks,
- BlkList &compress_blocks)
+LRU::findReplacement(Addr addr, PacketList &writebacks)
{
- unsigned set = extractSet(pkt->paddr);
+ unsigned set = extractSet(addr);
// grab a replacement candidate
LRUBlk *blk = sets[set].blks[assoc-1];
sets[set].moveToHead(blk);
if (blk->isValid()) {
- int thread_num = (blk->xc) ? blk->xc->getThreadNum() : 0;
- replacements[thread_num]++;
+ replacements[0]++;
totalRefs += blk->refCount;
++sampledRefs;
blk->refCount = 0;
+
+ DPRINTF(CacheRepl, "set %x: selecting blk %x for replacement\n",
+ set, regenerateBlkAddr(blk->tag, set));
} else if (!blk->isTouched) {
tagsInUse++;
blk->isTouched = true;
}
void
-LRU::invalidateBlk(int asid, Addr addr)
+LRU::invalidateBlk(LRU::BlkType *blk)
{
- LRUBlk *blk = findBlock(addr, asid);
if (blk) {
blk->status = 0;
blk->isTouched = false;
+ blk->clearLoadLocks();
tagsInUse--;
}
}
-void
-LRU::doCopy(Addr source, Addr dest, int asid, PacketList* &writebacks)
-{
- assert(source == blkAlign(source));
- assert(dest == blkAlign(dest));
- LRUBlk *source_blk = findBlock(source, asid);
- assert(source_blk);
- LRUBlk *dest_blk = findBlock(dest, asid);
- if (dest_blk == NULL) {
- // Need to do a replacement
- Packet * pkt = new Packet();
- pkt->paddr = dest;
- BlkList dummy_list;
- dest_blk = findReplacement(pkt, writebacks, dummy_list);
- if (dest_blk->isValid() && dest_blk->isModified()) {
- // Need to writeback data.
- pkt = buildWritebackReq(regenerateBlkAddr(dest_blk->tag,
- dest_blk->set),
- dest_blk->req->asid,
- dest_blk->xc,
- blkSize,
- (cache->doData())?dest_blk->data:0,
- dest_blk->size);
- writebacks.push_back(pkt);
- }
- dest_blk->tag = extractTag(dest);
- dest_blk->req->asid = asid;
- /**
- * @todo Do we need to pass in the execution context, or can we
- * assume its the same?
- */
- assert(source_blk->xc);
- dest_blk->xc = source_blk->xc;
- }
- /**
- * @todo Can't assume the status once we have coherence on copies.
- */
-
- // Set this block as readable, writeable, and dirty.
- dest_blk->status = 7;
- if (cache->doData()) {
- memcpy(dest_blk->data, source_blk->data, blkSize);
- }
-}
-
void
LRU::cleanupRefs()
{