Giacomo Travaglini has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/48146 )

Change subject: arch: Provide an alternative view of the TLBs in the BaseMMU
......................................................................

arch: Provide an alternative view of the TLBs in the BaseMMU

It is possible from the MMU to traverse the entire hierarchy of
TLBs, starting from the DTB and ITB (generally speaking from the
first level) up to the last level via the nextLevel pointer. So
in theory no extra data should be stored in the BaseMMU.

This design makes some operations a bit more complex. For example
if we have a unified (I+D) L2, it will be pointed by both ITB and
DTB. If we want to invalidate all TLB entries, we should be
careful to not invalidate L2 twice, but if we simply follow the
next level pointer, we might do so. This is not a problem from
a functional perspective but alters the TLB statistics (a single
invalidation is recorded twice)

We then provide a different view of the set of TLBs in the system.
At the init phase we traverse the TLB hierarchy and we add every
TLB to the appropriate set. This makes invalidation (and any
operation targeting a specific kind of TLBs) easier.

JIRA: https://gem5.atlassian.net/browse/GEM5-790

Change-Id: Ieb833c2328e9daeaf50a32b79b970f77f3e874f7
Signed-off-by: Giacomo Travaglini <giacomo.travagl...@arm.com>
---
M src/arch/arm/ArmMMU.py
M src/arch/generic/BaseMMU.py
M src/arch/generic/mmu.cc
M src/arch/generic/mmu.hh
4 files changed, 82 insertions(+), 3 deletions(-)



diff --git a/src/arch/arm/ArmMMU.py b/src/arch/arm/ArmMMU.py
index 1596574..0112bc9 100644
--- a/src/arch/arm/ArmMMU.py
+++ b/src/arch/arm/ArmMMU.py
@@ -93,6 +93,8 @@
     def init(self):
         self.getCCObject().wireComponents()

+        super(ArmMMU, self).init()
+
     @classmethod
     def walkerPorts(cls):
         return ["mmu.itb_walker.port", "mmu.dtb_walker.port",
diff --git a/src/arch/generic/BaseMMU.py b/src/arch/generic/BaseMMU.py
index c9ea25a..9ee4c70 100644
--- a/src/arch/generic/BaseMMU.py
+++ b/src/arch/generic/BaseMMU.py
@@ -37,7 +37,7 @@

 from m5.objects.BaseTLB import BaseTLB
 from m5.params import *
-from m5.SimObject import SimObject
+from m5.SimObject import SimObject, PyBindMethod

 class BaseMMU(SimObject):
     type = 'BaseMMU'
@@ -45,9 +45,16 @@
     cxx_header = "arch/generic/mmu.hh"
     cxx_class = 'gem5::BaseMMU'

+    cxx_exports = [
+        PyBindMethod('initMMU'),
+    ]
+
     itb = Param.BaseTLB("Instruction TLB")
     dtb = Param.BaseTLB("Data TLB")

+    def init(self):
+        self.getCCObject().initMMU()
+
     @classmethod
     def walkerPorts(cls):
         # This classmethod is used by the BaseCPU. It should return
diff --git a/src/arch/generic/mmu.cc b/src/arch/generic/mmu.cc
index 7aaec5b..5956293 100644
--- a/src/arch/generic/mmu.cc
+++ b/src/arch/generic/mmu.cc
@@ -48,10 +48,47 @@
 {

 void
+BaseMMU::initMMU()
+{
+    auto traverse_hierarchy = [this](BaseTLB *starter) {
+        for (BaseTLB *tlb = starter; tlb; tlb = tlb->getNextLevel()) {
+            switch (tlb->type()) {
+              case TypeTLB::instruction:
+                if (instruction.find(tlb) == instruction.end())
+                    instruction.insert(tlb);
+                break;
+              case TypeTLB::data:
+                if (data.find(tlb) == data.end())
+                    data.insert(tlb);
+                break;
+              case TypeTLB::unified:
+                if (unified.find(tlb) == unified.end())
+                    unified.insert(tlb);
+                break;
+              default:
+                panic("Invalid TLB type\n");
+            }
+        }
+    };
+
+    traverse_hierarchy(itb);
+    traverse_hierarchy(dtb);
+}
+
+void
 BaseMMU::flushAll()
 {
-    dtb->flushAll();
-    itb->flushAll();
+    for (auto tlb : instruction) {
+        tlb->flushAll();
+    }
+
+    for (auto tlb : data) {
+        tlb->flushAll();
+    }
+
+    for (auto tlb : unified) {
+        tlb->flushAll();
+    }
 }

 void
diff --git a/src/arch/generic/mmu.hh b/src/arch/generic/mmu.hh
index 8bcb3a7..4767278 100644
--- a/src/arch/generic/mmu.hh
+++ b/src/arch/generic/mmu.hh
@@ -38,6 +38,8 @@
 #ifndef __ARCH_GENERIC_MMU_HH__
 #define __ARCH_GENERIC_MMU_HH__

+#include <set>
+
 #include "params/BaseMMU.hh"
 #include "mem/request.hh"
 #include "sim/sim_object.hh"
@@ -98,6 +100,12 @@
     }

   public:
+    /**
+     * Called at init time, this method is traversing the TLB hierarchy
+     * and pupulating the instruction/data/unified containers accordingly
+     */
+    void initMMU();
+
     virtual void flushAll();

     void demapPage(Addr vaddr, uint64_t asn);
@@ -123,6 +131,31 @@
   public:
     BaseTLB* dtb;
     BaseTLB* itb;
+
+  protected:
+    /**
+     * It is possible from the MMU to traverse the entire hierarchy of
+     * TLBs, starting from the DTB and ITB (generally speaking from the
+     * first level) up to the last level via the nextLevel pointer. So
+     * in theory no extra data should be stored in the BaseMMU.
+     *
+     * This design makes some operations a bit more complex. For example
+     * if we have a unified (I+D) L2, it will be pointed by both ITB and
+     * DTB. If we want to invalidate all TLB entries, we should be
+     * careful to not invalidate L2 twice, but if we simply follow the
+     * next level pointer, we might do so. This is not a problem from
+     * a functional perspective but alters the TLB statistics (a single
+     * invalidation is recorded twice)
+     *
+     * We then provide a different view of the set of TLBs in the system.
+     * At the init phase we traverse the TLB hierarchy and we add every
+     * TLB to the appropriate set. This makes invalidation (and any
+     * operation targeting a specific kind of TLBs) easier.
+     */
+    std::set<BaseTLB*> instruction;
+    std::set<BaseTLB*> data;
+    std::set<BaseTLB*> unified;
+
 };

 } // namespace gem5

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/48146
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: Ieb833c2328e9daeaf50a32b79b970f77f3e874f7
Gerrit-Change-Number: 48146
Gerrit-PatchSet: 1
Gerrit-Owner: Giacomo Travaglini <giacomo.travagl...@arm.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