Merge zizzer:/bk/newmem
into zazzer.eecs.umich.edu:/z/rdreslin/m5bk/newmemcleanest --HG-- extra : convert_revision : 9e47881686a6c060fa28e7edfd9a0b556099bf30
This commit is contained in:
commit
63c2a782d6
|
@ -42,6 +42,8 @@ parser = optparse.OptionParser()
|
||||||
|
|
||||||
parser.add_option("-d", "--detailed", action="store_true")
|
parser.add_option("-d", "--detailed", action="store_true")
|
||||||
parser.add_option("-t", "--timing", action="store_true")
|
parser.add_option("-t", "--timing", action="store_true")
|
||||||
|
parser.add_option("-n", "--num_cpus", type="int", default=1)
|
||||||
|
parser.add_option("--caches", action="store_true")
|
||||||
parser.add_option("-m", "--maxtick", type="int")
|
parser.add_option("-m", "--maxtick", type="int")
|
||||||
parser.add_option("--maxtime", type="float")
|
parser.add_option("--maxtime", type="float")
|
||||||
parser.add_option("--dual", action="store_true",
|
parser.add_option("--dual", action="store_true",
|
||||||
|
@ -64,6 +66,13 @@ if args:
|
||||||
print "Error: script doesn't take any positional arguments"
|
print "Error: script doesn't take any positional arguments"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
class MyCache(BaseCache):
|
||||||
|
assoc = 2
|
||||||
|
block_size = 64
|
||||||
|
latency = 1
|
||||||
|
mshrs = 10
|
||||||
|
tgts_per_mshr = 5
|
||||||
|
|
||||||
# client system CPU is always simple... note this is an assignment of
|
# client system CPU is always simple... note this is an assignment of
|
||||||
# a class, not an instance.
|
# a class, not an instance.
|
||||||
ClientCPUClass = AtomicSimpleCPU
|
ClientCPUClass = AtomicSimpleCPU
|
||||||
|
@ -96,9 +105,14 @@ else:
|
||||||
bm = [SysConfig()]
|
bm = [SysConfig()]
|
||||||
|
|
||||||
server_sys = makeLinuxAlphaSystem(server_mem_mode, bm[0])
|
server_sys = makeLinuxAlphaSystem(server_mem_mode, bm[0])
|
||||||
server_sys.cpu = ServerCPUClass(cpu_id=0)
|
np = options.num_cpus
|
||||||
server_sys.cpu.connectMemPorts(server_sys.membus)
|
server_sys.cpu = [ServerCPUClass(cpu_id=i) for i in xrange(np)]
|
||||||
server_sys.cpu.mem = server_sys.physmem
|
for i in xrange(np):
|
||||||
|
if options.caches:
|
||||||
|
server_sys.cpu[i].addPrivateSplitL1Caches(MyCache(size = '32kB'),
|
||||||
|
MyCache(size = '64kB'))
|
||||||
|
server_sys.cpu[i].connectMemPorts(server_sys.membus)
|
||||||
|
server_sys.cpu[i].mem = server_sys.physmem
|
||||||
|
|
||||||
if len(bm) == 2:
|
if len(bm) == 2:
|
||||||
client_sys = makeLinuxAlphaSystem(client_mem_mode, bm[1])
|
client_sys = makeLinuxAlphaSystem(client_mem_mode, bm[1])
|
||||||
|
|
3
src/mem/cache/base_cache.cc
vendored
3
src/mem/cache/base_cache.cc
vendored
|
@ -34,9 +34,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mem/cache/base_cache.hh"
|
#include "mem/cache/base_cache.hh"
|
||||||
|
#include "mem/cache/miss/mshr.hh"
|
||||||
|
#include "mem/packet_impl.hh"
|
||||||
#include "cpu/smt.hh"
|
#include "cpu/smt.hh"
|
||||||
#include "cpu/base.hh"
|
#include "cpu/base.hh"
|
||||||
#include "mem/cache/miss/mshr.hh"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
1
src/mem/cache/base_cache.hh
vendored
1
src/mem/cache/base_cache.hh
vendored
|
@ -58,7 +58,6 @@ enum BlockedCause{
|
||||||
Blocked_NoTargets,
|
Blocked_NoTargets,
|
||||||
Blocked_NoWBBuffers,
|
Blocked_NoWBBuffers,
|
||||||
Blocked_Coherence,
|
Blocked_Coherence,
|
||||||
Blocked_Copy,
|
|
||||||
NUM_BLOCKED_CAUSES
|
NUM_BLOCKED_CAUSES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
41
src/mem/cache/cache.hh
vendored
41
src/mem/cache/cache.hh
vendored
|
@ -75,12 +75,6 @@ class Cache : public BaseCache
|
||||||
/** Prefetcher */
|
/** Prefetcher */
|
||||||
Prefetcher<TagStore, Buffering> *prefetcher;
|
Prefetcher<TagStore, Buffering> *prefetcher;
|
||||||
|
|
||||||
/** Do fast copies in this cache. */
|
|
||||||
bool doCopy;
|
|
||||||
|
|
||||||
/** Block on a delayed copy. */
|
|
||||||
bool blockOnCopy;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The clock ratio of the outgoing bus.
|
* The clock ratio of the outgoing bus.
|
||||||
* Used for calculating critical word first.
|
* Used for calculating critical word first.
|
||||||
|
@ -105,18 +99,6 @@ class Cache : public BaseCache
|
||||||
Packet * invalidatePkt;
|
Packet * invalidatePkt;
|
||||||
Request *invalidateReq;
|
Request *invalidateReq;
|
||||||
|
|
||||||
/**
|
|
||||||
* Temporarily move a block into a MSHR.
|
|
||||||
* @todo Remove this when LSQ/SB are fixed and implemented in memtest.
|
|
||||||
*/
|
|
||||||
void pseudoFill(Addr addr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Temporarily move a block into an existing MSHR.
|
|
||||||
* @todo Remove this when LSQ/SB are fixed and implemented in memtest.
|
|
||||||
*/
|
|
||||||
void pseudoFill(MSHR *mshr);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class Params
|
class Params
|
||||||
|
@ -125,19 +107,17 @@ class Cache : public BaseCache
|
||||||
TagStore *tags;
|
TagStore *tags;
|
||||||
Buffering *missQueue;
|
Buffering *missQueue;
|
||||||
Coherence *coherence;
|
Coherence *coherence;
|
||||||
bool doCopy;
|
|
||||||
bool blockOnCopy;
|
|
||||||
BaseCache::Params baseParams;
|
BaseCache::Params baseParams;
|
||||||
Prefetcher<TagStore, Buffering> *prefetcher;
|
Prefetcher<TagStore, Buffering> *prefetcher;
|
||||||
bool prefetchAccess;
|
bool prefetchAccess;
|
||||||
int hitLatency;
|
int hitLatency;
|
||||||
|
|
||||||
Params(TagStore *_tags, Buffering *mq, Coherence *coh,
|
Params(TagStore *_tags, Buffering *mq, Coherence *coh,
|
||||||
bool do_copy, BaseCache::Params params,
|
BaseCache::Params params,
|
||||||
Prefetcher<TagStore, Buffering> *_prefetcher,
|
Prefetcher<TagStore, Buffering> *_prefetcher,
|
||||||
bool prefetch_access, int hit_latency)
|
bool prefetch_access, int hit_latency)
|
||||||
: tags(_tags), missQueue(mq), coherence(coh), doCopy(do_copy),
|
: tags(_tags), missQueue(mq), coherence(coh),
|
||||||
blockOnCopy(false), baseParams(params),
|
baseParams(params),
|
||||||
prefetcher(_prefetcher), prefetchAccess(prefetch_access),
|
prefetcher(_prefetcher), prefetchAccess(prefetch_access),
|
||||||
hitLatency(hit_latency)
|
hitLatency(hit_latency)
|
||||||
{
|
{
|
||||||
|
@ -191,21 +171,6 @@ class Cache : public BaseCache
|
||||||
*/
|
*/
|
||||||
void handleResponse(Packet * &pkt);
|
void handleResponse(Packet * &pkt);
|
||||||
|
|
||||||
/**
|
|
||||||
* Start handling a copy transaction.
|
|
||||||
* @param pkt The copy request to perform.
|
|
||||||
*/
|
|
||||||
void startCopy(Packet * &pkt);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle a delayed copy transaction.
|
|
||||||
* @param pkt The delayed copy request to continue.
|
|
||||||
* @param addr The address being responded to.
|
|
||||||
* @param blk The block of the current response.
|
|
||||||
* @param mshr The mshr being handled.
|
|
||||||
*/
|
|
||||||
void handleCopy(Packet * &pkt, Addr addr, BlkType *blk, MSHR *mshr);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects a coherence message to forward to lower levels of the hierarchy.
|
* Selects a coherence message to forward to lower levels of the hierarchy.
|
||||||
* @return The coherence message to forward.
|
* @return The coherence message to forward.
|
||||||
|
|
4
src/mem/cache/cache_builder.cc
vendored
4
src/mem/cache/cache_builder.cc
vendored
|
@ -113,7 +113,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(BaseCache)
|
||||||
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;
|
|
||||||
SimObjectParam<CoherenceProtocol *> protocol;
|
SimObjectParam<CoherenceProtocol *> protocol;
|
||||||
Param<Addr> trace_addr;
|
Param<Addr> trace_addr;
|
||||||
Param<int> hash_delay;
|
Param<int> hash_delay;
|
||||||
|
@ -163,7 +162,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(BaseCache)
|
||||||
/* 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(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),
|
||||||
|
|
||||||
|
@ -228,7 +226,7 @@ END_INIT_SIM_OBJECT_PARAMS(BaseCache)
|
||||||
BUILD_NULL_PREFETCHER(t, comp, b); \
|
BUILD_NULL_PREFETCHER(t, comp, b); \
|
||||||
} \
|
} \
|
||||||
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, \
|
base_params, \
|
||||||
/*in_bus, out_bus,*/ pf, \
|
/*in_bus, out_bus,*/ pf, \
|
||||||
prefetch_access, hit_latency); \
|
prefetch_access, hit_latency); \
|
||||||
Cache<CacheTags<t, comp>, b, c> *retval = \
|
Cache<CacheTags<t, comp>, b, c> *retval = \
|
||||||
|
|
157
src/mem/cache/cache_impl.hh
vendored
157
src/mem/cache/cache_impl.hh
vendored
|
@ -148,7 +148,6 @@ Cache(const std::string &_name,
|
||||||
prefetchAccess(params.prefetchAccess),
|
prefetchAccess(params.prefetchAccess),
|
||||||
tags(params.tags), missQueue(params.missQueue),
|
tags(params.tags), missQueue(params.missQueue),
|
||||||
coherence(params.coherence), prefetcher(params.prefetcher),
|
coherence(params.coherence), prefetcher(params.prefetcher),
|
||||||
doCopy(params.doCopy), blockOnCopy(params.blockOnCopy),
|
|
||||||
hitLatency(params.hitLatency)
|
hitLatency(params.hitLatency)
|
||||||
{
|
{
|
||||||
tags->setCache(this);
|
tags->setCache(this);
|
||||||
|
@ -198,7 +197,8 @@ Cache<TagStore,Buffering,Coherence>::access(PacketPtr &pkt)
|
||||||
/** @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->getSize() >= 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->getAddr());
|
MSHR* outstanding_miss = missQueue->findMSHR(pkt->getAddr());
|
||||||
if (pkt->cmd == Packet::WriteInvalidateReq || !outstanding_miss) {
|
if (pkt->cmd == Packet::WriteInvalidateReq || !outstanding_miss) {
|
||||||
|
@ -255,7 +255,8 @@ Cache<TagStore,Buffering,Coherence>::getPacket()
|
||||||
Packet * pkt = missQueue->getPacket();
|
Packet * pkt = missQueue->getPacket();
|
||||||
if (pkt) {
|
if (pkt) {
|
||||||
if (!pkt->req->isUncacheable()) {
|
if (!pkt->req->isUncacheable()) {
|
||||||
if (pkt->cmd == Packet::HardPFReq) misses[Packet::HardPFReq][0/*pkt->req->getThreadNum()*/]++;
|
if (pkt->cmd == Packet::HardPFReq)
|
||||||
|
misses[Packet::HardPFReq][0/*pkt->req->getThreadNum()*/]++;
|
||||||
BlkType *blk = tags->findBlock(pkt);
|
BlkType *blk = tags->findBlock(pkt);
|
||||||
Packet::Command cmd = coherence->getBusCmd(pkt->cmd,
|
Packet::Command cmd = coherence->getBusCmd(pkt->cmd,
|
||||||
(blk)? blk->status : 0);
|
(blk)? blk->status : 0);
|
||||||
|
@ -270,10 +271,12 @@ Cache<TagStore,Buffering,Coherence>::getPacket()
|
||||||
|
|
||||||
template<class TagStore, class Buffering, class Coherence>
|
template<class TagStore, class Buffering, class Coherence>
|
||||||
void
|
void
|
||||||
Cache<TagStore,Buffering,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr, bool success)
|
Cache<TagStore,Buffering,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr,
|
||||||
|
bool success)
|
||||||
{
|
{
|
||||||
if (success && !(pkt && (pkt->flags & NACKED_LINE))) {
|
if (success && !(pkt && (pkt->flags & NACKED_LINE))) {
|
||||||
if (!mshr->pkt->needsResponse() && !(mshr->pkt->cmd == Packet::UpgradeReq)
|
if (!mshr->pkt->needsResponse()
|
||||||
|
&& !(mshr->pkt->cmd == Packet::UpgradeReq)
|
||||||
&& (pkt && (pkt->flags & SATISFIED))) {
|
&& (pkt && (pkt->flags & SATISFIED))) {
|
||||||
//Writeback, clean up the non copy version of the packet
|
//Writeback, clean up the non copy version of the packet
|
||||||
delete pkt;
|
delete pkt;
|
||||||
|
@ -287,8 +290,10 @@ Cache<TagStore,Buffering,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr, bool
|
||||||
CacheBlk::State old_state = (blk) ? blk->status : 0;
|
CacheBlk::State old_state = (blk) ? blk->status : 0;
|
||||||
CacheBlk::State new_state = coherence->getNewState(pkt,old_state);
|
CacheBlk::State new_state = coherence->getNewState(pkt,old_state);
|
||||||
if (old_state != new_state)
|
if (old_state != new_state)
|
||||||
DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n",
|
DPRINTF(Cache, "Block for blk addr %x moving from "
|
||||||
pkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state);
|
"state %i to %i\n",
|
||||||
|
pkt->getAddr() & (((ULL(1))<<48)-1),
|
||||||
|
old_state, new_state);
|
||||||
//Set the state on the upgrade
|
//Set the state on the upgrade
|
||||||
memcpy(pkt->getPtr<uint8_t>(), blk->data, blkSize);
|
memcpy(pkt->getPtr<uint8_t>(), blk->data, blkSize);
|
||||||
PacketList writebacks;
|
PacketList writebacks;
|
||||||
|
@ -320,7 +325,8 @@ Cache<TagStore,Buffering,Coherence>::handleResponse(Packet * &pkt)
|
||||||
((MSHR*)pkt->senderState)->pkt = pkt;
|
((MSHR*)pkt->senderState)->pkt = pkt;
|
||||||
if (pkt->result == Packet::Nacked) {
|
if (pkt->result == Packet::Nacked) {
|
||||||
//pkt->reinitFromRequest();
|
//pkt->reinitFromRequest();
|
||||||
warn("NACKs from devices not connected to the same bus not implemented\n");
|
warn("NACKs from devices not connected to the same bus "
|
||||||
|
"not implemented\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pkt->result == Packet::BadAddress) {
|
if (pkt->result == Packet::BadAddress) {
|
||||||
|
@ -336,8 +342,10 @@ Cache<TagStore,Buffering,Coherence>::handleResponse(Packet * &pkt)
|
||||||
PacketList writebacks;
|
PacketList writebacks;
|
||||||
CacheBlk::State new_state = coherence->getNewState(pkt,old_state);
|
CacheBlk::State new_state = coherence->getNewState(pkt,old_state);
|
||||||
if (old_state != new_state)
|
if (old_state != new_state)
|
||||||
DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n",
|
DPRINTF(Cache, "Block for blk addr %x moving from "
|
||||||
pkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state);
|
"state %i to %i\n",
|
||||||
|
pkt->getAddr() & (((ULL(1))<<48)-1),
|
||||||
|
old_state, new_state);
|
||||||
blk = tags->handleFill(blk, (MSHR*)pkt->senderState,
|
blk = tags->handleFill(blk, (MSHR*)pkt->senderState,
|
||||||
new_state, writebacks, pkt);
|
new_state, writebacks, pkt);
|
||||||
while (!writebacks.empty()) {
|
while (!writebacks.empty()) {
|
||||||
|
@ -349,43 +357,6 @@ Cache<TagStore,Buffering,Coherence>::handleResponse(Packet * &pkt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class TagStore, class Buffering, class Coherence>
|
|
||||||
void
|
|
||||||
Cache<TagStore,Buffering,Coherence>::pseudoFill(Addr addr)
|
|
||||||
{
|
|
||||||
// Need to temporarily move this blk into MSHRs
|
|
||||||
MSHR *mshr = missQueue->allocateTargetList(addr);
|
|
||||||
int lat;
|
|
||||||
PacketList dummy;
|
|
||||||
// Read the data into the mshr
|
|
||||||
BlkType *blk = tags->handleAccess(mshr->pkt, lat, dummy, false);
|
|
||||||
assert(dummy.empty());
|
|
||||||
assert(mshr->pkt->flags & SATISFIED);
|
|
||||||
// can overload order since it isn't used on non pending blocks
|
|
||||||
mshr->order = blk->status;
|
|
||||||
// temporarily remove the block from the cache.
|
|
||||||
tags->invalidateBlk(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TagStore, class Buffering, class Coherence>
|
|
||||||
void
|
|
||||||
Cache<TagStore,Buffering,Coherence>::pseudoFill(MSHR *mshr)
|
|
||||||
{
|
|
||||||
// Need to temporarily move this blk into MSHRs
|
|
||||||
assert(mshr->pkt->cmd == Packet::ReadReq);
|
|
||||||
int lat;
|
|
||||||
PacketList dummy;
|
|
||||||
// Read the data into the mshr
|
|
||||||
BlkType *blk = tags->handleAccess(mshr->pkt, lat, dummy, false);
|
|
||||||
assert(dummy.empty());
|
|
||||||
assert(mshr->pkt->flags & SATISFIED);
|
|
||||||
// can overload order since it isn't used on non pending blocks
|
|
||||||
mshr->order = blk->status;
|
|
||||||
// temporarily remove the block from the cache.
|
|
||||||
tags->invalidateBlk(mshr->pkt->getAddr());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class TagStore, class Buffering, class Coherence>
|
template<class TagStore, class Buffering, class Coherence>
|
||||||
Packet *
|
Packet *
|
||||||
Cache<TagStore,Buffering,Coherence>::getCoherencePacket()
|
Cache<TagStore,Buffering,Coherence>::getCoherencePacket()
|
||||||
|
@ -416,30 +387,36 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
|
||||||
BlkType *blk = tags->findBlock(pkt);
|
BlkType *blk = tags->findBlock(pkt);
|
||||||
MSHR *mshr = missQueue->findMSHR(blk_addr);
|
MSHR *mshr = missQueue->findMSHR(blk_addr);
|
||||||
if (coherence->hasProtocol()) { //@todo Move this into handle bus req
|
if (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) {
|
||||||
if (mshr->inService) {
|
if (mshr->inService) {
|
||||||
if ((mshr->pkt->isInvalidate() || !mshr->pkt->isCacheFill())
|
if ((mshr->pkt->isInvalidate() || !mshr->pkt->isCacheFill())
|
||||||
&& (pkt->cmd != Packet::InvalidateReq && pkt->cmd != Packet::WriteInvalidateReq)) {
|
&& (pkt->cmd != Packet::InvalidateReq
|
||||||
//If the outstanding request was an invalidate (upgrade,readex,..)
|
&& pkt->cmd != Packet::WriteInvalidateReq)) {
|
||||||
//Then we need to ACK the request until we get the data
|
//If the outstanding request was an invalidate
|
||||||
//Also NACK if the outstanding request is not a cachefill (writeback)
|
//(upgrade,readex,..) Then we need to ACK the request
|
||||||
|
//until we get the data Also NACK if the outstanding
|
||||||
|
//request is not a cachefill (writeback)
|
||||||
assert(!(pkt->flags & SATISFIED));
|
assert(!(pkt->flags & SATISFIED));
|
||||||
pkt->flags |= SATISFIED;
|
pkt->flags |= SATISFIED;
|
||||||
pkt->flags |= NACKED_LINE;
|
pkt->flags |= NACKED_LINE;
|
||||||
///@todo NACK's from other levels
|
///@todo NACK's from other levels
|
||||||
//warn("NACKs from devices not connected to the same bus not implemented\n");
|
//warn("NACKs from devices not connected to the same bus "
|
||||||
|
//"not implemented\n");
|
||||||
//respondToSnoop(pkt, curTick + hitLatency);
|
//respondToSnoop(pkt, curTick + hitLatency);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//The supplier will be someone else, because we are waiting for
|
//The supplier will be someone else, because we are
|
||||||
//the data. This should cause this cache to be forced to go to
|
//waiting for the data. This should cause this cache to
|
||||||
//the shared state, not the exclusive even though the shared line
|
//be forced to go to the shared state, not the exclusive
|
||||||
//won't be asserted. But for now we will just invlidate ourselves
|
//even though the shared line won't be asserted. But for
|
||||||
//and allow the other cache to go into the exclusive state.
|
//now we will just invlidate ourselves and allow the other
|
||||||
//@todo Make it so a read to a pending read doesn't invalidate.
|
//cache to go into the exclusive state. @todo Make it so
|
||||||
//@todo Make it so that a read to a pending read can't be exclusive now.
|
//a read to a pending read doesn't invalidate. @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
|
||||||
//panic("Don't have invalidates yet\n");
|
//panic("Don't have invalidates yet\n");
|
||||||
|
@ -447,7 +424,8 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
|
||||||
|
|
||||||
//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->getAddr() & (((ULL(1))<<48)-1));
|
DPRINTF(Cache, "Appending Invalidate to blk_addr: %x\n",
|
||||||
|
pkt->getAddr() & (((ULL(1))<<48)-1));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -455,7 +433,8 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
|
||||||
//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, writebacks)) {
|
if (missQueue->findWrites(blk_addr, writebacks)) {
|
||||||
DPRINTF(Cache, "Snoop hit in writeback to blk_addr: %x\n", pkt->getAddr() & (((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++) {
|
||||||
|
@ -483,7 +462,8 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pkt->isInvalidate()) {
|
if (pkt->isInvalidate()) {
|
||||||
//This must be an upgrade or other cache will take ownership
|
//This must be an upgrade or other cache will take
|
||||||
|
//ownership
|
||||||
missQueue->markInService(mshr->pkt, mshr);
|
missQueue->markInService(mshr->pkt, mshr);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -494,16 +474,17 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
|
||||||
CacheBlk::State new_state;
|
CacheBlk::State new_state;
|
||||||
bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state);
|
bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state);
|
||||||
if (satisfy) {
|
if (satisfy) {
|
||||||
DPRINTF(Cache, "Cache snooped a %s request for addr %x and now supplying data,"
|
DPRINTF(Cache, "Cache snooped a %s request for addr %x and "
|
||||||
"new state is %i\n",
|
"now supplying data, new state is %i\n",
|
||||||
pkt->cmdString(), blk_addr, new_state);
|
pkt->cmdString(), blk_addr, new_state);
|
||||||
|
|
||||||
tags->handleSnoop(blk, new_state, pkt);
|
tags->handleSnoop(blk, new_state, pkt);
|
||||||
respondToSnoop(pkt, curTick + hitLatency);
|
respondToSnoop(pkt, curTick + hitLatency);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (blk) DPRINTF(Cache, "Cache snooped a %s request for addr %x, new state is %i\n",
|
if (blk)
|
||||||
pkt->cmdString(), blk_addr, new_state);
|
DPRINTF(Cache, "Cache snooped a %s request for addr %x, "
|
||||||
|
"new state is %i\n", pkt->cmdString(), blk_addr, new_state);
|
||||||
tags->handleSnoop(blk, new_state);
|
tags->handleSnoop(blk, new_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,12 +497,13 @@ Cache<TagStore,Buffering,Coherence>::snoopResponse(Packet * &pkt)
|
||||||
//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
|
||||||
|
|
||||||
//For now this should never get called, we return false when we see a NACK
|
//For now this should never get called, we return false when we see a
|
||||||
//instead, by doing this we allow the bus_blocked mechanism to handle the retry
|
//NACK instead, by doing this we allow the bus_blocked mechanism to
|
||||||
//For now it retrys in just 2 cycles, need to figure out how to change that
|
//handle the retry For now it retrys in just 2 cycles, need to figure
|
||||||
//Eventually we will want to also have success come in as a parameter
|
//out how to change that Eventually we will want to also have success
|
||||||
//Need to make sure that we handle the functionality that happens on successufl
|
//come in as a parameter Need to make sure that we handle the
|
||||||
//return of the sendAddr function
|
//functionality that happens on successufl return of the sendAddr
|
||||||
|
//function
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,7 +520,8 @@ Cache<TagStore,Buffering,Coherence>::invalidateBlk(Addr addr)
|
||||||
*/
|
*/
|
||||||
template<class TagStore, class Buffering, class Coherence>
|
template<class TagStore, class Buffering, class Coherence>
|
||||||
Tick
|
Tick
|
||||||
Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update, CachePort* otherSidePort)
|
Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update,
|
||||||
|
CachePort* otherSidePort)
|
||||||
{
|
{
|
||||||
// MemDebug::cacheProbe(pkt);
|
// MemDebug::cacheProbe(pkt);
|
||||||
if (!pkt->req->isUncacheable()) {
|
if (!pkt->req->isUncacheable()) {
|
||||||
|
@ -687,13 +670,17 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update, CachePort
|
||||||
*/ misses[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++;
|
*/ misses[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++;
|
||||||
|
|
||||||
CacheBlk::State old_state = (blk) ? blk->status : 0;
|
CacheBlk::State old_state = (blk) ? blk->status : 0;
|
||||||
CacheBlk::State new_state = coherence->getNewState(busPkt, old_state);
|
CacheBlk::State new_state =
|
||||||
DPRINTF(Cache, "Receive response:%s for blk addr %x in state %i\n",
|
coherence->getNewState(busPkt, old_state);
|
||||||
busPkt->cmdString(),
|
DPRINTF(Cache,
|
||||||
busPkt->getAddr() & (((ULL(1))<<48)-1), old_state);
|
"Receive response:%s for blk addr %x in state %i\n",
|
||||||
|
busPkt->cmdString(),
|
||||||
|
busPkt->getAddr() & (((ULL(1))<<48)-1), old_state);
|
||||||
if (old_state != new_state)
|
if (old_state != new_state)
|
||||||
DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n",
|
DPRINTF(Cache, "Block for blk addr %x moving from "
|
||||||
busPkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state);
|
"state %i to %i\n",
|
||||||
|
busPkt->getAddr() & (((ULL(1))<<48)-1),
|
||||||
|
old_state, new_state);
|
||||||
|
|
||||||
tags->handleFill(blk, busPkt,
|
tags->handleFill(blk, busPkt,
|
||||||
new_state,
|
new_state,
|
||||||
|
@ -743,15 +730,17 @@ Cache<TagStore,Buffering,Coherence>::snoopProbe(PacketPtr &pkt)
|
||||||
CacheBlk::State new_state = 0;
|
CacheBlk::State new_state = 0;
|
||||||
bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state);
|
bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state);
|
||||||
if (satisfy) {
|
if (satisfy) {
|
||||||
DPRINTF(Cache, "Cache snooped a %s request for addr %x and now supplying data,"
|
DPRINTF(Cache, "Cache snooped a %s request for addr %x and "
|
||||||
"new state is %i\n",
|
"now supplying data, new state is %i\n",
|
||||||
pkt->cmdString(), blk_addr, new_state);
|
pkt->cmdString(), blk_addr, new_state);
|
||||||
|
|
||||||
tags->handleSnoop(blk, new_state, pkt);
|
tags->handleSnoop(blk, new_state, pkt);
|
||||||
return hitLatency;
|
return hitLatency;
|
||||||
}
|
}
|
||||||
if (blk) DPRINTF(Cache, "Cache snooped a %s request for addr %x, new state is %i\n",
|
if (blk)
|
||||||
pkt->cmdString(), blk_addr, new_state);
|
DPRINTF(Cache, "Cache snooped a %s request for addr %x, "
|
||||||
|
"new state is %i\n",
|
||||||
|
pkt->cmdString(), blk_addr, new_state);
|
||||||
tags->handleSnoop(blk, new_state);
|
tags->handleSnoop(blk, new_state);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
17
src/mem/cache/miss/mshr_queue.cc
vendored
17
src/mem/cache/miss/mshr_queue.cc
vendored
|
@ -103,23 +103,6 @@ MSHRQueue::findPending(Packet * &pkt) const
|
||||||
return mshr;
|
return mshr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//need to check destination address for copies.
|
|
||||||
//TEMP NOT DOING COPIES
|
|
||||||
#if 0
|
|
||||||
if (mshr->pkt->cmd == Copy) {
|
|
||||||
Addr dest = mshr->pkt->dest;
|
|
||||||
if (dest < pkt->addr) {
|
|
||||||
if (dest + mshr->pkt->size > pkt->addr) {
|
|
||||||
return mshr;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (pkt->addr + pkt->size > dest) {
|
|
||||||
return mshr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
19
src/mem/cache/tags/fa_lru.hh
vendored
19
src/mem/cache/tags/fa_lru.hh
vendored
|
@ -322,25 +322,6 @@ public:
|
||||||
PacketList &writebacks)
|
PacketList &writebacks)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Unimplemented. Perform a cache block copy from block aligned addresses.
|
|
||||||
* @param source The block aligned source address.
|
|
||||||
* @param dest The block aligned destination adddress.
|
|
||||||
* @param asid The address space ID.
|
|
||||||
* @param writebacks List for any generated writeback pktuests.
|
|
||||||
*/
|
|
||||||
void doCopy(Addr source, Addr dest, PacketList &writebacks)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unimplemented.
|
|
||||||
*/
|
|
||||||
void fixCopy(Packet * &pkt, PacketList &writebacks)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
102
src/mem/cache/tags/iic.cc
vendored
102
src/mem/cache/tags/iic.cc
vendored
|
@ -711,8 +711,8 @@ IIC::invalidateBlk(Addr addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
IIC::readData(IICTag *blk, uint8_t *data){
|
IIC::readData(IICTag *blk, uint8_t *data)
|
||||||
// assert(cache->doData());
|
{
|
||||||
assert(blk->size <= trivialSize || blk->numData > 0);
|
assert(blk->size <= trivialSize || blk->numData > 0);
|
||||||
int data_size = blk->size;
|
int data_size = blk->size;
|
||||||
if (data_size > trivialSize) {
|
if (data_size > trivialSize) {
|
||||||
|
@ -729,8 +729,8 @@ IIC::readData(IICTag *blk, uint8_t *data){
|
||||||
|
|
||||||
void
|
void
|
||||||
IIC::writeData(IICTag *blk, uint8_t *write_data, int size,
|
IIC::writeData(IICTag *blk, uint8_t *write_data, int size,
|
||||||
PacketList & writebacks){
|
PacketList & writebacks)
|
||||||
// assert(cache->doData());
|
{
|
||||||
assert(size < blkSize || !blk->isCompressed());
|
assert(size < blkSize || !blk->isCompressed());
|
||||||
DPRINTF(IIC, "Writing %d bytes to %x\n", size,
|
DPRINTF(IIC, "Writing %d bytes to %x\n", size,
|
||||||
blk->tag<<tagShift);
|
blk->tag<<tagShift);
|
||||||
|
@ -750,10 +750,6 @@ IIC::writeData(IICTag *blk, uint8_t *write_data, int size,
|
||||||
// can free data blocks
|
// can free data blocks
|
||||||
for (int i=num_subs; i < blk->numData; ++i){
|
for (int i=num_subs; i < blk->numData; ++i){
|
||||||
// decrement reference count and compare to zero
|
// decrement reference count and compare to zero
|
||||||
/**
|
|
||||||
* @todo
|
|
||||||
* Make this work with copying.
|
|
||||||
*/
|
|
||||||
if (--dataReferenceCount[blk->data_ptr[i]] == 0) {
|
if (--dataReferenceCount[blk->data_ptr[i]] == 0) {
|
||||||
freeDataBlock(blk->data_ptr[i]);
|
freeDataBlock(blk->data_ptr[i]);
|
||||||
}
|
}
|
||||||
|
@ -775,96 +771,6 @@ IIC::writeData(IICTag *blk, uint8_t *write_data, int size,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @todo This code can break if the src is evicted to get a tag for the dest.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
IIC::doCopy(Addr source, Addr dest, PacketList &writebacks)
|
|
||||||
{
|
|
||||||
//Copy unsuported now
|
|
||||||
#if 0
|
|
||||||
IICTag *dest_tag = findBlock(dest);
|
|
||||||
|
|
||||||
if (dest_tag) {
|
|
||||||
for (int i = 0; i < dest_tag->numData; ++i) {
|
|
||||||
if (--dataReferenceCount[dest_tag->data_ptr[i]] == 0) {
|
|
||||||
freeDataBlock(dest_tag->data_ptr[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Reset replacement entry
|
|
||||||
} else {
|
|
||||||
dest_tag = getFreeTag(hash(dest), writebacks);
|
|
||||||
dest_tag->re = (void*) repl->add(dest_tag - tagStore);
|
|
||||||
dest_tag->set = hash(dest);
|
|
||||||
dest_tag->tag = extractTag(dest);
|
|
||||||
dest_tag->status = BlkValid | BlkWritable;
|
|
||||||
}
|
|
||||||
// Find the source tag here since it might move if we need to find a
|
|
||||||
// tag for the destination.
|
|
||||||
IICTag *src_tag = findBlock(source);
|
|
||||||
assert(src_tag);
|
|
||||||
assert(!cache->doData() || src_tag->size <= trivialSize
|
|
||||||
|| src_tag->numData > 0);
|
|
||||||
// point dest to source data and inc counter
|
|
||||||
for (int i = 0; i < src_tag->numData; ++i) {
|
|
||||||
dest_tag->data_ptr[i] = src_tag->data_ptr[i];
|
|
||||||
++dataReferenceCount[dest_tag->data_ptr[i]];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maintain fast access data.
|
|
||||||
memcpy(dest_tag->data, src_tag->data, blkSize);
|
|
||||||
|
|
||||||
dest_tag->xc = src_tag->xc;
|
|
||||||
dest_tag->size = src_tag->size;
|
|
||||||
dest_tag->numData = src_tag->numData;
|
|
||||||
if (src_tag->numData == 0) {
|
|
||||||
// Data is stored in the trivial data, just copy it.
|
|
||||||
memcpy(dest_tag->trivialData, src_tag->trivialData, src_tag->size);
|
|
||||||
}
|
|
||||||
|
|
||||||
dest_tag->status |= BlkDirty;
|
|
||||||
if (dest_tag->size < blkSize) {
|
|
||||||
dest_tag->status |= BlkCompressed;
|
|
||||||
} else {
|
|
||||||
dest_tag->status &= ~BlkCompressed;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
IIC::fixCopy(Packet * &pkt, PacketList &writebacks)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
// if reference counter is greater than 1, do copy
|
|
||||||
// else do write
|
|
||||||
Addr blk_addr = blkAlign(pkt->getAddr);
|
|
||||||
IICTag* blk = findBlock(blk_addr);
|
|
||||||
|
|
||||||
if (blk->numData > 0 && dataReferenceCount[blk->data_ptr[0]] != 1) {
|
|
||||||
// copy the data
|
|
||||||
// Mark the block as referenced so it doesn't get replaced.
|
|
||||||
blk->status |= BlkReferenced;
|
|
||||||
for (int i = 0; i < blk->numData; ++i){
|
|
||||||
unsigned long new_data = getFreeDataBlock(writebacks);
|
|
||||||
// Need to refresh pointer
|
|
||||||
/**
|
|
||||||
* @todo Remove this refetch once we change IIC to pointer based
|
|
||||||
*/
|
|
||||||
blk = findBlock(blk_addr);
|
|
||||||
assert(blk);
|
|
||||||
if (cache->doData()) {
|
|
||||||
memcpy(&(dataBlks[new_data][0]),
|
|
||||||
&(dataBlks[blk->data_ptr[i]][0]),
|
|
||||||
subSize);
|
|
||||||
}
|
|
||||||
dataReferenceCount[blk->data_ptr[i]]--;
|
|
||||||
dataReferenceCount[new_data]++;
|
|
||||||
blk->data_ptr[i] = new_data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
IIC::cleanupRefs()
|
IIC::cleanupRefs()
|
||||||
{
|
{
|
||||||
|
|
16
src/mem/cache/tags/iic.hh
vendored
16
src/mem/cache/tags/iic.hh
vendored
|
@ -497,22 +497,6 @@ class IIC : public BaseTags
|
||||||
void writeData(IICTag *blk, uint8_t *data, int size,
|
void writeData(IICTag *blk, uint8_t *data, int size,
|
||||||
PacketList & writebacks);
|
PacketList & writebacks);
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform a block aligned copy from the source address to the destination.
|
|
||||||
* @param source The block-aligned source address.
|
|
||||||
* @param dest The block-aligned destination address.
|
|
||||||
* @param asid The address space DI.
|
|
||||||
* @param writebacks List for any generated writeback pktuests.
|
|
||||||
*/
|
|
||||||
void doCopy(Addr source, Addr dest, PacketList &writebacks);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If a block is currently marked copy on write, copy it before writing.
|
|
||||||
* @param pkt The write request.
|
|
||||||
* @param writebacks List for any generated writeback pktuests.
|
|
||||||
*/
|
|
||||||
void fixCopy(Packet * &pkt, PacketList &writebacks);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called at end of simulation to complete average block reference stats.
|
* Called at end of simulation to complete average block reference stats.
|
||||||
*/
|
*/
|
||||||
|
|
45
src/mem/cache/tags/lru.cc
vendored
45
src/mem/cache/tags/lru.cc
vendored
|
@ -250,51 +250,6 @@ LRU::invalidateBlk(Addr addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
LRU::doCopy(Addr source, Addr dest, PacketList &writebacks)
|
|
||||||
{
|
|
||||||
assert(source == blkAlign(source));
|
|
||||||
assert(dest == blkAlign(dest));
|
|
||||||
LRUBlk *source_blk = findBlock(source);
|
|
||||||
assert(source_blk);
|
|
||||||
LRUBlk *dest_blk = findBlock(dest);
|
|
||||||
if (dest_blk == NULL) {
|
|
||||||
// Need to do a replacement
|
|
||||||
Request *search = new Request(dest,1,0);
|
|
||||||
Packet * pkt = new Packet(search, Packet::ReadReq, -1);
|
|
||||||
BlkList dummy_list;
|
|
||||||
dest_blk = findReplacement(pkt, writebacks, dummy_list);
|
|
||||||
if (dest_blk->isValid() && dest_blk->isModified()) {
|
|
||||||
// Need to writeback data.
|
|
||||||
/* pkt = buildWritebackReq(regenerateBlkAddr(dest_blk->tag,
|
|
||||||
dest_blk->set),
|
|
||||||
dest_blk->req->asid,
|
|
||||||
dest_blk->xc,
|
|
||||||
blkSize,
|
|
||||||
dest_blk->data,
|
|
||||||
dest_blk->size);
|
|
||||||
*/
|
|
||||||
Request *writebackReq = new Request(regenerateBlkAddr(dest_blk->tag,
|
|
||||||
dest_blk->set),
|
|
||||||
blkSize, 0);
|
|
||||||
Packet *writeback = new Packet(writebackReq, Packet::Writeback, -1);
|
|
||||||
writeback->allocate();
|
|
||||||
memcpy(writeback->getPtr<uint8_t>(),dest_blk->data, blkSize);
|
|
||||||
writebacks.push_back(writeback);
|
|
||||||
}
|
|
||||||
dest_blk->tag = extractTag(dest);
|
|
||||||
delete search;
|
|
||||||
delete pkt;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @todo Can't assume the status once we have coherence on copies.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Set this block as readable, writeable, and dirty.
|
|
||||||
dest_blk->status = 7;
|
|
||||||
memcpy(dest_blk->data, source_blk->data, blkSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
LRU::cleanupRefs()
|
LRU::cleanupRefs()
|
||||||
{
|
{
|
||||||
|
|
16
src/mem/cache/tags/lru.hh
vendored
16
src/mem/cache/tags/lru.hh
vendored
|
@ -302,22 +302,6 @@ public:
|
||||||
blk->size = size;
|
blk->size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform a block aligned copy from the source address to the destination.
|
|
||||||
* @param source The block-aligned source address.
|
|
||||||
* @param dest The block-aligned destination address.
|
|
||||||
* @param asid The address space DI.
|
|
||||||
* @param writebacks List for any generated writeback pktuests.
|
|
||||||
*/
|
|
||||||
void doCopy(Addr source, Addr dest, PacketList &writebacks);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* No impl.
|
|
||||||
*/
|
|
||||||
void fixCopy(Packet * &pkt, PacketList &writebacks)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called at end of simulation to complete average block reference stats.
|
* Called at end of simulation to complete average block reference stats.
|
||||||
*/
|
*/
|
||||||
|
|
13
src/mem/cache/tags/split.cc
vendored
13
src/mem/cache/tags/split.cc
vendored
|
@ -421,19 +421,6 @@ Split::invalidateBlk(Addr addr)
|
||||||
tagsInUse--;
|
tagsInUse--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Split::doCopy(Addr source, Addr dest, PacketList &writebacks)
|
|
||||||
{
|
|
||||||
if (lru->probe( source))
|
|
||||||
lru->doCopy(source, dest, writebacks);
|
|
||||||
else {
|
|
||||||
if (lifo && lifo_net)
|
|
||||||
lifo_net->doCopy(source, dest, writebacks);
|
|
||||||
else if (lru_net)
|
|
||||||
lru_net->doCopy(source, dest, writebacks);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Split::cleanupRefs()
|
Split::cleanupRefs()
|
||||||
{
|
{
|
||||||
|
|
16
src/mem/cache/tags/split.hh
vendored
16
src/mem/cache/tags/split.hh
vendored
|
@ -310,22 +310,6 @@ class Split : public BaseTags
|
||||||
blk->size = size;
|
blk->size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform a block aligned copy from the source address to the destination.
|
|
||||||
* @param source The block-aligned source address.
|
|
||||||
* @param dest The block-aligned destination address.
|
|
||||||
* @param asid The address space DI.
|
|
||||||
* @param writebacks List for any generated writeback pktuests.
|
|
||||||
*/
|
|
||||||
void doCopy(Addr source, Addr dest, PacketList &writebacks);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* No impl.
|
|
||||||
*/
|
|
||||||
void fixCopy(Packet * &pkt, PacketList &writebacks)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called at end of simulation to complete average block reference stats.
|
* Called at end of simulation to complete average block reference stats.
|
||||||
*/
|
*/
|
||||||
|
|
46
src/mem/cache/tags/split_lifo.cc
vendored
46
src/mem/cache/tags/split_lifo.cc
vendored
|
@ -346,52 +346,6 @@ SplitLIFO::invalidateBlk(Addr addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
SplitLIFO::doCopy(Addr source, Addr dest, PacketList &writebacks)
|
|
||||||
{
|
|
||||||
//Copy Unsuported for now
|
|
||||||
#if 0
|
|
||||||
assert(source == blkAlign(source));
|
|
||||||
assert(dest == blkAlign(dest));
|
|
||||||
SplitBlk *source_blk = findBlock(source);
|
|
||||||
assert(source_blk);
|
|
||||||
SplitBlk *dest_blk = findBlock(dest);
|
|
||||||
if (dest_blk == NULL) {
|
|
||||||
// Need to do a replacement
|
|
||||||
Packet * pkt = new Packet();
|
|
||||||
pkt->paddr = dest;
|
|
||||||
BlkList dummy_list;
|
|
||||||
dest_blk = findReplacement(pkt, writebacks, dummy_list);
|
|
||||||
if (dest_blk->isValid() && dest_blk->isModified()) {
|
|
||||||
// Need to writeback data.
|
|
||||||
pkt = buildWritebackReq(regenerateBlkAddr(dest_blk->tag,
|
|
||||||
dest_blk->set),
|
|
||||||
dest_blk->xc,
|
|
||||||
blkSize,
|
|
||||||
(cache->doData())?dest_blk->data:0,
|
|
||||||
dest_blk->size);
|
|
||||||
writebacks.push_back(pkt);
|
|
||||||
}
|
|
||||||
dest_blk->tag = extractTag(dest);
|
|
||||||
/**
|
|
||||||
* @todo Do we need to pass in the execution context, or can we
|
|
||||||
* assume its the same?
|
|
||||||
*/
|
|
||||||
assert(source_blk->xc);
|
|
||||||
dest_blk->xc = source_blk->xc;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @todo Can't assume the status once we have coherence on copies.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Set this block as readable, writeable, and dirty.
|
|
||||||
dest_blk->status = 7;
|
|
||||||
if (cache->doData()) {
|
|
||||||
memcpy(dest_blk->data, source_blk->data, blkSize);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SplitLIFO::cleanupRefs()
|
SplitLIFO::cleanupRefs()
|
||||||
{
|
{
|
||||||
|
|
16
src/mem/cache/tags/split_lifo.hh
vendored
16
src/mem/cache/tags/split_lifo.hh
vendored
|
@ -325,22 +325,6 @@ public:
|
||||||
blk->size = size;
|
blk->size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform a block aligned copy from the source address to the destination.
|
|
||||||
* @param source The block-aligned source address.
|
|
||||||
* @param dest The block-aligned destination address.
|
|
||||||
* @param asid The address space DI.
|
|
||||||
* @param writebacks List for any generated writeback pktuests.
|
|
||||||
*/
|
|
||||||
void doCopy(Addr source, Addr dest, PacketList &writebacks);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* No impl.
|
|
||||||
*/
|
|
||||||
void fixCopy(Packet * &pkt, PacketList &writebacks)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called at end of simulation to complete average block reference stats.
|
* Called at end of simulation to complete average block reference stats.
|
||||||
*/
|
*/
|
||||||
|
|
46
src/mem/cache/tags/split_lru.cc
vendored
46
src/mem/cache/tags/split_lru.cc
vendored
|
@ -271,52 +271,6 @@ SplitLRU::invalidateBlk(Addr addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
SplitLRU::doCopy(Addr source, Addr dest, PacketList &writebacks)
|
|
||||||
{
|
|
||||||
//Copy not supported for now
|
|
||||||
#if 0
|
|
||||||
assert(source == blkAlign(source));
|
|
||||||
assert(dest == blkAlign(dest));
|
|
||||||
SplitBlk *source_blk = findBlock(source);
|
|
||||||
assert(source_blk);
|
|
||||||
SplitBlk *dest_blk = findBlock(dest);
|
|
||||||
if (dest_blk == NULL) {
|
|
||||||
// Need to do a replacement
|
|
||||||
Packet * pkt = new Packet();
|
|
||||||
pkt->paddr = dest;
|
|
||||||
BlkList dummy_list;
|
|
||||||
dest_blk = findReplacement(pkt, writebacks, dummy_list);
|
|
||||||
if (dest_blk->isValid() && dest_blk->isModified()) {
|
|
||||||
// Need to writeback data.
|
|
||||||
pkt = buildWritebackReq(regenerateBlkAddr(dest_blk->tag,
|
|
||||||
dest_blk->set),
|
|
||||||
dest_blk->xc,
|
|
||||||
blkSize,
|
|
||||||
(cache->doData())?dest_blk->data:0,
|
|
||||||
dest_blk->size);
|
|
||||||
writebacks.push_back(pkt);
|
|
||||||
}
|
|
||||||
dest_blk->tag = extractTag(dest);
|
|
||||||
/**
|
|
||||||
* @todo Do we need to pass in the execution context, or can we
|
|
||||||
* assume its the same?
|
|
||||||
*/
|
|
||||||
assert(source_blk->xc);
|
|
||||||
dest_blk->xc = source_blk->xc;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @todo Can't assume the status once we have coherence on copies.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Set this block as readable, writeable, and dirty.
|
|
||||||
dest_blk->status = 7;
|
|
||||||
if (cache->doData()) {
|
|
||||||
memcpy(dest_blk->data, source_blk->data, blkSize);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SplitLRU::cleanupRefs()
|
SplitLRU::cleanupRefs()
|
||||||
{
|
{
|
||||||
|
|
16
src/mem/cache/tags/split_lru.hh
vendored
16
src/mem/cache/tags/split_lru.hh
vendored
|
@ -308,22 +308,6 @@ public:
|
||||||
blk->size = size;
|
blk->size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform a block aligned copy from the source address to the destination.
|
|
||||||
* @param source The block-aligned source address.
|
|
||||||
* @param dest The block-aligned destination address.
|
|
||||||
* @param asid The address space DI.
|
|
||||||
* @param writebacks List for any generated writeback pktuests.
|
|
||||||
*/
|
|
||||||
void doCopy(Addr source, Addr dest, PacketList &writebacks);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* No impl.
|
|
||||||
*/
|
|
||||||
void fixCopy(Packet * &pkt, PacketList &writebacks)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called at end of simulation to complete average block reference stats.
|
* Called at end of simulation to complete average block reference stats.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
*
|
*
|
||||||
* Authors: Steve Reinhardt
|
* Authors: Steve Reinhardt
|
||||||
* Ron Dreslinski
|
* Ron Dreslinski
|
||||||
|
* Ali Saidi
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,6 +98,8 @@ PageTable::allocate(Addr vaddr, int64_t size)
|
||||||
// starting address must be page aligned
|
// starting address must be page aligned
|
||||||
assert(pageOffset(vaddr) == 0);
|
assert(pageOffset(vaddr) == 0);
|
||||||
|
|
||||||
|
DPRINTF(MMU, "Allocating Page: %#x-%#x\n", vaddr, vaddr+ size);
|
||||||
|
|
||||||
for (; size > 0; size -= pageSize, vaddr += pageSize) {
|
for (; size > 0; size -= pageSize, vaddr += pageSize) {
|
||||||
m5::hash_map<Addr,Addr>::iterator iter = pTable.find(vaddr);
|
m5::hash_map<Addr,Addr>::iterator iter = pTable.find(vaddr);
|
||||||
|
|
||||||
|
@ -159,3 +162,37 @@ PageTable::translate(RequestPtr &req)
|
||||||
req->setPaddr(paddr);
|
req->setPaddr(paddr);
|
||||||
return page_check(req->getPaddr(), req->getSize());
|
return page_check(req->getPaddr(), req->getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PageTable::serialize(std::ostream &os)
|
||||||
|
{
|
||||||
|
paramOut(os, "ptable.size", pTable.size());
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
m5::hash_map<Addr,Addr>::iterator iter;
|
||||||
|
while (iter != pTable.end()) {
|
||||||
|
paramOut(os, csprintf("ptable.entry%dvaddr", count),iter->first);
|
||||||
|
paramOut(os, csprintf("ptable.entry%dpaddr", count),iter->second);
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
assert(count == pTable.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PageTable::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
|
{
|
||||||
|
int i = 0, count;
|
||||||
|
paramIn(cp, section, "ptable.size", count);
|
||||||
|
Addr vaddr, paddr;
|
||||||
|
|
||||||
|
pTable.clear();
|
||||||
|
|
||||||
|
while(i < count) {
|
||||||
|
paramIn(cp, section, csprintf("ptable.entry%dvaddr", i), vaddr);
|
||||||
|
paramIn(cp, section, csprintf("ptable.entry%dpaddr", i), paddr);
|
||||||
|
pTable[vaddr] = paddr;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,8 @@ class PageTable
|
||||||
*/
|
*/
|
||||||
Fault translate(RequestPtr &req);
|
Fault translate(RequestPtr &req);
|
||||||
|
|
||||||
|
void serialize(std::ostream &os);
|
||||||
|
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,7 +4,7 @@ from Device import BasicPioDevice
|
||||||
|
|
||||||
class AlphaConsole(BasicPioDevice):
|
class AlphaConsole(BasicPioDevice):
|
||||||
type = 'AlphaConsole'
|
type = 'AlphaConsole'
|
||||||
cpu = Param.BaseCPU(Parent.any, "Processor")
|
cpu = Param.BaseCPU(Parent.cpu[0], "Processor")
|
||||||
disk = Param.SimpleDisk("Simple Disk")
|
disk = Param.SimpleDisk("Simple Disk")
|
||||||
sim_console = Param.SimConsole(Parent.any, "The Simulator Console")
|
sim_console = Param.SimConsole(Parent.any, "The Simulator Console")
|
||||||
system = Param.AlphaSystem(Parent.any, "system object")
|
system = Param.AlphaSystem(Parent.any, "system object")
|
||||||
|
|
|
@ -14,7 +14,6 @@ class BaseCache(MemObject):
|
||||||
"This cache connects to a compressed memory")
|
"This cache connects to a compressed memory")
|
||||||
compression_latency = Param.Latency('0ns',
|
compression_latency = Param.Latency('0ns',
|
||||||
"Latency in cycles of compression algorithm")
|
"Latency in cycles of compression algorithm")
|
||||||
do_copy = Param.Bool(False, "perform fast copies in the cache")
|
|
||||||
hash_delay = Param.Int(1, "time in cycles of hash access")
|
hash_delay = Param.Int(1, "time in cycles of hash access")
|
||||||
lifo = Param.Bool(False,
|
lifo = Param.Bool(False,
|
||||||
"whether this NIC partition should use LIFO repl. policy")
|
"whether this NIC partition should use LIFO repl. policy")
|
||||||
|
|
|
@ -3,4 +3,4 @@ from m5.params import *
|
||||||
from m5.proxy import *
|
from m5.proxy import *
|
||||||
class IntrControl(SimObject):
|
class IntrControl(SimObject):
|
||||||
type = 'IntrControl'
|
type = 'IntrControl'
|
||||||
cpu = Param.BaseCPU(Parent.any, "the cpu")
|
cpu = Param.BaseCPU(Parent.cpu[0], "the cpu")
|
||||||
|
|
|
@ -240,6 +240,41 @@ Process::sim_fd(int tgt_fd)
|
||||||
return fd_map[tgt_fd];
|
return fd_map[tgt_fd];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Process::serialize(std::ostream &os)
|
||||||
|
{
|
||||||
|
SERIALIZE_SCALAR(initialContextLoaded);
|
||||||
|
SERIALIZE_SCALAR(brk_point);
|
||||||
|
SERIALIZE_SCALAR(stack_base);
|
||||||
|
SERIALIZE_SCALAR(stack_size);
|
||||||
|
SERIALIZE_SCALAR(stack_min);
|
||||||
|
SERIALIZE_SCALAR(next_thread_stack_base);
|
||||||
|
SERIALIZE_SCALAR(mmap_start);
|
||||||
|
SERIALIZE_SCALAR(mmap_end);
|
||||||
|
SERIALIZE_SCALAR(nxm_start);
|
||||||
|
SERIALIZE_SCALAR(nxm_end);
|
||||||
|
SERIALIZE_ARRAY(fd_map, MAX_FD);
|
||||||
|
|
||||||
|
pTable->serialize(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Process::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
|
{
|
||||||
|
UNSERIALIZE_SCALAR(initialContextLoaded);
|
||||||
|
UNSERIALIZE_SCALAR(brk_point);
|
||||||
|
UNSERIALIZE_SCALAR(stack_base);
|
||||||
|
UNSERIALIZE_SCALAR(stack_size);
|
||||||
|
UNSERIALIZE_SCALAR(stack_min);
|
||||||
|
UNSERIALIZE_SCALAR(next_thread_stack_base);
|
||||||
|
UNSERIALIZE_SCALAR(mmap_start);
|
||||||
|
UNSERIALIZE_SCALAR(mmap_end);
|
||||||
|
UNSERIALIZE_SCALAR(nxm_start);
|
||||||
|
UNSERIALIZE_SCALAR(nxm_end);
|
||||||
|
UNSERIALIZE_ARRAY(fd_map, MAX_FD);
|
||||||
|
|
||||||
|
pTable->unserialize(cp, section);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -162,6 +162,9 @@ class Process : public SimObject
|
||||||
int sim_fd(int tgt_fd);
|
int sim_fd(int tgt_fd);
|
||||||
|
|
||||||
virtual void syscall(int64_t callnum, ThreadContext *tc) = 0;
|
virtual void syscall(int64_t callnum, ThreadContext *tc) = 0;
|
||||||
|
|
||||||
|
void serialize(std::ostream &os);
|
||||||
|
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -31,9 +31,6 @@ from m5.objects import *
|
||||||
m5.AddToPath('../configs/common')
|
m5.AddToPath('../configs/common')
|
||||||
import FSConfig
|
import FSConfig
|
||||||
|
|
||||||
AlphaConsole.cpu = Parent.cpu[0]
|
|
||||||
IntrControl.cpu = Parent.cpu[0]
|
|
||||||
|
|
||||||
cpus = [ AtomicSimpleCPU(cpu_id=i) for i in xrange(2) ]
|
cpus = [ AtomicSimpleCPU(cpu_id=i) for i in xrange(2) ]
|
||||||
system = FSConfig.makeLinuxAlphaSystem('atomic')
|
system = FSConfig.makeLinuxAlphaSystem('atomic')
|
||||||
system.cpu = cpus
|
system.cpu = cpus
|
||||||
|
|
|
@ -31,9 +31,6 @@ from m5.objects import *
|
||||||
m5.AddToPath('../configs/common')
|
m5.AddToPath('../configs/common')
|
||||||
import FSConfig
|
import FSConfig
|
||||||
|
|
||||||
AlphaConsole.cpu = Parent.cpu[0]
|
|
||||||
IntrControl.cpu = Parent.cpu[0]
|
|
||||||
|
|
||||||
cpus = [ TimingSimpleCPU(cpu_id=i) for i in xrange(2) ]
|
cpus = [ TimingSimpleCPU(cpu_id=i) for i in xrange(2) ]
|
||||||
system = FSConfig.makeLinuxAlphaSystem('timing')
|
system = FSConfig.makeLinuxAlphaSystem('timing')
|
||||||
system.cpu = cpus
|
system.cpu = cpus
|
||||||
|
|
Loading…
Reference in a new issue