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:
Steve Reinhardt 2006-12-13 22:04:36 -08:00
parent 98bb1c62b3
commit d172e1576a
4 changed files with 201 additions and 196 deletions

View file

@ -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()
{

View file

@ -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.

View file

@ -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 &params);
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);

View file

@ -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)
{
}