arm: Make semihosting use virtual addresses.
authorGabe Black <gabeblack@google.com>
Thu, 12 Mar 2020 08:43:46 +0000 (01:43 -0700)
committerGabe Black <gabeblack@google.com>
Mon, 30 Mar 2020 21:47:20 +0000 (21:47 +0000)
This is in accordance with the spec. To successfully translate requests
which need their secure flag set, build a translating port proxy with
that flag enabled.

Change-Id: I6ceec12aed297c57831a368a74d8b4e41f86f4c9
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/26624
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/arm/semihosting.cc
src/arch/arm/semihosting.hh

index 7b7592f921c9a37ed730ae8c00e3b5dc47557411..7718cd00222a0fa6bd046255af47fdeccc9a78cd 100644 (file)
 #include "debug/Semihosting.hh"
 #include "dev/serial/serial.hh"
 #include "mem/physical.hh"
-#include "mem/secure_port_proxy.hh"
+#include "mem/se_translating_port_proxy.hh"
+#include "mem/translating_port_proxy.hh"
 #include "params/ArmSemihosting.hh"
 #include "sim/byteswap.hh"
+#include "sim/full_system.hh"
 #include "sim/pseudo_inst.hh"
 #include "sim/sim_exit.hh"
 #include "sim/system.hh"
@@ -237,21 +239,28 @@ ArmSemihosting::unserialize(CheckpointIn &cp)
 }
 
 PortProxy &
-ArmSemihosting::physProxy(ThreadContext *tc)
+ArmSemihosting::portProxy(ThreadContext *tc)
 {
-    static std::unique_ptr<PortProxy> phys_proxy_s;
+    static std::unique_ptr<PortProxy> port_proxy_s;
     static System *secure_sys = nullptr;
 
     if (ArmISA::inSecureState(tc)) {
         System *sys = tc->getSystemPtr();
         if (sys != secure_sys) {
-            phys_proxy_s.reset(new SecurePortProxy(sys->getSystemPort(),
-                                                   sys->cacheLineSize()));
+            if (FullSystem) {
+                port_proxy_s.reset(
+                        new TranslatingPortProxy(tc, Request::SECURE));
+            } else {
+                port_proxy_s.reset(
+                        new SETranslatingPortProxy(
+                            tc, SETranslatingPortProxy::NextPage,
+                            Request::SECURE));
+            }
         }
         secure_sys = sys;
-        return *phys_proxy_s;
+        return *port_proxy_s;
     } else {
-        return tc->getPhysProxy();
+        return tc->getVirtProxy();
     }
 }
 
@@ -262,7 +271,7 @@ ArmSemihosting::readString(ThreadContext *tc, Addr ptr, size_t len)
     std::vector<char> buf(len + 1);
 
     buf[len] = '\0';
-    physProxy(tc).readBlob(ptr, buf.data(), len);
+    portProxy(tc).readBlob(ptr, buf.data(), len);
 
     return std::string(buf.data());
 }
@@ -320,7 +329,7 @@ ArmSemihosting::callClose(ThreadContext *tc, uint64_t handle)
 ArmSemihosting::RetErrno
 ArmSemihosting::callWriteC(ThreadContext *tc, InPlaceArg arg)
 {
-    const char c = physProxy(tc).read<char>(arg.addr);
+    const char c = portProxy(tc).read<char>(arg.addr);
 
     DPRINTF(Semihosting, "Semihosting SYS_WRITEC('%c')\n", c);
     std::cout.put(c);
@@ -332,7 +341,7 @@ ArmSemihosting::RetErrno
 ArmSemihosting::callWrite0(ThreadContext *tc, InPlaceArg arg)
 {
     DPRINTF(Semihosting, "Semihosting SYS_WRITE0(...)\n");
-    PortProxy &proxy = physProxy(tc);
+    PortProxy &proxy = portProxy(tc);
     std::string str;
     proxy.readString(str, arg.addr);
     std::cout.write(str.c_str(), str.size());
@@ -348,7 +357,7 @@ ArmSemihosting::callWrite(ThreadContext *tc, uint64_t handle, Addr addr,
         return RetErrno(size, EBADF);
 
     std::vector<uint8_t> buffer(size);
-    physProxy(tc).readBlob(addr, buffer.data(), buffer.size());
+    portProxy(tc).readBlob(addr, buffer.data(), buffer.size());
 
     int64_t ret = files[handle]->write(buffer.data(), buffer.size());
     if (ret < 0) {
@@ -375,7 +384,7 @@ ArmSemihosting::callRead(ThreadContext *tc, uint64_t handle, Addr addr,
     } else {
         panic_if(ret > buffer.size(), "Read longer than buffer size.");
 
-        physProxy(tc).writeBlob(addr, buffer.data(), ret);
+        portProxy(tc).writeBlob(addr, buffer.data(), ret);
 
         // Return the number of bytes not written
         return retOK(size - ret);
@@ -449,7 +458,7 @@ ArmSemihosting::callTmpNam(ThreadContext *tc, Addr addr, uint64_t id,
     if (path_len >= size)
         return retError(ENOSPC);
 
-    physProxy(tc).writeBlob(addr, path, path_len + 1);
+    portProxy(tc).writeBlob(addr, path, path_len + 1);
     return retOK(0);
 }
 
@@ -512,7 +521,7 @@ ArmSemihosting::RetErrno
 ArmSemihosting::callGetCmdLine(ThreadContext *tc, Addr addr,
                                InPlaceArg size_arg)
 {
-    PortProxy &proxy = physProxy(tc);
+    PortProxy &proxy = portProxy(tc);
     ByteOrder endian = ArmISA::byteOrder(tc);
     size_t size = size_arg.read(tc, endian);
 
@@ -576,7 +585,7 @@ ArmSemihosting::callHeapInfo32(ThreadContext *tc, Addr block_addr)
         (uint32_t)heap_base, (uint32_t)heap_limit,
         (uint32_t)stack_base, (uint32_t)stack_limit
     };
-    physProxy(tc).write(block_addr, block, ArmISA::byteOrder(tc));
+    portProxy(tc).write(block_addr, block, ArmISA::byteOrder(tc));
 
     return retOK(0);
 }
@@ -590,7 +599,7 @@ ArmSemihosting::callHeapInfo64(ThreadContext *tc, Addr block_addr)
     std::array<uint64_t, 4> block = {
         heap_base, heap_limit, stack_base, stack_limit
     };
-    physProxy(tc).write(block_addr, block, ArmISA::byteOrder(tc));
+    portProxy(tc).write(block_addr, block, ArmISA::byteOrder(tc));
 
     return retOK(0);
 }
index e255d201b058338d9bf02155525e7c3b1f85e7a8..83d41fd42572bec4808f4a39b13a974e2c986bc4 100644 (file)
@@ -73,7 +73,7 @@ class ArmSemihosting : public SimObject
 {
   public:
 
-    static PortProxy &physProxy(ThreadContext *tc);
+    static PortProxy &portProxy(ThreadContext *tc);
 
     struct AbiBase
     {
@@ -110,7 +110,7 @@ class ArmSemihosting : public SimObject
             Arg
             get(ThreadContext *tc)
             {
-                Arg arg = ArmSemihosting::physProxy(tc).read<Arg>(
+                Arg arg = ArmSemihosting::portProxy(tc).read<Arg>(
                         argPointer, endian);
                 argPointer += sizeof(Arg);
                 return arg;
@@ -159,7 +159,7 @@ class ArmSemihosting : public SimObject
         uint64_t
         read(ThreadContext *tc, ByteOrder endian)
         {
-            auto &proxy = ArmSemihosting::physProxy(tc);
+            auto &proxy = ArmSemihosting::portProxy(tc);
             if (size == 8)
                 return proxy.read<uint64_t>(addr, endian);
             else if (size == 4)
@@ -172,7 +172,7 @@ class ArmSemihosting : public SimObject
         void
         write(ThreadContext *tc, uint64_t val, ByteOrder endian)
         {
-            auto &proxy = ArmSemihosting::physProxy(tc);
+            auto &proxy = ArmSemihosting::portProxy(tc);
             if (size == 8)
                 proxy.write<uint64_t>(addr, val, endian);
             else if (size == 4)