fastmodel: Add an address translation mechanism to the ThreadContext.
authorGabe Black <gabeblack@google.com>
Sat, 19 Oct 2019 00:08:03 +0000 (17:08 -0700)
committerGabe Black <gabeblack@google.com>
Tue, 17 Dec 2019 23:17:28 +0000 (23:17 +0000)
This will be used by the TLB to do the actual translation.
Unfortunately there isn't a great way to tell what translation type to
use, so we just go through all of them for now. The ARM subclass might
specialize and figure out which address spaces to use based on control
register state.

Change-Id: Id1fcad66554acf9d69af683917b3c2834f825da0
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/22118
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/arm/fastmodel/iris/arm/thread_context.cc
src/arch/arm/fastmodel/iris/arm/thread_context.hh
src/arch/arm/fastmodel/iris/thread_context.cc
src/arch/arm/fastmodel/iris/thread_context.hh

index 26597d77148db76561b7db939262f70533b3ad92..181d2686d3ecb26185629c72e664bf761ef8c451 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "arch/arm/fastmodel/iris/arm/thread_context.hh"
 
+#include "arch/arm/fastmodel/iris/memory_spaces.hh"
 #include "iris/detail/IrisCppAdapter.h"
 #include "iris/detail/IrisObjects.h"
 
@@ -43,6 +44,43 @@ ArmThreadContext::ArmThreadContext(
     vecRegs(TheISA::NumVecRegs), pcRscId(iris::IRIS_UINT64_MAX)
 {}
 
+bool
+ArmThreadContext::translateAddress(Addr &paddr, Addr vaddr)
+{
+    // Determine what memory spaces are currently active.
+    CanonicalMsn in_msn;
+    switch (currEL(this)) {
+      case EL3:
+        in_msn = SecureMonitorMsn;
+        break;
+      case EL2:
+        in_msn = NsHypMsn;
+        break;
+      default:
+        in_msn = GuestMsn;
+        break;
+    }
+
+    CanonicalMsn out_msn = inSecureState(this) ?
+        PhysicalMemorySecureMsn : PhysicalMemoryNonSecureMsn;
+
+    // Figure out what memory spaces match the canonical numbers we need.
+    iris::MemorySpaceId in = iris::IRIS_UINT64_MAX;
+    iris::MemorySpaceId out = iris::IRIS_UINT64_MAX;
+
+    for (auto &space: memorySpaces) {
+        if (space.canonicalMsn == in_msn)
+            in = space.spaceId;
+        else if (space.canonicalMsn == out_msn)
+            out = space.spaceId;
+    }
+
+    panic_if(in == iris::IRIS_UINT64_MAX || out == iris::IRIS_UINT64_MAX,
+            "Canonical IRIS memory space numbers not found.");
+
+    return ThreadContext::translateAddress(paddr, out, vaddr, in);
+}
+
 void
 ArmThreadContext::initFromIrisInstance(const ResourceMap &resources)
 {
index 77603711d65e89bfc7b10888cdd528a53de4209f..6e28c3b8c9fadbc8b1ba2ad86ff017ffbf822cdd 100644 (file)
@@ -55,6 +55,8 @@ class ArmThreadContext : public Iris::ThreadContext
                      iris::IrisConnectionInterface *iris_if,
                      const std::string &iris_path);
 
+    bool translateAddress(Addr &paddr, Addr vaddr) override;
+
     void initFromIrisInstance(const ResourceMap &resources) override;
 
     TheISA::PCState pcState() const override;
index bccd7f4c0095fa68742309816dfd12bb62ad9509..89748957cc08eada9496714f5b6db68f6e81ff77 100644 (file)
@@ -43,6 +43,9 @@ ThreadContext::initFromIrisInstance(const ResourceMap &resources)
     _status = enabled ? Active : Suspended;
 
     suspend();
+
+    call().memory_getMemorySpaces(_instId, memorySpaces);
+    call().memory_getUsefulAddressTranslations(_instId, translations);
 }
 
 iris::ResourceId
@@ -231,6 +234,36 @@ ThreadContext::~ThreadContext()
     client.unregisterEventCallback("ec_IRIS_SIMULATION_TIME_EVENT");
 }
 
+bool
+ThreadContext::translateAddress(Addr &paddr, iris::MemorySpaceId p_space,
+                                Addr vaddr, iris::MemorySpaceId v_space)
+{
+    iris::MemoryAddressTranslationResult result;
+    auto ret = noThrow().memory_translateAddress(
+            _instId, result, v_space, vaddr, p_space);
+
+    if (ret != iris::E_ok) {
+        // Check if there was  a legal translation between these two spaces.
+        // If so, something else went wrong.
+        for (auto &trans: translations)
+            if (trans.inSpaceId == v_space && trans.outSpaceId == p_space)
+                return false;
+
+        panic("No legal translation IRIS address translation found.");
+    }
+
+    if (result.address.empty())
+        return false;
+
+    if (result.address.size() > 1) {
+        warn("Multiple mappings for address %#x.", vaddr);
+        return false;
+    }
+
+    paddr = result.address[0];
+    return true;
+}
+
 void
 ThreadContext::scheduleInstCountEvent(Event *event, Tick count)
 {
index d0e920e609793296cfdec22bfd0d2b01bd2d2873..49b3325e76c0dece29f1f2c27c5eb3eee1816d23 100644 (file)
@@ -74,6 +74,9 @@ class ThreadContext : public ::ThreadContext
     ResourceIds miscRegIds;
     ResourceIds intRegIds;
 
+    std::vector<iris::MemorySpaceInfo> memorySpaces;
+    std::vector<iris::MemorySupportedAddressTranslationResult> translations;
+
 
     // A queue to keep track of instruction count based events.
     EventQueue comInstEventQueue;
@@ -101,6 +104,9 @@ class ThreadContext : public ::ThreadContext
     iris::IrisCppAdapter &call() const { return client.irisCall(); }
     iris::IrisCppAdapter &noThrow() const { return client.irisCallNoThrow(); }
 
+    bool translateAddress(Addr &paddr, iris::MemorySpaceId p_space,
+                          Addr vaddr, iris::MemorySpaceId v_space);
+
   public:
     ThreadContext(::BaseCPU *cpu, int id, System *system,
                   ::BaseTLB *dtb, ::BaseTLB *itb,
@@ -108,6 +114,8 @@ class ThreadContext : public ::ThreadContext
                   const std::string &iris_path);
     virtual ~ThreadContext();
 
+    virtual bool translateAddress(Addr &paddr, Addr vaddr) = 0;
+
     bool schedule(PCEvent *e) override { return false; }
     bool remove(PCEvent *e) override { return false; }