summaryrefslogtreecommitdiff
path: root/src/mem
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem')
-rw-r--r--src/mem/cache/base_cache.cc52
-rw-r--r--src/mem/cache/base_cache.hh29
-rw-r--r--src/mem/cache/cache.hh7
-rw-r--r--src/mem/cache/cache_blk.hh4
-rw-r--r--src/mem/cache/cache_impl.hh26
-rw-r--r--src/mem/cache/coherence/coherence_protocol.cc4
-rw-r--r--src/mem/cache/miss/blocking_buffer.cc22
-rw-r--r--src/mem/cache/miss/blocking_buffer.hh7
-rw-r--r--src/mem/cache/miss/miss_queue.cc36
-rw-r--r--src/mem/cache/miss/miss_queue.hh4
-rw-r--r--src/mem/cache/miss/mshr.cc11
-rw-r--r--src/mem/cache/miss/mshr.hh2
-rw-r--r--src/mem/cache/miss/mshr_queue.cc6
-rw-r--r--src/mem/cache/miss/mshr_queue.hh4
-rw-r--r--src/mem/cache/prefetch/base_prefetcher.cc4
-rw-r--r--src/mem/cache/tags/fa_lru.cc4
-rw-r--r--src/mem/cache/tags/iic.cc4
-rw-r--r--src/mem/cache/tags/lru.cc4
-rw-r--r--src/mem/cache/tags/split_lifo.cc4
-rw-r--r--src/mem/cache/tags/split_lru.cc4
-rw-r--r--src/mem/config/cache.hh42
-rw-r--r--src/mem/packet.cc13
-rw-r--r--src/mem/packet.hh22
-rw-r--r--src/mem/request.hh3
24 files changed, 200 insertions, 118 deletions
diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc
index 10a49edb1..89e23ce31 100644
--- a/src/mem/cache/base_cache.cc
+++ b/src/mem/cache/base_cache.cc
@@ -45,11 +45,11 @@ BaseCache::CachePort::CachePort(const std::string &_name, BaseCache *_cache,
{
blocked = false;
//Start ports at null if more than one is created we should panic
- cpuSidePort = NULL;
- memSidePort = NULL;
+ //cpuSidePort = NULL;
+ //memSidePort = NULL;
}
-bool
+void
BaseCache::CachePort::recvStatusChange(Port::Status status)
{
cache->recvStatusChange(status, isCpuSide);
@@ -121,12 +121,16 @@ BaseCache::getPort(const std::string &if_name)
void
BaseCache::regStats()
{
+ Request temp_req;
+ Packet::Command temp_cmd = Packet::ReadReq;
+ Packet temp_pkt(&temp_req, temp_cmd, 0); //@todo FIx command strings so this isn't neccessary
+
using namespace Stats;
// Hit statistics
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::CommandEnum)access_idx;
- const string &cstr = cmd.toString();
+ Packet::Command cmd = (Packet::Command)access_idx;
+ const string &cstr = temp_pkt.cmdIdxToString(cmd);
hits[access_idx]
.init(maxThreadsPerCPU)
@@ -141,20 +145,20 @@ BaseCache::regStats()
.desc("number of demand (read+write) hits")
.flags(total)
;
- demandHits = hits[Read] + hits[Write];
+ demandHits = hits[Packet::ReadReq] + hits[Packet::WriteReq];
overallHits
.name(name() + ".overall_hits")
.desc("number of overall hits")
.flags(total)
;
- overallHits = demandHits + hits[Soft_Prefetch] + hits[Hard_Prefetch]
- + hits[Writeback];
+ overallHits = demandHits + hits[Packet::SoftPFReq] + hits[Packet::HardPFReq]
+ + hits[Packet::Writeback];
// Miss statistics
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::CommandEnum)access_idx;
- const string &cstr = cmd.toString();
+ Packet::Command cmd = (Packet::Command)access_idx;
+ const string &cstr = temp_pkt.cmdIdxToString(cmd);
misses[access_idx]
.init(maxThreadsPerCPU)
@@ -169,20 +173,20 @@ BaseCache::regStats()
.desc("number of demand (read+write) misses")
.flags(total)
;
- demandMisses = misses[Read] + misses[Write];
+ demandMisses = misses[Packet::ReadReq] + misses[Packet::WriteReq];
overallMisses
.name(name() + ".overall_misses")
.desc("number of overall misses")
.flags(total)
;
- overallMisses = demandMisses + misses[Soft_Prefetch] +
- misses[Hard_Prefetch] + misses[Writeback];
+ overallMisses = demandMisses + misses[Packet::SoftPFReq] +
+ misses[Packet::HardPFReq] + misses[Packet::Writeback];
// Miss latency statistics
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::CommandEnum)access_idx;
- const string &cstr = cmd.toString();
+ Packet::Command cmd = (Packet::Command)access_idx;
+ const string &cstr = temp_pkt.cmdIdxToString(cmd);
missLatency[access_idx]
.init(maxThreadsPerCPU)
@@ -197,20 +201,20 @@ BaseCache::regStats()
.desc("number of demand (read+write) miss cycles")
.flags(total)
;
- demandMissLatency = missLatency[Read] + missLatency[Write];
+ demandMissLatency = missLatency[Packet::ReadReq] + missLatency[Packet::WriteReq];
overallMissLatency
.name(name() + ".overall_miss_latency")
.desc("number of overall miss cycles")
.flags(total)
;
- overallMissLatency = demandMissLatency + missLatency[Soft_Prefetch] +
- missLatency[Hard_Prefetch];
+ overallMissLatency = demandMissLatency + missLatency[Packet::SoftPFReq] +
+ missLatency[Packet::HardPFReq];
// access formulas
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::CommandEnum)access_idx;
- const string &cstr = cmd.toString();
+ Packet::Command cmd = (Packet::Command)access_idx;
+ const string &cstr = temp_pkt.cmdIdxToString(cmd);
accesses[access_idx]
.name(name() + "." + cstr + "_accesses")
@@ -237,8 +241,8 @@ BaseCache::regStats()
// miss rate formulas
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::CommandEnum)access_idx;
- const string &cstr = cmd.toString();
+ Packet::Command cmd = (Packet::Command)access_idx;
+ const string &cstr = temp_pkt.cmdIdxToString(cmd);
missRate[access_idx]
.name(name() + "." + cstr + "_miss_rate")
@@ -265,8 +269,8 @@ BaseCache::regStats()
// miss latency formulas
for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) {
- Packet::Command cmd = (Packet::CommandEnum)access_idx;
- const string &cstr = cmd.toString();
+ Packet::Command cmd = (Packet::Command)access_idx;
+ const string &cstr = temp_pkt.cmdIdxToString(cmd);
avgMissLatency[access_idx]
.name(name() + "." + cstr + "_avg_miss_latency")
diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh
index 0170b0249..977e0ae29 100644
--- a/src/mem/cache/base_cache.hh
+++ b/src/mem/cache/base_cache.hh
@@ -47,6 +47,7 @@
#include "mem/packet.hh"
#include "mem/port.hh"
#include "mem/request.hh"
+#include "sim/eventq.hh"
/**
* Reasons for Caches to be Blocked.
@@ -82,7 +83,7 @@ class BaseCache : public MemObject
public:
CachePort(const std::string &_name, BaseCache *_cache, bool _isCpuSide);
- private:
+ protected:
virtual bool recvTiming(Packet *pkt);
virtual Tick recvAtomic(Packet *pkt);
@@ -96,6 +97,7 @@ class BaseCache : public MemObject
virtual int deviceBlockSize();
+ public:
void setBlocked();
void clearBlocked();
@@ -110,10 +112,10 @@ class BaseCache : public MemObject
Packet *pkt;
CachePort *cachePort;
- CacheResponseEvent(Packet *pkt, CachePort *cachePort);
+ CacheEvent(Packet *pkt, CachePort *cachePort);
void process();
const char *description();
- }
+ };
protected:
CachePort *cpuSidePort;
@@ -124,7 +126,7 @@ class BaseCache : public MemObject
private:
//To be defined in cache_impl.hh not in base class
- virtual bool doTimingAccess(Packet *pkt, MemoryPort *memoryPort, bool isCpuSide);
+ virtual bool doTimingAccess(Packet *pkt, CachePort *cachePort, bool isCpuSide);
virtual Tick doAtomicAccess(Packet *pkt, bool isCpuSide);
virtual void doFunctionalAccess(Packet *pkt, bool isCpuSide);
virtual void recvStatusChange(Port::Status status, bool isCpuSide);
@@ -275,12 +277,14 @@ class BaseCache : public MemObject
* of this cache.
* @param params The parameter object for this BaseCache.
*/
- BaseCache(const std::string &name, HierParams *hier_params, Params &params)
- : BaseMem(name, hier_params, params.hitLatency, params.addrRange),
- blocked(0), blockedSnoop(0), masterRequests(0), slaveRequests(0),
- topLevelCache(false), blkSize(params.blkSize),
+ BaseCache(const std::string &name, Params &params)
+ : MemObject(name), blocked(0), blockedSnoop(0), masterRequests(0),
+ slaveRequests(0), topLevelCache(false), blkSize(params.blkSize),
missCount(params.maxMisses)
{
+ //Start ports at null if more than one is created we should panic
+ cpuSidePort = NULL;
+ memSidePort = NULL;
}
/**
@@ -453,8 +457,8 @@ class BaseCache : public MemObject
*/
void respondToMiss(Packet *pkt, Tick time)
{
- if (!pkt->isUncacheable()) {
- missLatency[pkt->cmd.toIndex()][pkt->thread_num] += time - pkt->time;
+ if (!pkt->req->isUncacheable()) {
+ missLatency[pkt->cmdToIndex()][pkt->req->getThreadNum()] += time - pkt->time;
}
assert("Implement\n" && 0);
// si->respond(pkt,time);
@@ -475,6 +479,11 @@ class BaseCache : public MemObject
* to do for a cache.
*/
void rangeChange() {}
+
+ void getAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
+ {
+ panic("Unimplimented\n");
+ }
};
#endif //__BASE_CACHE_HH__
diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh
index dcb22a99c..78e87479b 100644
--- a/src/mem/cache/cache.hh
+++ b/src/mem/cache/cache.hh
@@ -46,7 +46,6 @@
// forward declarations
class Bus;
-class ExecContext;
/**
* A template-policy based cache. The behavior of the cache can be altered by
@@ -209,11 +208,11 @@ class Cache : public BaseCache
/**
* Aquash all requests associated with specified thread.
* intended for use by I-cache.
- * @param thread_number The thread to squash.
+ * @param req->getThreadNum()ber The thread to squash.
*/
- void squash(int thread_number)
+ void squash(int threadNum)
{
- missQueue->squash(thread_number);
+ missQueue->squash(threadNum);
}
/**
diff --git a/src/mem/cache/cache_blk.hh b/src/mem/cache/cache_blk.hh
index cf1bd20e2..02fdd7a51 100644
--- a/src/mem/cache/cache_blk.hh
+++ b/src/mem/cache/cache_blk.hh
@@ -37,7 +37,6 @@
#include "sim/root.hh" // for Tick
#include "arch/isa_traits.hh" // for Addr
-#include "cpu/exec_context.hh"
/**
* Cache block status bit assignments
@@ -88,9 +87,6 @@ class CacheBlk
/** Which curTick will this block be accessable */
Tick whenReady;
- /** Save the exec context so that writebacks can use them. */
- ExecContext *xc;
-
/**
* The set this block belongs to.
* @todo Move this into subclasses when we fix CacheTags to use them.
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index 3dd8d74cd..3dc95af68 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -175,7 +175,7 @@ Cache<TagStore,Buffering,Coherence>::access(Packet &pkt)
//We are determining prefetches on access stream, call prefetcher
prefetcher->handleMiss(pkt, curTick);
}
- if (!pkt->isUncacheable()) {
+ if (!pkt->req->isUncacheable()) {
if (pkt->cmd.isInvalidate() && !pkt->cmd.isRead()
&& !pkt->cmd.isWrite()) {
//Upgrade or Invalidate
@@ -220,7 +220,7 @@ Cache<TagStore,Buffering,Coherence>::access(Packet &pkt)
pkt->paddr & ~((Addr)blkSize - 1), pkt->pc);
if (blk) {
// Hit
- hits[pkt->cmd.toIndex()][pkt->thread_num]++;
+ hits[pkt->cmdToIndex()][pkt->req->getThreadNum()]++;
// clear dirty bit if write through
if (!pkt->cmd.isNoResponse())
respond(pkt, curTick+lat);
@@ -228,8 +228,8 @@ Cache<TagStore,Buffering,Coherence>::access(Packet &pkt)
}
// Miss
- if (!pkt->isUncacheable()) {
- misses[pkt->cmd.toIndex()][pkt->thread_num]++;
+ if (!pkt->req->isUncacheable()) {
+ misses[pkt->cmdToIndex()][pkt->req->getThreadNum()]++;
/** @todo Move miss count code into BaseCache */
if (missCount) {
--missCount;
@@ -248,8 +248,8 @@ Cache<TagStore,Buffering,Coherence>::getPacket()
{
Packet * pkt = missQueue->getPacket();
if (pkt) {
- if (!pkt->isUncacheable()) {
- if (pkt->cmd == Hard_Prefetch) misses[Hard_Prefetch][pkt->thread_num]++;
+ if (!pkt->req->isUncacheable()) {
+ if (pkt->cmd == Hard_Prefetch) misses[Hard_Prefetch][pkt->req->getThreadNum()]++;
BlkType *blk = tags->findBlock(pkt);
Packet::Command cmd = coherence->getBusCmd(pkt->cmd,
(blk)? blk->status : 0);
@@ -272,7 +272,7 @@ Cache<TagStore,Buffering,Coherence>::sendResult(MemPktPtr &pkt, bool success)
if (pkt->cmd == Upgrade) {
handleResponse(pkt);
}
- } else if (pkt && !pkt->isUncacheable()) {
+ } else if (pkt && !pkt->req->isUncacheable()) {
missQueue->restoreOrigCmd(pkt);
}
}
@@ -394,7 +394,7 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
for (int i=0; i<writebacks.size(); i++) {
mshr = writebacks[i];
- if (!mshr->pkt->isUncacheable()) {
+ if (!mshr->pkt->req->isUncacheable()) {
if (pkt->cmd.isRead()) {
//Only Upgrades don't get here
//Supply the data
@@ -469,7 +469,7 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update)
{
MemDebug::cacheProbe(pkt);
- if (!pkt->isUncacheable()) {
+ if (!pkt->req->isUncacheable()) {
if (pkt->cmd.isInvalidate() && !pkt->cmd.isRead()
&& !pkt->cmd.isWrite()) {
//Upgrade or Invalidate, satisfy it, don't forward
@@ -583,7 +583,7 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update)
// Can't handle it, return pktuest unsatisfied.
return 0;
}
- if (!pkt->isUncacheable()) {
+ if (!pkt->req->isUncacheable()) {
// Fetch the cache block to fill
Packet * busPkt = new MemPkt();
busPkt->paddr = blk_addr;
@@ -596,7 +596,7 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update)
busPkt->req->asid = pkt->req->asid;
busPkt->xc = pkt->xc;
- busPkt->thread_num = pkt->thread_num;
+ busPkt->req->setThreadNum() = pkt->req->getThreadNum();
busPkt->time = curTick;
lat = mi->sendProbe(busPkt, update);
@@ -606,7 +606,7 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update)
return 0;
}
- misses[pkt->cmd.toIndex()][pkt->thread_num]++;
+ misses[pkt->cmdToIndex()][pkt->req->getThreadNum()]++;
CacheBlk::State old_state = (blk) ? blk->status : 0;
tags->handleFill(blk, busPkt,
@@ -631,7 +631,7 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update)
}
if (update) {
- hits[pkt->cmd.toIndex()][pkt->thread_num]++;
+ hits[pkt->cmdToIndex()][pkt->req->getThreadNum()]++;
} else if (pkt->cmd.isWrite()) {
// Still need to change data in all locations.
return mi->sendProbe(pkt, update);
diff --git a/src/mem/cache/coherence/coherence_protocol.cc b/src/mem/cache/coherence/coherence_protocol.cc
index 107fd2502..9d5b8ef54 100644
--- a/src/mem/cache/coherence/coherence_protocol.cc
+++ b/src/mem/cache/coherence/coherence_protocol.cc
@@ -465,7 +465,7 @@ CacheBlk::State
CoherenceProtocol::getNewState(const Packet * &pkt, CacheBlk::State oldState)
{
CacheBlk::State state = oldState & stateMask;
- int cmd_idx = pkt->cmd.toIndex();
+ int cmd_idx = pkt->cmdToIndex();
assert(0 <= state && state <= stateMax);
assert(0 <= cmd_idx && cmd_idx < NUM_MEM_CMDS);
@@ -498,7 +498,7 @@ CoherenceProtocol::handleBusRequest(BaseCache *cache, Packet * &pkt,
}
CacheBlk::State state = blk->status & stateMask;
- int cmd_idx = pkt->cmd.toIndex();
+ int cmd_idx = pkt->cmdToIndex();
assert(0 <= state && state <= stateMax);
assert(0 <= cmd_idx && cmd_idx < NUM_MEM_CMDS);
diff --git a/src/mem/cache/miss/blocking_buffer.cc b/src/mem/cache/miss/blocking_buffer.cc
index 621855c3d..912a0f5bd 100644
--- a/src/mem/cache/miss/blocking_buffer.cc
+++ b/src/mem/cache/miss/blocking_buffer.cc
@@ -73,7 +73,7 @@ void
BlockingBuffer::handleMiss(Packet * &pkt, int blk_size, Tick time)
{
Addr blk_addr = pkt->paddr & ~(Addr)(blk_size - 1);
- if (pkt->cmd.isWrite() && (pkt->isUncacheable() || !writeAllocate ||
+ if (pkt->cmd.isWrite() && (pkt->req->isUncacheable() || !writeAllocate ||
pkt->cmd.isNoResponse())) {
if (pkt->cmd.isNoResponse()) {
wb.allocateAsBuffer(pkt);
@@ -93,7 +93,7 @@ BlockingBuffer::handleMiss(Packet * &pkt, int blk_size, Tick time)
} else {
miss.allocate(pkt->cmd, blk_addr, pkt->req->asid, blk_size, pkt);
}
- if (!pkt->isUncacheable()) {
+ if (!pkt->req->isUncacheable()) {
miss.pkt->flags |= CACHE_LINE_FILL;
}
cache->setBlocked(Blocked_NoMSHRs);
@@ -186,12 +186,12 @@ BlockingBuffer::handleResponse(Packet * &pkt, Tick time)
}
void
-BlockingBuffer::squash(int thread_number)
+BlockingBuffer::squash(int req->getThreadNum()ber)
{
- if (miss.threadNum == thread_number) {
+ if (miss.setThreadNum() == req->getThreadNum()ber) {
Packet * target = miss.getTarget();
miss.popTarget();
- assert(target->thread_num == thread_number);
+ assert(target->req->setThreadNum() == req->getThreadNum()ber);
if (target->completionEvent != NULL) {
delete target->completionEvent;
}
@@ -207,7 +207,7 @@ BlockingBuffer::squash(int thread_number)
}
void
-BlockingBuffer::doWriteback(Addr addr, int asid, ExecContext *xc,
+BlockingBuffer::doWriteback(Addr addr, int asid,
int size, uint8_t *data, bool compressed)
{
@@ -224,18 +224,14 @@ BlockingBuffer::doWriteback(Addr addr, int asid, ExecContext *xc,
* @todo Need to find a way to charge the writeback to the "correct"
* thread.
*/
- pkt->xc = xc;
- if (xc)
- pkt->thread_num = xc->getThreadNum();
- else
- pkt->thread_num = 0;
+ pkt->req->setThreadNum() = 0;
pkt->cmd = Writeback;
if (compressed) {
pkt->flags |= COMPRESSED;
}
- writebacks[pkt->thread_num]++;
+ writebacks[pkt->req->getThreadNum()]++;
wb.allocateAsBuffer(pkt);
cache->setMasterRequest(Request_WB, curTick);
@@ -247,7 +243,7 @@ BlockingBuffer::doWriteback(Addr addr, int asid, ExecContext *xc,
void
BlockingBuffer::doWriteback(Packet * &pkt)
{
- writebacks[pkt->thread_num]++;
+ writebacks[pkt->req->getThreadNum()]++;
wb.allocateAsBuffer(pkt);
diff --git a/src/mem/cache/miss/blocking_buffer.hh b/src/mem/cache/miss/blocking_buffer.hh
index 52256be74..08814b43e 100644
--- a/src/mem/cache/miss/blocking_buffer.hh
+++ b/src/mem/cache/miss/blocking_buffer.hh
@@ -164,9 +164,9 @@ public:
/**
* Removes all outstanding requests for a given thread number. If a request
* has been sent to the bus, this function removes all of its targets.
- * @param thread_number The thread number of the requests to squash.
+ * @param req->getThreadNum()ber The thread number of the requests to squash.
*/
- void squash(int thread_number);
+ void squash(int req->getThreadNum()ber);
/**
* Return the current number of outstanding misses.
@@ -212,12 +212,11 @@ public:
* Perform a writeback of dirty data to the given address.
* @param addr The address to write to.
* @param asid The address space id.
- * @param xc The execution context of the address space.
* @param size The number of bytes to write.
* @param data The data to write, can be NULL.
* @param compressed True if the data is compressed.
*/
- void doWriteback(Addr addr, int asid, ExecContext *xc,
+ void doWriteback(Addr addr, int asid,
int size, uint8_t *data, bool compressed);
/**
diff --git a/src/mem/cache/miss/miss_queue.cc b/src/mem/cache/miss/miss_queue.cc
index 7902fbcee..d02f27d52 100644
--- a/src/mem/cache/miss/miss_queue.cc
+++ b/src/mem/cache/miss/miss_queue.cc
@@ -347,7 +347,7 @@ MissQueue::allocateMiss(Packet * &pkt, int size, Tick time)
{
MSHR* mshr = mq.allocate(pkt, size);
mshr->order = order++;
- if (!pkt->isUncacheable() ){//&& !pkt->isNoAllocate()) {
+ if (!pkt->req->isUncacheable() ){//&& !pkt->isNoAllocate()) {
// Mark this as a cache line fill
mshr->pkt->flags |= CACHE_LINE_FILL;
}
@@ -399,13 +399,13 @@ MissQueue::handleMiss(Packet * &pkt, int blkSize, Tick time)
int size = blkSize;
Addr blkAddr = pkt->paddr & ~(Addr)(blkSize-1);
MSHR* mshr = NULL;
- if (!pkt->isUncacheable()) {
+ if (!pkt->req->isUncacheable()) {
mshr = mq.findMatch(blkAddr, pkt->req->asid);
if (mshr) {
//@todo remove hw_pf here
- mshr_hits[pkt->cmd.toIndex()][pkt->thread_num]++;
- if (mshr->threadNum != pkt->thread_num) {
- mshr->threadNum = -1;
+ mshr_hits[pkt->cmdToIndex()][pkt->req->getThreadNum()]++;
+ if (mshr->getThreadNum() != pkt->req->getThreadNum()) {
+ mshr->setThreadNum() = -1;
}
mq.allocateTarget(mshr, pkt);
if (mshr->pkt->isNoAllocate() && !pkt->isNoAllocate()) {
@@ -424,14 +424,14 @@ MissQueue::handleMiss(Packet * &pkt, int blkSize, Tick time)
mshr_no_allocate_misses++;
}
else {
- mshr_misses[pkt->cmd.toIndex()][pkt->thread_num]++;
+ mshr_misses[pkt->cmdToIndex()][pkt->req->getThreadNum()]++;
}
} else {
//Count uncacheable accesses
- mshr_uncacheable[pkt->cmd.toIndex()][pkt->thread_num]++;
+ mshr_uncacheable[pkt->cmdToIndex()][pkt->req->getThreadNum()]++;
size = pkt->size;
}
- if (pkt->cmd.isWrite() && (pkt->isUncacheable() || !writeAllocate ||
+ if (pkt->cmd.isWrite() && (pkt->req->isUncacheable() || !writeAllocate ||
pkt->cmd.isNoResponse())) {
/**
* @todo Add write merging here.
@@ -489,7 +489,7 @@ MissQueue::getPacket()
pkt = prefetcher->getPacket();
if (pkt) {
//Update statistic on number of prefetches issued (hwpf_mshr_misses)
- mshr_misses[pkt->cmd.toIndex()][pkt->thread_num]++;
+ mshr_misses[pkt->cmdToIndex()][pkt->req->getThreadNum()]++;
//It will request the bus for the future, but should clear that immedieatley
allocateMiss(pkt, pkt->size, curTick);
pkt = mq.getReq();
@@ -582,7 +582,7 @@ MissQueue::handleResponse(Packet * &pkt, Tick time)
BlockedCause cause = NUM_BLOCKED_CAUSES;
if (pkt->isCacheFill() && !pkt->isNoAllocate()) {
- mshr_miss_latency[mshr->originalCmd][pkt->thread_num] +=
+ mshr_miss_latency[mshr->originalCmd][pkt->req->getThreadNum()] +=
curTick - pkt->time;
// targets were handled in the cache tags
if (mshr == noTargetMSHR) {
@@ -608,11 +608,11 @@ MissQueue::handleResponse(Packet * &pkt, Tick time)
}
}
} else {
- if (pkt->isUncacheable()) {
- mshr_uncacheable_lat[pkt->cmd][pkt->thread_num] +=
+ if (pkt->req->isUncacheable()) {
+ mshr_uncacheable_lat[pkt->cmd][pkt->req->getThreadNum()] +=
curTick - pkt->time;
}
- if (mshr->hasTargets() && pkt->isUncacheable()) {
+ if (mshr->hasTargets() && pkt->req->isUncacheable()) {
// Should only have 1 target if we had any
assert(num_targets == 1);
Packet * target = mshr->getTarget();
@@ -660,12 +660,12 @@ MissQueue::handleResponse(Packet * &pkt, Tick time)
}
void
-MissQueue::squash(int thread_number)
+MissQueue::squash(int req->getThreadNum()ber)
{
bool unblock = false;
BlockedCause cause = NUM_BLOCKED_CAUSES;
- if (noTargetMSHR && noTargetMSHR->threadNum == thread_number) {
+ if (noTargetMSHR && noTargetMSHR->setThreadNum() == req->getThreadNum()ber) {
noTargetMSHR = NULL;
unblock = true;
cause = Blocked_NoTargets;
@@ -674,7 +674,7 @@ MissQueue::squash(int thread_number)
unblock = true;
cause = Blocked_NoMSHRs;
}
- mq.squash(thread_number);
+ mq.squash(req->getThreadNum()ber);
if (!mq.havePending()) {
cache->clearMasterRequest(Request_MSHR);
}
@@ -704,7 +704,7 @@ MissQueue::doWriteback(Addr addr, int asid,
Packet * pkt = buildWritebackReq(addr, asid, size, data,
compressed);
- writebacks[pkt->thread_num]++;
+ writebacks[pkt->req->getThreadNum()]++;
allocateWrite(pkt, 0, curTick);
}
@@ -713,7 +713,7 @@ MissQueue::doWriteback(Addr addr, int asid,
void
MissQueue::doWriteback(Packet * &pkt)
{
- writebacks[pkt->thread_num]++;
+ writebacks[pkt->req->getThreadNum()]++;
allocateWrite(pkt, 0, curTick);
}
diff --git a/src/mem/cache/miss/miss_queue.hh b/src/mem/cache/miss/miss_queue.hh
index ce827fe81..d45982108 100644
--- a/src/mem/cache/miss/miss_queue.hh
+++ b/src/mem/cache/miss/miss_queue.hh
@@ -268,9 +268,9 @@ class MissQueue
/**
* Removes all outstanding requests for a given thread number. If a request
* has been sent to the bus, this function removes all of its targets.
- * @param thread_number The thread number of the requests to squash.
+ * @param req->getThreadNum()ber The thread number of the requests to squash.
*/
- void squash(int thread_number);
+ void squash(int req->getThreadNum()ber);
/**
* Return the current number of outstanding misses.
diff --git a/src/mem/cache/miss/mshr.cc b/src/mem/cache/miss/mshr.cc
index 73aeaf6ca..5c3c9fd1d 100644
--- a/src/mem/cache/miss/mshr.cc
+++ b/src/mem/cache/miss/mshr.cc
@@ -50,7 +50,7 @@ MSHR::MSHR()
{
inService = false;
ntargets = 0;
- threadNum = -1;
+ setThreadNum() = -1;
}
void
@@ -68,7 +68,7 @@ MSHR::allocate(Packet::Command cmd, Addr _addr, int _asid, int size,
pkt->data = new uint8_t[size];
pkt->senderState = this;
//Set the time here for latency calculations
- //pkt->time = curTick;
+ pkt->time = curTick;
if (target) {
pkt->req = target->req;
@@ -85,7 +85,7 @@ MSHR::allocateAsBuffer(Packet * &target)
{
addr = target->paddr;
asid = target->req->asid;
- threadNum = target->thread_num;
+ setThreadNum() = target->req->getThreadNum();
pkt = new Packet();
pkt->addr = target->addr;
pkt->dest = target->dest;
@@ -94,6 +94,7 @@ MSHR::allocateAsBuffer(Packet * &target)
pkt->req = target->req;
pkt->data = new uint8_t[target->size];
pkt->senderState = this;
+ pkt->time = curTick;
}
void
@@ -161,14 +162,14 @@ MSHR::dump()
"inService: %d thread: %d\n"
"Addr: %x asid: %d ntargets %d\n"
"Targets:\n",
- inService, threadNum, addr, asid, ntargets);
+ inService, getThreadNum(), addr, asid, ntargets);
TargetListIterator tar_it = targets.begin();
for (int i = 0; i < ntargets; i++) {
assert(tar_it != targets.end());
ccprintf(cerr, "\t%d: Addr: %x cmd: %d\n",
- i, (*tar_it)->paddr, (*tar_it)->cmd.toIndex());
+ i, (*tar_it)->paddr, (*tar_it)->cmdToIndex());
tar_it++;
}
diff --git a/src/mem/cache/miss/mshr.hh b/src/mem/cache/miss/mshr.hh
index 167aa26cd..3bd6d36d1 100644
--- a/src/mem/cache/miss/mshr.hh
+++ b/src/mem/cache/miss/mshr.hh
@@ -66,7 +66,7 @@ class MSHR {
/** True if the request has been sent to the bus. */
bool inService;
/** Thread number of the miss. */
- int threadNum;
+ int getThreadNum();
/** The request that is forwarded to the next level of the hierarchy. */
Packet * pkt;
/** The number of currently allocated targets. */
diff --git a/src/mem/cache/miss/mshr_queue.cc b/src/mem/cache/miss/mshr_queue.cc
index 72c8cc498..ced43d30a 100644
--- a/src/mem/cache/miss/mshr_queue.cc
+++ b/src/mem/cache/miss/mshr_queue.cc
@@ -237,18 +237,18 @@ MSHRQueue::markPending(MSHR* mshr, Packet::Command cmd)
}
void
-MSHRQueue::squash(int thread_number)
+MSHRQueue::squash(int req->getThreadNum()ber)
{
MSHR::Iterator i = allocatedList.begin();
MSHR::Iterator end = allocatedList.end();
for (; i != end;) {
MSHR *mshr = *i;
- if (mshr->threadNum == thread_number) {
+ if (mshr->setThreadNum() == req->getThreadNum()ber) {
while (mshr->hasTargets()) {
Packet * target = mshr->getTarget();
mshr->popTarget();
- assert(target->thread_num == thread_number);
+ assert(target->req->setThreadNum() == req->getThreadNum()ber);
if (target->completionEvent != NULL) {
delete target->completionEvent;
}
diff --git a/src/mem/cache/miss/mshr_queue.hh b/src/mem/cache/miss/mshr_queue.hh
index 3e1d3f39f..563368d29 100644
--- a/src/mem/cache/miss/mshr_queue.hh
+++ b/src/mem/cache/miss/mshr_queue.hh
@@ -190,9 +190,9 @@ class MSHRQueue {
/**
* Squash outstanding requests with the given thread number. If a request
* is in service, just squashes the targets.
- * @param thread_number The thread to squash.
+ * @param req->getThreadNum()ber The thread to squash.
*/
- void squash(int thread_number);
+ void squash(int req->getThreadNum()ber);
/**
* Returns true if the pending list is not empty.
diff --git a/src/mem/cache/prefetch/base_prefetcher.cc b/src/mem/cache/prefetch/base_prefetcher.cc
index 14beef260..7b2d57cd5 100644
--- a/src/mem/cache/prefetch/base_prefetcher.cc
+++ b/src/mem/cache/prefetch/base_prefetcher.cc
@@ -132,7 +132,7 @@ BasePrefetcher::getPacket()
void
BasePrefetcher::handleMiss(Packet * &pkt, Tick time)
{
- if (!pkt->isUncacheable() && !(pkt->isInstRead() && only_data))
+ if (!pkt->req->isUncacheable() && !(pkt->isInstRead() && only_data))
{
//Calculate the blk address
Addr blkAddr = pkt->paddr & ~(Addr)(blkSize-1);
@@ -185,7 +185,7 @@ BasePrefetcher::handleMiss(Packet * &pkt, Tick time)
prefetch->xc = pkt->xc;
prefetch->data = new uint8_t[blkSize];
prefetch->req->asid = pkt->req->asid;
- prefetch->thread_num = pkt->thread_num;
+ prefetch->req->setThreadNum() = pkt->req->getThreadNum();
prefetch->time = time + (*delay); //@todo ADD LATENCY HERE
//... initialize
diff --git a/src/mem/cache/tags/fa_lru.cc b/src/mem/cache/tags/fa_lru.cc
index 66d91b35b..43ab36309 100644
--- a/src/mem/cache/tags/fa_lru.cc
+++ b/src/mem/cache/tags/fa_lru.cc
@@ -264,8 +264,8 @@ FALRU::findReplacement(Packet * &pkt, PacketList* &writebacks,
tagHash.erase(blk->tag);
tagHash[blkAlign(pkt->paddr)] = blk;
if (blk->isValid()) {
- int thread_num = (blk->xc) ? blk->xc->getThreadNum() : 0;
- replacements[thread_num]++;
+ int req->setThreadNum() = (blk->xc) ? blk->xc->getThreadNum() : 0;
+ replacements[req->getThreadNum()]++;
} else {
tagsInUse++;
blk->isTouched = true;
diff --git a/src/mem/cache/tags/iic.cc b/src/mem/cache/tags/iic.cc
index a574adaa3..f4641401f 100644
--- a/src/mem/cache/tags/iic.cc
+++ b/src/mem/cache/tags/iic.cc
@@ -418,8 +418,8 @@ IIC::freeReplacementBlock(PacketList* & writebacks)
tag_ptr->isModified() ? "writeback" : "clean");
/* write back replaced block data */
if (tag_ptr && (tag_ptr->isValid())) {
- int thread_num = (tag_ptr->xc) ? tag_ptr->xc->getThreadNum() : 0;
- replacements[thread_num]++;
+ int req->setThreadNum() = (tag_ptr->xc) ? tag_ptr->xc->getThreadNum() : 0;
+ replacements[req->getThreadNum()]++;
totalRefs += tag_ptr->refCount;
++sampledRefs;
tag_ptr->refCount = 0;
diff --git a/src/mem/cache/tags/lru.cc b/src/mem/cache/tags/lru.cc
index 0fe88fd08..19a52aade 100644
--- a/src/mem/cache/tags/lru.cc
+++ b/src/mem/cache/tags/lru.cc
@@ -225,8 +225,8 @@ LRU::findReplacement(Packet * &pkt, PacketList* &writebacks,
LRUBlk *blk = sets[set].blks[assoc-1];
sets[set].moveToHead(blk);
if (blk->isValid()) {
- int thread_num = (blk->xc) ? blk->xc->getThreadNum() : 0;
- replacements[thread_num]++;
+ int req->setThreadNum() = (blk->xc) ? blk->xc->getThreadNum() : 0;
+ replacements[req->getThreadNum()]++;
totalRefs += blk->refCount;
++sampledRefs;
blk->refCount = 0;
diff --git a/src/mem/cache/tags/split_lifo.cc b/src/mem/cache/tags/split_lifo.cc
index f2c37c80d..c6bb91eff 100644
--- a/src/mem/cache/tags/split_lifo.cc
+++ b/src/mem/cache/tags/split_lifo.cc
@@ -317,8 +317,8 @@ SplitLIFO::findReplacement(Packet * &pkt, PacketList* &writebacks,
DPRINTF(Split, "just assigned %#x addr into LIFO, replacing %#x status %#x\n",
pkt->paddr, regenerateBlkAddr(blk->tag, set), blk->status);
if (blk->isValid()) {
- int thread_num = (blk->xc) ? blk->xc->getThreadNum() : 0;
- replacements[thread_num]++;
+ int req->setThreadNum() = (blk->xc) ? blk->xc->getThreadNum() : 0;
+ replacements[req->getThreadNum()]++;
totalRefs += blk->refCount;
++sampledRefs;
blk->refCount = 0;
diff --git a/src/mem/cache/tags/split_lru.cc b/src/mem/cache/tags/split_lru.cc
index ea5b92d6f..4b7f4c114 100644
--- a/src/mem/cache/tags/split_lru.cc
+++ b/src/mem/cache/tags/split_lru.cc
@@ -244,8 +244,8 @@ SplitLRU::findReplacement(Packet * &pkt, PacketList* &writebacks,
SplitBlk *blk = sets[set].blks[assoc-1];
sets[set].moveToHead(blk);
if (blk->isValid()) {
- int thread_num = (blk->xc) ? blk->xc->getThreadNum() : 0;
- replacements[thread_num]++;
+ int req->setThreadNum() = (blk->xc) ? blk->xc->getThreadNum() : 0;
+ replacements[req->getThreadNum()]++;
totalRefs += blk->refCount;
++sampledRefs;
blk->refCount = 0;
diff --git a/src/mem/config/cache.hh b/src/mem/config/cache.hh
new file mode 100644
index 000000000..24da04021
--- /dev/null
+++ b/src/mem/config/cache.hh
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ */
+
+/**
+ * @file
+ * Central location to configure which cache types we want to build
+ * into the simulator. In the future, this should probably be
+ * autogenerated by some sort of configuration script.
+ */
+#define USE_CACHE_LRU 1
+#define USE_CACHE_FALRU 1
+// #define USE_CACHE_SPLIT 1
+// #define USE_CACHE_SPLIT_LIFO 1
+#define USE_CACHE_IIC 1
+
diff --git a/src/mem/packet.cc b/src/mem/packet.cc
index 56dd2bdfa..91298df8c 100644
--- a/src/mem/packet.cc
+++ b/src/mem/packet.cc
@@ -57,6 +57,19 @@ Packet::cmdString() const
}
}
+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;
+ default: return OtherCmdString;
+ }
+}
+
/** delete the data pointed to in the data pointer. Ok to call to matter how
* data was allocted. */
void
diff --git a/src/mem/packet.hh b/src/mem/packet.hh
index 403039d96..176c6f793 100644
--- a/src/mem/packet.hh
+++ b/src/mem/packet.hh
@@ -46,6 +46,10 @@ struct Packet;
typedef Packet* PacketPtr;
typedef uint8_t* PacketDataPtr;
+//For statistics we need max number of commands, hard code it at
+//20 for now. @todo fix later
+#define NUM_MEM_CMDS 1 << 9
+
/**
* 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
@@ -102,6 +106,9 @@ class Packet
public:
+ /** Used to calculate latencies for each packet.*/
+ Tick time;
+
/** The special destination address indicating that the packet
* should be routed based on its address. */
static const short Broadcast = -1;
@@ -149,6 +156,8 @@ class Packet
IsRequest = 1 << 4,
IsResponse = 1 << 5,
NeedsResponse = 1 << 6,
+ IsSWPrefetch = 1 << 7,
+ IsHWPrefetch = 1 << 8
};
public:
@@ -159,13 +168,24 @@ class Packet
WriteReq = IsWrite | IsRequest | NeedsResponse,
WriteReqNoAck = IsWrite | IsRequest,
ReadResp = IsRead | IsResponse,
- WriteResp = IsWrite | IsResponse
+ WriteResp = IsWrite | IsResponse,
+ Writeback = IsWrite | IsRequest,
+ SoftPFReq = IsRead | IsRequest | IsSWPrefetch | NeedsResponse,
+ HardPFReq = IsRead | IsRequest | IsHWPrefetch | NeedsResponse,
+ SoftPFResp = IsRead | IsRequest | IsSWPrefetch | IsResponse,
+ HardPFResp = IsRead | IsRequest | IsHWPrefetch | IsResponse
};
/** 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);
+
+ /** Return the index of this command. */
+ inline int cmdToIndex() const { return (int) cmd; }
+
/** The command field of the packet. */
Command cmd;
diff --git a/src/mem/request.hh b/src/mem/request.hh
index af1d6d8a8..469184b13 100644
--- a/src/mem/request.hh
+++ b/src/mem/request.hh
@@ -224,6 +224,9 @@ class Request
/** Accessor function for pc.*/
Addr getPC() { assert(validPC); return pc; }
+ /** Accessor Function to Check Cacheability. */
+ bool isUncacheable() { return getFlags() & UNCACHEABLE; }
+
friend class Packet;
};