mem-cache: Fix setting prefetch bit
[gem5.git] / src / mem / port_proxy.hh
index ac1873b3cb3223ee46e8dde46070fc1be79ce7ff..9f3945be8ad1a9aa6c7cf8b2e38c672ab795b007 100644 (file)
@@ -33,8 +33,6 @@
  * 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: Andreas Hansson
  */
 
 /**
 #ifndef __MEM_PORT_PROXY_HH__
 #define __MEM_PORT_PROXY_HH__
 
-#include "config/the_isa.hh"
-#if THE_ISA != NULL_ISA
-    #include "arch/isa_traits.hh"
-#endif
+#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 RequestPort &port, unsigned int cacheLineSize) :
+        sendFunctional([&port](PacketPtr pkt)->void {
+                port.sendFunctional(pkt);
+            }), _cacheLineSize(cacheLineSize)
+    {}
     virtual ~PortProxy() { }
 
+
+
+    /** Fixed functionality for use in base classes. */
+
+    /**
+     * Read size bytes memory at physical address and store in p.
+     */
+    void readBlobPhys(Addr addr, Request::Flags flags,
+                      void *p, int size) const;
+
+    /**
+     * Write size bytes from p to physical address.
+     */
+    void writeBlobPhys(Addr addr, Request::Flags flags,
+                       const void *p, int size) const;
+
+    /**
+     * Fill size bytes starting at physical addr with byte value val.
+     */
+    void memsetBlobPhys(Addr addr, Request::Flags flags,
+                        uint8_t v, int size) const;
+
+
+
+    /** Methods to override in base classes */
+
     /**
      * Read size bytes memory at address and store in p.
+     * Returns true on success and false on failure.
      */
-    virtual void readBlob(Addr addr, uint8_t* p, int size) const;
+    virtual bool
+    tryReadBlob(Addr addr, void *p, int size) const
+    {
+        readBlobPhys(addr, 0, p, size);
+        return true;
+    }
 
     /**
      * Write size bytes from p to address.
+     * Returns true on success and false on failure.
      */
-    virtual void writeBlob(Addr addr, const uint8_t* p, int size) const;
+    virtual bool
+    tryWriteBlob(Addr addr, const void *p, int size) const
+    {
+        writeBlobPhys(addr, 0, p, size);
+        return true;
+    }
 
     /**
      * Fill size bytes starting at addr with byte value val.
+     * Returns true on success and false on failure.
      */
-    virtual void memsetBlob(Addr addr, uint8_t v, int size) const;
+    virtual bool
+    tryMemsetBlob(Addr addr, uint8_t val, int size) const
+    {
+        memsetBlobPhys(addr, 0, val, size);
+        return true;
+    }
+
+
+
+    /** Higher level interfaces based on the above. */
+
+    /**
+     * Same as tryReadBlob, but insists on success.
+     */
+    void
+    readBlob(Addr addr, void *p, int size) const
+    {
+        if (!tryReadBlob(addr, p, size))
+            fatal("readBlob(%#x, ...) failed", addr);
+    }
+
+    /**
+     * Same as tryWriteBlob, but insists on success.
+     */
+    void
+    writeBlob(Addr addr, const void *p, int size) const
+    {
+        if (!tryWriteBlob(addr, p, size))
+            fatal("writeBlob(%#x, ...) failed", addr);
+    }
+
+    /**
+     * Same as tryMemsetBlob, but insists on success.
+     */
+    void
+    memsetBlob(Addr addr, uint8_t v, int size) const
+    {
+        if (!tryMemsetBlob(addr, v, size))
+            fatal("memsetBlob(%#x, ...) failed", addr);
+    }
 
     /**
      * Read sizeof(T) bytes from address and return as object T.
@@ -121,37 +210,70 @@ class PortProxy
      * Write object T to address. Writes sizeof(T) bytes.
      */
     template <typename T>
-    void write(Addr address, data) const;
+    void write(Addr address, const T &data) const;
 
     /**
      * Read sizeof(T) bytes from address and return as object T.
-     * Performs selected endianness transform.
+     * Performs endianness conversion from the selected guest to host order.
      */
     template <typename T>
-    T readGtoH(Addr address, ByteOrder guest_byte_order) const;
+    T read(Addr address, ByteOrder guest_byte_order) const;
 
     /**
      * Write object T to address. Writes sizeof(T) bytes.
-     * Performs selected endianness transform.
+     * Performs endianness conversion from host to the selected guest order.
      */
     template <typename T>
-    void writeHtoG(Addr address, T data, ByteOrder guest_byte_order) const;
+    void write(Addr address, T data, ByteOrder guest_byte_order) const;
 
-#if THE_ISA != NULL_ISA
     /**
-     * Read sizeof(T) bytes from address and return as object T.
-     * Performs Guest to Host endianness transform.
+     * Write the string str into guest memory at address addr.
+     * Returns true on success and false on failure.
      */
-    template <typename T>
-    T readGtoH(Addr address) const;
+    bool tryWriteString(Addr addr, const char *str) const;
 
     /**
-     * Write object T to address. Writes sizeof(T) bytes.
-     * Performs Host to Guest endianness transform.
+     * Same as tryWriteString, but insists on success.
      */
-    template <typename T>
-    void writeHtoG(Addr address, T data) const;
-#endif
+    void
+    writeString(Addr addr, const char *str) const
+    {
+        if (!tryWriteString(addr, str))
+            fatal("writeString(%#x, ...) failed", addr);
+    }
+
+    /**
+     * Reads the string at guest address addr into the std::string str.
+     * Returns true on success and false on failure.
+     */
+    bool tryReadString(std::string &str, Addr addr) const;
+
+    /**
+     * Same as tryReadString, but insists on success.
+     */
+    void
+    readString(std::string &str, Addr addr) const
+    {
+        if (!tryReadString(str, addr))
+            fatal("readString(%#x, ...) failed", addr);
+    }
+
+    /**
+     * Reads the string at guest address addr into the char * str, reading up
+     * to maxlen characters. The last character read is always a nul
+     * terminator. Returns true on success and false on failure.
+     */
+    bool tryReadString(char *str, Addr addr, size_t maxlen) const;
+
+    /**
+     * Same as tryReadString, but insists on success.
+     */
+    void
+    readString(char *str, Addr addr, size_t maxlen) const
+    {
+        if (!tryReadString(str, addr, maxlen))
+            fatal("readString(%#x, ...) failed", addr);
+    }
 };
 
 
@@ -160,51 +282,32 @@ T
 PortProxy::read(Addr address) const
 {
     T data;
-    readBlob(address, (uint8_t*)&data, sizeof(T));
+    readBlob(address, &data, sizeof(T));
     return data;
 }
 
 template <typename T>
 void
-PortProxy::write(Addr address, data) const
+PortProxy::write(Addr address, const T &data) const
 {
-    writeBlob(address, (uint8_t*)&data, sizeof(T));
+    writeBlob(address, &data, sizeof(T));
 }
 
 template <typename T>
 T
-PortProxy::readGtoH(Addr address, ByteOrder byte_order) const
+PortProxy::read(Addr address, ByteOrder byte_order) const
 {
     T data;
-    readBlob(address, (uint8_t*)&data, sizeof(T));
+    readBlob(address, &data, sizeof(T));
     return gtoh(data, byte_order);
 }
 
 template <typename T>
 void
-PortProxy::writeHtoG(Addr address, T data, ByteOrder byte_order) const
+PortProxy::write(Addr address, T data, ByteOrder byte_order) const
 {
     data = htog(data, byte_order);
-    writeBlob(address, (uint8_t*)&data, sizeof(T));
-}
-
-#if THE_ISA != NULL_ISA
-template <typename T>
-T
-PortProxy::readGtoH(Addr address) const
-{
-    T data;
-    readBlob(address, (uint8_t*)&data, sizeof(T));
-    return TheISA::gtoh(data);
-}
-
-template <typename T>
-void
-PortProxy::writeHtoG(Addr address, T data) const
-{
-    data = TheISA::htog(data);
-    writeBlob(address, (uint8_t*)&data, sizeof(T));
+    writeBlob(address, &data, sizeof(T));
 }
-#endif
 
 #endif // __MEM_PORT_PROXY_HH__