Giacomo Travaglini has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/48148 )

Change subject: arch-arm: Explicitly implement I/DTLBI Ops in TLB
......................................................................

arch-arm: Explicitly implement I/DTLBI Ops in TLB

At the moment the ITLBI and DTLBI operations where implicitly
implemented as generic TLBIs

e.g:

* DTLBIASID, ITLBIASID = TLBIASID

This was possible as a single TLB was either an instruction TLB
or a data TLB and no generic/shared TLB option was available.
In other words, an ITLBI Op to an ITB was invalidating all entries
as we were sure the ITB was not containing data entries.

With shared TLBs, this doesn't hold true and we need to explicitly
implement I/DTLBIs

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

Change-Id: I39a4add7674f6008dacaedfd1fd90560d264048e
Signed-off-by: Giacomo Travaglini <giacomo.travagl...@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/48148
Reviewed-by: Andreas Sandberg <andreas.sandb...@arm.com>
Maintainer: Andreas Sandberg <andreas.sandb...@arm.com>
Tested-by: kokoro <noreply+kok...@google.com>
---
M src/arch/arm/tlb.cc
M src/arch/arm/tlb.hh
2 files changed, 145 insertions(+), 5 deletions(-)

Approvals:
  Andreas Sandberg: Looks good to me, approved; Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index dc0e155..666836b 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -229,6 +229,56 @@
 }

 void
+TLB::flush(const ITLBIALL& tlbi_op)
+{
+    DPRINTF(TLB, "Flushing all ITLB entries (%s lookup)\n",
+            (tlbi_op.secureLookup ? "secure" : "non-secure"));
+    int x = 0;
+    TlbEntry *te;
+    while (x < size) {
+        te = &table[x];
+        const bool el_match = te->checkELMatch(
+            tlbi_op.targetEL, tlbi_op.inHost);
+        if (te->type & TypeTLB::instruction && te->valid &&
+            tlbi_op.secureLookup == !te->nstid &&
+            (te->vmid == vmid || tlbi_op.el2Enabled) && el_match) {
+
+            DPRINTF(TLB, " -  %s\n", te->print());
+            te->valid = false;
+            stats.flushedEntries++;
+        }
+        ++x;
+    }
+
+    stats.flushTlb++;
+}
+
+void
+TLB::flush(const DTLBIALL& tlbi_op)
+{
+    DPRINTF(TLB, "Flushing all DTLB entries (%s lookup)\n",
+            (tlbi_op.secureLookup ? "secure" : "non-secure"));
+    int x = 0;
+    TlbEntry *te;
+    while (x < size) {
+        te = &table[x];
+        const bool el_match = te->checkELMatch(
+            tlbi_op.targetEL, tlbi_op.inHost);
+        if (te->type & TypeTLB::data && te->valid &&
+            tlbi_op.secureLookup == !te->nstid &&
+            (te->vmid == vmid || tlbi_op.el2Enabled) && el_match) {
+
+            DPRINTF(TLB, " -  %s\n", te->print());
+            te->valid = false;
+            stats.flushedEntries++;
+        }
+        ++x;
+    }
+
+    stats.flushTlb++;
+}
+
+void
 TLB::flush(const TLBIALLEL &tlbi_op)
 {
     DPRINTF(TLB, "Flushing all TLB entries (%s lookup)\n",
@@ -307,7 +357,29 @@
             "(%s lookup)\n", tlbi_op.addr, tlbi_op.asid,
             (tlbi_op.secureLookup ? "secure" : "non-secure"));
     _flushMva(tlbi_op.addr, tlbi_op.asid, tlbi_op.secureLookup, false,
-        tlbi_op.targetEL, tlbi_op.inHost);
+        tlbi_op.targetEL, tlbi_op.inHost, TypeTLB::unified);
+    stats.flushTlbMvaAsid++;
+}
+
+void
+TLB::flush(const ITLBIMVA &tlbi_op)
+{
+    DPRINTF(TLB, "Flushing ITLB entries with mva: %#x, asid: %#x "
+            "(%s lookup)\n", tlbi_op.addr, tlbi_op.asid,
+            (tlbi_op.secureLookup ? "secure" : "non-secure"));
+    _flushMva(tlbi_op.addr, tlbi_op.asid, tlbi_op.secureLookup, false,
+        tlbi_op.targetEL, tlbi_op.inHost, TypeTLB::instruction);
+    stats.flushTlbMvaAsid++;
+}
+
+void
+TLB::flush(const DTLBIMVA &tlbi_op)
+{
+    DPRINTF(TLB, "Flushing DTLB entries with mva: %#x, asid: %#x "
+            "(%s lookup)\n", tlbi_op.addr, tlbi_op.asid,
+            (tlbi_op.secureLookup ? "secure" : "non-secure"));
+    _flushMva(tlbi_op.addr, tlbi_op.asid, tlbi_op.secureLookup, false,
+        tlbi_op.targetEL, tlbi_op.inHost, TypeTLB::data);
     stats.flushTlbMvaAsid++;
 }

@@ -337,19 +409,72 @@
 }

 void
+TLB::flush(const ITLBIASID &tlbi_op)
+{
+    DPRINTF(TLB, "Flushing ITLB entries with asid: %#x (%s lookup)\n",
+ tlbi_op.asid, (tlbi_op.secureLookup ? "secure" : "non-secure"));
+
+    int x = 0 ;
+    TlbEntry *te;
+
+    while (x < size) {
+        te = &table[x];
+        if (te->type & TypeTLB::instruction &&
+            te->valid && te->asid == tlbi_op.asid &&
+            tlbi_op.secureLookup == !te->nstid &&
+            (te->vmid == vmid || tlbi_op.el2Enabled) &&
+            te->checkELMatch(tlbi_op.targetEL, tlbi_op.inHost)) {
+
+            te->valid = false;
+            DPRINTF(TLB, " -  %s\n", te->print());
+            stats.flushedEntries++;
+        }
+        ++x;
+    }
+    stats.flushTlbAsid++;
+}
+
+void
+TLB::flush(const DTLBIASID &tlbi_op)
+{
+    DPRINTF(TLB, "Flushing DTLB entries with asid: %#x (%s lookup)\n",
+ tlbi_op.asid, (tlbi_op.secureLookup ? "secure" : "non-secure"));
+
+    int x = 0 ;
+    TlbEntry *te;
+
+    while (x < size) {
+        te = &table[x];
+        if (te->type & TypeTLB::data &&
+            te->valid && te->asid == tlbi_op.asid &&
+            tlbi_op.secureLookup == !te->nstid &&
+            (te->vmid == vmid || tlbi_op.el2Enabled) &&
+            te->checkELMatch(tlbi_op.targetEL, tlbi_op.inHost)) {
+
+            te->valid = false;
+            DPRINTF(TLB, " -  %s\n", te->print());
+            stats.flushedEntries++;
+        }
+        ++x;
+    }
+    stats.flushTlbAsid++;
+}
+
+void
 TLB::flush(const TLBIMVAA &tlbi_op) {

     DPRINTF(TLB, "Flushing TLB entries with mva: %#x (%s lookup)\n",
             tlbi_op.addr,
             (tlbi_op.secureLookup ? "secure" : "non-secure"));
     _flushMva(tlbi_op.addr, 0xbeef, tlbi_op.secureLookup, true,
-        tlbi_op.targetEL, tlbi_op.inHost);
+        tlbi_op.targetEL, tlbi_op.inHost, TypeTLB::unified);
     stats.flushTlbMva++;
 }

 void
 TLB::_flushMva(Addr mva, uint64_t asn, bool secure_lookup,
-               bool ignore_asn, ExceptionLevel target_el, bool in_host)
+               bool ignore_asn, ExceptionLevel target_el, bool in_host,
+               TypeTLB entry_type)
 {
     TlbEntry *te;
     // D5.7.2: Sign-extend address to 64 bits
@@ -360,7 +485,8 @@
     te = lookup(mva, asn, vmid, hyp, secure_lookup, true, ignore_asn,
                 target_el, in_host, BaseMMU::Read);
     while (te != NULL) {
-        if (secure_lookup == !te->nstid) {
+        bool matching_type = (te->type & entry_type);
+        if (matching_type && secure_lookup == !te->nstid) {
             DPRINTF(TLB, " -  %s\n", te->print());
             te->valid = false;
             stats.flushedEntries++;
diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh
index 927ac23..fa5e894 100644
--- a/src/arch/arm/tlb.hh
+++ b/src/arch/arm/tlb.hh
@@ -47,6 +47,7 @@
 #include "arch/arm/utility.hh"
 #include "arch/generic/tlb.hh"
 #include "base/statistics.hh"
+#include "enums/TypeTLB.hh"
 #include "mem/request.hh"
 #include "params/ArmTLB.hh"
 #include "sim/probe/pmu.hh"
@@ -62,11 +63,17 @@
 class TLB;

 class TLBIALL;
+class ITLBIALL;
+class DTLBIALL;
 class TLBIALLEL;
 class TLBIVMALL;
 class TLBIALLN;
 class TLBIMVA;
+class ITLBIMVA;
+class DTLBIMVA;
 class TLBIASID;
+class ITLBIASID;
+class DTLBIASID;
 class TLBIMVAA;

 class TlbTestInterface
@@ -191,6 +198,8 @@
     /** Reset the entire TLB
      */
     void flush(const TLBIALL &tlbi_op);
+    void flush(const ITLBIALL &tlbi_op);
+    void flush(const DTLBIALL &tlbi_op);

     /** Implementaton of AArch64 TLBI ALLE1(IS), ALLE2(IS), ALLE3(IS)
      * instructions
@@ -210,10 +219,14 @@
     /** Remove any entries that match both a va and asn
      */
     void flush(const TLBIMVA &tlbi_op);
+    void flush(const ITLBIMVA &tlbi_op);
+    void flush(const DTLBIMVA &tlbi_op);

     /** Remove any entries that match the asn
      */
     void flush(const TLBIASID &tlbi_op);
+    void flush(const ITLBIASID &tlbi_op);
+    void flush(const DTLBIASID &tlbi_op);

     /** Remove all entries that match the va regardless of asn
      */
@@ -283,10 +296,11 @@
      * @param secure_lookup if the operation affects the secure world
      * @param ignore_asn if the flush should ignore the asn
      * @param in_host if hcr.e2h == 1 and hcr.tge == 1 for VHE.
+     * @param entry_type type of entry to flush (instruction/data/unified)
      */
     void _flushMva(Addr mva, uint64_t asn, bool secure_lookup,
                    bool ignore_asn, ExceptionLevel target_el,
-                   bool in_host);
+                   bool in_host, TypeTLB entry_type);
 };

 } // namespace ArmISA

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/48148
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: I39a4add7674f6008dacaedfd1fd90560d264048e
Gerrit-Change-Number: 48148
Gerrit-PatchSet: 12
Gerrit-Owner: Giacomo Travaglini <giacomo.travagl...@arm.com>
Gerrit-Reviewer: Andreas Sandberg <andreas.sandb...@arm.com>
Gerrit-Reviewer: Giacomo Travaglini <giacomo.travagl...@arm.com>
Gerrit-Reviewer: kokoro <noreply+kok...@google.com>
Gerrit-MessageType: merged
_______________________________________________
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