Make memory commands dense again to avoid cache stat table explosion.
Created MemCmd class to wrap enum and provide handy methods to check attributes, convert to string/int, etc. --HG-- extra : convert_revision : 57f147ad893443e3a2040c6d5b4cdb1a8033930b
This commit is contained in:
parent
23d970e6b9
commit
997fc505a8
31 changed files with 447 additions and 403 deletions
|
@ -226,8 +226,8 @@ MemTest::completeRequest(PacketPtr pkt)
|
|||
assert(removeAddr != outstandingAddrs.end());
|
||||
outstandingAddrs.erase(removeAddr);
|
||||
|
||||
switch (pkt->cmd) {
|
||||
case Packet::ReadResp:
|
||||
switch (pkt->cmd.toInt()) {
|
||||
case MemCmd::ReadResp:
|
||||
|
||||
if (memcmp(pkt_data, data, pkt->getSize()) != 0) {
|
||||
cerr << name() << ": on read of 0x" << hex << req->getPaddr()
|
||||
|
@ -254,7 +254,7 @@ MemTest::completeRequest(PacketPtr pkt)
|
|||
exitSimLoop("Maximum number of loads reached!");
|
||||
break;
|
||||
|
||||
case Packet::WriteResp:
|
||||
case MemCmd::WriteResp:
|
||||
numWritesStat++;
|
||||
break;
|
||||
/*
|
||||
|
@ -389,7 +389,7 @@ MemTest::tick()
|
|||
<< dec << curTick << endl;
|
||||
}
|
||||
|
||||
PacketPtr pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast);
|
||||
PacketPtr pkt = new Packet(req, MemCmd::ReadReq, Packet::Broadcast);
|
||||
pkt->dataDynamicArray(new uint8_t[req->getSize()]);
|
||||
MemTestSenderState *state = new MemTestSenderState(result);
|
||||
pkt->senderState = state;
|
||||
|
@ -429,7 +429,7 @@ MemTest::tick()
|
|||
<< dec << curTick << endl;
|
||||
}
|
||||
*/
|
||||
PacketPtr pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
|
||||
PacketPtr pkt = new Packet(req, MemCmd::WriteReq, Packet::Broadcast);
|
||||
uint8_t *pkt_data = new uint8_t[req->getSize()];
|
||||
pkt->dataDynamicArray(pkt_data);
|
||||
memcpy(pkt_data, &data, req->getSize());
|
||||
|
|
|
@ -602,7 +602,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
|
|||
|
||||
// Build packet here.
|
||||
PacketPtr data_pkt = new Packet(mem_req,
|
||||
Packet::ReadReq, Packet::Broadcast);
|
||||
MemCmd::ReadReq, Packet::Broadcast);
|
||||
data_pkt->dataDynamicArray(new uint8_t[cacheBlkSize]);
|
||||
|
||||
cacheDataPC[tid] = block_PC;
|
||||
|
|
|
@ -574,7 +574,8 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
|
|||
"addr %#x, data %#x\n",
|
||||
store_idx, req->getVaddr(), data);
|
||||
|
||||
PacketPtr data_pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast);
|
||||
PacketPtr data_pkt = new Packet(req, MemCmd::ReadReq,
|
||||
Packet::Broadcast);
|
||||
data_pkt->dataStatic(load_inst->memData);
|
||||
|
||||
WritebackEvent *wb = new WritebackEvent(load_inst, data_pkt, this);
|
||||
|
@ -638,7 +639,7 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
|
|||
// if we the cache is not blocked, do cache access
|
||||
if (!lsq->cacheBlocked()) {
|
||||
PacketPtr data_pkt =
|
||||
new Packet(req, Packet::ReadReq, Packet::Broadcast);
|
||||
new Packet(req, MemCmd::ReadReq, Packet::Broadcast);
|
||||
data_pkt->dataStatic(load_inst->memData);
|
||||
|
||||
LSQSenderState *state = new LSQSenderState;
|
||||
|
|
|
@ -613,7 +613,8 @@ LSQUnit<Impl>::writebackStores()
|
|||
(sizeof(TheISA::IntReg) - req->getSize()) : 0),
|
||||
req->getSize());
|
||||
|
||||
PacketPtr data_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
|
||||
PacketPtr data_pkt = new Packet(req, MemCmd::WriteReq,
|
||||
Packet::Broadcast);
|
||||
data_pkt->dataStatic(inst->memData);
|
||||
|
||||
LSQSenderState *state = new LSQSenderState;
|
||||
|
|
|
@ -138,18 +138,18 @@ AtomicSimpleCPU::AtomicSimpleCPU(Params *p)
|
|||
|
||||
ifetch_req = new Request();
|
||||
ifetch_req->setThreadContext(p->cpu_id, 0); // Add thread ID if we add MT
|
||||
ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast);
|
||||
ifetch_pkt = new Packet(ifetch_req, MemCmd::ReadReq, Packet::Broadcast);
|
||||
ifetch_pkt->dataStatic(&inst);
|
||||
|
||||
data_read_req = new Request();
|
||||
data_read_req->setThreadContext(p->cpu_id, 0); // Add thread ID here too
|
||||
data_read_pkt = new Packet(data_read_req, Packet::ReadReq,
|
||||
data_read_pkt = new Packet(data_read_req, MemCmd::ReadReq,
|
||||
Packet::Broadcast);
|
||||
data_read_pkt->dataStatic(&dataReg);
|
||||
|
||||
data_write_req = new Request();
|
||||
data_write_req->setThreadContext(p->cpu_id, 0); // Add thread ID here too
|
||||
data_write_pkt = new Packet(data_write_req, Packet::WriteReq,
|
||||
data_write_pkt = new Packet(data_write_req, MemCmd::WriteReq,
|
||||
Packet::Broadcast);
|
||||
}
|
||||
|
||||
|
|
|
@ -286,7 +286,7 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
|
|||
// Now do the access.
|
||||
if (fault == NoFault) {
|
||||
PacketPtr pkt =
|
||||
new Packet(req, Packet::ReadReq, Packet::Broadcast);
|
||||
new Packet(req, MemCmd::ReadReq, Packet::Broadcast);
|
||||
pkt->dataDynamic<T>(new T);
|
||||
|
||||
if (!dcachePort.sendTiming(pkt)) {
|
||||
|
@ -365,7 +365,7 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
|
|||
// Now do the access.
|
||||
if (fault == NoFault) {
|
||||
assert(dcache_pkt == NULL);
|
||||
dcache_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
|
||||
dcache_pkt = new Packet(req, MemCmd::WriteReq, Packet::Broadcast);
|
||||
dcache_pkt->allocate();
|
||||
dcache_pkt->set(data);
|
||||
|
||||
|
@ -454,7 +454,7 @@ TimingSimpleCPU::fetch()
|
|||
ifetch_req->setThreadContext(cpu_id, /* thread ID */ 0);
|
||||
Fault fault = setupFetchRequest(ifetch_req);
|
||||
|
||||
ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast);
|
||||
ifetch_pkt = new Packet(ifetch_req, MemCmd::ReadReq, Packet::Broadcast);
|
||||
ifetch_pkt->dataStatic(&inst);
|
||||
|
||||
if (fault == NoFault) {
|
||||
|
|
|
@ -256,10 +256,13 @@ class DmaDevice : public PioDevice
|
|||
virtual ~DmaDevice();
|
||||
|
||||
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data)
|
||||
{ dmaPort->dmaAction(Packet::WriteInvalidateReq, addr, size, event, data) ; }
|
||||
{
|
||||
dmaPort->dmaAction(MemCmd::WriteInvalidateReq,
|
||||
addr, size, event, data);
|
||||
}
|
||||
|
||||
void dmaRead(Addr addr, int size, Event *event, uint8_t *data = NULL)
|
||||
{ dmaPort->dmaAction(Packet::ReadReq, addr, size, event, data); }
|
||||
{ dmaPort->dmaAction(MemCmd::ReadReq, addr, size, event, data); }
|
||||
|
||||
bool dmaPending() { return dmaPort->dmaPending(); }
|
||||
|
||||
|
|
59
src/mem/cache/base_cache.cc
vendored
59
src/mem/cache/base_cache.cc
vendored
|
@ -370,17 +370,12 @@ BaseCache::init()
|
|||
void
|
||||
BaseCache::regStats()
|
||||
{
|
||||
Request temp_req((Addr) NULL, 4, 0);
|
||||
Packet::Command temp_cmd = Packet::ReadReq;
|
||||
Packet temp_pkt(&temp_req, temp_cmd, 0); //@todo FIx command strings so this isn't neccessary
|
||||
temp_pkt.allocate(); //Temp allocate, all need data
|
||||
|
||||
using namespace Stats;
|
||||
|
||||
// Hit statistics
|
||||
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
|
||||
Packet::Command cmd = (Packet::Command)access_idx;
|
||||
const string &cstr = temp_pkt.cmdIdxToString(cmd);
|
||||
for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
|
||||
MemCmd cmd(access_idx);
|
||||
const string &cstr = cmd.toString();
|
||||
|
||||
hits[access_idx]
|
||||
.init(maxThreadsPerCPU)
|
||||
|
@ -395,20 +390,20 @@ BaseCache::regStats()
|
|||
.desc("number of demand (read+write) hits")
|
||||
.flags(total)
|
||||
;
|
||||
demandHits = hits[Packet::ReadReq] + hits[Packet::WriteReq];
|
||||
demandHits = hits[MemCmd::ReadReq] + hits[MemCmd::WriteReq];
|
||||
|
||||
overallHits
|
||||
.name(name() + ".overall_hits")
|
||||
.desc("number of overall hits")
|
||||
.flags(total)
|
||||
;
|
||||
overallHits = demandHits + hits[Packet::SoftPFReq] + hits[Packet::HardPFReq]
|
||||
+ hits[Packet::Writeback];
|
||||
overallHits = demandHits + hits[MemCmd::SoftPFReq] + hits[MemCmd::HardPFReq]
|
||||
+ hits[MemCmd::Writeback];
|
||||
|
||||
// Miss statistics
|
||||
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
|
||||
Packet::Command cmd = (Packet::Command)access_idx;
|
||||
const string &cstr = temp_pkt.cmdIdxToString(cmd);
|
||||
for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
|
||||
MemCmd cmd(access_idx);
|
||||
const string &cstr = cmd.toString();
|
||||
|
||||
misses[access_idx]
|
||||
.init(maxThreadsPerCPU)
|
||||
|
@ -423,20 +418,20 @@ BaseCache::regStats()
|
|||
.desc("number of demand (read+write) misses")
|
||||
.flags(total)
|
||||
;
|
||||
demandMisses = misses[Packet::ReadReq] + misses[Packet::WriteReq];
|
||||
demandMisses = misses[MemCmd::ReadReq] + misses[MemCmd::WriteReq];
|
||||
|
||||
overallMisses
|
||||
.name(name() + ".overall_misses")
|
||||
.desc("number of overall misses")
|
||||
.flags(total)
|
||||
;
|
||||
overallMisses = demandMisses + misses[Packet::SoftPFReq] +
|
||||
misses[Packet::HardPFReq] + misses[Packet::Writeback];
|
||||
overallMisses = demandMisses + misses[MemCmd::SoftPFReq] +
|
||||
misses[MemCmd::HardPFReq] + misses[MemCmd::Writeback];
|
||||
|
||||
// Miss latency statistics
|
||||
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
|
||||
Packet::Command cmd = (Packet::Command)access_idx;
|
||||
const string &cstr = temp_pkt.cmdIdxToString(cmd);
|
||||
for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
|
||||
MemCmd cmd(access_idx);
|
||||
const string &cstr = cmd.toString();
|
||||
|
||||
missLatency[access_idx]
|
||||
.init(maxThreadsPerCPU)
|
||||
|
@ -451,20 +446,20 @@ BaseCache::regStats()
|
|||
.desc("number of demand (read+write) miss cycles")
|
||||
.flags(total)
|
||||
;
|
||||
demandMissLatency = missLatency[Packet::ReadReq] + missLatency[Packet::WriteReq];
|
||||
demandMissLatency = missLatency[MemCmd::ReadReq] + missLatency[MemCmd::WriteReq];
|
||||
|
||||
overallMissLatency
|
||||
.name(name() + ".overall_miss_latency")
|
||||
.desc("number of overall miss cycles")
|
||||
.flags(total)
|
||||
;
|
||||
overallMissLatency = demandMissLatency + missLatency[Packet::SoftPFReq] +
|
||||
missLatency[Packet::HardPFReq];
|
||||
overallMissLatency = demandMissLatency + missLatency[MemCmd::SoftPFReq] +
|
||||
missLatency[MemCmd::HardPFReq];
|
||||
|
||||
// access formulas
|
||||
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
|
||||
Packet::Command cmd = (Packet::Command)access_idx;
|
||||
const string &cstr = temp_pkt.cmdIdxToString(cmd);
|
||||
for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
|
||||
MemCmd cmd(access_idx);
|
||||
const string &cstr = cmd.toString();
|
||||
|
||||
accesses[access_idx]
|
||||
.name(name() + "." + cstr + "_accesses")
|
||||
|
@ -490,9 +485,9 @@ BaseCache::regStats()
|
|||
overallAccesses = overallHits + overallMisses;
|
||||
|
||||
// miss rate formulas
|
||||
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
|
||||
Packet::Command cmd = (Packet::Command)access_idx;
|
||||
const string &cstr = temp_pkt.cmdIdxToString(cmd);
|
||||
for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
|
||||
MemCmd cmd(access_idx);
|
||||
const string &cstr = cmd.toString();
|
||||
|
||||
missRate[access_idx]
|
||||
.name(name() + "." + cstr + "_miss_rate")
|
||||
|
@ -518,9 +513,9 @@ BaseCache::regStats()
|
|||
overallMissRate = overallMisses / overallAccesses;
|
||||
|
||||
// miss latency formulas
|
||||
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
|
||||
Packet::Command cmd = (Packet::Command)access_idx;
|
||||
const string &cstr = temp_pkt.cmdIdxToString(cmd);
|
||||
for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
|
||||
MemCmd cmd(access_idx);
|
||||
const string &cstr = cmd.toString();
|
||||
|
||||
avgMissLatency[access_idx]
|
||||
.name(name() + "." + cstr + "_avg_miss_latency")
|
||||
|
|
16
src/mem/cache/base_cache.hh
vendored
16
src/mem/cache/base_cache.hh
vendored
|
@ -200,14 +200,14 @@ class BaseCache : public MemObject
|
|||
*/
|
||||
|
||||
/** Number of hits per thread for each type of command. @sa Packet::Command */
|
||||
Stats::Vector<> hits[NUM_MEM_CMDS];
|
||||
Stats::Vector<> hits[MemCmd::NUM_MEM_CMDS];
|
||||
/** Number of hits for demand accesses. */
|
||||
Stats::Formula demandHits;
|
||||
/** Number of hit for all accesses. */
|
||||
Stats::Formula overallHits;
|
||||
|
||||
/** Number of misses per thread for each type of command. @sa Packet::Command */
|
||||
Stats::Vector<> misses[NUM_MEM_CMDS];
|
||||
Stats::Vector<> misses[MemCmd::NUM_MEM_CMDS];
|
||||
/** Number of misses for demand accesses. */
|
||||
Stats::Formula demandMisses;
|
||||
/** Number of misses for all accesses. */
|
||||
|
@ -217,28 +217,28 @@ class BaseCache : public MemObject
|
|||
* Total number of cycles per thread/command spent waiting for a miss.
|
||||
* Used to calculate the average miss latency.
|
||||
*/
|
||||
Stats::Vector<> missLatency[NUM_MEM_CMDS];
|
||||
Stats::Vector<> missLatency[MemCmd::NUM_MEM_CMDS];
|
||||
/** Total number of cycles spent waiting for demand misses. */
|
||||
Stats::Formula demandMissLatency;
|
||||
/** Total number of cycles spent waiting for all misses. */
|
||||
Stats::Formula overallMissLatency;
|
||||
|
||||
/** The number of accesses per command and thread. */
|
||||
Stats::Formula accesses[NUM_MEM_CMDS];
|
||||
Stats::Formula accesses[MemCmd::NUM_MEM_CMDS];
|
||||
/** The number of demand accesses. */
|
||||
Stats::Formula demandAccesses;
|
||||
/** The number of overall accesses. */
|
||||
Stats::Formula overallAccesses;
|
||||
|
||||
/** The miss rate per command and thread. */
|
||||
Stats::Formula missRate[NUM_MEM_CMDS];
|
||||
Stats::Formula missRate[MemCmd::NUM_MEM_CMDS];
|
||||
/** The miss rate of all demand accesses. */
|
||||
Stats::Formula demandMissRate;
|
||||
/** The miss rate for all accesses. */
|
||||
Stats::Formula overallMissRate;
|
||||
|
||||
/** The average miss latency per command and thread. */
|
||||
Stats::Formula avgMissLatency[NUM_MEM_CMDS];
|
||||
Stats::Formula avgMissLatency[MemCmd::NUM_MEM_CMDS];
|
||||
/** The average miss latency for demand misses. */
|
||||
Stats::Formula demandAvgMissLatency;
|
||||
/** The average miss latency for all misses. */
|
||||
|
@ -535,7 +535,7 @@ class BaseCache : public MemObject
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (pkt->cmd != Packet::UpgradeReq)
|
||||
if (pkt->cmd != MemCmd::UpgradeReq)
|
||||
{
|
||||
delete pkt->req;
|
||||
delete pkt;
|
||||
|
@ -594,7 +594,7 @@ class BaseCache : public MemObject
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (pkt->cmd != Packet::UpgradeReq)
|
||||
if (pkt->cmd != MemCmd::UpgradeReq)
|
||||
{
|
||||
delete pkt->req;
|
||||
delete pkt;
|
||||
|
|
38
src/mem/cache/cache_impl.hh
vendored
38
src/mem/cache/cache_impl.hh
vendored
|
@ -90,7 +90,7 @@ Cache(const std::string &_name,
|
|||
coherence->setCache(this);
|
||||
prefetcher->setCache(this);
|
||||
invalidateReq = new Request((Addr) NULL, blkSize, 0);
|
||||
invalidatePkt = new Packet(invalidateReq, Packet::InvalidateReq, 0);
|
||||
invalidatePkt = new Packet(invalidateReq, MemCmd::InvalidateReq, 0);
|
||||
}
|
||||
|
||||
template<class TagStore, class Coherence>
|
||||
|
@ -239,7 +239,7 @@ Cache<TagStore,Coherence>::handleFill(BlkType *blk, PacketPtr &pkt,
|
|||
|
||||
target->flags |= SATISFIED;
|
||||
|
||||
if (target->cmd == Packet::InvalidateReq) {
|
||||
if (target->cmd == MemCmd::InvalidateReq) {
|
||||
tags->invalidateBlk(blk);
|
||||
blk = NULL;
|
||||
}
|
||||
|
@ -316,7 +316,7 @@ Cache<TagStore,Coherence>::handleFill(BlkType *blk, MSHR * mshr,
|
|||
Tick completion_time = tags->getHitLatency() +
|
||||
transfer_offset ? pkt->finishTime : pkt->firstWordTime;
|
||||
|
||||
if (target->cmd == Packet::InvalidateReq) {
|
||||
if (target->cmd == MemCmd::InvalidateReq) {
|
||||
//Mark the blk as invalid now, if it hasn't been already
|
||||
if (blk) {
|
||||
tags->invalidateBlk(blk);
|
||||
|
@ -430,7 +430,7 @@ Cache<TagStore,Coherence>::writebackBlk(BlkType *blk)
|
|||
|
||||
Request *writebackReq =
|
||||
new Request(tags->regenerateBlkAddr(blk->tag, blk->set), blkSize, 0);
|
||||
PacketPtr writeback = new Packet(writebackReq, Packet::Writeback, -1);
|
||||
PacketPtr writeback = new Packet(writebackReq, MemCmd::Writeback, -1);
|
||||
writeback->allocate();
|
||||
std::memcpy(writeback->getPtr<uint8_t>(),blk->data,blkSize);
|
||||
|
||||
|
@ -555,11 +555,11 @@ Cache<TagStore,Coherence>::access(PacketPtr &pkt)
|
|||
/** @todo make the fast write alloc (wh64) work with coherence. */
|
||||
/** @todo Do we want to do fast writes for writebacks as well? */
|
||||
if (!blk && pkt->getSize() >= blkSize && coherence->allowFastWrites() &&
|
||||
(pkt->cmd == Packet::WriteReq
|
||||
|| pkt->cmd == Packet::WriteInvalidateReq) ) {
|
||||
(pkt->cmd == MemCmd::WriteReq
|
||||
|| pkt->cmd == MemCmd::WriteInvalidateReq) ) {
|
||||
// not outstanding misses, can do this
|
||||
MSHR* outstanding_miss = missQueue->findMSHR(pkt->getAddr());
|
||||
if (pkt->cmd == Packet::WriteInvalidateReq || !outstanding_miss) {
|
||||
if (pkt->cmd == MemCmd::WriteInvalidateReq || !outstanding_miss) {
|
||||
if (outstanding_miss) {
|
||||
warn("WriteInv doing a fastallocate"
|
||||
"with an outstanding miss to the same address\n");
|
||||
|
@ -583,7 +583,7 @@ Cache<TagStore,Coherence>::access(PacketPtr &pkt)
|
|||
// clear dirty bit if write through
|
||||
if (pkt->needsResponse())
|
||||
respond(pkt, curTick+lat);
|
||||
if (pkt->cmd == Packet::Writeback) {
|
||||
if (pkt->cmd == MemCmd::Writeback) {
|
||||
//Signal that you can kill the pkt/req
|
||||
pkt->flags |= SATISFIED;
|
||||
}
|
||||
|
@ -610,7 +610,7 @@ Cache<TagStore,Coherence>::access(PacketPtr &pkt)
|
|||
missQueue->handleMiss(pkt, size, curTick + hitLatency);
|
||||
}
|
||||
|
||||
if (pkt->cmd == Packet::Writeback) {
|
||||
if (pkt->cmd == MemCmd::Writeback) {
|
||||
//Need to clean up the packet on a writeback miss, but leave the request
|
||||
delete pkt;
|
||||
}
|
||||
|
@ -627,11 +627,11 @@ Cache<TagStore,Coherence>::getPacket()
|
|||
PacketPtr pkt = missQueue->getPacket();
|
||||
if (pkt) {
|
||||
if (!pkt->req->isUncacheable()) {
|
||||
if (pkt->cmd == Packet::HardPFReq)
|
||||
misses[Packet::HardPFReq][0/*pkt->req->getThreadNum()*/]++;
|
||||
if (pkt->cmd == MemCmd::HardPFReq)
|
||||
misses[MemCmd::HardPFReq][0/*pkt->req->getThreadNum()*/]++;
|
||||
BlkType *blk = tags->findBlock(pkt->getAddr());
|
||||
Packet::Command cmd = coherence->getBusCmd(pkt->cmd,
|
||||
(blk)? blk->status : 0);
|
||||
MemCmd cmd =
|
||||
coherence->getBusCmd(pkt->cmd, (blk) ? blk->status : 0);
|
||||
missQueue->setBusCmd(pkt, cmd);
|
||||
}
|
||||
}
|
||||
|
@ -650,7 +650,7 @@ Cache<TagStore,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr,
|
|||
if (success && !(SIGNAL_NACK_HACK)) {
|
||||
//Remember if it was an upgrade because writeback MSHR's are removed
|
||||
//in Mark in Service
|
||||
bool upgrade = (mshr->pkt && mshr->pkt->cmd == Packet::UpgradeReq);
|
||||
bool upgrade = (mshr->pkt && mshr->pkt->cmd == MemCmd::UpgradeReq);
|
||||
|
||||
missQueue->markInService(mshr->pkt, mshr);
|
||||
|
||||
|
@ -775,8 +775,8 @@ Cache<TagStore,Coherence>::snoop(PacketPtr &pkt)
|
|||
if (mshr) {
|
||||
if (mshr->inService) {
|
||||
if ((mshr->pkt->isInvalidate() || !mshr->pkt->isCacheFill())
|
||||
&& (pkt->cmd != Packet::InvalidateReq
|
||||
&& pkt->cmd != Packet::WriteInvalidateReq)) {
|
||||
&& (pkt->cmd != MemCmd::InvalidateReq
|
||||
&& pkt->cmd != MemCmd::WriteInvalidateReq)) {
|
||||
//If the outstanding request was an invalidate
|
||||
//(upgrade,readex,..) Then we need to ACK the request
|
||||
//until we get the data Also NACK if the outstanding
|
||||
|
@ -982,11 +982,11 @@ Cache<TagStore,Coherence>::probe(PacketPtr &pkt, bool update,
|
|||
panic("Atomic access ran into outstanding MSHR's or WB's!");
|
||||
}
|
||||
if (!pkt->req->isUncacheable() /*Uncacheables just go through*/
|
||||
&& (pkt->cmd != Packet::Writeback)/*Writebacks on miss fall through*/) {
|
||||
&& (pkt->cmd != MemCmd::Writeback)/*Writebacks on miss fall through*/) {
|
||||
// Fetch the cache block to fill
|
||||
BlkType *blk = tags->findBlock(pkt->getAddr());
|
||||
Packet::Command temp_cmd = coherence->getBusCmd(pkt->cmd,
|
||||
(blk)? blk->status : 0);
|
||||
MemCmd temp_cmd =
|
||||
coherence->getBusCmd(pkt->cmd, (blk) ? blk->status : 0);
|
||||
|
||||
PacketPtr busPkt = new Packet(pkt->req,temp_cmd, -1, blkSize);
|
||||
|
||||
|
|
146
src/mem/cache/coherence/coherence_protocol.cc
vendored
146
src/mem/cache/coherence/coherence_protocol.cc
vendored
|
@ -47,7 +47,7 @@ using namespace std;
|
|||
|
||||
|
||||
CoherenceProtocol::StateTransition::StateTransition()
|
||||
: busCmd(Packet::InvalidCmd), newState(-1), snoopFunc(invalidTransition)
|
||||
: busCmd(MemCmd::InvalidCmd), newState(-1), snoopFunc(invalidTransition)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -59,132 +59,132 @@ CoherenceProtocol::regStats()
|
|||
// requestCount and snoopCount arrays, most of these are invalid,
|
||||
// so we just select the interesting ones to print here.
|
||||
|
||||
requestCount[Invalid][Packet::ReadReq]
|
||||
requestCount[Invalid][MemCmd::ReadReq]
|
||||
.name(name() + ".read_invalid")
|
||||
.desc("read misses to invalid blocks")
|
||||
;
|
||||
|
||||
requestCount[Invalid][Packet::WriteReq]
|
||||
requestCount[Invalid][MemCmd::WriteReq]
|
||||
.name(name() +".write_invalid")
|
||||
.desc("write misses to invalid blocks")
|
||||
;
|
||||
|
||||
requestCount[Invalid][Packet::SoftPFReq]
|
||||
requestCount[Invalid][MemCmd::SoftPFReq]
|
||||
.name(name() +".swpf_invalid")
|
||||
.desc("soft prefetch misses to invalid blocks")
|
||||
;
|
||||
|
||||
requestCount[Invalid][Packet::HardPFReq]
|
||||
requestCount[Invalid][MemCmd::HardPFReq]
|
||||
.name(name() +".hwpf_invalid")
|
||||
.desc("hard prefetch misses to invalid blocks")
|
||||
;
|
||||
|
||||
requestCount[Shared][Packet::WriteReq]
|
||||
requestCount[Shared][MemCmd::WriteReq]
|
||||
.name(name() + ".write_shared")
|
||||
.desc("write misses to shared blocks")
|
||||
;
|
||||
|
||||
requestCount[Owned][Packet::WriteReq]
|
||||
requestCount[Owned][MemCmd::WriteReq]
|
||||
.name(name() + ".write_owned")
|
||||
.desc("write misses to owned blocks")
|
||||
;
|
||||
|
||||
snoopCount[Shared][Packet::ReadReq]
|
||||
snoopCount[Shared][MemCmd::ReadReq]
|
||||
.name(name() + ".snoop_read_shared")
|
||||
.desc("read snoops on shared blocks")
|
||||
;
|
||||
|
||||
snoopCount[Shared][Packet::ReadExReq]
|
||||
snoopCount[Shared][MemCmd::ReadExReq]
|
||||
.name(name() + ".snoop_readex_shared")
|
||||
.desc("readEx snoops on shared blocks")
|
||||
;
|
||||
|
||||
snoopCount[Shared][Packet::UpgradeReq]
|
||||
snoopCount[Shared][MemCmd::UpgradeReq]
|
||||
.name(name() + ".snoop_upgrade_shared")
|
||||
.desc("upgradee snoops on shared blocks")
|
||||
;
|
||||
|
||||
snoopCount[Modified][Packet::ReadReq]
|
||||
snoopCount[Modified][MemCmd::ReadReq]
|
||||
.name(name() + ".snoop_read_modified")
|
||||
.desc("read snoops on modified blocks")
|
||||
;
|
||||
|
||||
snoopCount[Modified][Packet::ReadExReq]
|
||||
snoopCount[Modified][MemCmd::ReadExReq]
|
||||
.name(name() + ".snoop_readex_modified")
|
||||
.desc("readEx snoops on modified blocks")
|
||||
;
|
||||
|
||||
snoopCount[Owned][Packet::ReadReq]
|
||||
snoopCount[Owned][MemCmd::ReadReq]
|
||||
.name(name() + ".snoop_read_owned")
|
||||
.desc("read snoops on owned blocks")
|
||||
;
|
||||
|
||||
snoopCount[Owned][Packet::ReadExReq]
|
||||
snoopCount[Owned][MemCmd::ReadExReq]
|
||||
.name(name() + ".snoop_readex_owned")
|
||||
.desc("readEx snoops on owned blocks")
|
||||
;
|
||||
|
||||
snoopCount[Owned][Packet::UpgradeReq]
|
||||
snoopCount[Owned][MemCmd::UpgradeReq]
|
||||
.name(name() + ".snoop_upgrade_owned")
|
||||
.desc("upgrade snoops on owned blocks")
|
||||
;
|
||||
|
||||
snoopCount[Exclusive][Packet::ReadReq]
|
||||
snoopCount[Exclusive][MemCmd::ReadReq]
|
||||
.name(name() + ".snoop_read_exclusive")
|
||||
.desc("read snoops on exclusive blocks")
|
||||
;
|
||||
|
||||
snoopCount[Exclusive][Packet::ReadExReq]
|
||||
snoopCount[Exclusive][MemCmd::ReadExReq]
|
||||
.name(name() + ".snoop_readex_exclusive")
|
||||
.desc("readEx snoops on exclusive blocks")
|
||||
;
|
||||
|
||||
snoopCount[Shared][Packet::InvalidateReq]
|
||||
snoopCount[Shared][MemCmd::InvalidateReq]
|
||||
.name(name() + ".snoop_inv_shared")
|
||||
.desc("Invalidate snoops on shared blocks")
|
||||
;
|
||||
|
||||
snoopCount[Owned][Packet::InvalidateReq]
|
||||
snoopCount[Owned][MemCmd::InvalidateReq]
|
||||
.name(name() + ".snoop_inv_owned")
|
||||
.desc("Invalidate snoops on owned blocks")
|
||||
;
|
||||
|
||||
snoopCount[Exclusive][Packet::InvalidateReq]
|
||||
snoopCount[Exclusive][MemCmd::InvalidateReq]
|
||||
.name(name() + ".snoop_inv_exclusive")
|
||||
.desc("Invalidate snoops on exclusive blocks")
|
||||
;
|
||||
|
||||
snoopCount[Modified][Packet::InvalidateReq]
|
||||
snoopCount[Modified][MemCmd::InvalidateReq]
|
||||
.name(name() + ".snoop_inv_modified")
|
||||
.desc("Invalidate snoops on modified blocks")
|
||||
;
|
||||
|
||||
snoopCount[Invalid][Packet::InvalidateReq]
|
||||
snoopCount[Invalid][MemCmd::InvalidateReq]
|
||||
.name(name() + ".snoop_inv_invalid")
|
||||
.desc("Invalidate snoops on invalid blocks")
|
||||
;
|
||||
|
||||
snoopCount[Shared][Packet::WriteInvalidateReq]
|
||||
snoopCount[Shared][MemCmd::WriteInvalidateReq]
|
||||
.name(name() + ".snoop_writeinv_shared")
|
||||
.desc("WriteInvalidate snoops on shared blocks")
|
||||
;
|
||||
|
||||
snoopCount[Owned][Packet::WriteInvalidateReq]
|
||||
snoopCount[Owned][MemCmd::WriteInvalidateReq]
|
||||
.name(name() + ".snoop_writeinv_owned")
|
||||
.desc("WriteInvalidate snoops on owned blocks")
|
||||
;
|
||||
|
||||
snoopCount[Exclusive][Packet::WriteInvalidateReq]
|
||||
snoopCount[Exclusive][MemCmd::WriteInvalidateReq]
|
||||
.name(name() + ".snoop_writeinv_exclusive")
|
||||
.desc("WriteInvalidate snoops on exclusive blocks")
|
||||
;
|
||||
|
||||
snoopCount[Modified][Packet::WriteInvalidateReq]
|
||||
snoopCount[Modified][MemCmd::WriteInvalidateReq]
|
||||
.name(name() + ".snoop_writeinv_modified")
|
||||
.desc("WriteInvalidate snoops on modified blocks")
|
||||
;
|
||||
|
||||
snoopCount[Invalid][Packet::WriteInvalidateReq]
|
||||
snoopCount[Invalid][MemCmd::WriteInvalidateReq]
|
||||
.name(name() + ".snoop_writeinv_invalid")
|
||||
.desc("WriteInvalidate snoops on invalid blocks")
|
||||
;
|
||||
|
@ -278,11 +278,13 @@ CoherenceProtocol::CoherenceProtocol(const string &name,
|
|||
}
|
||||
|
||||
// set up a few shortcuts to save typing & visual clutter
|
||||
typedef Packet P;
|
||||
StateTransition (&tt)[stateMax+1][NUM_MEM_CMDS] = transitionTable;
|
||||
typedef MemCmd MC;
|
||||
StateTransition (&tt)[stateMax+1][MC::NUM_MEM_CMDS] = transitionTable;
|
||||
|
||||
P::Command writeToSharedCmd = doUpgrades ? P::UpgradeReq : P::ReadExReq;
|
||||
P::Command writeToSharedResp = doUpgrades ? P::UpgradeReq : P::ReadExResp;
|
||||
MC::Command writeToSharedCmd =
|
||||
doUpgrades ? MC::UpgradeReq : MC::ReadExReq;
|
||||
MC::Command writeToSharedResp =
|
||||
doUpgrades ? MC::UpgradeReq : MC::ReadExResp;
|
||||
|
||||
// Note that all transitions by default cause a panic.
|
||||
// Override the valid transitions with the appropriate actions here.
|
||||
|
@ -290,34 +292,34 @@ CoherenceProtocol::CoherenceProtocol(const string &name,
|
|||
//
|
||||
// ----- incoming requests: specify outgoing bus request -----
|
||||
//
|
||||
tt[Invalid][P::ReadReq].onRequest(P::ReadReq);
|
||||
tt[Invalid][MC::ReadReq].onRequest(MC::ReadReq);
|
||||
// we only support write allocate right now
|
||||
tt[Invalid][P::WriteReq].onRequest(P::ReadExReq);
|
||||
tt[Shared][P::WriteReq].onRequest(writeToSharedCmd);
|
||||
tt[Invalid][MC::WriteReq].onRequest(MC::ReadExReq);
|
||||
tt[Shared][MC::WriteReq].onRequest(writeToSharedCmd);
|
||||
if (hasOwned) {
|
||||
tt[Owned][P::WriteReq].onRequest(writeToSharedCmd);
|
||||
tt[Owned][MC::WriteReq].onRequest(writeToSharedCmd);
|
||||
}
|
||||
|
||||
// Prefetching causes a read
|
||||
tt[Invalid][P::SoftPFReq].onRequest(P::ReadReq);
|
||||
tt[Invalid][P::HardPFReq].onRequest(P::ReadReq);
|
||||
tt[Invalid][MC::SoftPFReq].onRequest(MC::ReadReq);
|
||||
tt[Invalid][MC::HardPFReq].onRequest(MC::ReadReq);
|
||||
|
||||
//
|
||||
// ----- on response to given request: specify new state -----
|
||||
//
|
||||
tt[Invalid][P::ReadExResp].onResponse(Modified);
|
||||
tt[Invalid][MC::ReadExResp].onResponse(Modified);
|
||||
tt[Shared][writeToSharedResp].onResponse(Modified);
|
||||
// Go to Exclusive state on read response if we have one (will
|
||||
// move into shared if the shared line is asserted in the
|
||||
// getNewState function)
|
||||
//
|
||||
// originally had this as:
|
||||
// tt[Invalid][P::ReadResp].onResponse(hasExclusive ? Exclusive: Shared);
|
||||
// tt[Invalid][MC::ReadResp].onResponse(hasExclusive ? Exclusive: Shared);
|
||||
// ...but for some reason that caused a link error...
|
||||
if (hasExclusive) {
|
||||
tt[Invalid][P::ReadResp].onResponse(Exclusive);
|
||||
tt[Invalid][MC::ReadResp].onResponse(Exclusive);
|
||||
} else {
|
||||
tt[Invalid][P::ReadResp].onResponse(Shared);
|
||||
tt[Invalid][MC::ReadResp].onResponse(Shared);
|
||||
}
|
||||
if (hasOwned) {
|
||||
tt[Owned][writeToSharedResp].onResponse(Modified);
|
||||
|
@ -326,58 +328,58 @@ CoherenceProtocol::CoherenceProtocol(const string &name,
|
|||
//
|
||||
// ----- bus snoop transition functions -----
|
||||
//
|
||||
tt[Invalid][P::ReadReq].onSnoop(nullTransition);
|
||||
tt[Invalid][P::ReadExReq].onSnoop(nullTransition);
|
||||
tt[Invalid][P::InvalidateReq].onSnoop(invalidateTrans);
|
||||
tt[Invalid][P::WriteInvalidateReq].onSnoop(invalidateTrans);
|
||||
tt[Shared][P::ReadReq].onSnoop(hasExclusive
|
||||
tt[Invalid][MC::ReadReq].onSnoop(nullTransition);
|
||||
tt[Invalid][MC::ReadExReq].onSnoop(nullTransition);
|
||||
tt[Invalid][MC::InvalidateReq].onSnoop(invalidateTrans);
|
||||
tt[Invalid][MC::WriteInvalidateReq].onSnoop(invalidateTrans);
|
||||
tt[Shared][MC::ReadReq].onSnoop(hasExclusive
|
||||
? assertShared : nullTransition);
|
||||
tt[Shared][P::ReadExReq].onSnoop(invalidateTrans);
|
||||
tt[Shared][P::InvalidateReq].onSnoop(invalidateTrans);
|
||||
tt[Shared][P::WriteInvalidateReq].onSnoop(invalidateTrans);
|
||||
tt[Shared][MC::ReadExReq].onSnoop(invalidateTrans);
|
||||
tt[Shared][MC::InvalidateReq].onSnoop(invalidateTrans);
|
||||
tt[Shared][MC::WriteInvalidateReq].onSnoop(invalidateTrans);
|
||||
if (doUpgrades) {
|
||||
tt[Invalid][P::UpgradeReq].onSnoop(nullTransition);
|
||||
tt[Shared][P::UpgradeReq].onSnoop(invalidateTrans);
|
||||
tt[Invalid][MC::UpgradeReq].onSnoop(nullTransition);
|
||||
tt[Shared][MC::UpgradeReq].onSnoop(invalidateTrans);
|
||||
}
|
||||
tt[Modified][P::ReadExReq].onSnoop(supplyAndInvalidateTrans);
|
||||
tt[Modified][P::ReadReq].onSnoop(hasOwned
|
||||
tt[Modified][MC::ReadExReq].onSnoop(supplyAndInvalidateTrans);
|
||||
tt[Modified][MC::ReadReq].onSnoop(hasOwned
|
||||
? supplyAndGotoOwnedTrans
|
||||
: supplyAndGotoSharedTrans);
|
||||
tt[Modified][P::InvalidateReq].onSnoop(invalidateTrans);
|
||||
tt[Modified][P::WriteInvalidateReq].onSnoop(invalidateTrans);
|
||||
tt[Modified][MC::InvalidateReq].onSnoop(invalidateTrans);
|
||||
tt[Modified][MC::WriteInvalidateReq].onSnoop(invalidateTrans);
|
||||
|
||||
if (hasExclusive) {
|
||||
tt[Exclusive][P::ReadReq].onSnoop(assertShared);
|
||||
tt[Exclusive][P::ReadExReq].onSnoop(invalidateTrans);
|
||||
tt[Exclusive][P::InvalidateReq].onSnoop(invalidateTrans);
|
||||
tt[Exclusive][P::WriteInvalidateReq].onSnoop(invalidateTrans);
|
||||
tt[Exclusive][MC::ReadReq].onSnoop(assertShared);
|
||||
tt[Exclusive][MC::ReadExReq].onSnoop(invalidateTrans);
|
||||
tt[Exclusive][MC::InvalidateReq].onSnoop(invalidateTrans);
|
||||
tt[Exclusive][MC::WriteInvalidateReq].onSnoop(invalidateTrans);
|
||||
}
|
||||
|
||||
if (hasOwned) {
|
||||
tt[Owned][P::ReadReq].onSnoop(supplyAndGotoOwnedTrans);
|
||||
tt[Owned][P::ReadExReq].onSnoop(supplyAndInvalidateTrans);
|
||||
tt[Owned][P::UpgradeReq].onSnoop(invalidateTrans);
|
||||
tt[Owned][P::InvalidateReq].onSnoop(invalidateTrans);
|
||||
tt[Owned][P::WriteInvalidateReq].onSnoop(invalidateTrans);
|
||||
tt[Owned][MC::ReadReq].onSnoop(supplyAndGotoOwnedTrans);
|
||||
tt[Owned][MC::ReadExReq].onSnoop(supplyAndInvalidateTrans);
|
||||
tt[Owned][MC::UpgradeReq].onSnoop(invalidateTrans);
|
||||
tt[Owned][MC::InvalidateReq].onSnoop(invalidateTrans);
|
||||
tt[Owned][MC::WriteInvalidateReq].onSnoop(invalidateTrans);
|
||||
}
|
||||
|
||||
// @todo add in hardware prefetch to this list
|
||||
}
|
||||
|
||||
|
||||
Packet::Command
|
||||
CoherenceProtocol::getBusCmd(Packet::Command cmdIn, CacheBlk::State state,
|
||||
MemCmd
|
||||
CoherenceProtocol::getBusCmd(MemCmd cmdIn, CacheBlk::State state,
|
||||
MSHR *mshr)
|
||||
{
|
||||
state &= stateMask;
|
||||
int cmd_idx = (int) cmdIn;
|
||||
int cmd_idx = cmdIn.toInt();
|
||||
|
||||
assert(0 <= state && state <= stateMax);
|
||||
assert(0 <= cmd_idx && cmd_idx < NUM_MEM_CMDS);
|
||||
assert(0 <= cmd_idx && cmd_idx < MemCmd::NUM_MEM_CMDS);
|
||||
|
||||
Packet::Command cmdOut = transitionTable[state][cmd_idx].busCmd;
|
||||
MemCmd::Command cmdOut = transitionTable[state][cmd_idx].busCmd;
|
||||
|
||||
assert(cmdOut != Packet::InvalidCmd);
|
||||
assert(cmdOut != MemCmd::InvalidCmd);
|
||||
|
||||
++requestCount[state][cmd_idx];
|
||||
|
||||
|
@ -392,7 +394,7 @@ CoherenceProtocol::getNewState(PacketPtr &pkt, CacheBlk::State oldState)
|
|||
int cmd_idx = pkt->cmdToIndex();
|
||||
|
||||
assert(0 <= state && state <= stateMax);
|
||||
assert(0 <= cmd_idx && cmd_idx < NUM_MEM_CMDS);
|
||||
assert(0 <= cmd_idx && cmd_idx < MemCmd::NUM_MEM_CMDS);
|
||||
|
||||
CacheBlk::State newState = transitionTable[state][cmd_idx].newState;
|
||||
|
||||
|
@ -425,7 +427,7 @@ CoherenceProtocol::handleBusRequest(BaseCache *cache, PacketPtr &pkt,
|
|||
int cmd_idx = pkt->cmdToIndex();
|
||||
|
||||
assert(0 <= state && state <= stateMax);
|
||||
assert(0 <= cmd_idx && cmd_idx < NUM_MEM_CMDS);
|
||||
assert(0 <= cmd_idx && cmd_idx < MemCmd::NUM_MEM_CMDS);
|
||||
|
||||
// assert(mshr == NULL); // can't currently handle outstanding requests
|
||||
//Check first if MSHR, and also insure, if there is one, that it is not in service
|
||||
|
|
|
@ -80,7 +80,7 @@ class CoherenceProtocol : public SimObject
|
|||
* @param mshr The MSHR matching the request.
|
||||
* @return The proper bus command, as determined by the protocol.
|
||||
*/
|
||||
Packet::Command getBusCmd(Packet::Command cmd, CacheBlk::State status,
|
||||
MemCmd getBusCmd(MemCmd cmd, CacheBlk::State status,
|
||||
MSHR *mshr = NULL);
|
||||
|
||||
/**
|
||||
|
@ -235,7 +235,7 @@ class CoherenceProtocol : public SimObject
|
|||
* The table of all possible transitions, organized by starting state and
|
||||
* request command.
|
||||
*/
|
||||
StateTransition transitionTable[stateMax+1][NUM_MEM_CMDS];
|
||||
StateTransition transitionTable[stateMax+1][MemCmd::NUM_MEM_CMDS];
|
||||
|
||||
/**
|
||||
* @addtogroup CoherenceStatistics
|
||||
|
@ -244,11 +244,11 @@ class CoherenceProtocol : public SimObject
|
|||
/**
|
||||
* State accesses from parent cache.
|
||||
*/
|
||||
Stats::Scalar<> requestCount[stateMax+1][NUM_MEM_CMDS];
|
||||
Stats::Scalar<> requestCount[stateMax+1][MemCmd::NUM_MEM_CMDS];
|
||||
/**
|
||||
* State accesses from snooped requests.
|
||||
*/
|
||||
Stats::Scalar<> snoopCount[stateMax+1][NUM_MEM_CMDS];
|
||||
Stats::Scalar<> snoopCount[stateMax+1][MemCmd::NUM_MEM_CMDS];
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
7
src/mem/cache/coherence/simple_coherence.hh
vendored
7
src/mem/cache/coherence/simple_coherence.hh
vendored
|
@ -131,7 +131,7 @@ class SimpleCoherence
|
|||
//Got rid of, there could be an MSHR, but it can't be in service
|
||||
if (blk != NULL)
|
||||
{
|
||||
if (pkt->cmd != Packet::Writeback) {
|
||||
if (pkt->cmd != MemCmd::Writeback) {
|
||||
return protocol->handleBusRequest(cache, pkt, blk, mshr,
|
||||
new_state);
|
||||
}
|
||||
|
@ -148,9 +148,10 @@ class SimpleCoherence
|
|||
* @param state The current state of the cache block.
|
||||
* @return The proper bus command, as determined by the protocol.
|
||||
*/
|
||||
Packet::Command getBusCmd(Packet::Command &cmd, CacheBlk::State state)
|
||||
MemCmd getBusCmd(MemCmd cmd,
|
||||
CacheBlk::State state)
|
||||
{
|
||||
if (cmd == Packet::Writeback) return Packet::Writeback;
|
||||
if (cmd == MemCmd::Writeback) return MemCmd::Writeback;
|
||||
return protocol->getBusCmd(cmd, state);
|
||||
}
|
||||
|
||||
|
|
8
src/mem/cache/coherence/uni_coherence.cc
vendored
8
src/mem/cache/coherence/uni_coherence.cc
vendored
|
@ -99,19 +99,19 @@ UniCoherence::propogateInvalidate(PacketPtr pkt, bool isTiming)
|
|||
if (isTiming) {
|
||||
// Forward to other caches
|
||||
Request* req = new Request(pkt->req->getPaddr(), pkt->getSize(), 0);
|
||||
PacketPtr tmp = new Packet(req, Packet::InvalidateReq, -1);
|
||||
PacketPtr tmp = new Packet(req, MemCmd::InvalidateReq, -1);
|
||||
cshrs.allocate(tmp);
|
||||
cache->setSlaveRequest(Request_Coherence, curTick);
|
||||
if (cshrs.isFull())
|
||||
cache->setBlockedForSnoop(Blocked_Coherence);
|
||||
}
|
||||
else {
|
||||
PacketPtr tmp = new Packet(pkt->req, Packet::InvalidateReq, -1);
|
||||
PacketPtr tmp = new Packet(pkt->req, MemCmd::InvalidateReq, -1);
|
||||
cache->cpuSidePort->sendAtomic(tmp);
|
||||
delete tmp;
|
||||
}
|
||||
/**/
|
||||
/* PacketPtr tmp = new Packet(pkt->req, Packet::InvalidateReq, -1);
|
||||
/* PacketPtr tmp = new Packet(pkt->req, MemCmd::InvalidateReq, -1);
|
||||
cache->cpuSidePort->sendFunctional(tmp);
|
||||
delete tmp;
|
||||
*/
|
||||
|
@ -119,7 +119,7 @@ UniCoherence::propogateInvalidate(PacketPtr pkt, bool isTiming)
|
|||
if (pkt->isRead()) {
|
||||
/*For now we will see if someone above us has the data by
|
||||
doing a functional access on reads. Fix this later */
|
||||
PacketPtr tmp = new Packet(pkt->req, Packet::ReadReq, -1);
|
||||
PacketPtr tmp = new Packet(pkt->req, MemCmd::ReadReq, -1);
|
||||
tmp->allocate();
|
||||
cache->cpuSidePort->sendFunctional(tmp);
|
||||
bool hit = (tmp->result == Packet::Success);
|
||||
|
|
12
src/mem/cache/coherence/uni_coherence.hh
vendored
12
src/mem/cache/coherence/uni_coherence.hh
vendored
|
@ -77,13 +77,13 @@ class UniCoherence
|
|||
* @return The proper bus command, as determined by the protocol.
|
||||
* @todo Make changes so writebacks don't get here.
|
||||
*/
|
||||
Packet::Command getBusCmd(Packet::Command &cmd, CacheBlk::State state)
|
||||
MemCmd getBusCmd(MemCmd cmd, CacheBlk::State state)
|
||||
{
|
||||
if (cmd == Packet::HardPFReq && state)
|
||||
if (cmd == MemCmd::HardPFReq && state)
|
||||
warn("Trying to issue a prefetch to a block we already have\n");
|
||||
if (cmd == Packet::Writeback)
|
||||
return Packet::Writeback;
|
||||
return Packet::ReadReq;
|
||||
if (cmd == MemCmd::Writeback)
|
||||
return MemCmd::Writeback;
|
||||
return MemCmd::ReadReq;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -96,7 +96,7 @@ class UniCoherence
|
|||
{
|
||||
if (pkt->senderState) //Blocking Buffers don't get mshrs
|
||||
{
|
||||
if (((MSHR *)(pkt->senderState))->originalCmd == Packet::HardPFReq) {
|
||||
if (((MSHR *)(pkt->senderState))->originalCmd == MemCmd::HardPFReq) {
|
||||
DPRINTF(HWPrefetch, "Marking a hardware prefetch as such in the state\n");
|
||||
return BlkHWPrefetched | BlkValid | BlkWritable;
|
||||
}
|
||||
|
|
4
src/mem/cache/miss/blocking_buffer.cc
vendored
4
src/mem/cache/miss/blocking_buffer.cc
vendored
|
@ -90,7 +90,7 @@ BlockingBuffer::getPacket()
|
|||
}
|
||||
|
||||
void
|
||||
BlockingBuffer::setBusCmd(PacketPtr &pkt, Packet::Command cmd)
|
||||
BlockingBuffer::setBusCmd(PacketPtr &pkt, MemCmd cmd)
|
||||
{
|
||||
MSHR *mshr = (MSHR*) pkt->senderState;
|
||||
mshr->originalCmd = pkt->cmd;
|
||||
|
@ -189,7 +189,7 @@ BlockingBuffer::doWriteback(Addr addr,
|
|||
{
|
||||
// Generate request
|
||||
Request * req = new Request(addr, size, 0);
|
||||
PacketPtr pkt = new Packet(req, Packet::Writeback, -1);
|
||||
PacketPtr pkt = new Packet(req, MemCmd::Writeback, -1);
|
||||
pkt->allocate();
|
||||
if (data) {
|
||||
std::memcpy(pkt->getPtr<uint8_t>(), data, size);
|
||||
|
|
2
src/mem/cache/miss/blocking_buffer.hh
vendored
2
src/mem/cache/miss/blocking_buffer.hh
vendored
|
@ -104,7 +104,7 @@ public:
|
|||
* @param pkt The request to update.
|
||||
* @param cmd The bus command to use.
|
||||
*/
|
||||
void setBusCmd(PacketPtr &pkt, Packet::Command cmd);
|
||||
void setBusCmd(PacketPtr &pkt, MemCmd cmd);
|
||||
|
||||
/**
|
||||
* Restore the original command in case of a bus transmission error.
|
||||
|
|
2
src/mem/cache/miss/miss_buffer.hh
vendored
2
src/mem/cache/miss/miss_buffer.hh
vendored
|
@ -123,7 +123,7 @@ class MissBuffer
|
|||
* @param pkt The request to update.
|
||||
* @param cmd The bus command to use.
|
||||
*/
|
||||
virtual void setBusCmd(PacketPtr &pkt, Packet::Command cmd) = 0;
|
||||
virtual void setBusCmd(PacketPtr &pkt, MemCmd cmd) = 0;
|
||||
|
||||
/**
|
||||
* Restore the original command in case of a bus transmission error.
|
||||
|
|
111
src/mem/cache/miss/miss_queue.cc
vendored
111
src/mem/cache/miss/miss_queue.cc
vendored
|
@ -67,17 +67,12 @@ MissQueue::regStats(const string &name)
|
|||
{
|
||||
MissBuffer::regStats(name);
|
||||
|
||||
Request temp_req((Addr) NULL, 4, 0);
|
||||
Packet::Command temp_cmd = Packet::ReadReq;
|
||||
Packet temp_pkt(&temp_req, temp_cmd, 0); //@todo FIx command strings so this isn't neccessary
|
||||
temp_pkt.allocate();
|
||||
|
||||
using namespace Stats;
|
||||
|
||||
// MSHR hit statistics
|
||||
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
|
||||
Packet::Command cmd = (Packet::Command)access_idx;
|
||||
const string &cstr = temp_pkt.cmdIdxToString(cmd);
|
||||
for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
|
||||
MemCmd cmd(access_idx);
|
||||
const string &cstr = cmd.toString();
|
||||
|
||||
mshr_hits[access_idx]
|
||||
.init(maxThreadsPerCPU)
|
||||
|
@ -92,20 +87,20 @@ MissQueue::regStats(const string &name)
|
|||
.desc("number of demand (read+write) MSHR hits")
|
||||
.flags(total)
|
||||
;
|
||||
demandMshrHits = mshr_hits[Packet::ReadReq] + mshr_hits[Packet::WriteReq];
|
||||
demandMshrHits = mshr_hits[MemCmd::ReadReq] + mshr_hits[MemCmd::WriteReq];
|
||||
|
||||
overallMshrHits
|
||||
.name(name + ".overall_mshr_hits")
|
||||
.desc("number of overall MSHR hits")
|
||||
.flags(total)
|
||||
;
|
||||
overallMshrHits = demandMshrHits + mshr_hits[Packet::SoftPFReq] +
|
||||
mshr_hits[Packet::HardPFReq];
|
||||
overallMshrHits = demandMshrHits + mshr_hits[MemCmd::SoftPFReq] +
|
||||
mshr_hits[MemCmd::HardPFReq];
|
||||
|
||||
// MSHR miss statistics
|
||||
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
|
||||
Packet::Command cmd = (Packet::Command)access_idx;
|
||||
const string &cstr = temp_pkt.cmdIdxToString(cmd);
|
||||
for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
|
||||
MemCmd cmd(access_idx);
|
||||
const string &cstr = cmd.toString();
|
||||
|
||||
mshr_misses[access_idx]
|
||||
.init(maxThreadsPerCPU)
|
||||
|
@ -120,20 +115,20 @@ MissQueue::regStats(const string &name)
|
|||
.desc("number of demand (read+write) MSHR misses")
|
||||
.flags(total)
|
||||
;
|
||||
demandMshrMisses = mshr_misses[Packet::ReadReq] + mshr_misses[Packet::WriteReq];
|
||||
demandMshrMisses = mshr_misses[MemCmd::ReadReq] + mshr_misses[MemCmd::WriteReq];
|
||||
|
||||
overallMshrMisses
|
||||
.name(name + ".overall_mshr_misses")
|
||||
.desc("number of overall MSHR misses")
|
||||
.flags(total)
|
||||
;
|
||||
overallMshrMisses = demandMshrMisses + mshr_misses[Packet::SoftPFReq] +
|
||||
mshr_misses[Packet::HardPFReq];
|
||||
overallMshrMisses = demandMshrMisses + mshr_misses[MemCmd::SoftPFReq] +
|
||||
mshr_misses[MemCmd::HardPFReq];
|
||||
|
||||
// MSHR miss latency statistics
|
||||
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
|
||||
Packet::Command cmd = (Packet::Command)access_idx;
|
||||
const string &cstr = temp_pkt.cmdIdxToString(cmd);
|
||||
for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
|
||||
MemCmd cmd(access_idx);
|
||||
const string &cstr = cmd.toString();
|
||||
|
||||
mshr_miss_latency[access_idx]
|
||||
.init(maxThreadsPerCPU)
|
||||
|
@ -148,8 +143,8 @@ MissQueue::regStats(const string &name)
|
|||
.desc("number of demand (read+write) MSHR miss cycles")
|
||||
.flags(total)
|
||||
;
|
||||
demandMshrMissLatency = mshr_miss_latency[Packet::ReadReq]
|
||||
+ mshr_miss_latency[Packet::WriteReq];
|
||||
demandMshrMissLatency = mshr_miss_latency[MemCmd::ReadReq]
|
||||
+ mshr_miss_latency[MemCmd::WriteReq];
|
||||
|
||||
overallMshrMissLatency
|
||||
.name(name + ".overall_mshr_miss_latency")
|
||||
|
@ -157,12 +152,12 @@ MissQueue::regStats(const string &name)
|
|||
.flags(total)
|
||||
;
|
||||
overallMshrMissLatency = demandMshrMissLatency +
|
||||
mshr_miss_latency[Packet::SoftPFReq] + mshr_miss_latency[Packet::HardPFReq];
|
||||
mshr_miss_latency[MemCmd::SoftPFReq] + mshr_miss_latency[MemCmd::HardPFReq];
|
||||
|
||||
// MSHR uncacheable statistics
|
||||
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
|
||||
Packet::Command cmd = (Packet::Command)access_idx;
|
||||
const string &cstr = temp_pkt.cmdIdxToString(cmd);
|
||||
for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
|
||||
MemCmd cmd(access_idx);
|
||||
const string &cstr = cmd.toString();
|
||||
|
||||
mshr_uncacheable[access_idx]
|
||||
.init(maxThreadsPerCPU)
|
||||
|
@ -177,14 +172,14 @@ MissQueue::regStats(const string &name)
|
|||
.desc("number of overall MSHR uncacheable misses")
|
||||
.flags(total)
|
||||
;
|
||||
overallMshrUncacheable = mshr_uncacheable[Packet::ReadReq]
|
||||
+ mshr_uncacheable[Packet::WriteReq] + mshr_uncacheable[Packet::SoftPFReq]
|
||||
+ mshr_uncacheable[Packet::HardPFReq];
|
||||
overallMshrUncacheable = mshr_uncacheable[MemCmd::ReadReq]
|
||||
+ mshr_uncacheable[MemCmd::WriteReq] + mshr_uncacheable[MemCmd::SoftPFReq]
|
||||
+ mshr_uncacheable[MemCmd::HardPFReq];
|
||||
|
||||
// MSHR miss latency statistics
|
||||
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
|
||||
Packet::Command cmd = (Packet::Command)access_idx;
|
||||
const string &cstr = temp_pkt.cmdIdxToString(cmd);
|
||||
for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
|
||||
MemCmd cmd(access_idx);
|
||||
const string &cstr = cmd.toString();
|
||||
|
||||
mshr_uncacheable_lat[access_idx]
|
||||
.init(maxThreadsPerCPU)
|
||||
|
@ -199,16 +194,16 @@ MissQueue::regStats(const string &name)
|
|||
.desc("number of overall MSHR uncacheable cycles")
|
||||
.flags(total)
|
||||
;
|
||||
overallMshrUncacheableLatency = mshr_uncacheable_lat[Packet::ReadReq]
|
||||
+ mshr_uncacheable_lat[Packet::WriteReq]
|
||||
+ mshr_uncacheable_lat[Packet::SoftPFReq]
|
||||
+ mshr_uncacheable_lat[Packet::HardPFReq];
|
||||
overallMshrUncacheableLatency = mshr_uncacheable_lat[MemCmd::ReadReq]
|
||||
+ mshr_uncacheable_lat[MemCmd::WriteReq]
|
||||
+ mshr_uncacheable_lat[MemCmd::SoftPFReq]
|
||||
+ mshr_uncacheable_lat[MemCmd::HardPFReq];
|
||||
|
||||
#if 0
|
||||
// MSHR access formulas
|
||||
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
|
||||
Packet::Command cmd = (Packet::Command)access_idx;
|
||||
const string &cstr = temp_pkt.cmdIdxToString(cmd);
|
||||
for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
|
||||
MemCmd cmd(access_idx);
|
||||
const string &cstr = cmd.toString();
|
||||
|
||||
mshrAccesses[access_idx]
|
||||
.name(name + "." + cstr + "_mshr_accesses")
|
||||
|
@ -237,9 +232,9 @@ MissQueue::regStats(const string &name)
|
|||
#endif
|
||||
|
||||
// MSHR miss rate formulas
|
||||
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
|
||||
Packet::Command cmd = (Packet::Command)access_idx;
|
||||
const string &cstr = temp_pkt.cmdIdxToString(cmd);
|
||||
for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
|
||||
MemCmd cmd(access_idx);
|
||||
const string &cstr = cmd.toString();
|
||||
|
||||
mshrMissRate[access_idx]
|
||||
.name(name + "." + cstr + "_mshr_miss_rate")
|
||||
|
@ -266,9 +261,9 @@ MissQueue::regStats(const string &name)
|
|||
overallMshrMissRate = overallMshrMisses / cache->overallAccesses;
|
||||
|
||||
// mshrMiss latency formulas
|
||||
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
|
||||
Packet::Command cmd = (Packet::Command)access_idx;
|
||||
const string &cstr = temp_pkt.cmdIdxToString(cmd);
|
||||
for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
|
||||
MemCmd cmd(access_idx);
|
||||
const string &cstr = cmd.toString();
|
||||
|
||||
avgMshrMissLatency[access_idx]
|
||||
.name(name + "." + cstr + "_avg_mshr_miss_latency")
|
||||
|
@ -295,9 +290,9 @@ MissQueue::regStats(const string &name)
|
|||
overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
|
||||
|
||||
// mshrUncacheable latency formulas
|
||||
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
|
||||
Packet::Command cmd = (Packet::Command)access_idx;
|
||||
const string &cstr = temp_pkt.cmdIdxToString(cmd);
|
||||
for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
|
||||
MemCmd cmd(access_idx);
|
||||
const string &cstr = cmd.toString();
|
||||
|
||||
avgMshrUncacheableLatency[access_idx]
|
||||
.name(name + "." + cstr + "_avg_mshr_uncacheable_latency")
|
||||
|
@ -351,7 +346,7 @@ MissQueue::allocateMiss(PacketPtr &pkt, int size, Tick time)
|
|||
if (mq.isFull()) {
|
||||
cache->setBlocked(Blocked_NoMSHRs);
|
||||
}
|
||||
if (pkt->cmd != Packet::HardPFReq) {
|
||||
if (pkt->cmd != MemCmd::HardPFReq) {
|
||||
//If we need to request the bus (not on HW prefetch), do so
|
||||
cache->setMasterRequest(Request_MSHR, time);
|
||||
}
|
||||
|
@ -500,17 +495,17 @@ MissQueue::getPacket()
|
|||
}
|
||||
|
||||
void
|
||||
MissQueue::setBusCmd(PacketPtr &pkt, Packet::Command cmd)
|
||||
MissQueue::setBusCmd(PacketPtr &pkt, MemCmd cmd)
|
||||
{
|
||||
assert(pkt->senderState != 0);
|
||||
MSHR * mshr = (MSHR*)pkt->senderState;
|
||||
mshr->originalCmd = pkt->cmd;
|
||||
if (cmd == Packet::UpgradeReq || cmd == Packet::InvalidateReq) {
|
||||
if (cmd == MemCmd::UpgradeReq || cmd == MemCmd::InvalidateReq) {
|
||||
pkt->flags |= NO_ALLOCATE;
|
||||
pkt->flags &= ~CACHE_LINE_FILL;
|
||||
}
|
||||
else if (!pkt->req->isUncacheable() && !pkt->isNoAllocate() &&
|
||||
(cmd & (1 << 6)/*NeedsResponse*/)) {
|
||||
cmd.needsResponse()) {
|
||||
pkt->flags |= CACHE_LINE_FILL;
|
||||
}
|
||||
if (pkt->isCacheFill() || pkt->isNoAllocate())
|
||||
|
@ -552,7 +547,7 @@ MissQueue::markInService(PacketPtr &pkt, MSHR* mshr)
|
|||
if (!mq.havePending()){
|
||||
cache->clearMasterRequest(Request_MSHR);
|
||||
}
|
||||
if (mshr->originalCmd == Packet::HardPFReq) {
|
||||
if (mshr->originalCmd == MemCmd::HardPFReq) {
|
||||
DPRINTF(HWPrefetch, "%s:Marking a HW_PF in service\n",
|
||||
cache->name());
|
||||
//Also clear pending if need be
|
||||
|
@ -576,7 +571,7 @@ void
|
|||
MissQueue::handleResponse(PacketPtr &pkt, Tick time)
|
||||
{
|
||||
MSHR* mshr = (MSHR*)pkt->senderState;
|
||||
if (((MSHR*)(pkt->senderState))->originalCmd == Packet::HardPFReq) {
|
||||
if (((MSHR*)(pkt->senderState))->originalCmd == MemCmd::HardPFReq) {
|
||||
DPRINTF(HWPrefetch, "%s:Handling the response to a HW_PF\n",
|
||||
cache->name());
|
||||
}
|
||||
|
@ -589,7 +584,7 @@ MissQueue::handleResponse(PacketPtr &pkt, Tick time)
|
|||
BlockedCause cause = NUM_BLOCKED_CAUSES;
|
||||
|
||||
if (pkt->isCacheFill() && !pkt->isNoAllocate()) {
|
||||
mshr_miss_latency[mshr->originalCmd][0/*pkt->req->getThreadNum()*/] +=
|
||||
mshr_miss_latency[mshr->originalCmd.toInt()][0/*pkt->req->getThreadNum()*/] +=
|
||||
curTick - pkt->time;
|
||||
// targets were handled in the cache tags
|
||||
if (mshr == noTargetMSHR) {
|
||||
|
@ -601,7 +596,7 @@ MissQueue::handleResponse(PacketPtr &pkt, Tick time)
|
|||
|
||||
if (mshr->hasTargets()) {
|
||||
// Didn't satisfy all the targets, need to resend
|
||||
Packet::Command cmd = mshr->getTarget()->cmd;
|
||||
MemCmd cmd = mshr->getTarget()->cmd;
|
||||
mshr->pkt->setDest(Packet::Broadcast);
|
||||
mshr->pkt->result = Packet::Unknown;
|
||||
mq.markPending(mshr, cmd);
|
||||
|
@ -618,7 +613,7 @@ MissQueue::handleResponse(PacketPtr &pkt, Tick time)
|
|||
}
|
||||
} else {
|
||||
if (pkt->req->isUncacheable()) {
|
||||
mshr_uncacheable_lat[pkt->cmd][0/*pkt->req->getThreadNum()*/] +=
|
||||
mshr_uncacheable_lat[pkt->cmd.toInt()][0/*pkt->req->getThreadNum()*/] +=
|
||||
curTick - pkt->time;
|
||||
}
|
||||
if (mshr->hasTargets() && pkt->req->isUncacheable()) {
|
||||
|
@ -713,7 +708,7 @@ MissQueue::doWriteback(Addr addr,
|
|||
{
|
||||
// Generate request
|
||||
Request * req = new Request(addr, size, 0);
|
||||
PacketPtr pkt = new Packet(req, Packet::Writeback, -1);
|
||||
PacketPtr pkt = new Packet(req, MemCmd::Writeback, -1);
|
||||
pkt->allocate();
|
||||
if (data) {
|
||||
memcpy(pkt->getPtr<uint8_t>(), data, size);
|
||||
|
|
20
src/mem/cache/miss/miss_queue.hh
vendored
20
src/mem/cache/miss/miss_queue.hh
vendored
|
@ -77,59 +77,59 @@ class MissQueue : public MissBuffer
|
|||
* @{
|
||||
*/
|
||||
/** Number of misses that hit in the MSHRs per command and thread. */
|
||||
Stats::Vector<> mshr_hits[NUM_MEM_CMDS];
|
||||
Stats::Vector<> mshr_hits[MemCmd::NUM_MEM_CMDS];
|
||||
/** Demand misses that hit in the MSHRs. */
|
||||
Stats::Formula demandMshrHits;
|
||||
/** Total number of misses that hit in the MSHRs. */
|
||||
Stats::Formula overallMshrHits;
|
||||
|
||||
/** Number of misses that miss in the MSHRs, per command and thread. */
|
||||
Stats::Vector<> mshr_misses[NUM_MEM_CMDS];
|
||||
Stats::Vector<> mshr_misses[MemCmd::NUM_MEM_CMDS];
|
||||
/** Demand misses that miss in the MSHRs. */
|
||||
Stats::Formula demandMshrMisses;
|
||||
/** Total number of misses that miss in the MSHRs. */
|
||||
Stats::Formula overallMshrMisses;
|
||||
|
||||
/** Number of misses that miss in the MSHRs, per command and thread. */
|
||||
Stats::Vector<> mshr_uncacheable[NUM_MEM_CMDS];
|
||||
Stats::Vector<> mshr_uncacheable[MemCmd::NUM_MEM_CMDS];
|
||||
/** Total number of misses that miss in the MSHRs. */
|
||||
Stats::Formula overallMshrUncacheable;
|
||||
|
||||
/** Total cycle latency of each MSHR miss, per command and thread. */
|
||||
Stats::Vector<> mshr_miss_latency[NUM_MEM_CMDS];
|
||||
Stats::Vector<> mshr_miss_latency[MemCmd::NUM_MEM_CMDS];
|
||||
/** Total cycle latency of demand MSHR misses. */
|
||||
Stats::Formula demandMshrMissLatency;
|
||||
/** Total cycle latency of overall MSHR misses. */
|
||||
Stats::Formula overallMshrMissLatency;
|
||||
|
||||
/** Total cycle latency of each MSHR miss, per command and thread. */
|
||||
Stats::Vector<> mshr_uncacheable_lat[NUM_MEM_CMDS];
|
||||
Stats::Vector<> mshr_uncacheable_lat[MemCmd::NUM_MEM_CMDS];
|
||||
/** Total cycle latency of overall MSHR misses. */
|
||||
Stats::Formula overallMshrUncacheableLatency;
|
||||
|
||||
/** The total number of MSHR accesses per command and thread. */
|
||||
Stats::Formula mshrAccesses[NUM_MEM_CMDS];
|
||||
Stats::Formula mshrAccesses[MemCmd::NUM_MEM_CMDS];
|
||||
/** The total number of demand MSHR accesses. */
|
||||
Stats::Formula demandMshrAccesses;
|
||||
/** The total number of MSHR accesses. */
|
||||
Stats::Formula overallMshrAccesses;
|
||||
|
||||
/** The miss rate in the MSHRs pre command and thread. */
|
||||
Stats::Formula mshrMissRate[NUM_MEM_CMDS];
|
||||
Stats::Formula mshrMissRate[MemCmd::NUM_MEM_CMDS];
|
||||
/** The demand miss rate in the MSHRs. */
|
||||
Stats::Formula demandMshrMissRate;
|
||||
/** The overall miss rate in the MSHRs. */
|
||||
Stats::Formula overallMshrMissRate;
|
||||
|
||||
/** The average latency of an MSHR miss, per command and thread. */
|
||||
Stats::Formula avgMshrMissLatency[NUM_MEM_CMDS];
|
||||
Stats::Formula avgMshrMissLatency[MemCmd::NUM_MEM_CMDS];
|
||||
/** The average latency of a demand MSHR miss. */
|
||||
Stats::Formula demandAvgMshrMissLatency;
|
||||
/** The average overall latency of an MSHR miss. */
|
||||
Stats::Formula overallAvgMshrMissLatency;
|
||||
|
||||
/** The average latency of an MSHR miss, per command and thread. */
|
||||
Stats::Formula avgMshrUncacheableLatency[NUM_MEM_CMDS];
|
||||
Stats::Formula avgMshrUncacheableLatency[MemCmd::NUM_MEM_CMDS];
|
||||
/** The average overall latency of an MSHR miss. */
|
||||
Stats::Formula overallAvgMshrUncacheableLatency;
|
||||
|
||||
|
@ -220,7 +220,7 @@ class MissQueue : public MissBuffer
|
|||
* @param pkt The request to update.
|
||||
* @param cmd The bus command to use.
|
||||
*/
|
||||
void setBusCmd(PacketPtr &pkt, Packet::Command cmd);
|
||||
void setBusCmd(PacketPtr &pkt, MemCmd cmd);
|
||||
|
||||
/**
|
||||
* Restore the original command in case of a bus transmission error.
|
||||
|
|
4
src/mem/cache/miss/mshr.cc
vendored
4
src/mem/cache/miss/mshr.cc
vendored
|
@ -54,7 +54,7 @@ MSHR::MSHR()
|
|||
}
|
||||
|
||||
void
|
||||
MSHR::allocate(Packet::Command cmd, Addr _addr, int size,
|
||||
MSHR::allocate(MemCmd cmd, Addr _addr, int size,
|
||||
PacketPtr &target)
|
||||
{
|
||||
addr = _addr;
|
||||
|
@ -148,7 +148,7 @@ MSHR::allocateTarget(PacketPtr &target)
|
|||
*/
|
||||
|
||||
if (!inService && target->isWrite()) {
|
||||
pkt->cmd = Packet::WriteReq;
|
||||
pkt->cmd = MemCmd::WriteReq;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
4
src/mem/cache/miss/mshr.hh
vendored
4
src/mem/cache/miss/mshr.hh
vendored
|
@ -72,7 +72,7 @@ class MSHR {
|
|||
/** The number of currently allocated targets. */
|
||||
short ntargets;
|
||||
/** The original requesting command. */
|
||||
Packet::Command originalCmd;
|
||||
MemCmd originalCmd;
|
||||
/** Order number of assigned by the miss queue. */
|
||||
uint64_t order;
|
||||
|
||||
|
@ -100,7 +100,7 @@ public:
|
|||
* @param size The number of bytes to request.
|
||||
* @param pkt The original miss.
|
||||
*/
|
||||
void allocate(Packet::Command cmd, Addr addr, int size,
|
||||
void allocate(MemCmd cmd, Addr addr, int size,
|
||||
PacketPtr &pkt);
|
||||
|
||||
/**
|
||||
|
|
8
src/mem/cache/miss/mshr_queue.cc
vendored
8
src/mem/cache/miss/mshr_queue.cc
vendored
|
@ -136,7 +136,7 @@ MSHRQueue::allocateFetch(Addr addr, int size, PacketPtr &target)
|
|||
MSHR *mshr = freeList.front();
|
||||
assert(mshr->getNumTargets() == 0);
|
||||
freeList.pop_front();
|
||||
mshr->allocate(Packet::ReadReq, addr, size, target);
|
||||
mshr->allocate(MemCmd::ReadReq, addr, size, target);
|
||||
mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
|
||||
mshr->readyIter = pendingList.insert(pendingList.end(), mshr);
|
||||
|
||||
|
@ -151,7 +151,7 @@ MSHRQueue::allocateTargetList(Addr addr, int size)
|
|||
assert(mshr->getNumTargets() == 0);
|
||||
freeList.pop_front();
|
||||
PacketPtr dummy;
|
||||
mshr->allocate(Packet::ReadReq, addr, size, dummy);
|
||||
mshr->allocate(MemCmd::ReadReq, addr, size, dummy);
|
||||
mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
|
||||
mshr->inService = true;
|
||||
++inServiceMSHRs;
|
||||
|
@ -196,7 +196,7 @@ void
|
|||
MSHRQueue::markInService(MSHR* mshr)
|
||||
{
|
||||
//assert(mshr == pendingList.front());
|
||||
if (!mshr->pkt->needsResponse() && !(mshr->pkt->cmd == Packet::UpgradeReq)) {
|
||||
if (!mshr->pkt->needsResponse() && !(mshr->pkt->cmd == MemCmd::UpgradeReq)) {
|
||||
assert(mshr->getNumTargets() == 0);
|
||||
deallocate(mshr);
|
||||
return;
|
||||
|
@ -209,7 +209,7 @@ MSHRQueue::markInService(MSHR* mshr)
|
|||
}
|
||||
|
||||
void
|
||||
MSHRQueue::markPending(MSHR* mshr, Packet::Command cmd)
|
||||
MSHRQueue::markPending(MSHR* mshr, MemCmd cmd)
|
||||
{
|
||||
//assert(mshr->readyIter == NULL);
|
||||
mshr->pkt->cmd = cmd;
|
||||
|
|
2
src/mem/cache/miss/mshr_queue.hh
vendored
2
src/mem/cache/miss/mshr_queue.hh
vendored
|
@ -185,7 +185,7 @@ class MSHRQueue {
|
|||
* @param mshr The MSHR to resend.
|
||||
* @param cmd The command to resend.
|
||||
*/
|
||||
void markPending(MSHR* mshr, Packet::Command cmd);
|
||||
void markPending(MSHR* mshr, MemCmd cmd);
|
||||
|
||||
/**
|
||||
* Squash outstanding requests with the given thread number. If a request
|
||||
|
|
2
src/mem/cache/prefetch/base_prefetcher.cc
vendored
2
src/mem/cache/prefetch/base_prefetcher.cc
vendored
|
@ -200,7 +200,7 @@ BasePrefetcher::handleMiss(PacketPtr &pkt, Tick time)
|
|||
//create a prefetch memreq
|
||||
Request * prefetchReq = new Request(*addr, blkSize, 0);
|
||||
PacketPtr prefetch;
|
||||
prefetch = new Packet(prefetchReq, Packet::HardPFReq, -1);
|
||||
prefetch = new Packet(prefetchReq, MemCmd::HardPFReq, -1);
|
||||
prefetch->allocate();
|
||||
prefetch->req->setThreadContext(pkt->req->getCpuNum(),
|
||||
pkt->req->getThreadNum());
|
||||
|
|
3
src/mem/cache/tags/iic.cc
vendored
3
src/mem/cache/tags/iic.cc
vendored
|
@ -372,7 +372,8 @@ IIC::freeReplacementBlock(PacketList & writebacks)
|
|||
*/
|
||||
Request *writebackReq = new Request(regenerateBlkAddr(tag_ptr->tag, 0),
|
||||
blkSize, 0);
|
||||
PacketPtr writeback = new Packet(writebackReq, Packet::Writeback, -1);
|
||||
PacketPtr writeback = new Packet(writebackReq, MemCmd::Writeback,
|
||||
-1);
|
||||
writeback->allocate();
|
||||
memcpy(writeback->getPtr<uint8_t>(), tag_ptr->data, blkSize);
|
||||
|
||||
|
|
|
@ -41,68 +41,62 @@
|
|||
#include "base/trace.hh"
|
||||
#include "mem/packet.hh"
|
||||
|
||||
static const std::string ReadReqString("ReadReq");
|
||||
static const std::string WriteReqString("WriteReq");
|
||||
static const std::string WriteReqNoAckString("WriteReqNoAck|Writeback");
|
||||
static const std::string ReadRespString("ReadResp");
|
||||
static const std::string WriteRespString("WriteResp");
|
||||
static const std::string SoftPFReqString("SoftPFReq");
|
||||
static const std::string SoftPFRespString("SoftPFResp");
|
||||
static const std::string HardPFReqString("HardPFReq");
|
||||
static const std::string HardPFRespString("HardPFResp");
|
||||
static const std::string InvalidateReqString("InvalidateReq");
|
||||
static const std::string WriteInvalidateReqString("WriteInvalidateReq");
|
||||
static const std::string WriteInvalidateRespString("WriteInvalidateResp");
|
||||
static const std::string UpgradeReqString("UpgradeReq");
|
||||
static const std::string ReadExReqString("ReadExReq");
|
||||
static const std::string ReadExRespString("ReadExResp");
|
||||
static const std::string OtherCmdString("<other>");
|
||||
// The one downside to bitsets is that static initializers can get ugly.
|
||||
#define SET1(a1) (1 << (a1))
|
||||
#define SET2(a1, a2) (SET1(a1) | SET1(a2))
|
||||
#define SET3(a1, a2, a3) (SET2(a1, a2) | SET1(a3))
|
||||
#define SET4(a1, a2, a3, a4) (SET3(a1, a2, a3) | SET1(a4))
|
||||
#define SET5(a1, a2, a3, a4, a5) (SET4(a1, a2, a3, a4) | SET1(a5))
|
||||
#define SET6(a1, a2, a3, a4, a5, a6) (SET5(a1, a2, a3, a4, a5) | SET1(a6))
|
||||
|
||||
const std::string &
|
||||
Packet::cmdString() const
|
||||
const MemCmd::CommandInfo
|
||||
MemCmd::commandInfo[] =
|
||||
{
|
||||
switch (cmd) {
|
||||
case ReadReq: return ReadReqString;
|
||||
case WriteReq: return WriteReqString;
|
||||
case WriteReqNoAck: return WriteReqNoAckString;
|
||||
case ReadResp: return ReadRespString;
|
||||
case WriteResp: return WriteRespString;
|
||||
case SoftPFReq: return SoftPFReqString;
|
||||
case SoftPFResp: return SoftPFRespString;
|
||||
case HardPFReq: return HardPFReqString;
|
||||
case HardPFResp: return HardPFRespString;
|
||||
case InvalidateReq: return InvalidateReqString;
|
||||
case WriteInvalidateReq:return WriteInvalidateReqString;
|
||||
case WriteInvalidateResp:return WriteInvalidateRespString;
|
||||
case UpgradeReq: return UpgradeReqString;
|
||||
case ReadExReq: return ReadExReqString;
|
||||
case ReadExResp: return ReadExRespString;
|
||||
default: return OtherCmdString;
|
||||
}
|
||||
}
|
||||
/* InvalidCmd */
|
||||
{ 0, InvalidCmd, "InvalidCmd" },
|
||||
/* ReadReq */
|
||||
{ SET3(IsRead, IsRequest, NeedsResponse), ReadResp, "ReadReq" },
|
||||
/* WriteReq */
|
||||
{ SET4(IsWrite, IsRequest, NeedsResponse, HasData),
|
||||
WriteResp, "WriteReq" },
|
||||
/* WriteReqNoAck */
|
||||
{ SET3(IsWrite, IsRequest, HasData), InvalidCmd, "WriteReqNoAck" },
|
||||
/* ReadResp */
|
||||
{ SET3(IsRead, IsResponse, HasData), InvalidCmd, "ReadResp" },
|
||||
/* WriteResp */
|
||||
{ SET2(IsWrite, IsResponse), InvalidCmd, "WriteResp" },
|
||||
/* Writeback */
|
||||
{ SET3(IsWrite, IsRequest, HasData), InvalidCmd, "Writeback" },
|
||||
/* SoftPFReq */
|
||||
{ SET4(IsRead, IsRequest, IsSWPrefetch, NeedsResponse),
|
||||
SoftPFResp, "SoftPFReq" },
|
||||
/* HardPFReq */
|
||||
{ SET4(IsRead, IsRequest, IsHWPrefetch, NeedsResponse),
|
||||
HardPFResp, "HardPFReq" },
|
||||
/* SoftPFResp */
|
||||
{ SET4(IsRead, IsResponse, IsSWPrefetch, HasData),
|
||||
InvalidCmd, "SoftPFResp" },
|
||||
/* HardPFResp */
|
||||
{ SET4(IsRead, IsResponse, IsHWPrefetch, HasData),
|
||||
InvalidCmd, "HardPFResp" },
|
||||
/* InvalidateReq */
|
||||
{ SET2(IsInvalidate, IsRequest), InvalidCmd, "InvalidateReq" },
|
||||
/* WriteInvalidateReq */
|
||||
{ SET5(IsWrite, IsInvalidate, IsRequest, HasData, NeedsResponse),
|
||||
WriteInvalidateResp, "WriteInvalidateReq" },
|
||||
/* WriteInvalidateResp */
|
||||
{ SET5(IsWrite, IsInvalidate, IsRequest, NeedsResponse, IsResponse),
|
||||
InvalidCmd, "WriteInvalidateResp" },
|
||||
/* UpgradeReq */
|
||||
{ SET3(IsInvalidate, IsRequest, IsUpgrade), InvalidCmd, "UpgradeReq" },
|
||||
/* ReadExReq */
|
||||
{ SET4(IsRead, IsInvalidate, IsRequest, NeedsResponse),
|
||||
ReadExResp, "ReadExReq" },
|
||||
/* ReadExResp */
|
||||
{ SET4(IsRead, IsInvalidate, IsResponse, HasData),
|
||||
InvalidCmd, "ReadExResp" }
|
||||
};
|
||||
|
||||
const std::string &
|
||||
Packet::cmdIdxToString(Packet::Command idx)
|
||||
{
|
||||
switch (idx) {
|
||||
case ReadReq: return ReadReqString;
|
||||
case WriteReq: return WriteReqString;
|
||||
case WriteReqNoAck: return WriteReqNoAckString;
|
||||
case ReadResp: return ReadRespString;
|
||||
case WriteResp: return WriteRespString;
|
||||
case SoftPFReq: return SoftPFReqString;
|
||||
case SoftPFResp: return SoftPFRespString;
|
||||
case HardPFReq: return HardPFReqString;
|
||||
case HardPFResp: return HardPFRespString;
|
||||
case InvalidateReq: return InvalidateReqString;
|
||||
case WriteInvalidateReq:return WriteInvalidateReqString;
|
||||
case WriteInvalidateResp:return WriteInvalidateRespString;
|
||||
case UpgradeReq: return UpgradeReqString;
|
||||
case ReadExReq: return ReadExReqString;
|
||||
case ReadExResp: return ReadExRespString;
|
||||
default: return OtherCmdString;
|
||||
}
|
||||
}
|
||||
|
||||
/** delete the data pointed to in the data pointer. Ok to call to matter how
|
||||
* data was allocted. */
|
||||
|
@ -149,9 +143,17 @@ fixDelayedResponsePacket(PacketPtr func, PacketPtr timing)
|
|||
bool result;
|
||||
|
||||
if (timing->isRead() || timing->isWrite()) {
|
||||
timing->toggleData();
|
||||
// Ugly hack to deal with the fact that we queue the requests
|
||||
// and don't convert them to responses until we issue them on
|
||||
// the bus. I tried to avoid this by converting packets to
|
||||
// responses right away, but this breaks during snoops where a
|
||||
// responder may do the conversion before other caches have
|
||||
// done the snoop. Would work if we copied the packet instead
|
||||
// of just hanging on to a pointer.
|
||||
MemCmd oldCmd = timing->cmd;
|
||||
timing->cmd = timing->cmd.responseCommand();
|
||||
result = fixPacket(func, timing);
|
||||
timing->toggleData();
|
||||
timing->cmd = oldCmd;
|
||||
}
|
||||
else {
|
||||
//Don't toggle if it isn't a read/write response
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
|
||||
#include <cassert>
|
||||
#include <list>
|
||||
#include <bitset>
|
||||
|
||||
#include "base/misc.hh"
|
||||
#include "mem/request.hh"
|
||||
|
@ -61,8 +62,114 @@ typedef std::list<PacketPtr> PacketList;
|
|||
#define NO_ALLOCATE (1 << 5)
|
||||
#define SNOOP_COMMIT (1 << 6)
|
||||
|
||||
//for now. @todo fix later
|
||||
#define NUM_MEM_CMDS (1 << 11)
|
||||
|
||||
class MemCmd
|
||||
{
|
||||
public:
|
||||
|
||||
/** List of all commands associated with a packet. */
|
||||
enum Command
|
||||
{
|
||||
InvalidCmd,
|
||||
ReadReq,
|
||||
WriteReq,
|
||||
WriteReqNoAck,
|
||||
ReadResp,
|
||||
WriteResp,
|
||||
Writeback,
|
||||
SoftPFReq,
|
||||
HardPFReq,
|
||||
SoftPFResp,
|
||||
HardPFResp,
|
||||
InvalidateReq,
|
||||
WriteInvalidateReq,
|
||||
WriteInvalidateResp,
|
||||
UpgradeReq,
|
||||
ReadExReq,
|
||||
ReadExResp,
|
||||
NUM_MEM_CMDS
|
||||
};
|
||||
|
||||
private:
|
||||
/** List of command attributes. */
|
||||
enum Attribute
|
||||
{
|
||||
IsRead,
|
||||
IsWrite,
|
||||
IsPrefetch,
|
||||
IsInvalidate,
|
||||
IsRequest,
|
||||
IsResponse,
|
||||
NeedsResponse,
|
||||
IsSWPrefetch,
|
||||
IsHWPrefetch,
|
||||
IsUpgrade,
|
||||
HasData,
|
||||
NUM_COMMAND_ATTRIBUTES
|
||||
};
|
||||
|
||||
/** Structure that defines attributes and other data associated
|
||||
* with a Command. */
|
||||
struct CommandInfo {
|
||||
/** Set of attribute flags. */
|
||||
const std::bitset<NUM_COMMAND_ATTRIBUTES> attributes;
|
||||
/** Corresponding response for requests; InvalidCmd if no
|
||||
* response is applicable. */
|
||||
const Command response;
|
||||
/** String representation (for printing) */
|
||||
const std::string str;
|
||||
};
|
||||
|
||||
/** Array to map Command enum to associated info. */
|
||||
static const CommandInfo commandInfo[];
|
||||
|
||||
private:
|
||||
|
||||
Command cmd;
|
||||
|
||||
bool testCmdAttrib(MemCmd::Attribute attrib) const {
|
||||
return commandInfo[cmd].attributes[attrib] != 0;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
bool isRead() const { return testCmdAttrib(IsRead); }
|
||||
bool isWrite() const { return testCmdAttrib(IsWrite); }
|
||||
bool isRequest() const { return testCmdAttrib(IsRequest); }
|
||||
bool isResponse() const { return testCmdAttrib(IsResponse); }
|
||||
bool needsResponse() const { return testCmdAttrib(NeedsResponse); }
|
||||
bool isInvalidate() const { return testCmdAttrib(IsInvalidate); }
|
||||
bool hasData() const { return testCmdAttrib(HasData); }
|
||||
|
||||
const Command responseCommand() const {
|
||||
return commandInfo[cmd].response;
|
||||
}
|
||||
|
||||
/** Return the string to a cmd given by idx. */
|
||||
const std::string &toString() const {
|
||||
return commandInfo[cmd].str;
|
||||
}
|
||||
|
||||
int toInt() const { return (int)cmd; }
|
||||
|
||||
MemCmd(Command _cmd)
|
||||
: cmd(_cmd)
|
||||
{ }
|
||||
|
||||
MemCmd(int _cmd)
|
||||
: cmd((Command)_cmd)
|
||||
{ }
|
||||
|
||||
MemCmd()
|
||||
: cmd(InvalidCmd)
|
||||
{ }
|
||||
|
||||
bool operator==(MemCmd c2) { return (cmd == c2.cmd); }
|
||||
bool operator!=(MemCmd c2) { return (cmd != c2.cmd); }
|
||||
|
||||
friend class Packet;
|
||||
};
|
||||
|
||||
/**
|
||||
* A Packet is used to encapsulate a transfer between two objects in
|
||||
* the memory system (e.g., the L1 and L2 cache). (In contrast, a
|
||||
|
@ -73,6 +180,9 @@ typedef std::list<PacketPtr> PacketList;
|
|||
class Packet
|
||||
{
|
||||
public:
|
||||
|
||||
typedef MemCmd::Command Command;
|
||||
|
||||
/** Temporary FLAGS field until cache gets working, this should be in coherence/sender state. */
|
||||
uint64_t flags;
|
||||
|
||||
|
@ -168,73 +278,27 @@ class Packet
|
|||
* to cast to the state appropriate to the sender. */
|
||||
SenderState *senderState;
|
||||
|
||||
private:
|
||||
/** List of command attributes. */
|
||||
// If you add a new CommandAttribute, make sure to increase NUM_MEM_CMDS
|
||||
// as well.
|
||||
enum CommandAttribute
|
||||
{
|
||||
IsRead = 1 << 0,
|
||||
IsWrite = 1 << 1,
|
||||
IsPrefetch = 1 << 2,
|
||||
IsInvalidate = 1 << 3,
|
||||
IsRequest = 1 << 4,
|
||||
IsResponse = 1 << 5,
|
||||
NeedsResponse = 1 << 6,
|
||||
IsSWPrefetch = 1 << 7,
|
||||
IsHWPrefetch = 1 << 8,
|
||||
IsUpgrade = 1 << 9,
|
||||
HasData = 1 << 10
|
||||
};
|
||||
|
||||
public:
|
||||
/** List of all commands associated with a packet. */
|
||||
enum Command
|
||||
{
|
||||
InvalidCmd = 0,
|
||||
ReadReq = IsRead | IsRequest | NeedsResponse,
|
||||
WriteReq = IsWrite | IsRequest | NeedsResponse | HasData,
|
||||
WriteReqNoAck = IsWrite | IsRequest | HasData,
|
||||
ReadResp = IsRead | IsResponse | NeedsResponse | HasData,
|
||||
WriteResp = IsWrite | IsResponse | NeedsResponse,
|
||||
Writeback = IsWrite | IsRequest | HasData,
|
||||
SoftPFReq = IsRead | IsRequest | IsSWPrefetch | NeedsResponse,
|
||||
HardPFReq = IsRead | IsRequest | IsHWPrefetch | NeedsResponse,
|
||||
SoftPFResp = IsRead | IsResponse | IsSWPrefetch
|
||||
| NeedsResponse | HasData,
|
||||
HardPFResp = IsRead | IsResponse | IsHWPrefetch
|
||||
| NeedsResponse | HasData,
|
||||
InvalidateReq = IsInvalidate | IsRequest,
|
||||
WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest
|
||||
| HasData | NeedsResponse,
|
||||
WriteInvalidateResp = IsWrite | IsInvalidate | IsRequest
|
||||
| NeedsResponse | IsResponse,
|
||||
UpgradeReq = IsInvalidate | IsRequest | IsUpgrade,
|
||||
ReadExReq = IsRead | IsInvalidate | IsRequest | NeedsResponse,
|
||||
ReadExResp = IsRead | IsInvalidate | IsResponse
|
||||
| NeedsResponse | HasData
|
||||
};
|
||||
|
||||
/** The command field of the packet. */
|
||||
MemCmd cmd;
|
||||
|
||||
/** Return the string name of the cmd field (for debugging and
|
||||
* tracing). */
|
||||
const std::string &cmdString() const;
|
||||
|
||||
/** Reutrn the string to a cmd given by idx. */
|
||||
const std::string &cmdIdxToString(Command idx);
|
||||
const std::string &cmdString() const { return cmd.toString(); }
|
||||
|
||||
/** Return the index of this command. */
|
||||
inline int cmdToIndex() const { return (int) cmd; }
|
||||
inline int cmdToIndex() const { return cmd.toInt(); }
|
||||
|
||||
/** The command field of the packet. */
|
||||
Command cmd;
|
||||
public:
|
||||
|
||||
bool isRead() const { return (cmd & IsRead) != 0; }
|
||||
bool isWrite() const { return (cmd & IsWrite) != 0; }
|
||||
bool isRequest() const { return (cmd & IsRequest) != 0; }
|
||||
bool isResponse() const { return (cmd & IsResponse) != 0; }
|
||||
bool needsResponse() const { return (cmd & NeedsResponse) != 0; }
|
||||
bool isInvalidate() const { return (cmd & IsInvalidate) != 0; }
|
||||
bool hasData() const { return (cmd & HasData) != 0; }
|
||||
bool isRead() const { return cmd.isRead(); }
|
||||
bool isWrite() const { return cmd.isWrite(); }
|
||||
bool isRequest() const { return cmd.isRequest(); }
|
||||
bool isResponse() const { return cmd.isResponse(); }
|
||||
bool needsResponse() const { return cmd.needsResponse(); }
|
||||
bool isInvalidate() const { return cmd.isInvalidate(); }
|
||||
bool hasData() const { return cmd.hasData(); }
|
||||
|
||||
bool isCacheFill() const { return (flags & CACHE_LINE_FILL) != 0; }
|
||||
bool isNoAllocate() const { return (flags & NO_ALLOCATE) != 0; }
|
||||
|
@ -268,13 +332,13 @@ class Packet
|
|||
Addr getOffset(int blkSize) const { return addr & (Addr)(blkSize - 1); }
|
||||
|
||||
void addrOverride(Addr newAddr) { assert(addrSizeValid); addr = newAddr; }
|
||||
void cmdOverride(Command newCmd) { cmd = newCmd; }
|
||||
void cmdOverride(MemCmd newCmd) { cmd = newCmd; }
|
||||
|
||||
/** Constructor. Note that a Request object must be constructed
|
||||
* first, but the Requests's physical address and size fields
|
||||
* need not be valid. The command and destination addresses
|
||||
* must be supplied. */
|
||||
Packet(Request *_req, Command _cmd, short _dest)
|
||||
Packet(Request *_req, MemCmd _cmd, short _dest)
|
||||
: data(NULL), staticData(false), dynamicData(false), arrayData(false),
|
||||
addr(_req->paddr), size(_req->size), dest(_dest),
|
||||
addrSizeValid(_req->validPaddr),
|
||||
|
@ -289,7 +353,7 @@ class Packet
|
|||
/** 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)
|
||||
Packet(Request *_req, MemCmd _cmd, short _dest, int _blkSize)
|
||||
: data(NULL), staticData(false), dynamicData(false), arrayData(false),
|
||||
addr(_req->paddr & ~(_blkSize - 1)), size(_blkSize),
|
||||
dest(_dest),
|
||||
|
@ -334,25 +398,11 @@ class Packet
|
|||
void makeTimingResponse() {
|
||||
assert(needsResponse());
|
||||
assert(isRequest());
|
||||
int icmd = (int)cmd;
|
||||
icmd &= ~(IsRequest);
|
||||
icmd |= IsResponse;
|
||||
if (isRead())
|
||||
icmd |= HasData;
|
||||
if (isWrite())
|
||||
icmd &= ~HasData;
|
||||
cmd = (Command)icmd;
|
||||
cmd = cmd.responseCommand();
|
||||
dest = src;
|
||||
srcValid = false;
|
||||
}
|
||||
|
||||
|
||||
void toggleData() {
|
||||
int icmd = (int)cmd;
|
||||
icmd ^= HasData;
|
||||
cmd = (Command)icmd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take a request packet and modify it in place to be suitable for
|
||||
* returning as a response to that request.
|
||||
|
@ -361,14 +411,7 @@ class Packet
|
|||
{
|
||||
assert(needsResponse());
|
||||
assert(isRequest());
|
||||
int icmd = (int)cmd;
|
||||
icmd &= ~(IsRequest);
|
||||
icmd |= IsResponse;
|
||||
if (isRead())
|
||||
icmd |= HasData;
|
||||
if (isWrite())
|
||||
icmd &= ~HasData;
|
||||
cmd = (Command)icmd;
|
||||
cmd = cmd.responseCommand();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -46,7 +46,7 @@ Port::setPeer(Port *port)
|
|||
}
|
||||
|
||||
void
|
||||
Port::blobHelper(Addr addr, uint8_t *p, int size, Packet::Command cmd)
|
||||
Port::blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd)
|
||||
{
|
||||
Request req;
|
||||
Packet pkt(&req, cmd, Packet::Broadcast);
|
||||
|
@ -64,13 +64,13 @@ Port::blobHelper(Addr addr, uint8_t *p, int size, Packet::Command cmd)
|
|||
void
|
||||
Port::writeBlob(Addr addr, uint8_t *p, int size)
|
||||
{
|
||||
blobHelper(addr, p, size, Packet::WriteReq);
|
||||
blobHelper(addr, p, size, MemCmd::WriteReq);
|
||||
}
|
||||
|
||||
void
|
||||
Port::readBlob(Addr addr, uint8_t *p, int size)
|
||||
{
|
||||
blobHelper(addr, p, size, Packet::ReadReq);
|
||||
blobHelper(addr, p, size, MemCmd::ReadReq);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -80,7 +80,7 @@ Port::memsetBlob(Addr addr, uint8_t val, int size)
|
|||
uint8_t *buf = new uint8_t[size];
|
||||
|
||||
std::memset(buf, val, size);
|
||||
blobHelper(addr, buf, size, Packet::WriteReq);
|
||||
blobHelper(addr, buf, size, MemCmd::WriteReq);
|
||||
|
||||
delete [] buf;
|
||||
}
|
||||
|
|
|
@ -245,7 +245,7 @@ class Port
|
|||
|
||||
/** Internal helper function for read/writeBlob().
|
||||
*/
|
||||
void blobHelper(Addr addr, uint8_t *p, int size, Packet::Command cmd);
|
||||
void blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd);
|
||||
};
|
||||
|
||||
/** A simple functional port that is only meant for one way communication to
|
||||
|
|
|
@ -68,7 +68,7 @@ SimpleTimingPort::recvTiming(PacketPtr pkt)
|
|||
sendTiming(pkt, latency);
|
||||
}
|
||||
else {
|
||||
if (pkt->cmd != Packet::UpgradeReq)
|
||||
if (pkt->cmd != MemCmd::UpgradeReq)
|
||||
{
|
||||
delete pkt->req;
|
||||
delete pkt;
|
||||
|
|
Loading…
Reference in a new issue