Still missing prefetch and tags directories as well as cache builder.

Some implementation details were left blank still, need to fill them in.

src/SConscript:
    Reorder build to compile all files first
src/mem/cache/cache.hh:
src/mem/cache/cache_builder.cc:
src/mem/cache/cache_impl.hh:
src/mem/cache/coherence/coherence_protocol.cc:
src/mem/cache/coherence/uni_coherence.cc:
src/mem/cache/coherence/uni_coherence.hh:
src/mem/cache/miss/blocking_buffer.cc:
src/mem/cache/miss/miss_queue.cc:
src/mem/cache/miss/mshr.cc:
src/mem/cache/miss/mshr.hh:
src/mem/cache/miss/mshr_queue.cc:
    More changesets pulled, now compiles everything in /miss directory and in the root directory
src/mem/packet.hh:
    Add some more support, need to clean some of it out once everything is working

--HG--
extra : convert_revision : ba73676165810edf2c2effaf5fbad8397d6bd800
This commit is contained in:
Ron Dreslinski 2006-06-29 16:07:19 -04:00
parent 0d323c753d
commit eafb5c4936
13 changed files with 491 additions and 432 deletions

View file

@ -103,7 +103,6 @@ base_sources = Split('''
mem/cache/base_cache.cc mem/cache/base_cache.cc
mem/cache/cache.cc mem/cache/cache.cc
mem/cache/cache_builder.cc
mem/cache/coherence/coherence_protocol.cc mem/cache/coherence/coherence_protocol.cc
mem/cache/coherence/uni_coherence.cc mem/cache/coherence/uni_coherence.cc
mem/cache/miss/blocking_buffer.cc mem/cache/miss/blocking_buffer.cc
@ -126,6 +125,8 @@ base_sources = Split('''
mem/cache/tags/split_lifo.cc mem/cache/tags/split_lifo.cc
mem/cache/tags/split_lru.cc mem/cache/tags/split_lru.cc
mem/cache/cache_builder.cc
sim/builder.cc sim/builder.cc
sim/debug.cc sim/debug.cc
sim/eventq.cc sim/eventq.cc

View file

@ -44,8 +44,9 @@
#include "mem/cache/base_cache.hh" #include "mem/cache/base_cache.hh"
#include "mem/cache/prefetch/prefetcher.hh" #include "mem/cache/prefetch/prefetcher.hh"
// forward declarations //Forward decleration
class Bus; class MSHR;
/** /**
* A template-policy based cache. The behavior of the cache can be altered by * A template-policy based cache. The behavior of the cache can be altered by
@ -92,6 +93,11 @@ class Cache : public BaseCache
*/ */
int busWidth; int busWidth;
/**
* The latency of a hit in this device.
*/
int hitLatency;
/** /**
* A permanent mem req to always be used to cause invalidations. * A permanent mem req to always be used to cause invalidations.
* Used to append to target list, to cause an invalidation. * Used to append to target list, to cause an invalidation.
@ -121,18 +127,18 @@ class Cache : public BaseCache
bool doCopy; bool doCopy;
bool blockOnCopy; bool blockOnCopy;
BaseCache::Params baseParams; BaseCache::Params baseParams;
Bus *in;
Bus *out;
Prefetcher<TagStore, Buffering> *prefetcher; Prefetcher<TagStore, Buffering> *prefetcher;
bool prefetchAccess; bool prefetchAccess;
int hitLatency;
Params(TagStore *_tags, Buffering *mq, Coherence *coh, Params(TagStore *_tags, Buffering *mq, Coherence *coh,
bool do_copy, BaseCache::Params params, Bus * in_bus, bool do_copy, BaseCache::Params params,
Bus * out_bus, Prefetcher<TagStore, Buffering> *_prefetcher, Prefetcher<TagStore, Buffering> *_prefetcher,
bool prefetch_access) bool prefetch_access, int hit_latency)
: tags(_tags), missQueue(mq), coherence(coh), doCopy(do_copy), : tags(_tags), missQueue(mq), coherence(coh), doCopy(do_copy),
blockOnCopy(false), baseParams(params), in(in_bus), out(out_bus), blockOnCopy(false), baseParams(params),
prefetcher(_prefetcher), prefetchAccess(prefetch_access) prefetcher(_prefetcher), prefetchAccess(prefetch_access),
hitLatency(hit_latency)
{ {
} }
}; };
@ -140,6 +146,17 @@ class Cache : public BaseCache
/** Instantiates a basic cache object. */ /** Instantiates a basic cache object. */
Cache(const std::string &_name, Params &params); Cache(const std::string &_name, Params &params);
bool doTimingAccess(Packet *pkt, CachePort *cachePort,
bool isCpuSide);
Tick doAtomicAccess(Packet *pkt, CachePort *cachePort,
bool isCpuSide);
void doFunctionalAccess(Packet *pkt, CachePort *cachePort,
bool isCpuSide);
void recvStatusChange(Port::Status status, bool isCpuSide);
void regStats(); void regStats();
/** /**

View file

@ -42,7 +42,7 @@
#include "mem/cache/base_cache.hh" #include "mem/cache/base_cache.hh"
#include "mem/cache/cache.hh" #include "mem/cache/cache.hh"
#include "mem/bus/bus.hh" #include "mem/bus.hh"
#include "mem/cache/coherence/coherence_protocol.hh" #include "mem/cache/coherence/coherence_protocol.hh"
#include "sim/builder.hh" #include "sim/builder.hh"
@ -84,13 +84,6 @@
#include "mem/cache/coherence/uni_coherence.hh" #include "mem/cache/coherence/uni_coherence.hh"
#include "mem/cache/coherence/simple_coherence.hh" #include "mem/cache/coherence/simple_coherence.hh"
// Bus Interfaces
#include "mem/bus/slave_interface.hh"
#include "mem/bus/master_interface.hh"
#include "mem/memory_interface.hh"
#include "mem/trace/mem_trace_writer.hh"
//Prefetcher Headers //Prefetcher Headers
#if defined(USE_GHB) #if defined(USE_GHB)
#include "mem/cache/prefetch/ghb_prefetcher.hh" #include "mem/cache/prefetch/ghb_prefetcher.hh"
@ -118,8 +111,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(BaseCache)
Param<int> tgts_per_mshr; Param<int> tgts_per_mshr;
Param<int> write_buffers; Param<int> write_buffers;
Param<bool> prioritizeRequests; Param<bool> prioritizeRequests;
SimObjectParam<Bus *> in_bus; // SimObjectParam<Bus *> in_bus;
SimObjectParam<Bus *> out_bus; // SimObjectParam<Bus *> out_bus;
Param<bool> do_copy; Param<bool> do_copy;
SimObjectParam<CoherenceProtocol *> protocol; SimObjectParam<CoherenceProtocol *> protocol;
Param<Addr> trace_addr; Param<Addr> trace_addr;
@ -133,9 +126,9 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(BaseCache)
Param<int> compression_latency; Param<int> compression_latency;
Param<int> subblock_size; Param<int> subblock_size;
Param<Counter> max_miss_count; Param<Counter> max_miss_count;
SimObjectParam<HierParams *> hier; // SimObjectParam<HierParams *> hier;
VectorParam<Range<Addr> > addr_range; VectorParam<Range<Addr> > addr_range;
SimObjectParam<MemTraceWriter *> mem_trace; // SimObjectParam<MemTraceWriter *> mem_trace;
Param<bool> split; Param<bool> split;
Param<int> split_size; Param<int> split_size;
Param<bool> lifo; Param<bool> lifo;
@ -151,6 +144,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(BaseCache)
Param<bool> prefetch_cache_check_push; Param<bool> prefetch_cache_check_push;
Param<bool> prefetch_use_cpu_id; Param<bool> prefetch_use_cpu_id;
Param<bool> prefetch_data_accesses_only; Param<bool> prefetch_data_accesses_only;
Param<int> hit_latency;
END_DECLARE_SIM_OBJECT_PARAMS(BaseCache) END_DECLARE_SIM_OBJECT_PARAMS(BaseCache)
@ -166,8 +160,9 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(BaseCache)
INIT_PARAM_DFLT(write_buffers, "number of write buffers", 8), INIT_PARAM_DFLT(write_buffers, "number of write buffers", 8),
INIT_PARAM_DFLT(prioritizeRequests, "always service demand misses first", INIT_PARAM_DFLT(prioritizeRequests, "always service demand misses first",
false), false),
INIT_PARAM_DFLT(in_bus, "incoming bus object", NULL), /* INIT_PARAM_DFLT(in_bus, "incoming bus object", NULL),
INIT_PARAM(out_bus, "outgoing bus object"), INIT_PARAM(out_bus, "outgoing bus object"),
*/
INIT_PARAM_DFLT(do_copy, "perform fast copies in the cache", false), INIT_PARAM_DFLT(do_copy, "perform fast copies in the cache", false),
INIT_PARAM_DFLT(protocol, "coherence protocol to use in the cache", NULL), INIT_PARAM_DFLT(protocol, "coherence protocol to use in the cache", NULL),
INIT_PARAM_DFLT(trace_addr, "address to trace", 0), INIT_PARAM_DFLT(trace_addr, "address to trace", 0),
@ -192,12 +187,13 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(BaseCache)
INIT_PARAM_DFLT(max_miss_count, INIT_PARAM_DFLT(max_miss_count,
"The number of misses to handle before calling exit", "The number of misses to handle before calling exit",
0), 0),
INIT_PARAM_DFLT(hier, /* INIT_PARAM_DFLT(hier,
"Hierarchy global variables", "Hierarchy global variables",
&defaultHierParams), &defaultHierParams),
*/
INIT_PARAM_DFLT(addr_range, "The address range in bytes", INIT_PARAM_DFLT(addr_range, "The address range in bytes",
vector<Range<Addr> >(1,RangeIn((Addr)0, MaxAddr))), vector<Range<Addr> >(1,RangeIn((Addr)0, MaxAddr))),
INIT_PARAM_DFLT(mem_trace, "Memory trace to write accesses to", NULL), // INIT_PARAM_DFLT(mem_trace, "Memory trace to write accesses to", NULL),
INIT_PARAM_DFLT(split, "Whether this is a partitioned cache", false), INIT_PARAM_DFLT(split, "Whether this is a partitioned cache", false),
INIT_PARAM_DFLT(split_size, "the number of \"ways\" belonging to the LRU partition", 0), INIT_PARAM_DFLT(split_size, "the number of \"ways\" belonging to the LRU partition", 0),
INIT_PARAM_DFLT(lifo, "whether you are using a LIFO repl. policy", false), INIT_PARAM_DFLT(lifo, "whether you are using a LIFO repl. policy", false),
@ -212,7 +208,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(BaseCache)
INIT_PARAM_DFLT(prefetch_policy, "Type of prefetcher to use", "none"), INIT_PARAM_DFLT(prefetch_policy, "Type of prefetcher to use", "none"),
INIT_PARAM_DFLT(prefetch_cache_check_push, "Check if in cash on push or pop of prefetch queue", true), INIT_PARAM_DFLT(prefetch_cache_check_push, "Check if in cash on push or pop of prefetch queue", true),
INIT_PARAM_DFLT(prefetch_use_cpu_id, "Use the CPU ID to seperate calculations of prefetches", true), INIT_PARAM_DFLT(prefetch_use_cpu_id, "Use the CPU ID to seperate calculations of prefetches", true),
INIT_PARAM_DFLT(prefetch_data_accesses_only, "Only prefetch on data not on instruction accesses", false) INIT_PARAM_DFLT(prefetch_data_accesses_only, "Only prefetch on data not on instruction accesses", false),
INIT_PARAM_DFLT(hit_latency, "Hit Latecny for a succesful access", 1)
END_INIT_SIM_OBJECT_PARAMS(BaseCache) END_INIT_SIM_OBJECT_PARAMS(BaseCache)
@ -232,12 +229,12 @@ END_INIT_SIM_OBJECT_PARAMS(BaseCache)
} \ } \
Cache<CacheTags<t, comp>, b, c>::Params params(tagStore, mq, coh, \ Cache<CacheTags<t, comp>, b, c>::Params params(tagStore, mq, coh, \
do_copy, base_params, \ do_copy, base_params, \
in_bus, out_bus, pf, \ /*in_bus, out_bus,*/ pf, \
prefetch_access); \ prefetch_access); \
Cache<CacheTags<t, comp>, b, c> *retval = \ Cache<CacheTags<t, comp>, b, c> *retval = \
new Cache<CacheTags<t, comp>, b, c>(getInstanceName(), hier, \ new Cache<CacheTags<t, comp>, b, c>(getInstanceName(), /*hier,*/ \
params); \ params); \
if (in_bus == NULL) { \ /* if (in_bus == NULL) { \
retval->setSlaveInterface(new MemoryInterface<Cache<CacheTags<t, comp>, b, c> >(getInstanceName(), hier, retval, mem_trace)); \ retval->setSlaveInterface(new MemoryInterface<Cache<CacheTags<t, comp>, b, c> >(getInstanceName(), hier, retval, mem_trace)); \
} else { \ } else { \
retval->setSlaveInterface(new SlaveInterface<Cache<CacheTags<t, comp>, b, c>, Bus>(getInstanceName(), hier, retval, in_bus, mem_trace)); \ retval->setSlaveInterface(new SlaveInterface<Cache<CacheTags<t, comp>, b, c>, Bus>(getInstanceName(), hier, retval, in_bus, mem_trace)); \
@ -245,6 +242,7 @@ END_INIT_SIM_OBJECT_PARAMS(BaseCache)
retval->setMasterInterface(new MasterInterface<Cache<CacheTags<t, comp>, b, c>, Bus>(getInstanceName(), hier, retval, out_bus)); \ retval->setMasterInterface(new MasterInterface<Cache<CacheTags<t, comp>, b, c>, Bus>(getInstanceName(), hier, retval, out_bus)); \
out_bus->rangeChange(); \ out_bus->rangeChange(); \
return retval; \ return retval; \
*/return true; \
} while (0) } while (0)
#define BUILD_CACHE_PANIC(x) do { \ #define BUILD_CACHE_PANIC(x) do { \
@ -465,7 +463,7 @@ CREATE_SIM_OBJECT(BaseCache)
const void *repl = NULL; const void *repl = NULL;
#endif #endif
if (mshrs == 1 || out_bus->doEvents() == false) { if (mshrs == 1 /*|| out_bus->doEvents() == false*/) {
BlockingBuffer *mq = new BlockingBuffer(true); BlockingBuffer *mq = new BlockingBuffer(true);
BUILD_COHERENCE(BlockingBuffer); BUILD_COHERENCE(BlockingBuffer);
} else { } else {

View file

@ -90,6 +90,8 @@ doAtomicAccess(Packet *pkt, CachePort *cachePort, bool isCpuSide)
else else
snoopProbe(pkt, true); snoopProbe(pkt, true);
} }
//Fix this timing info
return hitLatency;
} }
template<class TagStore, class Buffering, class Coherence> template<class TagStore, class Buffering, class Coherence>
@ -129,10 +131,12 @@ Cache(const std::string &_name,
coherence(params.coherence), prefetcher(params.prefetcher), coherence(params.coherence), prefetcher(params.prefetcher),
doCopy(params.doCopy), blockOnCopy(params.blockOnCopy) doCopy(params.doCopy), blockOnCopy(params.blockOnCopy)
{ {
if (params.in == NULL) { //FIX BUS POINTERS
// if (params.in == NULL) {
topLevelCache = true; topLevelCache = true;
} // }
tags->setCache(this, params.out->width, params.out->clockRate); //PLEASE FIX THIS, BUS SIZES NOT BEING USED
tags->setCache(this, blkSize, 1/*params.out->width, params.out->clockRate*/);
tags->setPrefetcher(prefetcher); tags->setPrefetcher(prefetcher);
missQueue->setCache(this); missQueue->setCache(this);
missQueue->setPrefetcher(prefetcher); missQueue->setPrefetcher(prefetcher);
@ -140,8 +144,10 @@ Cache(const std::string &_name,
prefetcher->setCache(this); prefetcher->setCache(this);
prefetcher->setTags(tags); prefetcher->setTags(tags);
prefetcher->setBuffer(missQueue); prefetcher->setBuffer(missQueue);
#if 0
invalidatePkt = new Packet; invalidatePkt = new Packet;
invalidatePkt->cmd = Packet::InvalidateReq; invalidatePkt->cmd = Packet::InvalidateReq;
#endif
} }
template<class TagStore, class Buffering, class Coherence> template<class TagStore, class Buffering, class Coherence>
@ -175,27 +181,27 @@ Cache<TagStore,Buffering,Coherence>::access(PacketPtr &pkt)
//Upgrade or Invalidate //Upgrade or Invalidate
//Look into what happens if two slave caches on bus //Look into what happens if two slave caches on bus
DPRINTF(Cache, "%s %d %x ? blk_addr: %x\n", pkt->cmdString(), DPRINTF(Cache, "%s %d %x ? blk_addr: %x\n", pkt->cmdString(),
pkt->req->asid, pkt->addr & (((ULL(1))<<48)-1), pkt->req->getAsid(), pkt->getAddr() & (((ULL(1))<<48)-1),
pkt->addr & ~((Addr)blkSize - 1)); pkt->getAddr() & ~((Addr)blkSize - 1));
//@todo Should this return latency have the hit latency in it? //@todo Should this return latency have the hit latency in it?
// respond(pkt,curTick+lat); // respond(pkt,curTick+lat);
(int)pkt->coherence |= SATISFIED; pkt->flags |= SATISFIED;
// return MA_HIT; //@todo, return values // return MA_HIT; //@todo, return values
return true; return true;
} }
blk = tags->handleAccess(pkt, lat, writebacks); blk = tags->handleAccess(pkt, lat, writebacks);
} else { } else {
size = pkt->size; size = pkt->getSize();
} }
// If this is a block size write/hint (WH64) allocate the block here // If this is a block size write/hint (WH64) allocate the block here
// if the coherence protocol allows it. // if the coherence protocol allows it.
/** @todo make the fast write alloc (wh64) work with coherence. */ /** @todo make the fast write alloc (wh64) work with coherence. */
/** @todo Do we want to do fast writes for writebacks as well? */ /** @todo Do we want to do fast writes for writebacks as well? */
if (!blk && pkt->size >= blkSize && coherence->allowFastWrites() && if (!blk && pkt->getSize() >= blkSize && coherence->allowFastWrites() &&
(pkt->cmd == Packet::WriteReq || pkt->cmd == Packet::WriteInvalidateReq) ) { (pkt->cmd == Packet::WriteReq || pkt->cmd == Packet::WriteInvalidateReq) ) {
// not outstanding misses, can do this // not outstanding misses, can do this
MSHR* outstanding_miss = missQueue->findMSHR(pkt->addr, pkt->req->asid); MSHR* outstanding_miss = missQueue->findMSHR(pkt->getAddr(), pkt->req->getAsid());
if (pkt->cmd == Packet::WriteInvalidateReq || !outstanding_miss) { if (pkt->cmd == Packet::WriteInvalidateReq || !outstanding_miss) {
if (outstanding_miss) { if (outstanding_miss) {
warn("WriteInv doing a fastallocate" warn("WriteInv doing a fastallocate"
@ -211,8 +217,8 @@ Cache<TagStore,Buffering,Coherence>::access(PacketPtr &pkt)
writebacks.pop_front(); writebacks.pop_front();
} }
DPRINTF(Cache, "%s %d %x %s blk_addr: %x pc %x\n", pkt->cmdString(), DPRINTF(Cache, "%s %d %x %s blk_addr: %x pc %x\n", pkt->cmdString(),
pkt->req->asid, pkt->addr & (((ULL(1))<<48)-1), (blk) ? "hit" : "miss", pkt->req->getAsid(), pkt->getAddr() & (((ULL(1))<<48)-1), (blk) ? "hit" : "miss",
pkt->addr & ~((Addr)blkSize - 1), pkt->req->pc); pkt->getAddr() & ~((Addr)blkSize - 1), pkt->req->getPC());
if (blk) { if (blk) {
// Hit // Hit
hits[pkt->cmdToIndex()][pkt->req->getThreadNum()]++; hits[pkt->cmdToIndex()][pkt->req->getThreadNum()]++;
@ -230,7 +236,7 @@ Cache<TagStore,Buffering,Coherence>::access(PacketPtr &pkt)
if (missCount) { if (missCount) {
--missCount; --missCount;
if (missCount == 0) if (missCount == 0)
new SimLoopExitEvent("A cache reached the maximum miss count"); new SimLoopExitEvent(curTick, "A cache reached the maximum miss count");
} }
} }
missQueue->handleMiss(pkt, size, curTick + hitLatency); missQueue->handleMiss(pkt, size, curTick + hitLatency);
@ -281,14 +287,14 @@ Cache<TagStore,Buffering,Coherence>::handleResponse(Packet * &pkt)
BlkType *blk = NULL; BlkType *blk = NULL;
if (pkt->senderState) { if (pkt->senderState) {
// MemDebug::cacheResponse(pkt); // MemDebug::cacheResponse(pkt);
DPRINTF(Cache, "Handling reponse to %x, blk addr: %x\n",pkt->addr, DPRINTF(Cache, "Handling reponse to %x, blk addr: %x\n",pkt->getAddr(),
pkt->addr & (((ULL(1))<<48)-1)); pkt->getAddr() & (((ULL(1))<<48)-1));
if (pkt->isCacheFill() && !pkt->isNoAllocate()) { if (pkt->isCacheFill() && !pkt->isNoAllocate()) {
blk = tags->findBlock(pkt); blk = tags->findBlock(pkt);
CacheBlk::State old_state = (blk) ? blk->status : 0; CacheBlk::State old_state = (blk) ? blk->status : 0;
PacketList writebacks; PacketList writebacks;
blk = tags->handleFill(blk, pkt->senderState, blk = tags->handleFill(blk, (MSHR*)pkt->senderState,
coherence->getNewState(pkt,old_state), coherence->getNewState(pkt,old_state),
writebacks); writebacks);
while (!writebacks.empty()) { while (!writebacks.empty()) {
@ -310,7 +316,7 @@ Cache<TagStore,Buffering,Coherence>::pseudoFill(Addr addr, int asid)
// Read the data into the mshr // Read the data into the mshr
BlkType *blk = tags->handleAccess(mshr->pkt, lat, dummy, false); BlkType *blk = tags->handleAccess(mshr->pkt, lat, dummy, false);
assert(dummy.empty()); assert(dummy.empty());
assert((int)mshr->pkt->coherence & SATISFIED); assert(mshr->pkt->flags & SATISFIED);
// can overload order since it isn't used on non pending blocks // can overload order since it isn't used on non pending blocks
mshr->order = blk->status; mshr->order = blk->status;
// temporarily remove the block from the cache. // temporarily remove the block from the cache.
@ -328,11 +334,11 @@ Cache<TagStore,Buffering,Coherence>::pseudoFill(MSHR *mshr)
// Read the data into the mshr // Read the data into the mshr
BlkType *blk = tags->handleAccess(mshr->pkt, lat, dummy, false); BlkType *blk = tags->handleAccess(mshr->pkt, lat, dummy, false);
assert(dummy.empty()); assert(dummy.empty());
assert((int)mshr->pkt->coherence & SATISFIED); assert(mshr->pkt->flags & SATISFIED);
// can overload order since it isn't used on non pending blocks // can overload order since it isn't used on non pending blocks
mshr->order = blk->status; mshr->order = blk->status;
// temporarily remove the block from the cache. // temporarily remove the block from the cache.
tags->invalidateBlk(mshr->pkt->addr, mshr->pkt->req->asid); tags->invalidateBlk(mshr->pkt->getAddr(), mshr->pkt->req->getAsid());
} }
@ -348,9 +354,10 @@ template<class TagStore, class Buffering, class Coherence>
void void
Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt) Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
{ {
Addr blk_addr = pkt->addr & ~(Addr(blkSize-1));
Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
BlkType *blk = tags->findBlock(pkt); BlkType *blk = tags->findBlock(pkt);
MSHR *mshr = missQueue->findMSHR(blk_addr, pkt->req->asid); MSHR *mshr = missQueue->findMSHR(blk_addr, pkt->req->getAsid());
if (isTopLevel() && coherence->hasProtocol()) { //@todo Move this into handle bus req if (isTopLevel() && coherence->hasProtocol()) { //@todo Move this into handle bus req
//If we find an mshr, and it is in service, we need to NACK or invalidate //If we find an mshr, and it is in service, we need to NACK or invalidate
if (mshr) { if (mshr) {
@ -360,7 +367,7 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
//If the outstanding request was an invalidate (upgrade,readex,..) //If the outstanding request was an invalidate (upgrade,readex,..)
//Then we need to ACK the request until we get the data //Then we need to ACK the request until we get the data
//Also NACK if the outstanding request is not a cachefill (writeback) //Also NACK if the outstanding request is not a cachefill (writeback)
(int)pkt->coherence |= NACKED_LINE; pkt->flags |= NACKED_LINE;
return; return;
} }
else { else {
@ -373,19 +380,19 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
//@todo Make it so that a read to a pending read can't be exclusive now. //@todo Make it so that a read to a pending read can't be exclusive now.
//Set the address so find match works //Set the address so find match works
invalidatePkt->addr = pkt->addr; invalidatePkt->addrOverride(pkt->getAddr());
//Append the invalidate on //Append the invalidate on
missQueue->addTarget(mshr,invalidatePkt); missQueue->addTarget(mshr,invalidatePkt);
DPRINTF(Cache, "Appending Invalidate to blk_addr: %x\n", pkt->addr & (((ULL(1))<<48)-1)); DPRINTF(Cache, "Appending Invalidate to blk_addr: %x\n", pkt->getAddr() & (((ULL(1))<<48)-1));
return; return;
} }
} }
} }
//We also need to check the writeback buffers and handle those //We also need to check the writeback buffers and handle those
std::vector<MSHR *> writebacks; std::vector<MSHR *> writebacks;
if (missQueue->findWrites(blk_addr, pkt->req->asid, writebacks)) { if (missQueue->findWrites(blk_addr, pkt->req->getAsid(), writebacks)) {
DPRINTF(Cache, "Snoop hit in writeback to blk_addr: %x\n", pkt->addr & (((ULL(1))<<48)-1)); DPRINTF(Cache, "Snoop hit in writeback to blk_addr: %x\n", pkt->getAddr() & (((ULL(1))<<48)-1));
//Look through writebacks for any non-uncachable writes, use that //Look through writebacks for any non-uncachable writes, use that
for (int i=0; i<writebacks.size(); i++) { for (int i=0; i<writebacks.size(); i++) {
@ -395,17 +402,18 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
if (pkt->isRead()) { if (pkt->isRead()) {
//Only Upgrades don't get here //Only Upgrades don't get here
//Supply the data //Supply the data
(int)pkt->coherence |= SATISFIED; pkt->flags |= SATISFIED;
//If we are in an exclusive protocol, make it ask again //If we are in an exclusive protocol, make it ask again
//to get write permissions (upgrade), signal shared //to get write permissions (upgrade), signal shared
(int)pkt->coherence |= SHARED_LINE; pkt->flags |= SHARED_LINE;
assert(pkt->isRead()); assert(pkt->isRead());
assert(pkt->offset < blkSize); Addr offset = pkt->getAddr() & ~(blkSize - 1);
assert(pkt->size <= blkSize); assert(offset < blkSize);
assert(pkt->offset + pkt->size <=blkSize); assert(pkt->getSize() <= blkSize);
memcpy(pkt->data, mshr->pkt->data + pkt->offset, pkt->size); assert(offset + pkt->getSize() <=blkSize);
memcpy(pkt->getPtr<uint8_t>(), mshr->pkt->getPtr<uint8_t>() + offset, pkt->getSize());
respondToSnoop(pkt); respondToSnoop(pkt);
} }
@ -434,7 +442,7 @@ void
Cache<TagStore,Buffering,Coherence>::snoopResponse(Packet * &pkt) Cache<TagStore,Buffering,Coherence>::snoopResponse(Packet * &pkt)
{ {
//Need to handle the response, if NACKED //Need to handle the response, if NACKED
if ((int)pkt->coherence & NACKED_LINE) { if (pkt->flags & NACKED_LINE) {
//Need to mark it as not in service, and retry for bus //Need to mark it as not in service, and retry for bus
assert(0); //Yeah, we saw a NACK come through assert(0); //Yeah, we saw a NACK come through
@ -463,41 +471,35 @@ Tick
Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update) Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update)
{ {
// MemDebug::cacheProbe(pkt); // MemDebug::cacheProbe(pkt);
if (!pkt->req->isUncacheable()) { if (!pkt->req->isUncacheable()) {
if (pkt->isInvalidate() && !pkt->isRead() if (pkt->isInvalidate() && !pkt->isRead()
&& !pkt->isWrite()) { && !pkt->isWrite()) {
//Upgrade or Invalidate, satisfy it, don't forward //Upgrade or Invalidate, satisfy it, don't forward
DPRINTF(Cache, "%s %d %x ? blk_addr: %x\n", pkt->cmdString(), DPRINTF(Cache, "%s %d %x ? blk_addr: %x\n", pkt->cmdString(),
pkt->req->asid, pkt->addr & (((ULL(1))<<48)-1), pkt->req->getAsid(), pkt->getAddr() & (((ULL(1))<<48)-1),
pkt->addr & ~((Addr)blkSize - 1)); pkt->getAddr() & ~((Addr)blkSize - 1));
(int)pkt->coherence |= SATISFIED; pkt->flags |= SATISFIED;
return 0; return 0;
} }
} }
if (!update && !doData()) {
// Nothing to do here
return mi->sendProbe(pkt,update);
}
PacketList writebacks; PacketList writebacks;
int lat; int lat;
BlkType *blk = tags->handleAccess(pkt, lat, writebacks, update); BlkType *blk = tags->handleAccess(pkt, lat, writebacks, update);
if (!blk) { if (!blk) {
// Need to check for outstanding misses and writes // Need to check for outstanding misses and writes
Addr blk_addr = pkt->addr & ~(blkSize - 1); Addr blk_addr = pkt->getAddr() & ~(blkSize - 1);
// There can only be one matching outstanding miss. // There can only be one matching outstanding miss.
MSHR* mshr = missQueue->findMSHR(blk_addr, pkt->req->asid); MSHR* mshr = missQueue->findMSHR(blk_addr, pkt->req->getAsid());
// There can be many matching outstanding writes. // There can be many matching outstanding writes.
vector<MSHR*> writes; vector<MSHR*> writes;
missQueue->findWrites(blk_addr, pkt->req->asid, writes); missQueue->findWrites(blk_addr, pkt->req->getAsid(), writes);
if (!update) { if (!update) {
mi->sendProbe(pkt, update); memSidePort->sendFunctional(pkt);
// Check for data in MSHR and writebuffer. // Check for data in MSHR and writebuffer.
if (mshr) { if (mshr) {
warn("Found outstanding miss on an non-update probe"); warn("Found outstanding miss on an non-update probe");
@ -508,26 +510,26 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update)
Packet * target = *i; Packet * target = *i;
// If the target contains data, and it overlaps the // If the target contains data, and it overlaps the
// probed request, need to update data // probed request, need to update data
if (target->isWrite() && target->overlaps(pkt)) { if (target->isWrite() && target->intersect(pkt)) {
uint8_t* pkt_data; uint8_t* pkt_data;
uint8_t* write_data; uint8_t* write_data;
int data_size; int data_size;
if (target->addr < pkt->addr) { if (target->getAddr() < pkt->getAddr()) {
int offset = pkt->addr - target->paddr; int offset = pkt->getAddr() - target->getAddr();
pkt_data = pkt->data; pkt_data = pkt->getPtr<uint8_t>();
write_data = target->data + offset; write_data = target->getPtr<uint8_t>() + offset;
data_size = target->size - offset; data_size = target->getSize() - offset;
assert(data_size > 0); assert(data_size > 0);
if (data_size > pkt->size) if (data_size > pkt->getSize())
data_size = pkt->size; data_size = pkt->getSize();
} else { } else {
int offset = target->addr - pkt->addr; int offset = target->getAddr() - pkt->getAddr();
pkt_data = pkt->data + offset; pkt_data = pkt->getPtr<uint8_t>() + offset;
write_data = target->data; write_data = target->getPtr<uint8_t>();
data_size = pkt->size - offset; data_size = pkt->getSize() - offset;
assert(data_size > pkt->size); assert(data_size > pkt->getSize());
if (data_size > target->size) if (data_size > target->getSize())
data_size = target->size; data_size = target->getSize();
} }
if (pkt->isWrite()) { if (pkt->isWrite()) {
@ -540,27 +542,27 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update)
} }
for (int i = 0; i < writes.size(); ++i) { for (int i = 0; i < writes.size(); ++i) {
Packet * write = writes[i]->pkt; Packet * write = writes[i]->pkt;
if (write->overlaps(pkt)) { if (write->intersect(pkt)) {
warn("Found outstanding write on an non-update probe"); warn("Found outstanding write on an non-update probe");
uint8_t* pkt_data; uint8_t* pkt_data;
uint8_t* write_data; uint8_t* write_data;
int data_size; int data_size;
if (write->addr < pkt->addr) { if (write->getAddr() < pkt->getAddr()) {
int offset = pkt->addr - write->addr; int offset = pkt->getAddr() - write->getAddr();
pkt_data = pkt->data; pkt_data = pkt->getPtr<uint8_t>();
write_data = write->data + offset; write_data = write->getPtr<uint8_t>() + offset;
data_size = write->size - offset; data_size = write->getSize() - offset;
assert(data_size > 0); assert(data_size > 0);
if (data_size > pkt->size) if (data_size > pkt->getSize())
data_size = pkt->size; data_size = pkt->getSize();
} else { } else {
int offset = write->addr - pkt->addr; int offset = write->getAddr() - pkt->getAddr();
pkt_data = pkt->data + offset; pkt_data = pkt->getPtr<uint8_t>() + offset;
write_data = write->data; write_data = write->getPtr<uint8_t>();
data_size = pkt->size - offset; data_size = pkt->getSize() - offset;
assert(data_size > pkt->size); assert(data_size > pkt->getSize());
if (data_size > write->size) if (data_size > write->getSize())
data_size = write->size; data_size = write->getSize();
} }
if (pkt->isWrite()) { if (pkt->isWrite()) {
@ -580,23 +582,20 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update)
} }
if (!pkt->req->isUncacheable()) { if (!pkt->req->isUncacheable()) {
// Fetch the cache block to fill // Fetch the cache block to fill
Packet * busPkt = new Packet();
busPkt->addr = blk_addr;
busPkt->size = blkSize;
busPkt->data = new uint8_t[blkSize];
BlkType *blk = tags->findBlock(pkt); BlkType *blk = tags->findBlock(pkt);
busPkt->cmd = coherence->getBusCmd(pkt->cmd, Packet::Command temp_cmd = coherence->getBusCmd(pkt->cmd,
(blk)? blk->status : 0); (blk)? blk->status : 0);
busPkt->req->asid = pkt->req->asid; Packet * busPkt = new Packet(pkt->req,temp_cmd, -1, blkSize);
busPkt->xc = pkt->xc;
busPkt->req->setThreadNum() = pkt->req->getThreadNum(); uint8_t* temp_data = new uint8_t[blkSize];
busPkt->dataDynamicArray<uint8_t>(temp_data);
busPkt->time = curTick; busPkt->time = curTick;
lat = mi->sendProbe(busPkt, update); lat = memSidePort->sendAtomic(busPkt);
if (!busPkt->isSatisfied()) { if (!(busPkt->flags & SATISFIED)) {
// blocked at a higher level, just return // blocked at a higher level, just return
return 0; return 0;
} }
@ -609,19 +608,19 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update)
writebacks, pkt); writebacks, pkt);
// Handle writebacks if needed // Handle writebacks if needed
while (!writebacks.empty()){ while (!writebacks.empty()){
mi->sendProbe(writebacks.front(), update); memSidePort->sendAtomic(writebacks.front());
writebacks.pop_front(); writebacks.pop_front();
} }
return lat + hitLatency; return lat + hitLatency;
} else { } else {
return mi->sendProbe(pkt,update); return memSidePort->sendAtomic(pkt);
} }
} }
} else { } else {
// There was a cache hit. // There was a cache hit.
// Handle writebacks if needed // Handle writebacks if needed
while (!writebacks.empty()){ while (!writebacks.empty()){
mi->sendProbe(writebacks.front(), update); memSidePort->sendAtomic(writebacks.front());
writebacks.pop_front(); writebacks.pop_front();
} }
@ -629,7 +628,7 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update)
hits[pkt->cmdToIndex()][pkt->req->getThreadNum()]++; hits[pkt->cmdToIndex()][pkt->req->getThreadNum()]++;
} else if (pkt->isWrite()) { } else if (pkt->isWrite()) {
// Still need to change data in all locations. // Still need to change data in all locations.
return mi->sendProbe(pkt, update); return memSidePort->sendAtomic(pkt);
} }
return curTick + lat; return curTick + lat;
} }
@ -641,11 +640,11 @@ template<class TagStore, class Buffering, class Coherence>
Tick Tick
Cache<TagStore,Buffering,Coherence>::snoopProbe(PacketPtr &pkt, bool update) Cache<TagStore,Buffering,Coherence>::snoopProbe(PacketPtr &pkt, bool update)
{ {
Addr blk_addr = pkt->addr & ~(Addr(blkSize-1)); Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
BlkType *blk = tags->findBlock(pkt); BlkType *blk = tags->findBlock(pkt);
MSHR *mshr = missQueue->findMSHR(blk_addr, pkt->req->asid); MSHR *mshr = missQueue->findMSHR(blk_addr, pkt->req->getAsid());
CacheBlk::State new_state = 0; CacheBlk::State new_state = 0;
bool satisfy = coherence->handleBusPktuest(pkt,blk,mshr, new_state); bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state);
if (satisfy) { if (satisfy) {
tags->handleSnoop(blk, new_state, pkt); tags->handleSnoop(blk, new_state, pkt);
return hitLatency; return hitLatency;

View file

@ -47,7 +47,7 @@ using namespace std;
CoherenceProtocol::StateTransition::StateTransition() CoherenceProtocol::StateTransition::StateTransition()
: busCmd(InvalidCmd), newState(-1), snoopFunc(invalidTransition) : busCmd(Packet::InvalidCmd), newState(-1), snoopFunc(invalidTransition)
{ {
} }
@ -59,132 +59,132 @@ CoherenceProtocol::regStats()
// requestCount and snoopCount arrays, most of these are invalid, // requestCount and snoopCount arrays, most of these are invalid,
// so we just select the interesting ones to print here. // so we just select the interesting ones to print here.
requestCount[Invalid][Read] requestCount[Invalid][Packet::ReadReq]
.name(name() + ".read_invalid") .name(name() + ".read_invalid")
.desc("read misses to invalid blocks") .desc("read misses to invalid blocks")
; ;
requestCount[Invalid][Write] requestCount[Invalid][Packet::WriteReq]
.name(name() +".write_invalid") .name(name() +".write_invalid")
.desc("write misses to invalid blocks") .desc("write misses to invalid blocks")
; ;
requestCount[Invalid][Soft_Prefetch] requestCount[Invalid][Packet::SoftPFReq]
.name(name() +".swpf_invalid") .name(name() +".swpf_invalid")
.desc("soft prefetch misses to invalid blocks") .desc("soft prefetch misses to invalid blocks")
; ;
requestCount[Invalid][Hard_Prefetch] requestCount[Invalid][Packet::HardPFReq]
.name(name() +".hwpf_invalid") .name(name() +".hwpf_invalid")
.desc("hard prefetch misses to invalid blocks") .desc("hard prefetch misses to invalid blocks")
; ;
requestCount[Shared][Write] requestCount[Shared][Packet::WriteReq]
.name(name() + ".write_shared") .name(name() + ".write_shared")
.desc("write misses to shared blocks") .desc("write misses to shared blocks")
; ;
requestCount[Owned][Write] requestCount[Owned][Packet::WriteReq]
.name(name() + ".write_owned") .name(name() + ".write_owned")
.desc("write misses to owned blocks") .desc("write misses to owned blocks")
; ;
snoopCount[Shared][Read] snoopCount[Shared][Packet::ReadReq]
.name(name() + ".snoop_read_shared") .name(name() + ".snoop_read_shared")
.desc("read snoops on shared blocks") .desc("read snoops on shared blocks")
; ;
snoopCount[Shared][ReadEx] snoopCount[Shared][Packet::ReadExReq]
.name(name() + ".snoop_readex_shared") .name(name() + ".snoop_readex_shared")
.desc("readEx snoops on shared blocks") .desc("readEx snoops on shared blocks")
; ;
snoopCount[Shared][Upgrade] snoopCount[Shared][Packet::UpgradeReq]
.name(name() + ".snoop_upgrade_shared") .name(name() + ".snoop_upgrade_shared")
.desc("upgradee snoops on shared blocks") .desc("upgradee snoops on shared blocks")
; ;
snoopCount[Modified][Read] snoopCount[Modified][Packet::ReadReq]
.name(name() + ".snoop_read_modified") .name(name() + ".snoop_read_modified")
.desc("read snoops on modified blocks") .desc("read snoops on modified blocks")
; ;
snoopCount[Modified][ReadEx] snoopCount[Modified][Packet::ReadExReq]
.name(name() + ".snoop_readex_modified") .name(name() + ".snoop_readex_modified")
.desc("readEx snoops on modified blocks") .desc("readEx snoops on modified blocks")
; ;
snoopCount[Owned][Read] snoopCount[Owned][Packet::ReadReq]
.name(name() + ".snoop_read_owned") .name(name() + ".snoop_read_owned")
.desc("read snoops on owned blocks") .desc("read snoops on owned blocks")
; ;
snoopCount[Owned][ReadEx] snoopCount[Owned][Packet::ReadExReq]
.name(name() + ".snoop_readex_owned") .name(name() + ".snoop_readex_owned")
.desc("readEx snoops on owned blocks") .desc("readEx snoops on owned blocks")
; ;
snoopCount[Owned][Upgrade] snoopCount[Owned][Packet::UpgradeReq]
.name(name() + ".snoop_upgrade_owned") .name(name() + ".snoop_upgrade_owned")
.desc("upgrade snoops on owned blocks") .desc("upgrade snoops on owned blocks")
; ;
snoopCount[Exclusive][Read] snoopCount[Exclusive][Packet::ReadReq]
.name(name() + ".snoop_read_exclusive") .name(name() + ".snoop_read_exclusive")
.desc("read snoops on exclusive blocks") .desc("read snoops on exclusive blocks")
; ;
snoopCount[Exclusive][ReadEx] snoopCount[Exclusive][Packet::ReadExReq]
.name(name() + ".snoop_readex_exclusive") .name(name() + ".snoop_readex_exclusive")
.desc("readEx snoops on exclusive blocks") .desc("readEx snoops on exclusive blocks")
; ;
snoopCount[Shared][Invalidate] snoopCount[Shared][Packet::InvalidateReq]
.name(name() + ".snoop_inv_shared") .name(name() + ".snoop_inv_shared")
.desc("Invalidate snoops on shared blocks") .desc("Invalidate snoops on shared blocks")
; ;
snoopCount[Owned][Invalidate] snoopCount[Owned][Packet::InvalidateReq]
.name(name() + ".snoop_inv_owned") .name(name() + ".snoop_inv_owned")
.desc("Invalidate snoops on owned blocks") .desc("Invalidate snoops on owned blocks")
; ;
snoopCount[Exclusive][Invalidate] snoopCount[Exclusive][Packet::InvalidateReq]
.name(name() + ".snoop_inv_exclusive") .name(name() + ".snoop_inv_exclusive")
.desc("Invalidate snoops on exclusive blocks") .desc("Invalidate snoops on exclusive blocks")
; ;
snoopCount[Modified][Invalidate] snoopCount[Modified][Packet::InvalidateReq]
.name(name() + ".snoop_inv_modified") .name(name() + ".snoop_inv_modified")
.desc("Invalidate snoops on modified blocks") .desc("Invalidate snoops on modified blocks")
; ;
snoopCount[Invalid][Invalidate] snoopCount[Invalid][Packet::InvalidateReq]
.name(name() + ".snoop_inv_invalid") .name(name() + ".snoop_inv_invalid")
.desc("Invalidate snoops on invalid blocks") .desc("Invalidate snoops on invalid blocks")
; ;
snoopCount[Shared][WriteInvalidate] snoopCount[Shared][Packet::WriteInvalidateReq]
.name(name() + ".snoop_writeinv_shared") .name(name() + ".snoop_writeinv_shared")
.desc("WriteInvalidate snoops on shared blocks") .desc("WriteInvalidate snoops on shared blocks")
; ;
snoopCount[Owned][WriteInvalidate] snoopCount[Owned][Packet::WriteInvalidateReq]
.name(name() + ".snoop_writeinv_owned") .name(name() + ".snoop_writeinv_owned")
.desc("WriteInvalidate snoops on owned blocks") .desc("WriteInvalidate snoops on owned blocks")
; ;
snoopCount[Exclusive][WriteInvalidate] snoopCount[Exclusive][Packet::WriteInvalidateReq]
.name(name() + ".snoop_writeinv_exclusive") .name(name() + ".snoop_writeinv_exclusive")
.desc("WriteInvalidate snoops on exclusive blocks") .desc("WriteInvalidate snoops on exclusive blocks")
; ;
snoopCount[Modified][WriteInvalidate] snoopCount[Modified][Packet::WriteInvalidateReq]
.name(name() + ".snoop_writeinv_modified") .name(name() + ".snoop_writeinv_modified")
.desc("WriteInvalidate snoops on modified blocks") .desc("WriteInvalidate snoops on modified blocks")
; ;
snoopCount[Invalid][WriteInvalidate] snoopCount[Invalid][Packet::WriteInvalidateReq]
.name(name() + ".snoop_writeinv_invalid") .name(name() + ".snoop_writeinv_invalid")
.desc("WriteInvalidate snoops on invalid blocks") .desc("WriteInvalidate snoops on invalid blocks")
; ;
@ -270,167 +270,168 @@ CoherenceProtocol::CoherenceProtocol(const string &name,
fatal(""); fatal("");
} }
Packet::CommandEnum writeToSharedCmd = doUpgrades ? Upgrade : ReadEx; Packet::Command writeToSharedCmd = doUpgrades ? Packet::UpgradeReq : Packet::ReadExReq;
Packet::Command writeToSharedResp = doUpgrades ? Packet::UpgradeResp : Packet::ReadExResp;
//@todo add in hardware prefetch to this list //@todo add in hardware prefetch to this list
if (protocol == "msi") { if (protocol == "msi") {
// incoming requests: specify outgoing bus request // incoming requests: specify outgoing bus request
transitionTable[Invalid][Read].onRequest(Read); transitionTable[Invalid][Packet::ReadReq].onRequest(Packet::ReadReq);
transitionTable[Invalid][Write].onRequest(ReadEx); transitionTable[Invalid][Packet::WriteReq].onRequest(Packet::ReadExReq);
transitionTable[Shared][Write].onRequest(writeToSharedCmd); transitionTable[Shared][Packet::WriteReq].onRequest(writeToSharedCmd);
//Prefetching causes a read //Prefetching causes a read
transitionTable[Invalid][Soft_Prefetch].onRequest(Read); transitionTable[Invalid][Packet::SoftPFReq].onRequest(Packet::ReadReq);
transitionTable[Invalid][Hard_Prefetch].onRequest(Read); transitionTable[Invalid][Packet::HardPFReq].onRequest(Packet::ReadReq);
// on response to given request: specify new state // on response to given request: specify new state
transitionTable[Invalid][Read].onResponse(Shared); transitionTable[Invalid][Packet::ReadResp].onResponse(Shared);
transitionTable[Invalid][ReadEx].onResponse(Modified); transitionTable[Invalid][Packet::ReadExResp].onResponse(Modified);
transitionTable[Shared][writeToSharedCmd].onResponse(Modified); transitionTable[Shared][writeToSharedResp].onResponse(Modified);
// bus snoop transition functions // bus snoop transition functions
transitionTable[Invalid][Read].onSnoop(nullTransition); transitionTable[Invalid][Packet::ReadReq].onSnoop(nullTransition);
transitionTable[Invalid][ReadEx].onSnoop(nullTransition); transitionTable[Invalid][Packet::ReadExReq].onSnoop(nullTransition);
transitionTable[Shared][Read].onSnoop(nullTransition); transitionTable[Shared][Packet::ReadReq].onSnoop(nullTransition);
transitionTable[Shared][ReadEx].onSnoop(invalidateTrans); transitionTable[Shared][Packet::ReadExReq].onSnoop(invalidateTrans);
transitionTable[Modified][ReadEx].onSnoop(supplyAndInvalidateTrans); transitionTable[Modified][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans);
transitionTable[Modified][Read].onSnoop(supplyAndGotoSharedTrans); transitionTable[Modified][Packet::ReadReq].onSnoop(supplyAndGotoSharedTrans);
//Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv) //Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv)
transitionTable[Invalid][Invalidate].onSnoop(invalidateTrans); transitionTable[Invalid][Packet::InvalidateReq].onSnoop(invalidateTrans);
transitionTable[Shared][Invalidate].onSnoop(invalidateTrans); transitionTable[Shared][Packet::InvalidateReq].onSnoop(invalidateTrans);
transitionTable[Modified][Invalidate].onSnoop(invalidateTrans); transitionTable[Modified][Packet::InvalidateReq].onSnoop(invalidateTrans);
transitionTable[Invalid][WriteInvalidate].onSnoop(invalidateTrans); transitionTable[Invalid][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
transitionTable[Shared][WriteInvalidate].onSnoop(invalidateTrans); transitionTable[Shared][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
transitionTable[Modified][WriteInvalidate].onSnoop(invalidateTrans); transitionTable[Modified][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
if (doUpgrades) { if (doUpgrades) {
transitionTable[Invalid][Upgrade].onSnoop(nullTransition); transitionTable[Invalid][Packet::UpgradeReq].onSnoop(nullTransition);
transitionTable[Shared][Upgrade].onSnoop(invalidateTrans); transitionTable[Shared][Packet::UpgradeReq].onSnoop(invalidateTrans);
} }
} }
else if(protocol == "mesi") { else if(protocol == "mesi") {
// incoming requests: specify outgoing bus request // incoming requests: specify outgoing bus request
transitionTable[Invalid][Read].onRequest(Read); transitionTable[Invalid][Packet::ReadReq].onRequest(Packet::ReadReq);
transitionTable[Invalid][Write].onRequest(ReadEx); transitionTable[Invalid][Packet::WriteReq].onRequest(Packet::ReadExReq);
transitionTable[Shared][Write].onRequest(writeToSharedCmd); transitionTable[Shared][Packet::WriteReq].onRequest(writeToSharedCmd);
//Prefetching causes a read //Prefetching causes a read
transitionTable[Invalid][Soft_Prefetch].onRequest(Read); transitionTable[Invalid][Packet::SoftPFReq].onRequest(Packet::ReadReq);
transitionTable[Invalid][Hard_Prefetch].onRequest(Read); transitionTable[Invalid][Packet::HardPFReq].onRequest(Packet::ReadReq);
// on response to given request: specify new state // on response to given request: specify new state
transitionTable[Invalid][Read].onResponse(Exclusive); transitionTable[Invalid][Packet::ReadResp].onResponse(Exclusive);
//It will move into shared if the shared line is asserted in the //It will move into shared if the shared line is asserted in the
//getNewState function //getNewState function
transitionTable[Invalid][ReadEx].onResponse(Modified); transitionTable[Invalid][Packet::ReadExResp].onResponse(Modified);
transitionTable[Shared][writeToSharedCmd].onResponse(Modified); transitionTable[Shared][writeToSharedResp].onResponse(Modified);
// bus snoop transition functions // bus snoop transition functions
transitionTable[Invalid][Read].onSnoop(nullTransition); transitionTable[Invalid][Packet::ReadReq].onSnoop(nullTransition);
transitionTable[Invalid][ReadEx].onSnoop(nullTransition); transitionTable[Invalid][Packet::ReadExReq].onSnoop(nullTransition);
transitionTable[Shared][Read].onSnoop(assertShared); transitionTable[Shared][Packet::ReadReq].onSnoop(assertShared);
transitionTable[Shared][ReadEx].onSnoop(invalidateTrans); transitionTable[Shared][Packet::ReadExReq].onSnoop(invalidateTrans);
transitionTable[Exclusive][Read].onSnoop(assertShared); transitionTable[Exclusive][Packet::ReadReq].onSnoop(assertShared);
transitionTable[Exclusive][ReadEx].onSnoop(invalidateTrans); transitionTable[Exclusive][Packet::ReadExReq].onSnoop(invalidateTrans);
transitionTable[Modified][ReadEx].onSnoop(supplyAndInvalidateTrans); transitionTable[Modified][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans);
transitionTable[Modified][Read].onSnoop(supplyAndGotoSharedTrans); transitionTable[Modified][Packet::ReadReq].onSnoop(supplyAndGotoSharedTrans);
//Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv) //Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv)
transitionTable[Invalid][Invalidate].onSnoop(invalidateTrans); transitionTable[Invalid][Packet::InvalidateReq].onSnoop(invalidateTrans);
transitionTable[Shared][Invalidate].onSnoop(invalidateTrans); transitionTable[Shared][Packet::InvalidateReq].onSnoop(invalidateTrans);
transitionTable[Modified][Invalidate].onSnoop(invalidateTrans); transitionTable[Modified][Packet::InvalidateReq].onSnoop(invalidateTrans);
transitionTable[Exclusive][Invalidate].onSnoop(invalidateTrans); transitionTable[Exclusive][Packet::InvalidateReq].onSnoop(invalidateTrans);
transitionTable[Invalid][WriteInvalidate].onSnoop(invalidateTrans); transitionTable[Invalid][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
transitionTable[Shared][WriteInvalidate].onSnoop(invalidateTrans); transitionTable[Shared][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
transitionTable[Modified][WriteInvalidate].onSnoop(invalidateTrans); transitionTable[Modified][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
transitionTable[Exclusive][WriteInvalidate].onSnoop(invalidateTrans); transitionTable[Exclusive][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
if (doUpgrades) { if (doUpgrades) {
transitionTable[Invalid][Upgrade].onSnoop(nullTransition); transitionTable[Invalid][Packet::UpgradeReq].onSnoop(nullTransition);
transitionTable[Shared][Upgrade].onSnoop(invalidateTrans); transitionTable[Shared][Packet::UpgradeReq].onSnoop(invalidateTrans);
} }
} }
else if(protocol == "mosi") { else if(protocol == "mosi") {
// incoming requests: specify outgoing bus request // incoming requests: specify outgoing bus request
transitionTable[Invalid][Read].onRequest(Read); transitionTable[Invalid][Packet::ReadReq].onRequest(Packet::ReadReq);
transitionTable[Invalid][Write].onRequest(ReadEx); transitionTable[Invalid][Packet::WriteReq].onRequest(Packet::ReadExReq);
transitionTable[Shared][Write].onRequest(writeToSharedCmd); transitionTable[Shared][Packet::WriteReq].onRequest(writeToSharedCmd);
transitionTable[Owned][Write].onRequest(writeToSharedCmd); transitionTable[Owned][Packet::WriteReq].onRequest(writeToSharedCmd);
//Prefetching causes a read //Prefetching causes a read
transitionTable[Invalid][Soft_Prefetch].onRequest(Read); transitionTable[Invalid][Packet::SoftPFReq].onRequest(Packet::ReadReq);
transitionTable[Invalid][Hard_Prefetch].onRequest(Read); transitionTable[Invalid][Packet::HardPFReq].onRequest(Packet::ReadReq);
// on response to given request: specify new state // on response to given request: specify new state
transitionTable[Invalid][Read].onResponse(Shared); transitionTable[Invalid][Packet::ReadResp].onResponse(Shared);
transitionTable[Invalid][ReadEx].onResponse(Modified); transitionTable[Invalid][Packet::ReadExResp].onResponse(Modified);
transitionTable[Shared][writeToSharedCmd].onResponse(Modified); transitionTable[Shared][writeToSharedResp].onResponse(Modified);
transitionTable[Owned][writeToSharedCmd].onResponse(Modified); transitionTable[Owned][writeToSharedResp].onResponse(Modified);
// bus snoop transition functions // bus snoop transition functions
transitionTable[Invalid][Read].onSnoop(nullTransition); transitionTable[Invalid][Packet::ReadReq].onSnoop(nullTransition);
transitionTable[Invalid][ReadEx].onSnoop(nullTransition); transitionTable[Invalid][Packet::ReadExReq].onSnoop(nullTransition);
transitionTable[Invalid][Upgrade].onSnoop(nullTransition); transitionTable[Invalid][Packet::UpgradeReq].onSnoop(nullTransition);
transitionTable[Shared][Read].onSnoop(assertShared); transitionTable[Shared][Packet::ReadReq].onSnoop(assertShared);
transitionTable[Shared][ReadEx].onSnoop(invalidateTrans); transitionTable[Shared][Packet::ReadExReq].onSnoop(invalidateTrans);
transitionTable[Shared][Upgrade].onSnoop(invalidateTrans); transitionTable[Shared][Packet::UpgradeReq].onSnoop(invalidateTrans);
transitionTable[Modified][ReadEx].onSnoop(supplyAndInvalidateTrans); transitionTable[Modified][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans);
transitionTable[Modified][Read].onSnoop(supplyAndGotoOwnedTrans); transitionTable[Modified][Packet::ReadReq].onSnoop(supplyAndGotoOwnedTrans);
transitionTable[Owned][Read].onSnoop(supplyAndGotoOwnedTrans); transitionTable[Owned][Packet::ReadReq].onSnoop(supplyAndGotoOwnedTrans);
transitionTable[Owned][ReadEx].onSnoop(supplyAndInvalidateTrans); transitionTable[Owned][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans);
transitionTable[Owned][Upgrade].onSnoop(invalidateTrans); transitionTable[Owned][Packet::UpgradeReq].onSnoop(invalidateTrans);
//Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv) //Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv)
transitionTable[Invalid][Invalidate].onSnoop(invalidateTrans); transitionTable[Invalid][Packet::InvalidateReq].onSnoop(invalidateTrans);
transitionTable[Shared][Invalidate].onSnoop(invalidateTrans); transitionTable[Shared][Packet::InvalidateReq].onSnoop(invalidateTrans);
transitionTable[Modified][Invalidate].onSnoop(invalidateTrans); transitionTable[Modified][Packet::InvalidateReq].onSnoop(invalidateTrans);
transitionTable[Owned][Invalidate].onSnoop(invalidateTrans); transitionTable[Owned][Packet::InvalidateReq].onSnoop(invalidateTrans);
transitionTable[Invalid][WriteInvalidate].onSnoop(invalidateTrans); transitionTable[Invalid][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
transitionTable[Shared][WriteInvalidate].onSnoop(invalidateTrans); transitionTable[Shared][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
transitionTable[Modified][WriteInvalidate].onSnoop(invalidateTrans); transitionTable[Modified][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
transitionTable[Owned][WriteInvalidate].onSnoop(invalidateTrans); transitionTable[Owned][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
} }
else if(protocol == "moesi") { else if(protocol == "moesi") {
// incoming requests: specify outgoing bus request // incoming requests: specify outgoing bus request
transitionTable[Invalid][Read].onRequest(Read); transitionTable[Invalid][Packet::ReadReq].onRequest(Packet::ReadReq);
transitionTable[Invalid][Write].onRequest(ReadEx); transitionTable[Invalid][Packet::WriteReq].onRequest(Packet::ReadExReq);
transitionTable[Shared][Write].onRequest(writeToSharedCmd); transitionTable[Shared][Packet::WriteReq].onRequest(writeToSharedCmd);
transitionTable[Owned][Write].onRequest(writeToSharedCmd); transitionTable[Owned][Packet::WriteReq].onRequest(writeToSharedCmd);
//Prefetching causes a read //Prefetching causes a read
transitionTable[Invalid][Soft_Prefetch].onRequest(Read); transitionTable[Invalid][Packet::SoftPFReq].onRequest(Packet::ReadReq);
transitionTable[Invalid][Hard_Prefetch].onRequest(Read); transitionTable[Invalid][Packet::HardPFReq].onRequest(Packet::ReadReq);
// on response to given request: specify new state // on response to given request: specify new state
transitionTable[Invalid][Read].onResponse(Exclusive); transitionTable[Invalid][Packet::ReadResp].onResponse(Exclusive);
//It will move into shared if the shared line is asserted in the //It will move into shared if the shared line is asserted in the
//getNewState function //getNewState function
transitionTable[Invalid][ReadEx].onResponse(Modified); transitionTable[Invalid][Packet::ReadExResp].onResponse(Modified);
transitionTable[Shared][writeToSharedCmd].onResponse(Modified); transitionTable[Shared][writeToSharedResp].onResponse(Modified);
transitionTable[Owned][writeToSharedCmd].onResponse(Modified); transitionTable[Owned][writeToSharedResp].onResponse(Modified);
// bus snoop transition functions // bus snoop transition functions
transitionTable[Invalid][Read].onSnoop(nullTransition); transitionTable[Invalid][Packet::ReadReq].onSnoop(nullTransition);
transitionTable[Invalid][ReadEx].onSnoop(nullTransition); transitionTable[Invalid][Packet::ReadExReq].onSnoop(nullTransition);
transitionTable[Invalid][Upgrade].onSnoop(nullTransition); transitionTable[Invalid][Packet::UpgradeReq].onSnoop(nullTransition);
transitionTable[Shared][Read].onSnoop(assertShared); transitionTable[Shared][Packet::ReadReq].onSnoop(assertShared);
transitionTable[Shared][ReadEx].onSnoop(invalidateTrans); transitionTable[Shared][Packet::ReadExReq].onSnoop(invalidateTrans);
transitionTable[Shared][Upgrade].onSnoop(invalidateTrans); transitionTable[Shared][Packet::UpgradeReq].onSnoop(invalidateTrans);
transitionTable[Exclusive][Read].onSnoop(assertShared); transitionTable[Exclusive][Packet::ReadReq].onSnoop(assertShared);
transitionTable[Exclusive][ReadEx].onSnoop(invalidateTrans); transitionTable[Exclusive][Packet::ReadExReq].onSnoop(invalidateTrans);
transitionTable[Modified][Read].onSnoop(supplyAndGotoOwnedTrans); transitionTable[Modified][Packet::ReadReq].onSnoop(supplyAndGotoOwnedTrans);
transitionTable[Modified][ReadEx].onSnoop(supplyAndInvalidateTrans); transitionTable[Modified][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans);
transitionTable[Owned][Read].onSnoop(supplyAndGotoOwnedTrans); transitionTable[Owned][Packet::ReadReq].onSnoop(supplyAndGotoOwnedTrans);
transitionTable[Owned][ReadEx].onSnoop(supplyAndInvalidateTrans); transitionTable[Owned][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans);
transitionTable[Owned][Upgrade].onSnoop(invalidateTrans); transitionTable[Owned][Packet::UpgradeReq].onSnoop(invalidateTrans);
//Transitions on seeing a DMA (writeInv(samelevel) or DMAInv) //Transitions on seeing a DMA (writeInv(samelevel) or DMAInv)
transitionTable[Invalid][Invalidate].onSnoop(invalidateTrans); transitionTable[Invalid][Packet::InvalidateReq].onSnoop(invalidateTrans);
transitionTable[Shared][Invalidate].onSnoop(invalidateTrans); transitionTable[Shared][Packet::InvalidateReq].onSnoop(invalidateTrans);
transitionTable[Exclusive][Invalidate].onSnoop(invalidateTrans); transitionTable[Exclusive][Packet::InvalidateReq].onSnoop(invalidateTrans);
transitionTable[Modified][Invalidate].onSnoop(invalidateTrans); transitionTable[Modified][Packet::InvalidateReq].onSnoop(invalidateTrans);
transitionTable[Owned][Invalidate].onSnoop(invalidateTrans); transitionTable[Owned][Packet::InvalidateReq].onSnoop(invalidateTrans);
transitionTable[Invalid][WriteInvalidate].onSnoop(invalidateTrans); transitionTable[Invalid][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
transitionTable[Shared][WriteInvalidate].onSnoop(invalidateTrans); transitionTable[Shared][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
transitionTable[Exclusive][WriteInvalidate].onSnoop(invalidateTrans); transitionTable[Exclusive][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
transitionTable[Modified][WriteInvalidate].onSnoop(invalidateTrans); transitionTable[Modified][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
transitionTable[Owned][WriteInvalidate].onSnoop(invalidateTrans); transitionTable[Owned][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
} }
else { else {
@ -446,14 +447,14 @@ CoherenceProtocol::getBusCmd(Packet::Command cmdIn, CacheBlk::State state,
MSHR *mshr) MSHR *mshr)
{ {
state &= stateMask; state &= stateMask;
int cmd_idx = cmdIn.toIndex(); int cmd_idx = (int) cmdIn;
assert(0 <= state && state <= stateMax); assert(0 <= state && state <= stateMax);
assert(0 <= cmd_idx && cmd_idx < NUM_MEM_CMDS); assert(0 <= cmd_idx && cmd_idx < NUM_MEM_CMDS);
Packet::Command cmdOut = transitionTable[state][cmd_idx].busCmd; Packet::Command cmdOut = transitionTable[state][cmd_idx].busCmd;
assert(cmdOut != InvalidCmd); assert(cmdOut != Packet::InvalidCmd);
++requestCount[state][cmd_idx]; ++requestCount[state][cmd_idx];
@ -462,7 +463,7 @@ CoherenceProtocol::getBusCmd(Packet::Command cmdIn, CacheBlk::State state,
CacheBlk::State CacheBlk::State
CoherenceProtocol::getNewState(const Packet * &pkt, CacheBlk::State oldState) CoherenceProtocol::getNewState(Packet * &pkt, CacheBlk::State oldState)
{ {
CacheBlk::State state = oldState & stateMask; CacheBlk::State state = oldState & stateMask;
int cmd_idx = pkt->cmdToIndex(); int cmd_idx = pkt->cmdToIndex();

View file

@ -44,8 +44,8 @@ Packet *
UniCoherence::getPacket() UniCoherence::getPacket()
{ {
bool unblock = cshrs.isFull(); bool unblock = cshrs.isFull();
Packet * pkt = cshrs.getPkt(); Packet* pkt = cshrs.getReq();
cshrs.markInService(pkt->senderState); cshrs.markInService((MSHR*)pkt->senderState);
if (!cshrs.havePending()) { if (!cshrs.havePending()) {
cache->clearSlaveRequest(Request_Coherence); cache->clearSlaveRequest(Request_Coherence);
} }
@ -65,15 +65,12 @@ UniCoherence::handleBusRequest(Packet * &pkt, CacheBlk *blk, MSHR *mshr,
CacheBlk::State &new_state) CacheBlk::State &new_state)
{ {
new_state = 0; new_state = 0;
if (pkt->cmd.isInvalidate()) { if (pkt->isInvalidate()) {
DPRINTF(Cache, "snoop inval on blk %x (blk ptr %x)\n", DPRINTF(Cache, "snoop inval on blk %x (blk ptr %x)\n",
pkt->paddr, blk); pkt->getAddr(), blk);
if (!cache->isTopLevel()) { if (!cache->isTopLevel()) {
// Forward to other caches // Forward to other caches
Packet * tmp = new MemPkt(); Packet * tmp = new Packet(pkt->req, Packet::InvalidateReq, -1);
tmp->cmd = Invalidate;
tmp->paddr = pkt->paddr;
tmp->size = pkt->size;
cshrs.allocate(tmp); cshrs.allocate(tmp);
cache->setSlaveRequest(Request_Coherence, curTick); cache->setSlaveRequest(Request_Coherence, curTick);
if (cshrs.isFull()) { if (cshrs.isFull()) {

View file

@ -32,6 +32,7 @@
#define __UNI_COHERENCE_HH__ #define __UNI_COHERENCE_HH__
#include "base/trace.hh" #include "base/trace.hh"
#include "base/misc.hh"
#include "mem/cache/cache_blk.hh" #include "mem/cache/cache_blk.hh"
#include "mem/cache/miss/mshr_queue.hh" #include "mem/cache/miss/mshr_queue.hh"
#include "mem/packet.hh" #include "mem/packet.hh"

View file

@ -33,12 +33,12 @@
* Definitions of a simple buffer for a blocking cache. * Definitions of a simple buffer for a blocking cache.
*/ */
#include "cpu/exec_context.hh"
#include "cpu/smt.hh" //for maxThreadsPerCPU #include "cpu/smt.hh" //for maxThreadsPerCPU
#include "mem/cache/base_cache.hh" #include "mem/cache/base_cache.hh"
#include "mem/cache/miss/blocking_buffer.hh" #include "mem/cache/miss/blocking_buffer.hh"
#include "mem/cache/prefetch/base_prefetcher.hh" #include "mem/cache/prefetch/base_prefetcher.hh"
#include "sim/eventq.hh" // for Event declaration. #include "sim/eventq.hh" // for Event declaration.
#include "mem/request.hh"
using namespace TheISA; using namespace TheISA;
@ -72,26 +72,26 @@ BlockingBuffer::setPrefetcher(BasePrefetcher *_prefetcher)
void void
BlockingBuffer::handleMiss(Packet * &pkt, int blk_size, Tick time) BlockingBuffer::handleMiss(Packet * &pkt, int blk_size, Tick time)
{ {
Addr blk_addr = pkt->paddr & ~(Addr)(blk_size - 1); Addr blk_addr = pkt->getAddr() & ~(Addr)(blk_size - 1);
if (pkt->cmd.isWrite() && (pkt->req->isUncacheable() || !writeAllocate || if (pkt->isWrite() && (pkt->req->isUncacheable() || !writeAllocate ||
pkt->cmd.isNoResponse())) { !pkt->needsResponse())) {
if (pkt->cmd.isNoResponse()) { if (!pkt->needsResponse()) {
wb.allocateAsBuffer(pkt); wb.allocateAsBuffer(pkt);
} else { } else {
wb.allocate(pkt->cmd, blk_addr, pkt->req->asid, blk_size, pkt); wb.allocate(pkt->cmd, blk_addr, pkt->req->getAsid(), blk_size, pkt);
}
if (cache->doData()) {
memcpy(wb.pkt->data, pkt->data, blk_size);
} }
memcpy(wb.pkt->getPtr<uint8_t>(), pkt->getPtr<uint8_t>(), blk_size);
cache->setBlocked(Blocked_NoWBBuffers); cache->setBlocked(Blocked_NoWBBuffers);
cache->setMasterRequest(Request_WB, time); cache->setMasterRequest(Request_WB, time);
return; return;
} }
if (pkt->cmd.isNoResponse()) { if (!pkt->needsResponse()) {
miss.allocateAsBuffer(pkt); miss.allocateAsBuffer(pkt);
} else { } else {
miss.allocate(pkt->cmd, blk_addr, pkt->req->asid, blk_size, pkt); miss.allocate(pkt->cmd, blk_addr, pkt->req->getAsid(), blk_size, pkt);
} }
if (!pkt->req->isUncacheable()) { if (!pkt->req->isUncacheable()) {
miss.pkt->flags |= CACHE_LINE_FILL; miss.pkt->flags |= CACHE_LINE_FILL;
@ -112,27 +112,27 @@ BlockingBuffer::getPacket()
void void
BlockingBuffer::setBusCmd(Packet * &pkt, Packet::Command cmd) BlockingBuffer::setBusCmd(Packet * &pkt, Packet::Command cmd)
{ {
MSHR *mshr = pkt->senderState; MSHR *mshr = (MSHR*) pkt->senderState;
mshr->originalCmd = pkt->cmd; mshr->originalCmd = pkt->cmd;
if (pkt->isCacheFill()) if (pkt->isCacheFill())
pkt->cmd = cmd; pkt->cmdOverride(cmd);
} }
void void
BlockingBuffer::restoreOrigCmd(Packet * &pkt) BlockingBuffer::restoreOrigCmd(Packet * &pkt)
{ {
pkt->cmd = pkt->senderState->originalCmd; pkt->cmdOverride(((MSHR*)(pkt->senderState))->originalCmd);
} }
void void
BlockingBuffer::markInService(Packet * &pkt) BlockingBuffer::markInService(Packet * &pkt)
{ {
if (!pkt->isCacheFill() && pkt->cmd.isWrite()) { if (!pkt->isCacheFill() && pkt->isWrite()) {
// Forwarding a write/ writeback, don't need to change // Forwarding a write/ writeback, don't need to change
// the command // the command
assert(pkt->senderState == &wb); assert((MSHR*)pkt->senderState == &wb);
cache->clearMasterRequest(Request_WB); cache->clearMasterRequest(Request_WB);
if (pkt->cmd.isNoResponse()) { if (!pkt->needsResponse()) {
assert(wb.getNumTargets() == 0); assert(wb.getNumTargets() == 0);
wb.deallocate(); wb.deallocate();
cache->clearBlocked(Blocked_NoWBBuffers); cache->clearBlocked(Blocked_NoWBBuffers);
@ -140,9 +140,9 @@ BlockingBuffer::markInService(Packet * &pkt)
wb.inService = true; wb.inService = true;
} }
} else { } else {
assert(pkt->senderState == &miss); assert((MSHR*)pkt->senderState == &miss);
cache->clearMasterRequest(Request_MSHR); cache->clearMasterRequest(Request_MSHR);
if (pkt->cmd.isNoResponse()) { if (!pkt->needsResponse()) {
assert(miss.getNumTargets() == 0); assert(miss.getNumTargets() == 0);
miss.deallocate(); miss.deallocate();
cache->clearBlocked(Blocked_NoMSHRs); cache->clearBlocked(Blocked_NoMSHRs);
@ -158,24 +158,24 @@ BlockingBuffer::handleResponse(Packet * &pkt, Tick time)
{ {
if (pkt->isCacheFill()) { if (pkt->isCacheFill()) {
// targets were handled in the cache tags // targets were handled in the cache tags
assert(pkt->senderState == &miss); assert((MSHR*)pkt->senderState == &miss);
miss.deallocate(); miss.deallocate();
cache->clearBlocked(Blocked_NoMSHRs); cache->clearBlocked(Blocked_NoMSHRs);
} else { } else {
if (pkt->senderState->hasTargets()) { if (((MSHR*)(pkt->senderState))->hasTargets()) {
// Should only have 1 target if we had any // Should only have 1 target if we had any
assert(pkt->senderState->getNumTargets() == 1); assert(((MSHR*)(pkt->senderState))->getNumTargets() == 1);
Packet * target = pkt->senderState->getTarget(); Packet * target = ((MSHR*)(pkt->senderState))->getTarget();
pkt->senderState->popTarget(); ((MSHR*)(pkt->senderState))->popTarget();
if (cache->doData() && pkt->cmd.isRead()) { if (pkt->isRead()) {
memcpy(target->data, pkt->data, target->size); memcpy(target->getPtr<uint8_t>(), pkt->getPtr<uint8_t>(), target->getSize());
} }
cache->respond(target, time); cache->respond(target, time);
assert(!pkt->senderState->hasTargets()); assert(!((MSHR*)(pkt->senderState))->hasTargets());
} }
if (pkt->cmd.isWrite()) { if (pkt->isWrite()) {
assert(pkt->senderState == &wb); assert(((MSHR*)(pkt->senderState)) == &wb);
wb.deallocate(); wb.deallocate();
cache->clearBlocked(Blocked_NoWBBuffers); cache->clearBlocked(Blocked_NoWBBuffers);
} else { } else {
@ -186,15 +186,12 @@ BlockingBuffer::handleResponse(Packet * &pkt, Tick time)
} }
void void
BlockingBuffer::squash(int req->getThreadNum()ber) BlockingBuffer::squash(int threadNum)
{ {
if (miss.setThreadNum() == req->getThreadNum()ber) { if (miss.threadNum == threadNum) {
Packet * target = miss.getTarget(); Packet * target = miss.getTarget();
miss.popTarget(); miss.popTarget();
assert(target->req->setThreadNum() == req->getThreadNum()ber); assert(target->req->getThreadNum() == threadNum);
if (target->completionEvent != NULL) {
delete target->completionEvent;
}
target = NULL; target = NULL;
assert(!miss.hasTargets()); assert(!miss.hasTargets());
miss.ntargets=0; miss.ntargets=0;
@ -210,27 +207,20 @@ void
BlockingBuffer::doWriteback(Addr addr, int asid, BlockingBuffer::doWriteback(Addr addr, int asid,
int size, uint8_t *data, bool compressed) int size, uint8_t *data, bool compressed)
{ {
// Generate request // Generate request
Packet * pkt = new Packet(); Request * req = new Request(addr, size, 0);
pkt->paddr = addr; Packet * pkt = new Packet(req, Packet::Writeback, -1);
pkt->req->asid = asid; uint8_t *new_data = new uint8_t[size];
pkt->size = size; pkt->dataDynamicArray<uint8_t>(new_data);
pkt->data = new uint8_t[size];
if (data) { if (data) {
memcpy(pkt->data, data, size); memcpy(pkt->getPtr<uint8_t>(), data, size);
} }
/**
* @todo Need to find a way to charge the writeback to the "correct"
* thread.
*/
pkt->req->setThreadNum() = 0;
pkt->cmd = Writeback;
if (compressed) { if (compressed) {
pkt->flags |= COMPRESSED; pkt->flags |= COMPRESSED;
} }
///All writebacks charged to same thread @todo figure this out
writebacks[pkt->req->getThreadNum()]++; writebacks[pkt->req->getThreadNum()]++;
wb.allocateAsBuffer(pkt); wb.allocateAsBuffer(pkt);
@ -249,9 +239,8 @@ BlockingBuffer::doWriteback(Packet * &pkt)
// Since allocate as buffer copies the request, // Since allocate as buffer copies the request,
// need to copy data here. // need to copy data here.
if (cache->doData()) { memcpy(wb.pkt->getPtr<uint8_t>(), pkt->getPtr<uint8_t>(), pkt->getSize());
memcpy(wb.pkt->data, pkt->data, pkt->size);
}
cache->setBlocked(Blocked_NoWBBuffers); cache->setBlocked(Blocked_NoWBBuffers);
cache->setMasterRequest(Request_WB, curTick); cache->setMasterRequest(Request_WB, curTick);
} }

View file

@ -34,7 +34,6 @@
* Miss and writeback queue definitions. * Miss and writeback queue definitions.
*/ */
#include "cpu/exec_context.hh"
#include "cpu/smt.hh" //for maxThreadsPerCPU #include "cpu/smt.hh" //for maxThreadsPerCPU
#include "mem/cache/base_cache.hh" #include "mem/cache/base_cache.hh"
#include "mem/cache/miss/miss_queue.hh" #include "mem/cache/miss/miss_queue.hh"
@ -59,6 +58,10 @@ MissQueue::MissQueue(int numMSHRs, int numTargets, int write_buffers,
void void
MissQueue::regStats(const string &name) MissQueue::regStats(const string &name)
{ {
Request temp_req;
Packet::Command temp_cmd = Packet::ReadReq;
Packet temp_pkt(&temp_req, temp_cmd, 0); //@todo FIx command strings so this isn't neccessary
using namespace Stats; using namespace Stats;
writebacks writebacks
@ -71,7 +74,7 @@ MissQueue::regStats(const string &name)
// MSHR hit statistics // MSHR hit statistics
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
Packet::Command cmd = (Packet::Command)access_idx; Packet::Command cmd = (Packet::Command)access_idx;
const string &cstr = cmd.toString(); const string &cstr = temp_pkt.cmdIdxToString(cmd);
mshr_hits[access_idx] mshr_hits[access_idx]
.init(maxThreadsPerCPU) .init(maxThreadsPerCPU)
@ -86,20 +89,20 @@ MissQueue::regStats(const string &name)
.desc("number of demand (read+write) MSHR hits") .desc("number of demand (read+write) MSHR hits")
.flags(total) .flags(total)
; ;
demandMshrHits = mshr_hits[Read] + mshr_hits[Write]; demandMshrHits = mshr_hits[Packet::ReadReq] + mshr_hits[Packet::WriteReq];
overallMshrHits overallMshrHits
.name(name + ".overall_mshr_hits") .name(name + ".overall_mshr_hits")
.desc("number of overall MSHR hits") .desc("number of overall MSHR hits")
.flags(total) .flags(total)
; ;
overallMshrHits = demandMshrHits + mshr_hits[Soft_Prefetch] + overallMshrHits = demandMshrHits + mshr_hits[Packet::SoftPFReq] +
mshr_hits[Hard_Prefetch]; mshr_hits[Packet::HardPFReq];
// MSHR miss statistics // MSHR miss statistics
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
Packet::Command cmd = (Packet::CommandEnum)access_idx; Packet::Command cmd = (Packet::Command)access_idx;
const string &cstr = cmd.toString(); const string &cstr = temp_pkt.cmdIdxToString(cmd);
mshr_misses[access_idx] mshr_misses[access_idx]
.init(maxThreadsPerCPU) .init(maxThreadsPerCPU)
@ -114,20 +117,20 @@ MissQueue::regStats(const string &name)
.desc("number of demand (read+write) MSHR misses") .desc("number of demand (read+write) MSHR misses")
.flags(total) .flags(total)
; ;
demandMshrMisses = mshr_misses[Read] + mshr_misses[Write]; demandMshrMisses = mshr_misses[Packet::ReadReq] + mshr_misses[Packet::WriteReq];
overallMshrMisses overallMshrMisses
.name(name + ".overall_mshr_misses") .name(name + ".overall_mshr_misses")
.desc("number of overall MSHR misses") .desc("number of overall MSHR misses")
.flags(total) .flags(total)
; ;
overallMshrMisses = demandMshrMisses + mshr_misses[Soft_Prefetch] + overallMshrMisses = demandMshrMisses + mshr_misses[Packet::SoftPFReq] +
mshr_misses[Hard_Prefetch]; mshr_misses[Packet::HardPFReq];
// MSHR miss latency statistics // MSHR miss latency statistics
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
Packet::Command cmd = (Packet::CommandEnum)access_idx; Packet::Command cmd = (Packet::Command)access_idx;
const string &cstr = cmd.toString(); const string &cstr = temp_pkt.cmdIdxToString(cmd);
mshr_miss_latency[access_idx] mshr_miss_latency[access_idx]
.init(maxThreadsPerCPU) .init(maxThreadsPerCPU)
@ -142,7 +145,8 @@ MissQueue::regStats(const string &name)
.desc("number of demand (read+write) MSHR miss cycles") .desc("number of demand (read+write) MSHR miss cycles")
.flags(total) .flags(total)
; ;
demandMshrMissLatency = mshr_miss_latency[Read] + mshr_miss_latency[Write]; demandMshrMissLatency = mshr_miss_latency[Packet::ReadReq]
+ mshr_miss_latency[Packet::WriteReq];
overallMshrMissLatency overallMshrMissLatency
.name(name + ".overall_mshr_miss_latency") .name(name + ".overall_mshr_miss_latency")
@ -150,12 +154,12 @@ MissQueue::regStats(const string &name)
.flags(total) .flags(total)
; ;
overallMshrMissLatency = demandMshrMissLatency + overallMshrMissLatency = demandMshrMissLatency +
mshr_miss_latency[Soft_Prefetch] + mshr_miss_latency[Hard_Prefetch]; mshr_miss_latency[Packet::SoftPFReq] + mshr_miss_latency[Packet::HardPFReq];
// MSHR uncacheable statistics // MSHR uncacheable statistics
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
Packet::Command cmd = (Packet::CommandEnum)access_idx; Packet::Command cmd = (Packet::Command)access_idx;
const string &cstr = cmd.toString(); const string &cstr = temp_pkt.cmdIdxToString(cmd);
mshr_uncacheable[access_idx] mshr_uncacheable[access_idx]
.init(maxThreadsPerCPU) .init(maxThreadsPerCPU)
@ -170,13 +174,14 @@ MissQueue::regStats(const string &name)
.desc("number of overall MSHR uncacheable misses") .desc("number of overall MSHR uncacheable misses")
.flags(total) .flags(total)
; ;
overallMshrUncacheable = mshr_uncacheable[Read] + mshr_uncacheable[Write] overallMshrUncacheable = mshr_uncacheable[Packet::ReadReq]
+ mshr_uncacheable[Soft_Prefetch] + mshr_uncacheable[Hard_Prefetch]; + mshr_uncacheable[Packet::WriteReq] + mshr_uncacheable[Packet::SoftPFReq]
+ mshr_uncacheable[Packet::HardPFReq];
// MSHR miss latency statistics // MSHR miss latency statistics
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
Packet::Command cmd = (Packet::CommandEnum)access_idx; Packet::Command cmd = (Packet::Command)access_idx;
const string &cstr = cmd.toString(); const string &cstr = temp_pkt.cmdIdxToString(cmd);
mshr_uncacheable_lat[access_idx] mshr_uncacheable_lat[access_idx]
.init(maxThreadsPerCPU) .init(maxThreadsPerCPU)
@ -191,15 +196,16 @@ MissQueue::regStats(const string &name)
.desc("number of overall MSHR uncacheable cycles") .desc("number of overall MSHR uncacheable cycles")
.flags(total) .flags(total)
; ;
overallMshrUncacheableLatency = mshr_uncacheable_lat[Read] overallMshrUncacheableLatency = mshr_uncacheable_lat[Packet::ReadReq]
+ mshr_uncacheable_lat[Write] + mshr_uncacheable_lat[Soft_Prefetch] + mshr_uncacheable_lat[Packet::WriteReq]
+ mshr_uncacheable_lat[Hard_Prefetch]; + mshr_uncacheable_lat[Packet::SoftPFReq]
+ mshr_uncacheable_lat[Packet::HardPFReq];
#if 0 #if 0
// MSHR access formulas // MSHR access formulas
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
Packet::Command cmd = (Packet::CommandEnum)access_idx; Packet::Command cmd = (Packet::Command)access_idx;
const string &cstr = cmd.toString(); const string &cstr = temp_pkt.cmdIdxToString(cmd);
mshrAccesses[access_idx] mshrAccesses[access_idx]
.name(name + "." + cstr + "_mshr_accesses") .name(name + "." + cstr + "_mshr_accesses")
@ -229,8 +235,8 @@ MissQueue::regStats(const string &name)
// MSHR miss rate formulas // MSHR miss rate formulas
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
Packet::Command cmd = (Packet::CommandEnum)access_idx; Packet::Command cmd = (Packet::Command)access_idx;
const string &cstr = cmd.toString(); const string &cstr = temp_pkt.cmdIdxToString(cmd);
mshrMissRate[access_idx] mshrMissRate[access_idx]
.name(name + "." + cstr + "_mshr_miss_rate") .name(name + "." + cstr + "_mshr_miss_rate")
@ -258,8 +264,8 @@ MissQueue::regStats(const string &name)
// mshrMiss latency formulas // mshrMiss latency formulas
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
Packet::Command cmd = (Packet::CommandEnum)access_idx; Packet::Command cmd = (Packet::Command)access_idx;
const string &cstr = cmd.toString(); const string &cstr = temp_pkt.cmdIdxToString(cmd);
avgMshrMissLatency[access_idx] avgMshrMissLatency[access_idx]
.name(name + "." + cstr + "_avg_mshr_miss_latency") .name(name + "." + cstr + "_avg_mshr_miss_latency")
@ -287,8 +293,8 @@ MissQueue::regStats(const string &name)
// mshrUncacheable latency formulas // mshrUncacheable latency formulas
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
Packet::Command cmd = (Packet::CommandEnum)access_idx; Packet::Command cmd = (Packet::Command)access_idx;
const string &cstr = cmd.toString(); const string &cstr = temp_pkt.cmdIdxToString(cmd);
avgMshrUncacheableLatency[access_idx] avgMshrUncacheableLatency[access_idx]
.name(name + "." + cstr + "_avg_mshr_uncacheable_latency") .name(name + "." + cstr + "_avg_mshr_uncacheable_latency")
@ -354,7 +360,7 @@ MissQueue::allocateMiss(Packet * &pkt, int size, Tick time)
if (mq.isFull()) { if (mq.isFull()) {
cache->setBlocked(Blocked_NoMSHRs); cache->setBlocked(Blocked_NoMSHRs);
} }
if (pkt->cmd != Hard_Prefetch) { if (pkt->cmd != Packet::HardPFReq) {
//If we need to request the bus (not on HW prefetch), do so //If we need to request the bus (not on HW prefetch), do so
cache->setMasterRequest(Request_MSHR, time); cache->setMasterRequest(Request_MSHR, time);
} }
@ -365,18 +371,21 @@ MissQueue::allocateMiss(Packet * &pkt, int size, Tick time)
MSHR* MSHR*
MissQueue::allocateWrite(Packet * &pkt, int size, Tick time) MissQueue::allocateWrite(Packet * &pkt, int size, Tick time)
{ {
MSHR* mshr = wb.allocate(pkt,pkt->size); MSHR* mshr = wb.allocate(pkt,pkt->getSize());
mshr->order = order++; mshr->order = order++;
if (cache->doData()){
//REMOVING COMPRESSION FOR NOW
#if 0
if (pkt->isCompressed()) { if (pkt->isCompressed()) {
delete [] mshr->pkt->data; mshr->pkt->deleteData();
mshr->pkt->actualSize = pkt->actualSize; mshr->pkt->actualSize = pkt->actualSize;
mshr->pkt->data = new uint8_t[pkt->actualSize]; mshr->pkt->data = new uint8_t[pkt->actualSize];
memcpy(mshr->pkt->data, pkt->data, pkt->actualSize); memcpy(mshr->pkt->data, pkt->data, pkt->actualSize);
} else { } else {
memcpy(mshr->pkt->data, pkt->data, pkt->size); #endif
} memcpy(mshr->pkt->getPtr<uint8_t>(), pkt->getPtr<uint8_t>(), pkt->getSize());
} //{
if (wb.isFull()) { if (wb.isFull()) {
cache->setBlocked(Blocked_NoWBBuffers); cache->setBlocked(Blocked_NoWBBuffers);
} }
@ -397,15 +406,15 @@ MissQueue::handleMiss(Packet * &pkt, int blkSize, Tick time)
if (prefetchMiss) prefetcher->handleMiss(pkt, time); if (prefetchMiss) prefetcher->handleMiss(pkt, time);
int size = blkSize; int size = blkSize;
Addr blkAddr = pkt->paddr & ~(Addr)(blkSize-1); Addr blkAddr = pkt->getAddr() & ~(Addr)(blkSize-1);
MSHR* mshr = NULL; MSHR* mshr = NULL;
if (!pkt->req->isUncacheable()) { if (!pkt->req->isUncacheable()) {
mshr = mq.findMatch(blkAddr, pkt->req->asid); mshr = mq.findMatch(blkAddr, pkt->req->getAsid());
if (mshr) { if (mshr) {
//@todo remove hw_pf here //@todo remove hw_pf here
mshr_hits[pkt->cmdToIndex()][pkt->req->getThreadNum()]++; mshr_hits[pkt->cmdToIndex()][pkt->req->getThreadNum()]++;
if (mshr->getThreadNum() != pkt->req->getThreadNum()) { if (mshr->threadNum != pkt->req->getThreadNum()) {
mshr->setThreadNum() = -1; mshr->threadNum = -1;
} }
mq.allocateTarget(mshr, pkt); mq.allocateTarget(mshr, pkt);
if (mshr->pkt->isNoAllocate() && !pkt->isNoAllocate()) { if (mshr->pkt->isNoAllocate() && !pkt->isNoAllocate()) {
@ -429,14 +438,14 @@ MissQueue::handleMiss(Packet * &pkt, int blkSize, Tick time)
} else { } else {
//Count uncacheable accesses //Count uncacheable accesses
mshr_uncacheable[pkt->cmdToIndex()][pkt->req->getThreadNum()]++; mshr_uncacheable[pkt->cmdToIndex()][pkt->req->getThreadNum()]++;
size = pkt->size; size = pkt->getSize();
} }
if (pkt->cmd.isWrite() && (pkt->req->isUncacheable() || !writeAllocate || if (pkt->isWrite() && (pkt->req->isUncacheable() || !writeAllocate ||
pkt->cmd.isNoResponse())) { !pkt->needsResponse())) {
/** /**
* @todo Add write merging here. * @todo Add write merging here.
*/ */
mshr = allocateWrite(pkt, pkt->size, time); mshr = allocateWrite(pkt, pkt->getSize(), time);
return; return;
} }
@ -468,7 +477,7 @@ MissQueue::getPacket()
pkt = wb.getReq(); pkt = wb.getReq();
// Need to search for earlier miss. // Need to search for earlier miss.
MSHR *mshr = mq.findPending(pkt); MSHR *mshr = mq.findPending(pkt);
if (mshr && mshr->order < pkt->senderState->order) { if (mshr && mshr->order < ((MSHR*)(pkt->senderState))->order) {
// Service misses in order until conflict is cleared. // Service misses in order until conflict is cleared.
return mq.getReq(); return mq.getReq();
} }
@ -491,7 +500,7 @@ MissQueue::getPacket()
//Update statistic on number of prefetches issued (hwpf_mshr_misses) //Update statistic on number of prefetches issued (hwpf_mshr_misses)
mshr_misses[pkt->cmdToIndex()][pkt->req->getThreadNum()]++; mshr_misses[pkt->cmdToIndex()][pkt->req->getThreadNum()]++;
//It will request the bus for the future, but should clear that immedieatley //It will request the bus for the future, but should clear that immedieatley
allocateMiss(pkt, pkt->size, curTick); allocateMiss(pkt, pkt->getSize(), curTick);
pkt = mq.getReq(); pkt = mq.getReq();
assert(pkt); //We should get back a req b/c we just put one in assert(pkt); //We should get back a req b/c we just put one in
} }
@ -503,7 +512,7 @@ void
MissQueue::setBusCmd(Packet * &pkt, Packet::Command cmd) MissQueue::setBusCmd(Packet * &pkt, Packet::Command cmd)
{ {
assert(pkt->senderState != 0); assert(pkt->senderState != 0);
MSHR * mshr = pkt->senderState; MSHR * mshr = (MSHR*)pkt->senderState;
mshr->originalCmd = pkt->cmd; mshr->originalCmd = pkt->cmd;
if (pkt->isCacheFill() || pkt->isNoAllocate()) if (pkt->isCacheFill() || pkt->isNoAllocate())
pkt->cmd = cmd; pkt->cmd = cmd;
@ -512,7 +521,7 @@ MissQueue::setBusCmd(Packet * &pkt, Packet::Command cmd)
void void
MissQueue::restoreOrigCmd(Packet * &pkt) MissQueue::restoreOrigCmd(Packet * &pkt)
{ {
pkt->cmd = pkt->senderState->originalCmd; pkt->cmd = ((MSHR*)(pkt->senderState))->originalCmd;
} }
void void
@ -526,11 +535,11 @@ MissQueue::markInService(Packet * &pkt)
* @todo Should include MSHRQueue pointer in MSHR to select the correct * @todo Should include MSHRQueue pointer in MSHR to select the correct
* one. * one.
*/ */
if ((!pkt->isCacheFill() && pkt->cmd.isWrite()) || pkt->cmd == Copy) { if ((!pkt->isCacheFill() && pkt->isWrite())) {
// Forwarding a write/ writeback, don't need to change // Forwarding a write/ writeback, don't need to change
// the command // the command
unblock = wb.isFull(); unblock = wb.isFull();
wb.markInService(pkt->senderState); wb.markInService((MSHR*)pkt->senderState);
if (!wb.havePending()){ if (!wb.havePending()){
cache->clearMasterRequest(Request_WB); cache->clearMasterRequest(Request_WB);
} }
@ -541,11 +550,11 @@ MissQueue::markInService(Packet * &pkt)
} }
} else { } else {
unblock = mq.isFull(); unblock = mq.isFull();
mq.markInService(pkt->senderState); mq.markInService((MSHR*)pkt->senderState);
if (!mq.havePending()){ if (!mq.havePending()){
cache->clearMasterRequest(Request_MSHR); cache->clearMasterRequest(Request_MSHR);
} }
if (pkt->senderState->originalCmd == Hard_Prefetch) { if (((MSHR*)(pkt->senderState))->originalCmd == Packet::HardPFReq) {
DPRINTF(HWPrefetch, "%s:Marking a HW_PF in service\n", DPRINTF(HWPrefetch, "%s:Marking a HW_PF in service\n",
cache->name()); cache->name());
//Also clear pending if need be //Also clear pending if need be
@ -568,8 +577,8 @@ MissQueue::markInService(Packet * &pkt)
void void
MissQueue::handleResponse(Packet * &pkt, Tick time) MissQueue::handleResponse(Packet * &pkt, Tick time)
{ {
MSHR* mshr = pkt->senderState; MSHR* mshr = (MSHR*)pkt->senderState;
if (pkt->senderState->originalCmd == Hard_Prefetch) { if (((MSHR*)(pkt->senderState))->originalCmd == Packet::HardPFReq) {
DPRINTF(HWPrefetch, "%s:Handling the response to a HW_PF\n", DPRINTF(HWPrefetch, "%s:Handling the response to a HW_PF\n",
cache->name()); cache->name());
} }
@ -617,8 +626,9 @@ MissQueue::handleResponse(Packet * &pkt, Tick time)
assert(num_targets == 1); assert(num_targets == 1);
Packet * target = mshr->getTarget(); Packet * target = mshr->getTarget();
mshr->popTarget(); mshr->popTarget();
if (cache->doData() && pkt->cmd.isRead()) { if (pkt->isRead()) {
memcpy(target->data, pkt->data, target->size); memcpy(target->getPtr<uint8_t>(), pkt->getPtr<uint8_t>(),
target->getSize());
} }
cache->respond(target, time); cache->respond(target, time);
assert(!mshr->hasTargets()); assert(!mshr->hasTargets());
@ -629,14 +639,15 @@ MissQueue::handleResponse(Packet * &pkt, Tick time)
while (mshr->hasTargets()) { while (mshr->hasTargets()) {
Packet * target = mshr->getTarget(); Packet * target = mshr->getTarget();
mshr->popTarget(); mshr->popTarget();
if (cache->doData() && pkt->cmd.isRead()) { if (pkt->isRead()) {
memcpy(target->data, pkt->data, target->size); memcpy(target->getPtr<uint8_t>(), pkt->getPtr<uint8_t>(),
target->getSize());
} }
cache->respond(target, time); cache->respond(target, time);
} }
} }
if (pkt->cmd.isWrite()) { if (pkt->isWrite()) {
// If the wrtie buffer is full, we might unblock now // If the wrtie buffer is full, we might unblock now
unblock = wb.isFull(); unblock = wb.isFull();
wb.deallocate(mshr); wb.deallocate(mshr);
@ -660,12 +671,12 @@ MissQueue::handleResponse(Packet * &pkt, Tick time)
} }
void void
MissQueue::squash(int req->getThreadNum()ber) MissQueue::squash(int threadNum)
{ {
bool unblock = false; bool unblock = false;
BlockedCause cause = NUM_BLOCKED_CAUSES; BlockedCause cause = NUM_BLOCKED_CAUSES;
if (noTargetMSHR && noTargetMSHR->setThreadNum() == req->getThreadNum()ber) { if (noTargetMSHR && noTargetMSHR->threadNum == threadNum) {
noTargetMSHR = NULL; noTargetMSHR = NULL;
unblock = true; unblock = true;
cause = Blocked_NoTargets; cause = Blocked_NoTargets;
@ -674,7 +685,7 @@ MissQueue::squash(int req->getThreadNum()ber)
unblock = true; unblock = true;
cause = Blocked_NoMSHRs; cause = Blocked_NoMSHRs;
} }
mq.squash(req->getThreadNum()ber); mq.squash(threadNum);
if (!mq.havePending()) { if (!mq.havePending()) {
cache->clearMasterRequest(Request_MSHR); cache->clearMasterRequest(Request_MSHR);
} }
@ -701,9 +712,19 @@ MissQueue::doWriteback(Addr addr, int asid,
int size, uint8_t *data, bool compressed) int size, uint8_t *data, bool compressed)
{ {
// Generate request // Generate request
Packet * pkt = buildWritebackReq(addr, asid, size, data, Request * req = new Request(addr, size, 0);
compressed); Packet * pkt = new Packet(req, Packet::Writeback, -1);
uint8_t *new_data = new uint8_t[size];
pkt->dataDynamicArray<uint8_t>(new_data);
if (data) {
memcpy(pkt->getPtr<uint8_t>(), data, size);
}
if (compressed) {
pkt->flags |= COMPRESSED;
}
///All writebacks charged to same thread @todo figure this out
writebacks[pkt->req->getThreadNum()]++; writebacks[pkt->req->getThreadNum()]++;
allocateWrite(pkt, 0, curTick); allocateWrite(pkt, 0, curTick);

View file

@ -50,13 +50,15 @@ MSHR::MSHR()
{ {
inService = false; inService = false;
ntargets = 0; ntargets = 0;
setThreadNum() = -1; threadNum = -1;
} }
void void
MSHR::allocate(Packet::Command cmd, Addr _addr, int _asid, int size, MSHR::allocate(Packet::Command cmd, Addr _addr, int _asid, int size,
Packet * &target) Packet * &target)
{ {
assert("NEED TO FIX YET\n" && 0);
#if 0
assert(targets.empty()); assert(targets.empty());
addr = _addr; addr = _addr;
asid = _asid; asid = _asid;
@ -74,6 +76,7 @@ MSHR::allocate(Packet::Command cmd, Addr _addr, int _asid, int size,
pkt->req = target->req; pkt->req = target->req;
allocateTarget(target); allocateTarget(target);
} }
#endif
} }
// Since we aren't sure if data is being used, don't copy here. // Since we aren't sure if data is being used, don't copy here.
@ -83,17 +86,13 @@ MSHR::allocate(Packet::Command cmd, Addr _addr, int _asid, int size,
void void
MSHR::allocateAsBuffer(Packet * &target) MSHR::allocateAsBuffer(Packet * &target)
{ {
addr = target->paddr; addr = target->getAddr();
asid = target->req->asid; asid = target->req->getAsid();
setThreadNum() = target->req->getThreadNum(); threadNum = target->req->getThreadNum();
pkt = new Packet(); pkt = new Packet(target->req, target->cmd, -1);
pkt->addr = target->addr; uint8_t *new_data = new uint8_t[target->getSize()];
pkt->dest = target->dest; pkt->dataDynamicArray<uint8_t>(new_data);
pkt->cmd = target->cmd; pkt->senderState = (Packet::SenderState*)this;
pkt->size = target->size;
pkt->req = target->req;
pkt->data = new uint8_t[target->size];
pkt->senderState = this;
pkt->time = curTick; pkt->time = curTick;
} }
@ -117,11 +116,11 @@ MSHR::allocateTarget(Packet * &target)
//If we append an invalidate and we issued a read to the bus, //If we append an invalidate and we issued a read to the bus,
//but now have some pending writes, we need to move //but now have some pending writes, we need to move
//the invalidate to before the first non-read //the invalidate to before the first non-read
if (inService && pkt->cmd.isRead() && target->cmd.isInvalidate()) { if (inService && pkt->isRead() && target->isInvalidate()) {
std::list<Packet *> temp; std::list<Packet *> temp;
while (!targets.empty()) { while (!targets.empty()) {
if (!targets.front()->cmd.isRead()) break; if (!targets.front()->isRead()) break;
//Place on top of temp stack //Place on top of temp stack
temp.push_front(targets.front()); temp.push_front(targets.front());
//Remove from targets //Remove from targets
@ -148,8 +147,8 @@ MSHR::allocateTarget(Packet * &target)
* @todo really prioritize the target commands. * @todo really prioritize the target commands.
*/ */
if (!inService && target->cmd.isWrite()) { if (!inService && target->isWrite()) {
pkt->cmd = WriteReq; pkt->cmd = Packet::WriteReq;
} }
} }
@ -162,14 +161,14 @@ MSHR::dump()
"inService: %d thread: %d\n" "inService: %d thread: %d\n"
"Addr: %x asid: %d ntargets %d\n" "Addr: %x asid: %d ntargets %d\n"
"Targets:\n", "Targets:\n",
inService, getThreadNum(), addr, asid, ntargets); inService, threadNum, addr, asid, ntargets);
TargetListIterator tar_it = targets.begin(); TargetListIterator tar_it = targets.begin();
for (int i = 0; i < ntargets; i++) { for (int i = 0; i < ntargets; i++) {
assert(tar_it != targets.end()); assert(tar_it != targets.end());
ccprintf(cerr, "\t%d: Addr: %x cmd: %d\n", ccprintf(cerr, "\t%d: Addr: %x cmd: %d\n",
i, (*tar_it)->paddr, (*tar_it)->cmdToIndex()); i, (*tar_it)->getAddr(), (*tar_it)->cmdToIndex());
tar_it++; tar_it++;
} }

View file

@ -66,7 +66,7 @@ class MSHR {
/** True if the request has been sent to the bus. */ /** True if the request has been sent to the bus. */
bool inService; bool inService;
/** Thread number of the miss. */ /** Thread number of the miss. */
int getThreadNum(); int threadNum;
/** The request that is forwarded to the next level of the hierarchy. */ /** The request that is forwarded to the next level of the hierarchy. */
Packet * pkt; Packet * pkt;
/** The number of currently allocated targets. */ /** The number of currently allocated targets. */

View file

@ -94,17 +94,19 @@ MSHRQueue::findPending(Packet * &pkt) const
MSHR::ConstIterator end = pendingList.end(); MSHR::ConstIterator end = pendingList.end();
for (; i != end; ++i) { for (; i != end; ++i) {
MSHR *mshr = *i; MSHR *mshr = *i;
if (mshr->addr < pkt->addr) { if (mshr->addr < pkt->getAddr()) {
if (mshr->addr + mshr->pkt->size > pkt->addr) { if (mshr->addr + mshr->pkt->getSize() > pkt->getAddr()) {
return mshr; return mshr;
} }
} else { } else {
if (pkt->addr + pkt->size > mshr->addr) { if (pkt->getAddr() + pkt->getSize() > mshr->addr) {
return mshr; return mshr;
} }
} }
//need to check destination address for copies. //need to check destination address for copies.
//TEMP NOT DOING COPIES
#if 0
if (mshr->pkt->cmd == Copy) { if (mshr->pkt->cmd == Copy) {
Addr dest = mshr->pkt->dest; Addr dest = mshr->pkt->dest;
if (dest < pkt->addr) { if (dest < pkt->addr) {
@ -117,6 +119,7 @@ MSHRQueue::findPending(Packet * &pkt) const
} }
} }
} }
#endif
} }
return NULL; return NULL;
} }
@ -124,16 +127,16 @@ MSHRQueue::findPending(Packet * &pkt) const
MSHR* MSHR*
MSHRQueue::allocate(Packet * &pkt, int size) MSHRQueue::allocate(Packet * &pkt, int size)
{ {
Addr aligned_addr = pkt->addr & ~((Addr)size - 1); Addr aligned_addr = pkt->getAddr() & ~((Addr)size - 1);
MSHR *mshr = freeList.front(); MSHR *mshr = freeList.front();
assert(mshr->getNumTargets() == 0); assert(mshr->getNumTargets() == 0);
freeList.pop_front(); freeList.pop_front();
if (pkt->cmd.isNoResponse()) { if (!pkt->needsResponse()) {
mshr->allocateAsBuffer(pkt); mshr->allocateAsBuffer(pkt);
} else { } else {
assert(size !=0); assert(size !=0);
mshr->allocate(pkt->cmd, aligned_addr, pkt->req->req->asid, size, pkt); mshr->allocate(pkt->cmd, aligned_addr, pkt->req->getAsid(), size, pkt);
allocatedTargets += 1; allocatedTargets += 1;
} }
mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr); mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
@ -149,7 +152,7 @@ MSHRQueue::allocateFetch(Addr addr, int asid, int size, Packet * &target)
MSHR *mshr = freeList.front(); MSHR *mshr = freeList.front();
assert(mshr->getNumTargets() == 0); assert(mshr->getNumTargets() == 0);
freeList.pop_front(); freeList.pop_front();
mshr->allocate(Read, addr, asid, size, target); mshr->allocate(Packet::ReadReq, addr, asid, size, target);
mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr); mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
mshr->readyIter = pendingList.insert(pendingList.end(), mshr); mshr->readyIter = pendingList.insert(pendingList.end(), mshr);
@ -164,7 +167,7 @@ MSHRQueue::allocateTargetList(Addr addr, int asid, int size)
assert(mshr->getNumTargets() == 0); assert(mshr->getNumTargets() == 0);
freeList.pop_front(); freeList.pop_front();
Packet * dummy; Packet * dummy;
mshr->allocate(Read, addr, asid, size, dummy); mshr->allocate(Packet::ReadReq, addr, asid, size, dummy);
mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr); mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
mshr->inService = true; mshr->inService = true;
++inServiceMSHRs; ++inServiceMSHRs;
@ -209,7 +212,7 @@ void
MSHRQueue::markInService(MSHR* mshr) MSHRQueue::markInService(MSHR* mshr)
{ {
//assert(mshr == pendingList.front()); //assert(mshr == pendingList.front());
if (mshr->pkt->cmd.isNoResponse()) { if (!mshr->pkt->needsResponse()) {
assert(mshr->getNumTargets() == 0); assert(mshr->getNumTargets() == 0);
deallocate(mshr); deallocate(mshr);
return; return;
@ -237,21 +240,18 @@ MSHRQueue::markPending(MSHR* mshr, Packet::Command cmd)
} }
void void
MSHRQueue::squash(int req->getThreadNum()ber) MSHRQueue::squash(int threadNum)
{ {
MSHR::Iterator i = allocatedList.begin(); MSHR::Iterator i = allocatedList.begin();
MSHR::Iterator end = allocatedList.end(); MSHR::Iterator end = allocatedList.end();
for (; i != end;) { for (; i != end;) {
MSHR *mshr = *i; MSHR *mshr = *i;
if (mshr->setThreadNum() == req->getThreadNum()ber) { if (mshr->threadNum == threadNum) {
while (mshr->hasTargets()) { while (mshr->hasTargets()) {
Packet * target = mshr->getTarget(); Packet * target = mshr->getTarget();
mshr->popTarget(); mshr->popTarget();
assert(target->req->setThreadNum() == req->getThreadNum()ber); assert(target->req->getThreadNum() == threadNum);
if (target->completionEvent != NULL) {
delete target->completionEvent;
}
target = NULL; target = NULL;
} }
assert(!mshr->hasTargets()); assert(!mshr->hasTargets());

View file

@ -52,6 +52,9 @@ typedef std::list<PacketPtr> PacketList;
#define NACKED_LINE 1 << 0 #define NACKED_LINE 1 << 0
#define SATISFIED 1 << 1 #define SATISFIED 1 << 1
#define SHARED_LINE 1 << 2 #define SHARED_LINE 1 << 2
#define CACHE_LINE_FILL 1 << 3
#define COMPRESSED 1 << 4
#define NO_ALLOCATE 1 << 5
//For statistics we need max number of commands, hard code it at //For statistics we need max number of commands, hard code it at
//20 for now. @todo fix later //20 for now. @todo fix later
@ -66,6 +69,10 @@ typedef std::list<PacketPtr> PacketList;
*/ */
class Packet class Packet
{ {
public:
/** Temporary FLAGS field until cache gets working, this should be in coherence/sender state. */
uint64_t flags;
private: private:
/** A pointer to the data being transfered. It can be differnt /** A pointer to the data being transfered. It can be differnt
* sizes at each level of the heirarchy so it belongs in the * sizes at each level of the heirarchy so it belongs in the
@ -93,6 +100,9 @@ class Packet
/** The size of the request or transfer. */ /** The size of the request or transfer. */
int size; int size;
/** The offset within the block that represents the data. */
int offset;
/** Device address (e.g., bus ID) of the source of the /** Device address (e.g., bus ID) of the source of the
* transaction. The source is not responsible for setting this * transaction. The source is not responsible for setting this
* field; it is set implicitly by the interconnect when the * field; it is set implicitly by the interconnect when the
@ -110,6 +120,9 @@ class Packet
bool addrSizeValid; bool addrSizeValid;
/** Is the 'src' field valid? */ /** Is the 'src' field valid? */
bool srcValid; bool srcValid;
/** Is the offset valid. */
bool offsetValid;
public: public:
@ -171,6 +184,7 @@ class Packet
/** List of all commands associated with a packet. */ /** List of all commands associated with a packet. */
enum Command enum Command
{ {
InvalidCmd = 0,
ReadReq = IsRead | IsRequest | NeedsResponse, ReadReq = IsRead | IsRequest | NeedsResponse,
WriteReq = IsWrite | IsRequest | NeedsResponse, WriteReq = IsWrite | IsRequest | NeedsResponse,
WriteReqNoAck = IsWrite | IsRequest, WriteReqNoAck = IsWrite | IsRequest,
@ -183,7 +197,10 @@ class Packet
HardPFResp = IsRead | IsRequest | IsHWPrefetch | IsResponse, HardPFResp = IsRead | IsRequest | IsHWPrefetch | IsResponse,
InvalidateReq = IsInvalidate | IsRequest, InvalidateReq = IsInvalidate | IsRequest,
WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest, WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest,
UpgradeReq = IsInvalidate | NeedsResponse UpgradeReq = IsInvalidate | NeedsResponse,
UpgradeResp = IsInvalidate | IsResponse,
ReadExReq = IsRead | IsInvalidate | NeedsResponse,
ReadExResp = IsRead | IsInvalidate | IsResponse
}; };
/** Return the string name of the cmd field (for debugging and /** Return the string name of the cmd field (for debugging and
@ -206,8 +223,8 @@ class Packet
bool needsResponse() { return (cmd & NeedsResponse) != 0; } bool needsResponse() { return (cmd & NeedsResponse) != 0; }
bool isInvalidate() { return (cmd * IsInvalidate) != 0; } bool isInvalidate() { return (cmd * IsInvalidate) != 0; }
bool isCacheFill() { assert("Unimplemented yet\n" && 0); } bool isCacheFill() { return (flags & CACHE_LINE_FILL) != 0; }
bool isNoAllocate() { assert("Unimplemented yet\n" && 0); } bool isNoAllocate() { return (flags & NO_ALLOCATE) != 0; }
/** Possible results of a packet's request. */ /** Possible results of a packet's request. */
enum Result enum Result
@ -232,6 +249,10 @@ class Packet
Addr getAddr() const { assert(addrSizeValid); return addr; } Addr getAddr() const { assert(addrSizeValid); return addr; }
int getSize() const { assert(addrSizeValid); return size; } int getSize() const { assert(addrSizeValid); return size; }
int getOffset() const { assert(offsetValid); return offset; }
void addrOverride(Addr newAddr) { assert(addrSizeValid); addr = newAddr; }
void cmdOverride(Command newCmd) { cmd = newCmd; }
/** Constructor. Note that a Request object must be constructed /** Constructor. Note that a Request object must be constructed
* first, but the Requests's physical address and size fields * first, but the Requests's physical address and size fields
@ -241,10 +262,25 @@ class Packet
: data(NULL), staticData(false), dynamicData(false), arrayData(false), : data(NULL), staticData(false), dynamicData(false), arrayData(false),
addr(_req->paddr), size(_req->size), dest(_dest), addr(_req->paddr), size(_req->size), dest(_dest),
addrSizeValid(_req->validPaddr), addrSizeValid(_req->validPaddr),
srcValid(false), srcValid(false), offsetValid(false),
req(_req), coherence(NULL), senderState(NULL), cmd(_cmd), req(_req), coherence(NULL), senderState(NULL), cmd(_cmd),
result(Unknown) result(Unknown)
{ {
flags = 0;
}
/** Alternate constructor if you are trying to create a packet with
* a request that is for a whole block, not the address from the req.
* this allows for overriding the size/addr of the req.*/
Packet(Request *_req, Command _cmd, short _dest, int _blkSize)
: data(NULL), staticData(false), dynamicData(false), arrayData(false),
addr(_req->paddr & ~(_blkSize - 1)), size(_blkSize),
offset(_req->paddr & (_blkSize - 1)), dest(_dest),
addrSizeValid(_req->validPaddr), srcValid(false), offsetValid(true),
req(_req), coherence(NULL), senderState(NULL), cmd(_cmd),
result(Unknown)
{
flags = 0;
} }
/** Destructor. */ /** Destructor. */