Split CachePort class into CpuSidePort and MemSidePort
and push those into derived Cache template class to eliminate a few layers of virtual functions and conditionals ("if (isCpuSide) { ... }" etc.). --HG-- extra : convert_revision : cb1b88246c95b36aa0cf26d534127d3714ddb774
This commit is contained in:
parent
98bb1c62b3
commit
d172e1576a
4 changed files with 201 additions and 196 deletions
75
src/mem/cache/base_cache.cc
vendored
75
src/mem/cache/base_cache.cc
vendored
|
@ -51,6 +51,7 @@ BaseCache::CachePort::CachePort(const std::string &_name, BaseCache *_cache,
|
|||
//memSidePort = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BaseCache::CachePort::recvStatusChange(Port::Status status)
|
||||
{
|
||||
|
@ -70,38 +71,6 @@ BaseCache::CachePort::deviceBlockSize()
|
|||
return cache->getBlockSize();
|
||||
}
|
||||
|
||||
bool
|
||||
BaseCache::CachePort::recvTiming(PacketPtr pkt)
|
||||
{
|
||||
if (isCpuSide
|
||||
&& !pkt->req->isUncacheable()
|
||||
&& pkt->isInvalidate()
|
||||
&& !pkt->isRead() && !pkt->isWrite()) {
|
||||
//Upgrade or Invalidate
|
||||
//Look into what happens if two slave caches on bus
|
||||
DPRINTF(Cache, "%s %x ?\n", pkt->cmdString(), pkt->getAddr());
|
||||
|
||||
assert(!(pkt->flags & SATISFIED));
|
||||
pkt->flags |= SATISFIED;
|
||||
//Invalidates/Upgrades need no response if they get the bus
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pkt->isRequest() && blocked)
|
||||
{
|
||||
DPRINTF(Cache,"Scheduling a retry while blocked\n");
|
||||
mustSendRetry = true;
|
||||
return false;
|
||||
}
|
||||
return cache->doTimingAccess(pkt, this, isCpuSide);
|
||||
}
|
||||
|
||||
Tick
|
||||
BaseCache::CachePort::recvAtomic(PacketPtr pkt)
|
||||
{
|
||||
return cache->doAtomicAccess(pkt, isCpuSide);
|
||||
}
|
||||
|
||||
bool
|
||||
BaseCache::CachePort::checkFunctional(PacketPtr pkt)
|
||||
{
|
||||
|
@ -138,14 +107,6 @@ BaseCache::CachePort::checkFunctional(PacketPtr pkt)
|
|||
return notDone;
|
||||
}
|
||||
|
||||
void
|
||||
BaseCache::CachePort::recvFunctional(PacketPtr pkt)
|
||||
{
|
||||
bool notDone = checkFunctional(pkt);
|
||||
if (notDone)
|
||||
cache->doFunctionalAccess(pkt, isCpuSide);
|
||||
}
|
||||
|
||||
void
|
||||
BaseCache::CachePort::checkAndSendFunctional(PacketPtr pkt)
|
||||
{
|
||||
|
@ -398,40 +359,6 @@ BaseCache::CacheEvent::description()
|
|||
return "timing event\n";
|
||||
}
|
||||
|
||||
Port*
|
||||
BaseCache::getPort(const std::string &if_name, int idx)
|
||||
{
|
||||
if (if_name == "")
|
||||
{
|
||||
if(cpuSidePort == NULL) {
|
||||
cpuSidePort = new CachePort(name() + "-cpu_side_port", this, true);
|
||||
sendEvent = new CacheEvent(cpuSidePort, true);
|
||||
}
|
||||
return cpuSidePort;
|
||||
}
|
||||
else if (if_name == "functional")
|
||||
{
|
||||
return new CachePort(name() + "-cpu_side_port", this, true);
|
||||
}
|
||||
else if (if_name == "cpu_side")
|
||||
{
|
||||
if(cpuSidePort == NULL) {
|
||||
cpuSidePort = new CachePort(name() + "-cpu_side_port", this, true);
|
||||
sendEvent = new CacheEvent(cpuSidePort, true);
|
||||
}
|
||||
return cpuSidePort;
|
||||
}
|
||||
else if (if_name == "mem_side")
|
||||
{
|
||||
if (memSidePort != NULL)
|
||||
panic("Already have a mem side for this cache\n");
|
||||
memSidePort = new CachePort(name() + "-mem_side_port", this, false);
|
||||
memSendEvent = new CacheEvent(memSidePort, true);
|
||||
return memSidePort;
|
||||
}
|
||||
else panic("Port name %s unrecognized\n", if_name);
|
||||
}
|
||||
|
||||
void
|
||||
BaseCache::init()
|
||||
{
|
||||
|
|
54
src/mem/cache/base_cache.hh
vendored
54
src/mem/cache/base_cache.hh
vendored
|
@ -82,15 +82,8 @@ class BaseCache : public MemObject
|
|||
public:
|
||||
BaseCache *cache;
|
||||
|
||||
CachePort(const std::string &_name, BaseCache *_cache, bool _isCpuSide);
|
||||
|
||||
protected:
|
||||
virtual bool recvTiming(PacketPtr pkt);
|
||||
|
||||
virtual Tick recvAtomic(PacketPtr pkt);
|
||||
|
||||
virtual void recvFunctional(PacketPtr pkt);
|
||||
|
||||
CachePort(const std::string &_name, BaseCache *_cache, bool _isCpuSide);
|
||||
virtual void recvStatusChange(Status status);
|
||||
|
||||
virtual void getDeviceAddressRanges(AddrRangeList &resp,
|
||||
|
@ -137,33 +130,12 @@ class BaseCache : public MemObject
|
|||
|
||||
public: //Made public so coherence can get at it.
|
||||
CachePort *cpuSidePort;
|
||||
CachePort *memSidePort;
|
||||
|
||||
CacheEvent *sendEvent;
|
||||
CacheEvent *memSendEvent;
|
||||
|
||||
protected:
|
||||
CachePort *memSidePort;
|
||||
|
||||
public:
|
||||
virtual Port *getPort(const std::string &if_name, int idx = -1);
|
||||
|
||||
private:
|
||||
//To be defined in cache_impl.hh not in base class
|
||||
virtual bool doTimingAccess(PacketPtr pkt, CachePort *cachePort, bool isCpuSide)
|
||||
{
|
||||
fatal("No implementation");
|
||||
}
|
||||
|
||||
virtual Tick doAtomicAccess(PacketPtr pkt, bool isCpuSide)
|
||||
{
|
||||
fatal("No implementation");
|
||||
}
|
||||
|
||||
virtual void doFunctionalAccess(PacketPtr pkt, bool isCpuSide)
|
||||
{
|
||||
fatal("No implementation");
|
||||
}
|
||||
|
||||
void recvStatusChange(Port::Status status, bool isCpuSide)
|
||||
{
|
||||
if (status == Port::RangeChange){
|
||||
|
@ -176,27 +148,13 @@ class BaseCache : public MemObject
|
|||
}
|
||||
}
|
||||
|
||||
virtual PacketPtr getPacket()
|
||||
{
|
||||
fatal("No implementation");
|
||||
}
|
||||
virtual PacketPtr getPacket() = 0;
|
||||
|
||||
virtual PacketPtr getCoherencePacket()
|
||||
{
|
||||
fatal("No implementation");
|
||||
}
|
||||
virtual PacketPtr getCoherencePacket() = 0;
|
||||
|
||||
virtual void sendResult(PacketPtr &pkt, MSHR* mshr, bool success)
|
||||
{
|
||||
virtual void sendResult(PacketPtr &pkt, MSHR* mshr, bool success) = 0;
|
||||
|
||||
fatal("No implementation");
|
||||
}
|
||||
|
||||
virtual void sendCoherenceResult(PacketPtr &pkt, MSHR* mshr, bool success)
|
||||
{
|
||||
|
||||
fatal("No implementation");
|
||||
}
|
||||
virtual void sendCoherenceResult(PacketPtr &pkt, MSHR* mshr, bool success) = 0;
|
||||
|
||||
/**
|
||||
* Bit vector of the blocking reasons for the access path.
|
||||
|
|
48
src/mem/cache/cache.hh
vendored
48
src/mem/cache/cache.hh
vendored
|
@ -64,8 +64,49 @@ class Cache : public BaseCache
|
|||
typedef typename TagStore::BlkType BlkType;
|
||||
|
||||
bool prefetchAccess;
|
||||
|
||||
protected:
|
||||
|
||||
class CpuSidePort : public CachePort
|
||||
{
|
||||
public:
|
||||
CpuSidePort(const std::string &_name,
|
||||
Cache<TagStore,Coherence> *_cache);
|
||||
|
||||
// BaseCache::CachePort just has a BaseCache *; this function
|
||||
// lets us get back the type info we lost when we stored the
|
||||
// cache pointer there.
|
||||
Cache<TagStore,Coherence> *myCache() {
|
||||
return static_cast<Cache<TagStore,Coherence> *>(cache);
|
||||
}
|
||||
|
||||
virtual bool recvTiming(PacketPtr pkt);
|
||||
|
||||
virtual Tick recvAtomic(PacketPtr pkt);
|
||||
|
||||
virtual void recvFunctional(PacketPtr pkt);
|
||||
};
|
||||
|
||||
class MemSidePort : public CachePort
|
||||
{
|
||||
public:
|
||||
MemSidePort(const std::string &_name,
|
||||
Cache<TagStore,Coherence> *_cache);
|
||||
|
||||
// BaseCache::CachePort just has a BaseCache *; this function
|
||||
// lets us get back the type info we lost when we stored the
|
||||
// cache pointer there.
|
||||
Cache<TagStore,Coherence> *myCache() {
|
||||
return static_cast<Cache<TagStore,Coherence> *>(cache);
|
||||
}
|
||||
|
||||
virtual bool recvTiming(PacketPtr pkt);
|
||||
|
||||
virtual Tick recvAtomic(PacketPtr pkt);
|
||||
|
||||
virtual void recvFunctional(PacketPtr pkt);
|
||||
};
|
||||
|
||||
/** Tag and data Storage */
|
||||
TagStore *tags;
|
||||
/** Miss and Writeback handler */
|
||||
|
@ -128,12 +169,7 @@ class Cache : public BaseCache
|
|||
/** Instantiates a basic cache object. */
|
||||
Cache(const std::string &_name, Params ¶ms);
|
||||
|
||||
virtual bool doTimingAccess(PacketPtr pkt, CachePort *cachePort,
|
||||
bool isCpuSide);
|
||||
|
||||
virtual Tick doAtomicAccess(PacketPtr pkt, bool isCpuSide);
|
||||
|
||||
virtual void doFunctionalAccess(PacketPtr pkt, bool isCpuSide);
|
||||
virtual Port *getPort(const std::string &if_name, int idx = -1);
|
||||
|
||||
virtual void recvStatusChange(Port::Status status, bool isCpuSide);
|
||||
|
||||
|
|
220
src/mem/cache/cache_impl.hh
vendored
220
src/mem/cache/cache_impl.hh
vendored
|
@ -55,74 +55,6 @@
|
|||
|
||||
bool SIGNAL_NACK_HACK;
|
||||
|
||||
template<class TagStore, class Coherence>
|
||||
bool
|
||||
Cache<TagStore,Coherence>::
|
||||
doTimingAccess(PacketPtr pkt, CachePort *cachePort, bool isCpuSide)
|
||||
{
|
||||
if (isCpuSide)
|
||||
{
|
||||
if (pkt->isWrite() && (pkt->req->isLocked())) {
|
||||
pkt->req->setScResult(1);
|
||||
}
|
||||
access(pkt);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pkt->isResponse())
|
||||
handleResponse(pkt);
|
||||
else {
|
||||
//Check if we should do the snoop
|
||||
if (pkt->flags & SNOOP_COMMIT)
|
||||
snoop(pkt);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class TagStore, class Coherence>
|
||||
Tick
|
||||
Cache<TagStore,Coherence>::
|
||||
doAtomicAccess(PacketPtr pkt, bool isCpuSide)
|
||||
{
|
||||
if (isCpuSide)
|
||||
{
|
||||
probe(pkt, true, NULL);
|
||||
//TEMP ALWAYS SUCCES FOR NOW
|
||||
pkt->result = Packet::Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pkt->isResponse())
|
||||
handleResponse(pkt);
|
||||
else
|
||||
return snoopProbe(pkt);
|
||||
}
|
||||
//Fix this timing info
|
||||
return hitLatency;
|
||||
}
|
||||
|
||||
template<class TagStore, class Coherence>
|
||||
void
|
||||
Cache<TagStore,Coherence>::
|
||||
doFunctionalAccess(PacketPtr pkt, bool isCpuSide)
|
||||
{
|
||||
if (isCpuSide)
|
||||
{
|
||||
//TEMP USE CPU?THREAD 0 0
|
||||
pkt->req->setThreadContext(0,0);
|
||||
|
||||
probe(pkt, false, memSidePort);
|
||||
//TEMP ALWAYS SUCCESFUL FOR NOW
|
||||
pkt->result = Packet::Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
probe(pkt, false, cpuSidePort);
|
||||
}
|
||||
}
|
||||
|
||||
template<class TagStore, class Coherence>
|
||||
void
|
||||
Cache<TagStore,Coherence>::
|
||||
|
@ -727,3 +659,155 @@ Cache<TagStore,Coherence>::snoopProbe(PacketPtr &pkt)
|
|||
return 0;
|
||||
}
|
||||
|
||||
template<class TagStore, class Coherence>
|
||||
Port *
|
||||
Cache<TagStore,Coherence>::getPort(const std::string &if_name, int idx)
|
||||
{
|
||||
if (if_name == "")
|
||||
{
|
||||
if (cpuSidePort == NULL) {
|
||||
cpuSidePort = new CpuSidePort(name() + "-cpu_side_port", this);
|
||||
sendEvent = new CacheEvent(cpuSidePort, true);
|
||||
}
|
||||
return cpuSidePort;
|
||||
}
|
||||
else if (if_name == "functional")
|
||||
{
|
||||
return new CpuSidePort(name() + "-cpu_side_port", this);
|
||||
}
|
||||
else if (if_name == "cpu_side")
|
||||
{
|
||||
if (cpuSidePort == NULL) {
|
||||
cpuSidePort = new CpuSidePort(name() + "-cpu_side_port", this);
|
||||
sendEvent = new CacheEvent(cpuSidePort, true);
|
||||
}
|
||||
return cpuSidePort;
|
||||
}
|
||||
else if (if_name == "mem_side")
|
||||
{
|
||||
if (memSidePort != NULL)
|
||||
panic("Already have a mem side for this cache\n");
|
||||
memSidePort = new MemSidePort(name() + "-mem_side_port", this);
|
||||
memSendEvent = new CacheEvent(memSidePort, true);
|
||||
return memSidePort;
|
||||
}
|
||||
else panic("Port name %s unrecognized\n", if_name);
|
||||
}
|
||||
|
||||
|
||||
template<class TagStore, class Coherence>
|
||||
bool
|
||||
Cache<TagStore,Coherence>::CpuSidePort::recvTiming(PacketPtr pkt)
|
||||
{
|
||||
if (!pkt->req->isUncacheable()
|
||||
&& pkt->isInvalidate()
|
||||
&& !pkt->isRead() && !pkt->isWrite()) {
|
||||
//Upgrade or Invalidate
|
||||
//Look into what happens if two slave caches on bus
|
||||
DPRINTF(Cache, "%s %x ?\n", pkt->cmdString(), pkt->getAddr());
|
||||
|
||||
assert(!(pkt->flags & SATISFIED));
|
||||
pkt->flags |= SATISFIED;
|
||||
//Invalidates/Upgrades need no response if they get the bus
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pkt->isRequest() && blocked)
|
||||
{
|
||||
DPRINTF(Cache,"Scheduling a retry while blocked\n");
|
||||
mustSendRetry = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pkt->isWrite() && (pkt->req->isLocked())) {
|
||||
pkt->req->setScResult(1);
|
||||
}
|
||||
myCache()->access(pkt);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class TagStore, class Coherence>
|
||||
Tick
|
||||
Cache<TagStore,Coherence>::CpuSidePort::recvAtomic(PacketPtr pkt)
|
||||
{
|
||||
myCache()->probe(pkt, true, NULL);
|
||||
//TEMP ALWAYS SUCCES FOR NOW
|
||||
pkt->result = Packet::Success;
|
||||
//Fix this timing info
|
||||
return myCache()->hitLatency;
|
||||
}
|
||||
|
||||
template<class TagStore, class Coherence>
|
||||
void
|
||||
Cache<TagStore,Coherence>::CpuSidePort::recvFunctional(PacketPtr pkt)
|
||||
{
|
||||
if (checkFunctional(pkt)) {
|
||||
//TEMP USE CPU?THREAD 0 0
|
||||
pkt->req->setThreadContext(0,0);
|
||||
|
||||
myCache()->probe(pkt, false, cache->memSidePort);
|
||||
//TEMP ALWAYS SUCCESFUL FOR NOW
|
||||
pkt->result = Packet::Success;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class TagStore, class Coherence>
|
||||
bool
|
||||
Cache<TagStore,Coherence>::MemSidePort::recvTiming(PacketPtr pkt)
|
||||
{
|
||||
if (pkt->isRequest() && blocked)
|
||||
{
|
||||
DPRINTF(Cache,"Scheduling a retry while blocked\n");
|
||||
mustSendRetry = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pkt->isResponse())
|
||||
myCache()->handleResponse(pkt);
|
||||
else {
|
||||
//Check if we should do the snoop
|
||||
if (pkt->flags & SNOOP_COMMIT)
|
||||
myCache()->snoop(pkt);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class TagStore, class Coherence>
|
||||
Tick
|
||||
Cache<TagStore,Coherence>::MemSidePort::recvAtomic(PacketPtr pkt)
|
||||
{
|
||||
if (pkt->isResponse())
|
||||
myCache()->handleResponse(pkt);
|
||||
else
|
||||
return myCache()->snoopProbe(pkt);
|
||||
//Fix this timing info
|
||||
return myCache()->hitLatency;
|
||||
}
|
||||
|
||||
template<class TagStore, class Coherence>
|
||||
void
|
||||
Cache<TagStore,Coherence>::MemSidePort::recvFunctional(PacketPtr pkt)
|
||||
{
|
||||
if (checkFunctional(pkt)) {
|
||||
myCache()->probe(pkt, false, cache->cpuSidePort);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class TagStore, class Coherence>
|
||||
Cache<TagStore,Coherence>::
|
||||
CpuSidePort::CpuSidePort(const std::string &_name,
|
||||
Cache<TagStore,Coherence> *_cache)
|
||||
: BaseCache::CachePort(_name, _cache, true)
|
||||
{
|
||||
}
|
||||
|
||||
template<class TagStore, class Coherence>
|
||||
Cache<TagStore,Coherence>::
|
||||
MemSidePort::MemSidePort(const std::string &_name,
|
||||
Cache<TagStore,Coherence> *_cache)
|
||||
: BaseCache::CachePort(_name, _cache, false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue