Split CachePort class into CpuSidePort and MemSidePort
authorSteve Reinhardt <stever@eecs.umich.edu>
Thu, 14 Dec 2006 06:04:36 +0000 (22:04 -0800)
committerSteve Reinhardt <stever@eecs.umich.edu>
Thu, 14 Dec 2006 06:04:36 +0000 (22:04 -0800)
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

src/mem/cache/base_cache.cc
src/mem/cache/base_cache.hh
src/mem/cache/cache.hh
src/mem/cache/cache_impl.hh

index 3af61375d45e1a166f9b052e4e7ce915d27730b3..d9e6c5e1f89798f825a23d3e02cae35c4ceb1f61 100644 (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()
 {
index ef4955432d4b75897faa31bf0df6e4e018929c18..a7f035dced9c0814bc6fbe8a06d0b3d7189904e2 100644 (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 void sendResult(PacketPtr &pkt, MSHR* mshr, bool success)
-    {
+    virtual PacketPtr getCoherencePacket() = 0;
 
-        fatal("No implementation");
-    }
+    virtual void sendResult(PacketPtr &pkt, MSHR* mshr, bool success) = 0;
 
-    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.
index 29502042c6866ab902093e82043def53bcce7c42..097b0f513c51a0beafe4cfb1588d0ec8fd81afaa 100644 (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);
 
index 6742d5892eeab173d5ba1d1e27095d42355a3f85..9f48ff1f38c9b4366aa67dc615ea3837be8d8e7e 100644 (file)
 
 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)
+{
+}
+