arch-arm: Use ExceptionLevel type in TlbEntry

Replacing uint8_t with ExceptionLevel type in the arm TlbEntry. The
variable is representing the translation regime it is targeting.

Change-Id: Ifcd6e86c5d73f752e8476a2b7fda9ea74a0c7a3b
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/19488
Reviewed-by: Ciro Santilli <ciro.santilli@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
diff --git a/src/arch/arm/pagetable.hh b/src/arch/arm/pagetable.hh
index 856e0d5..240a1ca 100644
--- a/src/arch/arm/pagetable.hh
+++ b/src/arch/arm/pagetable.hh
@@ -133,7 +133,7 @@
     // True if the entry was brought in from a non-secure page table
     bool nstid;
     // Exception level on insert, AARCH64 EL0&1, AARCH32 -> el=1
-    uint8_t el;
+    ExceptionLevel el;
 
     // Type of memory
     bool nonCacheable;     // Can we wrap this in mtype?
@@ -154,7 +154,7 @@
          innerAttrs(0), outerAttrs(0), ap(read_only ? 0x3 : 0), hap(0x3),
          domain(DomainType::Client),  mtype(MemoryType::StronglyOrdered),
          longDescFormat(false), isHyp(false), global(false), valid(true),
-         ns(true), nstid(true), el(0), nonCacheable(uncacheable),
+         ns(true), nstid(true), el(EL0), nonCacheable(uncacheable),
          shareable(false), outerShareable(false), xn(0), pxn(0)
     {
         // no restrictions by default, hap = 0x3
@@ -169,7 +169,7 @@
          vmid(0), N(0), innerAttrs(0), outerAttrs(0), ap(0), hap(0x3),
          domain(DomainType::Client), mtype(MemoryType::StronglyOrdered),
          longDescFormat(false), isHyp(false), global(false), valid(false),
-         ns(true), nstid(true), el(0), nonCacheable(false),
+         ns(true), nstid(true), el(EL0), nonCacheable(false),
          shareable(false), outerShareable(false), xn(0), pxn(0)
     {
         // no restrictions by default, hap = 0x3
@@ -191,14 +191,14 @@
 
     bool
     match(Addr va, uint8_t _vmid, bool hypLookUp, bool secure_lookup,
-          uint8_t target_el) const
+          ExceptionLevel target_el) const
     {
         return match(va, 0, _vmid, hypLookUp, secure_lookup, true, target_el);
     }
 
     bool
     match(Addr va, uint16_t asn, uint8_t _vmid, bool hypLookUp,
-          bool secure_lookup, bool ignore_asn, uint8_t target_el) const
+          bool secure_lookup, bool ignore_asn, ExceptionLevel target_el) const
     {
         bool match = false;
         Addr v = vpn << N;
@@ -206,10 +206,8 @@
         if (valid && va >= v && va <= v + size && (secure_lookup == !nstid) &&
             (hypLookUp == isHyp))
         {
-            if (target_el == 2 || target_el == 3)
-                match = (el == target_el);
-            else
-                match = (el == 0) || (el == 1);
+            match = checkELMatch(target_el);
+
             if (match && !ignore_asn) {
                 match = global || (asn == asid);
             }
@@ -220,6 +218,16 @@
         return match;
     }
 
+    bool
+    checkELMatch(ExceptionLevel target_el) const
+    {
+        if (target_el == EL2 || target_el == EL3) {
+            return (el  == target_el);
+        } else {
+            return (el == EL0) || (el == EL1);
+        }
+    }
+
     Addr
     pAddr(Addr va) const
     {
diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc
index 461194d..3feffa9 100644
--- a/src/arch/arm/table_walker.cc
+++ b/src/arch/arm/table_walker.cc
@@ -2064,7 +2064,7 @@
     if (currState->aarch64)
         te.el         = currState->el;
     else
-        te.el         = 1;
+        te.el         = EL1;
 
     statPageSizes[pageSizeNtoStatBin(te.N)]++;
     statRequestOrigin[COMPLETED][currState->isFetch]++;
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index 2b50d4b..872f351 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -150,7 +150,7 @@
 
 TlbEntry*
 TLB::lookup(Addr va, uint16_t asn, uint8_t vmid, bool hyp, bool secure,
-            bool functional, bool ignore_asn, uint8_t target_el)
+            bool functional, bool ignore_asn, ExceptionLevel target_el)
 {
 
     TlbEntry *retval = NULL;
@@ -236,7 +236,8 @@
 }
 
 void
-TLB::flushAllSecurity(bool secure_lookup, uint8_t target_el, bool ignore_el)
+TLB::flushAllSecurity(bool secure_lookup, ExceptionLevel target_el,
+                      bool ignore_el)
 {
     DPRINTF(TLB, "Flushing all TLB entries (%s lookup)\n",
             (secure_lookup ? "secure" : "non-secure"));
@@ -244,9 +245,11 @@
     TlbEntry *te;
     while (x < size) {
         te = &table[x];
+        const bool el_match = ignore_el ?
+            true : te->checkELMatch(target_el);
+
         if (te->valid && secure_lookup == !te->nstid &&
-            (te->vmid == vmid || secure_lookup) &&
-            checkELMatch(target_el, te->el, ignore_el)) {
+            (te->vmid == vmid || secure_lookup) && el_match) {
 
             DPRINTF(TLB, " -  %s\n", te->print());
             te->valid = false;
@@ -260,12 +263,12 @@
     // If there's a second stage TLB (and we're not it) then flush it as well
     // if we're currently in hyp mode
     if (!isStage2 && isHyp) {
-        stage2Tlb->flushAllSecurity(secure_lookup, true);
+        stage2Tlb->flushAllSecurity(secure_lookup, EL1, true);
     }
 }
 
 void
-TLB::flushAllNs(uint8_t target_el, bool ignore_el)
+TLB::flushAllNs(ExceptionLevel target_el, bool ignore_el)
 {
     bool hyp = target_el == EL2;
 
@@ -275,8 +278,10 @@
     TlbEntry *te;
     while (x < size) {
         te = &table[x];
-        if (te->valid && te->nstid && te->isHyp == hyp &&
-            checkELMatch(target_el, te->el, ignore_el)) {
+        const bool el_match = ignore_el ?
+            true : te->checkELMatch(target_el);
+
+        if (te->valid && te->nstid && te->isHyp == hyp && el_match) {
 
             DPRINTF(TLB, " -  %s\n", te->print());
             flushedEntries++;
@@ -289,12 +294,13 @@
 
     // If there's a second stage TLB (and we're not it) then flush it as well
     if (!isStage2 && !hyp) {
-        stage2Tlb->flushAllNs(false, true);
+        stage2Tlb->flushAllNs(EL1, true);
     }
 }
 
 void
-TLB::flushMvaAsid(Addr mva, uint64_t asn, bool secure_lookup, uint8_t target_el)
+TLB::flushMvaAsid(Addr mva, uint64_t asn, bool secure_lookup,
+                  ExceptionLevel target_el)
 {
     DPRINTF(TLB, "Flushing TLB entries with mva: %#x, asid: %#x "
             "(%s lookup)\n", mva, asn, (secure_lookup ?
@@ -304,7 +310,7 @@
 }
 
 void
-TLB::flushAsid(uint64_t asn, bool secure_lookup, uint8_t target_el)
+TLB::flushAsid(uint64_t asn, bool secure_lookup, ExceptionLevel target_el)
 {
     DPRINTF(TLB, "Flushing TLB entries with asid: %#x (%s lookup)\n", asn,
             (secure_lookup ? "secure" : "non-secure"));
@@ -316,7 +322,7 @@
         te = &table[x];
         if (te->valid && te->asid == asn && secure_lookup == !te->nstid &&
             (te->vmid == vmid || secure_lookup) &&
-            checkELMatch(target_el, te->el, false)) {
+            te->checkELMatch(target_el)) {
 
             te->valid = false;
             DPRINTF(TLB, " -  %s\n", te->print());
@@ -328,7 +334,7 @@
 }
 
 void
-TLB::flushMva(Addr mva, bool secure_lookup, uint8_t target_el)
+TLB::flushMva(Addr mva, bool secure_lookup, ExceptionLevel target_el)
 {
     DPRINTF(TLB, "Flushing TLB entries with mva: %#x (%s lookup)\n", mva,
             (secure_lookup ? "secure" : "non-secure"));
@@ -338,7 +344,7 @@
 
 void
 TLB::_flushMva(Addr mva, uint64_t asn, bool secure_lookup,
-               bool ignore_asn, uint8_t target_el)
+               bool ignore_asn, ExceptionLevel target_el)
 {
     TlbEntry *te;
     // D5.7.2: Sign-extend address to 64 bits
@@ -360,26 +366,12 @@
 }
 
 void
-TLB::flushIpaVmid(Addr ipa, bool secure_lookup, uint8_t target_el)
+TLB::flushIpaVmid(Addr ipa, bool secure_lookup, ExceptionLevel target_el)
 {
     assert(!isStage2);
     stage2Tlb->_flushMva(ipa, 0xbeef, secure_lookup, true, target_el);
 }
 
-bool
-TLB::checkELMatch(uint8_t target_el, uint8_t tentry_el, bool ignore_el)
-{
-    bool elMatch = true;
-    if (!ignore_el) {
-        if (target_el == 2 || target_el == 3) {
-            elMatch = (tentry_el  == target_el);
-        } else {
-            elMatch = (tentry_el == 0) || (tentry_el  == 1);
-        }
-    }
-    return elMatch;
-}
-
 void
 TLB::drainResume()
 {
diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh
index fb8d794..a84e945 100644
--- a/src/arch/arm/tlb.hh
+++ b/src/arch/arm/tlb.hh
@@ -212,7 +212,7 @@
      */
     TlbEntry *lookup(Addr vpn, uint16_t asn, uint8_t vmid, bool hyp,
                      bool secure, bool functional,
-                     bool ignore_asn, uint8_t target_el);
+                     bool ignore_asn, ExceptionLevel target_el);
 
     virtual ~TLB();
 
@@ -249,13 +249,13 @@
     /** Reset the entire TLB
      * @param secure_lookup if the operation affects the secure world
      */
-    void flushAllSecurity(bool secure_lookup, uint8_t target_el,
+    void flushAllSecurity(bool secure_lookup, ExceptionLevel target_el,
                           bool ignore_el = false);
 
     /** Remove all entries in the non secure world, depending on whether they
      *  were allocated in hyp mode or not
      */
-    void flushAllNs(uint8_t target_el, bool ignore_el = false);
+    void flushAllNs(ExceptionLevel target_el, bool ignore_el = false);
 
 
     /** Reset the entire TLB. Used for CPU switching to prevent stale
@@ -263,8 +263,8 @@
      */
     void flushAll() override
     {
-        flushAllSecurity(false, 0, true);
-        flushAllSecurity(true, 0, true);
+        flushAllSecurity(false, EL0, true);
+        flushAllSecurity(true, EL0, true);
     }
 
     /** Remove any entries that match both a va and asn
@@ -273,19 +273,20 @@
      * @param secure_lookup if the operation affects the secure world
      */
     void flushMvaAsid(Addr mva, uint64_t asn, bool secure_lookup,
-                      uint8_t target_el);
+                      ExceptionLevel target_el);
 
     /** Remove any entries that match the asn
      * @param asn contextid/asn to flush on match
      * @param secure_lookup if the operation affects the secure world
      */
-    void flushAsid(uint64_t asn, bool secure_lookup, uint8_t target_el);
+    void flushAsid(uint64_t asn, bool secure_lookup,
+                   ExceptionLevel target_el);
 
     /** Remove all entries that match the va regardless of asn
      * @param mva address to flush from cache
      * @param secure_lookup if the operation affects the secure world
      */
-    void flushMva(Addr mva, bool secure_lookup, uint8_t target_el);
+    void flushMva(Addr mva, bool secure_lookup, ExceptionLevel target_el);
 
     /**
      * Invalidate all entries in the stage 2 TLB that match the given ipa
@@ -293,7 +294,7 @@
      * @param ipa the address to invalidate
      * @param secure_lookup if the operation affects the secure world
      */
-    void flushIpaVmid(Addr ipa, bool secure_lookup, uint8_t target_el);
+    void flushIpaVmid(Addr ipa, bool secure_lookup, ExceptionLevel target_el);
 
     Fault trickBoxCheck(const RequestPtr &req, Mode mode,
                         TlbEntry::DomainType domain);
@@ -450,9 +451,7 @@
      * @param ignore_asn if the flush should ignore the asn
      */
     void _flushMva(Addr mva, uint64_t asn, bool secure_lookup,
-                   bool ignore_asn, uint8_t target_el);
-
-    bool checkELMatch(uint8_t target_el, uint8_t tentry_el, bool ignore_el);
+                   bool ignore_asn, ExceptionLevel target_el);
 
   public: /* Testing */
     Fault testTranslation(const RequestPtr &req, Mode mode,