mem: Refactor port proxies to support secure accesses

The current physical port proxy doesn't know how to tag memory
accesses as secure. Refactor the class slightly to create a set of
methods (readBlobPhys, writeBlobPhys, memsetBlobPhys) that always
access physical memory and take a set of Request::Flags as an
argument. The new port proxy, SecurePortProxy, uses this interface to
issue secure physical accesses.

Change-Id: I8232a4b35025be04ec8f91a00f0580266bacb338
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/8364
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
diff --git a/src/mem/fs_translating_port_proxy.cc b/src/mem/fs_translating_port_proxy.cc
index 616c12e..ef86bf7 100644
--- a/src/mem/fs_translating_port_proxy.cc
+++ b/src/mem/fs_translating_port_proxy.cc
@@ -84,7 +84,7 @@
         else
             paddr = TheISA::vtophys(gen.addr());
 
-        PortProxy::readBlob(paddr, p, gen.size());
+        PortProxy::readBlobPhys(paddr, 0, p, gen.size());
         p += gen.size();
     }
 }
@@ -101,7 +101,7 @@
         else
             paddr = TheISA::vtophys(gen.addr());
 
-        PortProxy::writeBlob(paddr, p, gen.size());
+        PortProxy::writeBlobPhys(paddr, 0, p, gen.size());
         p += gen.size();
     }
 }
@@ -118,7 +118,7 @@
         else
             paddr = TheISA::vtophys(gen.addr());
 
-        PortProxy::memsetBlob(paddr, v, gen.size());
+        PortProxy::memsetBlobPhys(paddr, 0, v, gen.size());
     }
 }
 
diff --git a/src/mem/fs_translating_port_proxy.hh b/src/mem/fs_translating_port_proxy.hh
index e7b74d0..d4b4eb5 100644
--- a/src/mem/fs_translating_port_proxy.hh
+++ b/src/mem/fs_translating_port_proxy.hh
@@ -81,20 +81,20 @@
 
     FSTranslatingPortProxy(MasterPort &port, unsigned int cacheLineSize);
 
-    virtual ~FSTranslatingPortProxy();
+    ~FSTranslatingPortProxy();
 
     /** Version of readblob that translates virt->phys and deals
       * with page boundries. */
-    virtual void readBlob(Addr addr, uint8_t *p, int size) const;
+    void readBlob(Addr addr, uint8_t *p, int size) const override;
 
     /** Version of writeBlob that translates virt->phys and deals
       * with page boundries. */
-    virtual void writeBlob(Addr addr, const uint8_t *p, int size) const;
+    void writeBlob(Addr addr, const uint8_t *p, int size) const override;
 
     /**
      * Fill size bytes starting at addr with byte value val.
      */
-    virtual void memsetBlob(Addr address, uint8_t  v, int size) const;
+    void memsetBlob(Addr address, uint8_t  v, int size) const override;
 };
 
 void CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen);
diff --git a/src/mem/port_proxy.cc b/src/mem/port_proxy.cc
index f40c64e..d454ef7 100644
--- a/src/mem/port_proxy.cc
+++ b/src/mem/port_proxy.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2012, 2018 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -42,11 +42,12 @@
 #include "base/chunk_generator.hh"
 
 void
-PortProxy::readBlob(Addr addr, uint8_t *p, int size) const
+PortProxy::readBlobPhys(Addr addr, Request::Flags flags,
+                        uint8_t *p, int size) const
 {
     for (ChunkGenerator gen(addr, size, _cacheLineSize); !gen.done();
          gen.next()) {
-        Request req(gen.addr(), gen.size(), 0, Request::funcMasterId);
+        Request req(gen.addr(), gen.size(), flags, Request::funcMasterId);
         Packet pkt(&req, MemCmd::ReadReq);
         pkt.dataStatic(p);
         _port.sendFunctional(&pkt);
@@ -55,11 +56,12 @@
 }
 
 void
-PortProxy::writeBlob(Addr addr, const uint8_t *p, int size) const
+PortProxy::writeBlobPhys(Addr addr, Request::Flags flags,
+                         const uint8_t *p, int size) const
 {
     for (ChunkGenerator gen(addr, size, _cacheLineSize); !gen.done();
          gen.next()) {
-        Request req(gen.addr(), gen.size(), 0, Request::funcMasterId);
+        Request req(gen.addr(), gen.size(), flags, Request::funcMasterId);
         Packet pkt(&req, MemCmd::WriteReq);
         pkt.dataStaticConst(p);
         _port.sendFunctional(&pkt);
@@ -68,13 +70,33 @@
 }
 
 void
-PortProxy::memsetBlob(Addr addr, uint8_t v, int size) const
+PortProxy::memsetBlobPhys(Addr addr, Request::Flags flags,
+                          uint8_t v, int size) const
 {
     // quick and dirty...
     uint8_t *buf = new uint8_t[size];
 
     std::memset(buf, v, size);
-    PortProxy::writeBlob(addr, buf, size);
+    PortProxy::writeBlobPhys(addr, flags, buf, size);
 
     delete [] buf;
 }
+
+
+void
+SecurePortProxy::readBlob(Addr addr, uint8_t *p, int size) const
+{
+    readBlobPhys(addr, Request::SECURE, p, size);
+}
+
+void
+SecurePortProxy::writeBlob(Addr addr, const uint8_t *p, int size) const
+{
+    writeBlobPhys(addr, Request::SECURE, p, size);
+}
+
+void
+SecurePortProxy::memsetBlob(Addr addr, uint8_t v, int size) const
+{
+    memsetBlobPhys(addr, Request::SECURE, v, size);
+}
diff --git a/src/mem/port_proxy.hh b/src/mem/port_proxy.hh
index ac1873b..fe87bf5 100644
--- a/src/mem/port_proxy.hh
+++ b/src/mem/port_proxy.hh
@@ -99,17 +99,41 @@
     /**
      * Read size bytes memory at address and store in p.
      */
-    virtual void readBlob(Addr addr, uint8_t* p, int size) const;
+    virtual void readBlob(Addr addr, uint8_t* p, int size) const {
+        readBlobPhys(addr, 0, p, size);
+    }
 
     /**
      * Write size bytes from p to address.
      */
-    virtual void writeBlob(Addr addr, const uint8_t* p, int size) const;
+    virtual void writeBlob(Addr addr, const uint8_t* p, int size) const {
+        writeBlobPhys(addr, 0, p, size);
+    }
 
     /**
      * Fill size bytes starting at addr with byte value val.
      */
-    virtual void memsetBlob(Addr addr, uint8_t v, int size) const;
+    virtual void memsetBlob(Addr addr, uint8_t v, int size) const {
+        memsetBlobPhys(addr, 0, v, size);
+    }
+
+    /**
+     * Read size bytes memory at physical address and store in p.
+     */
+    void readBlobPhys(Addr addr, Request::Flags flags,
+                      uint8_t* p, int size) const;
+
+    /**
+     * Write size bytes from p to physical address.
+     */
+    void writeBlobPhys(Addr addr, Request::Flags flags,
+                       const uint8_t* 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;
 
     /**
      * Read sizeof(T) bytes from address and return as object T.
@@ -155,6 +179,23 @@
 };
 
 
+/**
+ * This object is a proxy for a structural port, to be used for debug
+ * accesses to secure memory.
+ *
+ * The addresses are interpreted as physical addresses to secure memory.
+ */
+class SecurePortProxy : public PortProxy
+{
+  public:
+    SecurePortProxy(MasterPort &port, unsigned int cache_line_size)
+        : PortProxy(port, cache_line_size) {}
+
+    void readBlob(Addr addr, uint8_t *p, int size) const override;
+    void writeBlob(Addr addr, const uint8_t *p, int size) const override;
+    void memsetBlob(Addr addr, uint8_t val, int size) const override;
+};
+
 template <typename T>
 T
 PortProxy::read(Addr address) const
diff --git a/src/mem/se_translating_port_proxy.cc b/src/mem/se_translating_port_proxy.cc
index 6c5191c..bb30ffb 100644
--- a/src/mem/se_translating_port_proxy.cc
+++ b/src/mem/se_translating_port_proxy.cc
@@ -75,7 +75,7 @@
         if (!pTable->translate(gen.addr(),paddr))
             return false;
 
-        PortProxy::readBlob(paddr, p + prevSize, gen.size());
+        PortProxy::readBlobPhys(paddr, 0, p + prevSize, gen.size());
         prevSize += gen.size();
     }
 
@@ -114,7 +114,7 @@
             pTable->translate(gen.addr(), paddr);
         }
 
-        PortProxy::writeBlob(paddr, p + prevSize, gen.size());
+        PortProxy::writeBlobPhys(paddr, 0, p + prevSize, gen.size());
         prevSize += gen.size();
     }
 
@@ -145,7 +145,7 @@
             }
         }
 
-        PortProxy::memsetBlob(paddr, val, gen.size());
+        PortProxy::memsetBlobPhys(paddr, 0, val, gen.size());
     }
 
     return true;
diff --git a/src/mem/se_translating_port_proxy.hh b/src/mem/se_translating_port_proxy.hh
index 2f2a81b..04bfd8a 100644
--- a/src/mem/se_translating_port_proxy.hh
+++ b/src/mem/se_translating_port_proxy.hh
@@ -81,7 +81,7 @@
 
   public:
     SETranslatingPortProxy(MasterPort& port, Process* p, AllocType alloc);
-    virtual ~SETranslatingPortProxy();
+    ~SETranslatingPortProxy();
 
     void setPageTable(EmulationPageTable *p) { pTable = p; }
     void setProcess(Process *p) { process = p; }
@@ -91,9 +91,9 @@
     bool tryWriteString(Addr addr, const char *str) const;
     bool tryReadString(std::string &str, Addr addr) const;
 
-    virtual void readBlob(Addr addr, uint8_t *p, int size) const;
-    virtual void writeBlob(Addr addr, const uint8_t *p, int size) const;
-    virtual void memsetBlob(Addr addr, uint8_t val, int size) const;
+    void readBlob(Addr addr, uint8_t *p, int size) const override;
+    void writeBlob(Addr addr, const uint8_t *p, int size) const override;
+    void memsetBlob(Addr addr, uint8_t val, int size) const override;
 
     void writeString(Addr addr, const char *str) const;
     void readString(std::string &str, Addr addr) const;