mem: Make PortProxy use a delegate for a sendFunctional function.
authorGabe Black <gabeblack@google.com>
Thu, 15 Aug 2019 23:53:20 +0000 (16:53 -0700)
committerGabe Black <gabeblack@google.com>
Wed, 28 Aug 2019 06:06:05 +0000 (06:06 +0000)
The only part of the MaserPort the PortProxy uses is the sendFunctional
function which is part of the functional protocol. Rather than require
a MasterPort which comes along with a lot of other mechanisms, this
change slightly adjusts the PortProxy to only require that function
through the use of a delegate. That allows lots of flexibility in how
the actual packet gets sent and what sends it.

In cases where code constructs a PortProxy and passes its constructor
an unbound MasterPort, the PortProxy will create a delegate to the
sendFunctional method on its own.

This should also make it easier for objects which don't have
traditional gem5 style ports, for instance systemc models, to implement
just the little bit of the protocol they need, rather than having to
stub out a whole port class, most of which will be ignored.

Change-Id: I234b42ce050f12313b551a61736186ddf2c9e2c7
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20229
Maintainer: Gabe Black <gabeblack@google.com>
Reviewed-by: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/mem/fs_translating_port_proxy.cc
src/mem/fs_translating_port_proxy.hh
src/mem/port_proxy.cc
src/mem/port_proxy.hh
src/mem/se_translating_port_proxy.cc
src/mem/se_translating_port_proxy.hh
src/mem/secure_port_proxy.hh

index 6a25d112121e86f2183e1db1fe91947f65569f3b..d12af13af9ec2117b812ee39d25e8aa7cd32be9e 100644 (file)
@@ -60,8 +60,14 @@ FSTranslatingPortProxy::FSTranslatingPortProxy(ThreadContext *tc)
 {
 }
 
-FSTranslatingPortProxy::FSTranslatingPortProxy(MasterPort &port,
-                                               unsigned int cacheLineSize)
+FSTranslatingPortProxy::FSTranslatingPortProxy(
+        SendFunctionalFunc func, unsigned int cacheLineSize)
+    : PortProxy(func, cacheLineSize), _tc(NULL)
+{
+}
+
+FSTranslatingPortProxy::FSTranslatingPortProxy(
+        MasterPort &port, unsigned int cacheLineSize)
     : PortProxy(port, cacheLineSize), _tc(NULL)
 {
 }
index 410eb7d789b74e775594fc84d5a9e5194e01a241..2ecd742bcec92bf25f9af22ad60fdb2c1b206eca 100644 (file)
@@ -79,7 +79,10 @@ class FSTranslatingPortProxy : public PortProxy
 
     FSTranslatingPortProxy(ThreadContext* tc);
 
-    FSTranslatingPortProxy(MasterPort &port, unsigned int cacheLineSize);
+    FSTranslatingPortProxy(SendFunctionalFunc func,
+                           unsigned int cacheLineSize);
+    FSTranslatingPortProxy(MasterPort &port,
+                           unsigned int cacheLineSize);
 
     ~FSTranslatingPortProxy() {}
 
index 60f79e375fae05e1588195b9c3281e89a1c391fe..b630d310a3830acfa3b8c9690f802924fcc8bed8 100644 (file)
@@ -53,7 +53,7 @@ PortProxy::readBlobPhys(Addr addr, Request::Flags flags,
 
         Packet pkt(req, MemCmd::ReadReq);
         pkt.dataStatic(static_cast<uint8_t *>(p));
-        _port.sendFunctional(&pkt);
+        sendFunctional(&pkt);
         p = static_cast<uint8_t *>(p) + gen.size();
     }
 }
@@ -70,7 +70,7 @@ PortProxy::writeBlobPhys(Addr addr, Request::Flags flags,
 
         Packet pkt(req, MemCmd::WriteReq);
         pkt.dataStaticConst(static_cast<const uint8_t *>(p));
-        _port.sendFunctional(&pkt);
+        sendFunctional(&pkt);
         p = static_cast<const uint8_t *>(p) + gen.size();
     }
 }
index 61a207146e8f7712afca73182a62d12bf44648bd..31ac3e941a5226c6d5ba7c1e20aeac365cd876a0 100644 (file)
 #ifndef __MEM_PORT_PROXY_HH__
 #define __MEM_PORT_PROXY_HH__
 
+#include <functional>
 #include <limits>
 
 #include "mem/port.hh"
 #include "sim/byteswap.hh"
 
 /**
- * This object is a proxy for a structural port, to be used for debug
- * accesses.
+ * This object is a proxy for a port or other object which implements the
+ * functional response protocol, to be used for debug accesses.
  *
  * This proxy object is used when non structural entities
  * (e.g. thread contexts, object file loaders) need access to the
  * memory system. It calls the corresponding functions on the underlying
- * structural port, and provides templatized convenience access functions.
+ * protocol, and provides templatized convenience access functions.
  *
  * The addresses are interpreted as physical addresses.
  *
  * @sa SETranslatingProxy
  * @sa FSTranslatingProxy
  */
-class PortProxy
+class PortProxy : FunctionalRequestProtocol
 {
-  private:
+  public:
+    typedef std::function<void(PacketPtr pkt)> SendFunctionalFunc;
 
-    /** The actual physical port used by this proxy. */
-    MasterPort &_port;
+  private:
+    SendFunctionalFunc sendFunctional;
 
     /** Granularity of any transactions issued through this proxy. */
     const unsigned int _cacheLineSize;
 
+    void
+    recvFunctionalSnoop(PacketPtr pkt) override
+    {
+        // Since port proxies aren't anyone else's peer, they should never
+        // receive snoops.
+        panic("Port proxies should never receive snoops.");
+    }
+
   public:
-    PortProxy(MasterPort &port, unsigned int cacheLineSize) :
-        _port(port), _cacheLineSize(cacheLineSize)
+    PortProxy(SendFunctionalFunc func, unsigned int cacheLineSize) :
+        sendFunctional(func), _cacheLineSize(cacheLineSize)
+    {}
+    PortProxy(const MasterPort &port, unsigned int cacheLineSize) :
+        sendFunctional([&port](PacketPtr pkt)->void {
+                port.sendFunctional(pkt);
+            }), _cacheLineSize(cacheLineSize)
     {}
     virtual ~PortProxy() { }
 
index c5f38f1cdf4ad86b28755bd504da34b6efd2c5ca..94d2ab3d1cdac38f344bd57559c31d2b1f076a98 100644 (file)
 
 using namespace TheISA;
 
-SETranslatingPortProxy::SETranslatingPortProxy(MasterPort& port, Process *p,
-                                           AllocType alloc)
+SETranslatingPortProxy::SETranslatingPortProxy(
+        SendFunctionalFunc func, Process *p, AllocType alloc)
+    : PortProxy(func, p->system->cacheLineSize()), pTable(p->pTable),
+      process(p), allocating(alloc)
+{ }
+SETranslatingPortProxy::SETranslatingPortProxy(MasterPort &port,
+                                               Process *p, AllocType alloc)
     : PortProxy(port, p->system->cacheLineSize()), pTable(p->pTable),
       process(p), allocating(alloc)
 { }
index 718e44a576cdb382d9d18d230075622ca81113e5..e32f1d0e3adfd74e16ec1c88bc71084afcba82ad 100644 (file)
@@ -80,7 +80,9 @@ class SETranslatingPortProxy : public PortProxy
     AllocType allocating;
 
   public:
-    SETranslatingPortProxy(MasterPort& port, Process* p, AllocType alloc);
+    SETranslatingPortProxy(SendFunctionalFunc func,
+                           Process* p, AllocType alloc);
+    SETranslatingPortProxy(MasterPort &port, Process* p, AllocType alloc);
     ~SETranslatingPortProxy() {}
 
     void setPageTable(EmulationPageTable *p) { pTable = p; }
index 9a2200c9e25d65bc9ea69c45fe0299697914e388..5ce0c299a29172130becc57a82645afd6ec7e8eb 100644 (file)
@@ -70,8 +70,7 @@
 class SecurePortProxy : public PortProxy
 {
   public:
-    SecurePortProxy(MasterPort &port, unsigned int cache_line_size)
-        : PortProxy(port, cache_line_size) {}
+    using PortProxy::PortProxy;
 
     bool tryReadBlob(Addr addr, void *p, int size) const override;
     bool tryWriteBlob(Addr addr, const void *p, int size) const override;