alpha: Implement a cache for recently used page table entries
authorVincentius Robby <acolyte@umich.edu>
Sat, 4 Aug 2007 18:25:35 +0000 (14:25 -0400)
committerVincentius Robby <acolyte@umich.edu>
Sat, 4 Aug 2007 18:25:35 +0000 (14:25 -0400)
--HG--
extra : convert_revision : 1bb80d71fa91e500a68390e5dc17464ce7136fba

src/arch/alpha/tlb.cc
src/arch/alpha/tlb.hh

index 214b2579f264522e00f89c3a952dd10bbe76d0c2..205b81baf96f9dcdb3674c3633b81265e5b15683 100644 (file)
@@ -64,6 +64,7 @@ TLB::TLB(const string &name, int s)
 {
     table = new PTE[size];
     memset(table, 0, sizeof(PTE[size]));
+    flushCache();
 }
 
 TLB::~TLB()
@@ -79,18 +80,29 @@ TLB::lookup(Addr vpn, uint8_t asn) const
     // assume not found...
     PTE *retval = NULL;
 
-    PageTable::const_iterator i = lookupTable.find(vpn);
-    if (i != lookupTable.end()) {
-        while (i->first == vpn) {
-            int index = i->second;
-            PTE *pte = &table[index];
-            assert(pte->valid);
-            if (vpn == pte->tag && (pte->asma || pte->asn == asn)) {
-                retval = pte;
-                break;
-            }
+    if (PTECache[0] && vpn == PTECache[0]->tag &&
+        (PTECache[0]->asma || PTECache[0]->asn == asn))
+        retval = PTECache[0];
+    else if (PTECache[1] && vpn == PTECache[1]->tag &&
+        (PTECache[1]->asma || PTECache[1]->asn == asn))
+        retval = PTECache[1];
+    else if (PTECache[2] && vpn == PTECache[2]->tag &&
+        (PTECache[2]->asma || PTECache[2]->asn == asn))
+        retval = PTECache[2];
+    else {
+        PageTable::const_iterator i = lookupTable.find(vpn);
+        if (i != lookupTable.end()) {
+            while (i->first == vpn) {
+                int index = i->second;
+                PTE *pte = &table[index];
+                assert(pte->valid);
+                if (vpn == pte->tag && (pte->asma || pte->asn == asn)) {
+                    retval = pte;
+                    break;
+                }
 
-            ++i;
+                ++i;
+            }
         }
     }
 
@@ -142,6 +154,7 @@ TLB::checkCacheability(RequestPtr &req)
 void
 TLB::insert(Addr addr, PTE &pte)
 {
+    flushCache();
     VAddr vaddr = addr;
     if (table[nlu].valid) {
         Addr oldvpn = table[nlu].tag;
@@ -178,6 +191,7 @@ TLB::flushAll()
 {
     DPRINTF(TLB, "flushAll\n");
     memset(table, 0, sizeof(PTE[size]));
+    flushCache();
     lookupTable.clear();
     nlu = 0;
 }
@@ -185,6 +199,7 @@ TLB::flushAll()
 void
 TLB::flushProcesses()
 {
+    flushCache();
     PageTable::iterator i = lookupTable.begin();
     PageTable::iterator end = lookupTable.end();
     while (i != end) {
@@ -208,6 +223,7 @@ TLB::flushProcesses()
 void
 TLB::flushAddr(Addr addr, uint8_t asn)
 {
+    flushCache();
     VAddr vaddr = addr;
 
     PageTable::iterator i = lookupTable.find(vaddr.vpn());
index ea5ba5539b3e396da1bea74eab534885db032440..20f0037fdbe010e5abc8dfe10732f5bb4692b1f9 100644 (file)
@@ -88,6 +88,10 @@ namespace AlphaISA
         // Checkpointing
         virtual void serialize(std::ostream &os);
         virtual void unserialize(Checkpoint *cp, const std::string &section);
+
+        // Most recently used page table entries
+        PTE *PTECache[2];
+        inline void flushCache() { memset(PTECache, 0, 2 * sizeof(PTE*)); }
     };
 
     class ITB : public TLB