Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/50760 )

Change subject: mem: Use the MMU's translation generator in translating proxies.
......................................................................

mem: Use the MMU's translation generator in translating proxies.

Use the more flexible MMU translation generator which does not need to
be told what page size to use, and which will be able to do flexible
things like translate across varying page sizes.

Change-Id: Ibfefc39d833f37bc35d703c505b193ea68988ab0
---
M src/mem/se_translating_port_proxy.cc
M src/mem/se_translating_port_proxy.hh
M src/mem/translating_port_proxy.cc
M src/mem/translating_port_proxy.hh
4 files changed, 57 insertions(+), 74 deletions(-)



diff --git a/src/mem/se_translating_port_proxy.cc b/src/mem/se_translating_port_proxy.cc
index 1a5fe96..8f4544c 100644
--- a/src/mem/se_translating_port_proxy.cc
+++ b/src/mem/se_translating_port_proxy.cc
@@ -52,15 +52,17 @@
 {}

 bool
-SETranslatingPortProxy::fixupAddr(Addr addr, BaseMMU::Mode mode) const
+SETranslatingPortProxy::fixupRange(const TranslationGen::Range &range,
+        BaseMMU::Mode mode) const
 {
     auto *process = _tc->getProcessPtr();

     if (mode == BaseMMU::Write) {
         if (allocating == Always) {
-            process->allocateMem(roundDown(addr, pageBytes), pageBytes);
+            process->allocateMem(range.vaddr, range.size);
             return true;
-        } else if (allocating == NextPage && process->fixupFault(addr)) {
+        } else if (allocating == NextPage &&
+                process->fixupFault(range.vaddr)) {
             // We've accessed the next page on the stack.
             return true;
         }
diff --git a/src/mem/se_translating_port_proxy.hh b/src/mem/se_translating_port_proxy.hh
index f46cfe4..0d7af4a 100644
--- a/src/mem/se_translating_port_proxy.hh
+++ b/src/mem/se_translating_port_proxy.hh
@@ -61,7 +61,8 @@
     AllocType allocating;

   protected:
-    bool fixupAddr(Addr addr, BaseMMU::Mode mode) const override;
+    bool fixupRange(const TranslationGen::Range &range,
+            BaseMMU::Mode mode) const override;

   public:
     SETranslatingPortProxy(ThreadContext *tc, AllocType alloc=NextPage,
diff --git a/src/mem/translating_port_proxy.cc b/src/mem/translating_port_proxy.cc
index 466b778..8ab859f 100644
--- a/src/mem/translating_port_proxy.cc
+++ b/src/mem/translating_port_proxy.cc
@@ -56,87 +56,69 @@

 TranslatingPortProxy::TranslatingPortProxy(
         ThreadContext *tc, Request::Flags _flags) :
-    PortProxy(tc, tc->getSystemPtr()->cacheLineSize()), _tc(tc),
-              pageBytes(tc->getSystemPtr()->getPageBytes()),
-              flags(_flags)
+ PortProxy(tc, tc->getSystemPtr()->cacheLineSize()), _tc(tc), flags(_flags)
 {}

 bool
-TranslatingPortProxy::tryTLBsOnce(RequestPtr req, BaseMMU::Mode mode) const
+TranslatingPortProxy::tryOnBlob(BaseMMU::Mode mode, TranslationGenPtr gen,
+        std::function<void(const TranslationGen::Range &)> func) const
 {
-    BaseMMU *mmu = _tc->getMMUPtr();
-    return mmu->translateFunctional(req, _tc, mode) == NoFault ||
-           mmu->translateFunctional(req, _tc, BaseMMU::Execute) == NoFault;
-}
+    // Wether we're trying to get past a fault.
+    bool faulting = false;
+    for (const auto &range: *gen) {
+        // Was there a fault this time?
+        if (range.fault) {
+            // If there was a fault last time too, or the fixup this time
+            // fails, then the operation has failed.
+            if (faulting || !fixupRange(range, mode))
+                return false;
+            // This must be the first time we've tried this translation, so
+            // record that we're making a second attempt and continue.
+            faulting = true;
+            continue;
+        }

-bool
-TranslatingPortProxy::tryTLBs(RequestPtr req, BaseMMU::Mode mode) const
-{
- // If at first this doesn't succeed, try to fixup and translate again. If
-    // it still fails, report failure.
-    return tryTLBsOnce(req, mode) ||
-        (fixupAddr(req->getVaddr(), mode) && tryTLBsOnce(req, mode));
+        // Run func() on this successful translation.
+        faulting = false;
+        func(range);
+    }
+    return true;
 }

 bool
 TranslatingPortProxy::tryReadBlob(Addr addr, void *p, int size) const
 {
-    for (ChunkGenerator gen(addr, size, pageBytes); !gen.done();
-         gen.next())
-    {
-        auto req = std::make_shared<Request>(
-                gen.addr(), gen.size(), flags, Request::funcRequestorId, 0,
-                _tc->contextId());
-
-        if (!tryTLBs(req, BaseMMU::Read))
-            return false;
-
-        PortProxy::readBlobPhys(
-                req->getPaddr(), req->getFlags(), p, gen.size());
-
-        p = static_cast<uint8_t *>(p) + gen.size();
-    }
-    return true;
+    constexpr auto mode = BaseMMU::Read;
+    return tryOnBlob(mode, _tc->getMMUPtr()->translateFunctional(
+            addr, size, _tc, mode, flags),
+        [this, &p](const auto &range) {
+            PortProxy::readBlobPhys(range.paddr, flags, p, range.size);
+            p = static_cast<uint8_t *>(p) + range.size;
+    });
 }

 bool
 TranslatingPortProxy::tryWriteBlob(
         Addr addr, const void *p, int size) const
 {
-    for (ChunkGenerator gen(addr, size, pageBytes); !gen.done();
-         gen.next())
-    {
-        auto req = std::make_shared<Request>(
-                gen.addr(), gen.size(), flags, Request::funcRequestorId, 0,
-                _tc->contextId());
-
-        if (!tryTLBs(req, BaseMMU::Write))
-            return false;
-
-        PortProxy::writeBlobPhys(
-                req->getPaddr(), req->getFlags(), p, gen.size());
-        p = static_cast<const uint8_t *>(p) + gen.size();
-    }
-    return true;
+    constexpr auto mode = BaseMMU::Write;
+    return tryOnBlob(mode, _tc->getMMUPtr()->translateFunctional(
+            addr, size, _tc, mode, flags),
+        [this, &p](const auto &range) {
+            PortProxy::writeBlobPhys(range.paddr, flags, p, range.size);
+            p = static_cast<const uint8_t *>(p) + range.size;
+    });
 }

 bool
-TranslatingPortProxy::tryMemsetBlob(Addr address, uint8_t v, int size) const
+TranslatingPortProxy::tryMemsetBlob(Addr addr, uint8_t v, int size) const
 {
-    for (ChunkGenerator gen(address, size, pageBytes); !gen.done();
-         gen.next())
-    {
-        auto req = std::make_shared<Request>(
-                gen.addr(), gen.size(), flags, Request::funcRequestorId, 0,
-                _tc->contextId());
-
-        if (!tryTLBs(req, BaseMMU::Write))
-            return false;
-
-        PortProxy::memsetBlobPhys(
-                req->getPaddr(), req->getFlags(), v, gen.size());
-    }
-    return true;
+    constexpr auto mode = BaseMMU::Write;
+    return tryOnBlob(mode, _tc->getMMUPtr()->translateFunctional(
+            addr, size, _tc, mode, flags),
+        [this, v](const auto &range) {
+            PortProxy::memsetBlobPhys(range.paddr, flags, v, range.size);
+    });
 }

 } // namespace gem5
diff --git a/src/mem/translating_port_proxy.hh b/src/mem/translating_port_proxy.hh
index 494ed8b..bedb57a 100644
--- a/src/mem/translating_port_proxy.hh
+++ b/src/mem/translating_port_proxy.hh
@@ -41,7 +41,9 @@
 #ifndef __MEM_TRANSLATING_PORT_PROXY_HH__
 #define __MEM_TRANSLATING_PORT_PROXY_HH__

-#include "arch/generic/tlb.hh"
+#include <functional>
+
+#include "arch/generic/mmu.hh"
 #include "mem/port_proxy.hh"

 namespace gem5
@@ -57,24 +59,20 @@
  */
 class TranslatingPortProxy : public PortProxy
 {
-  private:
-    bool tryTLBsOnce(RequestPtr req, BaseMMU::Mode) const;
-    bool tryTLBs(RequestPtr req, BaseMMU::Mode) const;
-
   protected:
     ThreadContext* _tc;
-    const Addr pageBytes;
-
     Request::Flags flags;

     virtual bool
-    fixupAddr(Addr addr, BaseMMU::Mode mode) const
+ fixupRange(const TranslationGen::Range &range, BaseMMU::Mode mode) const
     {
         return false;
     }

-  public:
+    bool tryOnBlob(BaseMMU::Mode mode, TranslationGenPtr gen,
+            std::function<void(const TranslationGen::Range &)> func) const;

+  public:
     TranslatingPortProxy(ThreadContext *tc, Request::Flags _flags=0);

     /** Version of tryReadblob that translates virt->phys and deals

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/50760
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: Ibfefc39d833f37bc35d703c505b193ea68988ab0
Gerrit-Change-Number: 50760
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <gabe.bl...@gmail.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to