#include "mem/cache/base_cache.hh"
#include "mem/cache/tags/iic.hh"
#include "base/intmath.hh"
-#include "sim/root.hh" // for curTick
+#include "sim/core.hh" // for curTick
#include "base/trace.hh" // for DPRINTF
// probe cache for presence of given block.
bool
-IIC::probe(int asid, Addr addr) const
+IIC::probe(Addr addr) const
{
- return (findBlock(addr,asid) != NULL);
+ return (findBlock(addr) != NULL);
}
IICTag*
-IIC::findBlock(Addr addr, int asid, int &lat)
+IIC::findBlock(Addr addr, int &lat)
{
Addr tag = extractTag(addr);
unsigned set = hash(addr);
if (PROFILE_IIC)
setAccess.sample(set);
- IICTag *tag_ptr = sets[set].findTag(asid, tag, chain_ptr);
+ IICTag *tag_ptr = sets[set].findTag(tag, chain_ptr);
set_lat = 1;
if (tag_ptr == NULL && chain_ptr != tagNull) {
int secondary_depth;
- tag_ptr = secondaryChain(asid, tag, chain_ptr, &secondary_depth);
+ tag_ptr = secondaryChain(tag, chain_ptr, &secondary_depth);
set_lat += secondary_depth;
// set depth for statistics fix this later!!! egh
sets[set].depth = set_lat;
// need to preserve chain: fix this egh
sets[set].tags[assoc-1]->chain_ptr = tag_ptr->chain_ptr;
tagSwap(tag_ptr - tagStore, sets[set].tags[assoc-1] - tagStore);
- tag_ptr = sets[set].findTag(asid, tag, chain_ptr);
+ tag_ptr = sets[set].findTag(tag, chain_ptr);
assert(tag_ptr!=NULL);
}
return tag_ptr;
}
-IICTag*
-IIC::findBlock(Packet * &pkt, int &lat)
-{
- Addr addr = pkt->paddr;
- int asid = pkt->req->asid;
-
- Addr tag = extractTag(addr);
- unsigned set = hash(addr);
- int set_lat;
-
- unsigned long chain_ptr;
-
- if (PROFILE_IIC)
- setAccess.sample(set);
-
- IICTag *tag_ptr = sets[set].findTag(asid, tag, chain_ptr);
- set_lat = 1;
- if (tag_ptr == NULL && chain_ptr != tagNull) {
- int secondary_depth;
- tag_ptr = secondaryChain(asid, tag, chain_ptr, &secondary_depth);
- set_lat += secondary_depth;
- // set depth for statistics fix this later!!! egh
- sets[set].depth = set_lat;
-
- if (tag_ptr != NULL) {
- /* need to move tag into primary table */
- // need to preserve chain: fix this egh
- sets[set].tags[assoc-1]->chain_ptr = tag_ptr->chain_ptr;
- tagSwap(tag_ptr - tagStore, sets[set].tags[assoc-1] - tagStore);
- tag_ptr = sets[set].findTag(asid, tag, chain_ptr);
- assert(tag_ptr!=NULL);
- }
-
- }
- set_lat = set_lat * hashDelay + hitLatency;
- if (tag_ptr != NULL) {
- // IIC replacement: if this is not the first element of
- // list, reorder
- sets[set].moveToHead(tag_ptr);
-
- hitHashDepth.sample(sets[set].depth);
- hashHit++;
- hitDepthTotal += sets[set].depth;
- tag_ptr->status |= BlkReferenced;
- lat = set_lat;
- if (tag_ptr->whenReady > curTick && tag_ptr->whenReady - curTick > set_lat) {
- lat = tag_ptr->whenReady - curTick;
- }
-
- tag_ptr->refCount += 1;
- }
- else {
- // fall through: cache block not found, not a hit...
- missHashDepth.sample(sets[set].depth);
- hashMiss++;
- missDepthTotal += sets[set].depth;
- lat = set_lat;
- }
- return tag_ptr;
-}
IICTag*
-IIC::findBlock(Addr addr, int asid) const
+IIC::findBlock(Addr addr) const
{
Addr tag = extractTag(addr);
unsigned set = hash(addr);
unsigned long chain_ptr;
- IICTag *tag_ptr = sets[set].findTag(asid, tag, chain_ptr);
+ IICTag *tag_ptr = sets[set].findTag(tag, chain_ptr);
if (tag_ptr == NULL && chain_ptr != tagNull) {
int secondary_depth;
- tag_ptr = secondaryChain(asid, tag, chain_ptr, &secondary_depth);
+ tag_ptr = secondaryChain(tag, chain_ptr, &secondary_depth);
}
return tag_ptr;
}
IICTag*
-IIC::findReplacement(Packet * &pkt, PacketList* &writebacks,
- BlkList &compress_blocks)
+IIC::findReplacement(Addr addr, PacketList &writebacks)
{
- DPRINTF(IIC, "Finding Replacement for %x\n", pkt->paddr);
- unsigned set = hash(pkt->paddr);
+ DPRINTF(IIC, "Finding Replacement for %x\n", addr);
+ unsigned set = hash(addr);
IICTag *tag_ptr;
unsigned long *tmp_data = new unsigned long[numSub];
list<unsigned long> tag_indexes;
repl->doAdvance(tag_indexes);
+/*
while (!tag_indexes.empty()) {
if (!tagStore[tag_indexes.front()].isCompressed()) {
compress_blocks.push_back(&tagStore[tag_indexes.front()]);
}
tag_indexes.pop_front();
}
+*/
tag_ptr->re = (void*)repl->add(tag_ptr-tagStore);
}
void
-IIC::freeReplacementBlock(PacketList* & writebacks)
+IIC::freeReplacementBlock(PacketList & writebacks)
{
IICTag *tag_ptr;
unsigned long data_ptr;
DPRINTF(Cache, "Replacing %x in IIC: %s\n",
regenerateBlkAddr(tag_ptr->tag,0),
- tag_ptr->isModified() ? "writeback" : "clean");
+ tag_ptr->isDirty() ? "writeback" : "clean");
/* write back replaced block data */
if (tag_ptr && (tag_ptr->isValid())) {
- int req->setThreadNum() = (tag_ptr->xc) ? tag_ptr->xc->getThreadNum() : 0;
- replacements[req->getThreadNum()]++;
+ replacements[0]++;
totalRefs += tag_ptr->refCount;
++sampledRefs;
tag_ptr->refCount = 0;
- if (tag_ptr->isModified()) {
- Packet * writeback =
+ if (tag_ptr->isDirty()) {
+/* PacketPtr writeback =
buildWritebackReq(regenerateBlkAddr(tag_ptr->tag, 0),
tag_ptr->req->asid, tag_ptr->xc, blkSize,
- (cache->doData())?tag_ptr->data:0,
+ tag_ptr->data,
tag_ptr->size);
+*/
+ Request *writebackReq = new Request(regenerateBlkAddr(tag_ptr->tag, 0),
+ blkSize, 0);
+ PacketPtr writeback = new Packet(writebackReq, MemCmd::Writeback,
+ -1);
+ writeback->allocate();
+ memcpy(writeback->getPtr<uint8_t>(), tag_ptr->data, blkSize);
+
writebacks.push_back(writeback);
}
}
}
unsigned long
-IIC::getFreeDataBlock(PacketList* & writebacks)
+IIC::getFreeDataBlock(PacketList & writebacks)
{
struct IICTag *tag_ptr;
unsigned long data_ptr;
IICTag*
-IIC::getFreeTag(int set, PacketList* & writebacks)
+IIC::getFreeTag(int set, PacketList & writebacks)
{
unsigned long tag_index;
IICTag *tag_ptr;
tag = extractTag(addr);
mask = hashSets-1; /* assumes iic_hash_size is a power of 2 */
x = tag & mask;
- y = (tag >> (int)(::log(hashSets)/::log(2))) & mask;
+ y = (tag >> (int)(::log((double)hashSets)/::log((double)2))) & mask;
assert (x < hashSets && y < hashSets);
return x ^ y;
#endif
IICTag *
-IIC::secondaryChain(int asid, Addr tag, unsigned long chain_ptr,
+IIC::secondaryChain(Addr tag, unsigned long chain_ptr,
int *_depth) const
{
int depth = 0;
DPRINTF(IIC,"Searching secondary at %d for %x\n", chain_ptr,
tag<<tagShift);
if (tagStore[chain_ptr].tag == tag &&
- tagStore[chain_ptr].asid == asid &&
(tagStore[chain_ptr].isValid())) {
*_depth = depth;
return &tagStore[chain_ptr];
}
void
-IIC::decompressBlock(unsigned long index)
-{
- IICTag *tag_ptr = &tagStore[index];
- if (tag_ptr->isCompressed()) {
- // decompress the data here.
- }
-}
-
-void
-IIC::compressBlock(unsigned long index)
-{
- IICTag *tag_ptr = &tagStore[index];
- if (!tag_ptr->isCompressed()) {
- // Compress the data here.
- }
-}
-
-void
-IIC::invalidateBlk(int asid, Addr addr)
+IIC::invalidateBlk(IIC::BlkType *tag_ptr)
{
- IICTag* tag_ptr = findBlock(addr, asid);
if (tag_ptr) {
for (int i = 0; i < tag_ptr->numData; ++i) {
dataReferenceCount[tag_ptr->data_ptr[i]]--;
}
void
-IIC::readData(IICTag *blk, uint8_t *data){
- assert(cache->doData());
+IIC::readData(IICTag *blk, uint8_t *data)
+{
assert(blk->size <= trivialSize || blk->numData > 0);
int data_size = blk->size;
if (data_size > trivialSize) {
void
IIC::writeData(IICTag *blk, uint8_t *write_data, int size,
- PacketList* & writebacks){
- assert(cache->doData());
- assert(size < blkSize || !blk->isCompressed());
+ PacketList & writebacks)
+{
DPRINTF(IIC, "Writing %d bytes to %x\n", size,
blk->tag<<tagShift);
// Find the number of subblocks needed, (round up)
// can free data blocks
for (int i=num_subs; i < blk->numData; ++i){
// decrement reference count and compare to zero
- /**
- * @todo
- * Make this work with copying.
- */
if (--dataReferenceCount[blk->data_ptr[i]] == 0) {
freeDataBlock(blk->data_ptr[i]);
}
}
-/**
- * @todo This code can break if the src is evicted to get a tag for the dest.
- */
-void
-IIC::doCopy(Addr source, Addr dest, int asid, PacketList* &writebacks)
-{
- IICTag *dest_tag = findBlock(dest, asid);
-
- if (dest_tag) {
- for (int i = 0; i < dest_tag->numData; ++i) {
- if (--dataReferenceCount[dest_tag->data_ptr[i]] == 0) {
- freeDataBlock(dest_tag->data_ptr[i]);
- }
- }
- // Reset replacement entry
- } else {
- dest_tag = getFreeTag(hash(dest), writebacks);
- dest_tag->re = (void*) repl->add(dest_tag - tagStore);
- dest_tag->set = hash(dest);
- dest_tag->tag = extractTag(dest);
- dest_tag->req->asid = asid;
- dest_tag->status = BlkValid | BlkWritable;
- }
- // Find the source tag here since it might move if we need to find a
- // tag for the destination.
- IICTag *src_tag = findBlock(source, asid);
- assert(src_tag);
- assert(!cache->doData() || src_tag->size <= trivialSize
- || src_tag->numData > 0);
- // point dest to source data and inc counter
- for (int i = 0; i < src_tag->numData; ++i) {
- dest_tag->data_ptr[i] = src_tag->data_ptr[i];
- ++dataReferenceCount[dest_tag->data_ptr[i]];
- }
-
- // Maintain fast access data.
- memcpy(dest_tag->data, src_tag->data, blkSize);
-
- dest_tag->xc = src_tag->xc;
- dest_tag->size = src_tag->size;
- dest_tag->numData = src_tag->numData;
- if (src_tag->numData == 0) {
- // Data is stored in the trivial data, just copy it.
- memcpy(dest_tag->trivialData, src_tag->trivialData, src_tag->size);
- }
-
- dest_tag->status |= BlkDirty;
- if (dest_tag->size < blkSize) {
- dest_tag->status |= BlkCompressed;
- } else {
- dest_tag->status &= ~BlkCompressed;
- }
-}
-
-void
-IIC::fixCopy(Packet * &pkt, PacketList* &writebacks)
-{
- // if reference counter is greater than 1, do copy
- // else do write
- Addr blk_addr = blkAlign(pkt->paddr);
- IICTag* blk = findBlock(blk_addr, pkt->req->asid);
-
- if (blk->numData > 0 && dataReferenceCount[blk->data_ptr[0]] != 1) {
- // copy the data
- // Mark the block as referenced so it doesn't get replaced.
- blk->status |= BlkReferenced;
- for (int i = 0; i < blk->numData; ++i){
- unsigned long new_data = getFreeDataBlock(writebacks);
- // Need to refresh pointer
- /**
- * @todo Remove this refetch once we change IIC to pointer based
- */
- blk = findBlock(blk_addr, pkt->req->asid);
- assert(blk);
- if (cache->doData()) {
- memcpy(&(dataBlks[new_data][0]),
- &(dataBlks[blk->data_ptr[i]][0]),
- subSize);
- }
- dataReferenceCount[blk->data_ptr[i]]--;
- dataReferenceCount[new_data]++;
- blk->data_ptr[i] = new_data;
- }
- }
-}
-
void
IIC::cleanupRefs()
{