X86: Implement tlb invalidation and make it happen some of the times it should.
authorGabe Black <gblack@eecs.umich.edu>
Mon, 12 Nov 2007 22:39:07 +0000 (14:39 -0800)
committerGabe Black <gblack@eecs.umich.edu>
Mon, 12 Nov 2007 22:39:07 +0000 (14:39 -0800)
--HG--
extra : convert_revision : 376516d33cd539fa526c834ef2b2c33069af3040

src/arch/x86/miscregfile.cc
src/arch/x86/tlb.cc
src/arch/x86/tlb.hh

index a6aed336fb2b70169ed8ff3adbdd13d2201b2d98..71908098e492a7c4924eeadc746df4381ac361ed 100644 (file)
@@ -86,6 +86,8 @@
  */
 
 #include "arch/x86/miscregfile.hh"
+#include "arch/x86/tlb.hh"
+#include "cpu/thread_context.hh"
 #include "sim/serialize.hh"
 
 using namespace X86ISA;
@@ -158,6 +160,10 @@ void MiscRegFile::setReg(int miscReg,
                     regVal[MISCREG_EFER] = efer;
                 }
             }
+            if (toggled.pg) {
+                tc->getITBPtr()->invalidateAll();
+                tc->getDTBPtr()->invalidateAll();
+            }
             //This must always be 1.
             newCR0.et = 1;
             newVal = newCR0;
@@ -166,8 +172,17 @@ void MiscRegFile::setReg(int miscReg,
       case MISCREG_CR2:
         break;
       case MISCREG_CR3:
+        tc->getITBPtr()->invalidateNonGlobal();
+        tc->getDTBPtr()->invalidateNonGlobal();
         break;
       case MISCREG_CR4:
+        {
+            CR4 toggled = regVal[miscReg] ^ val;
+            if (toggled.pae || toggled.pse || toggled.pge) {
+                tc->getITBPtr()->invalidateAll();
+                tc->getDTBPtr()->invalidateAll();
+            }
+        }
         break;
       case MISCREG_CR8:
         break;
index 704ab30270c8b762ee957058235924c2081f2d15..1184bf9de6fcab5dd0382b4755935b458cffc389 100644 (file)
@@ -380,6 +380,7 @@ TLB::Walker::start(ThreadContext * _tc, Addr vaddr)
             }
         }
     }
+
     nextState = Ready;
     entry.vaddr = vaddr;
 
@@ -595,11 +596,27 @@ TLB::lookup(Addr va, bool update_lru)
 void
 TLB::invalidateAll()
 {
+    DPRINTF(TLB, "Invalidating all entries.\n");
+    while (!entryList.empty()) {
+        TlbEntry *entry = entryList.front();
+        entryList.pop_front();
+        freeList.push_back(entry);
+    }
 }
 
 void
 TLB::invalidateNonGlobal()
 {
+    DPRINTF(TLB, "Invalidating all non global entries.\n");
+    EntryList::iterator entryIt;
+    for (entryIt = entryList.begin(); entryIt != entryList.end();) {
+        if (!(*entryIt)->global) {
+            freeList.push_back(*entryIt);
+            entryList.erase(entryIt++);
+        } else {
+            entryIt++;
+        }
+    }
 }
 
 void
index d45f94520853307819cee8b1df4402c4149afc39..93bbf2c9d82a07d7b3c64480eecd2f404e8ec4df 100644 (file)
@@ -215,6 +215,13 @@ namespace X86ISA
 
         Port *getPort(const std::string &if_name, int idx = -1);
 
+      public:
+        void invalidateAll();
+
+        void invalidateNonGlobal();
+
+        void demapPage(Addr va);
+
       protected:
         int size;
 
@@ -226,12 +233,6 @@ namespace X86ISA
 
         void insert(Addr vpn, TlbEntry &entry);
 
-        void invalidateAll();
-
-        void invalidateNonGlobal();
-
-        void demapPage(Addr va);
-
         template<class TlbFault>
         Fault translate(RequestPtr &req, ThreadContext *tc,
                 bool write, bool execute);