summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2007-11-12 14:39:07 -0800
committerGabe Black <gblack@eecs.umich.edu>2007-11-12 14:39:07 -0800
commit49507982685b4e807e612ff176fb67901415a2ce (patch)
tree5f056c6d333f78cc8f0e071eddb238d15216e756
parentf1f5dd79bf8c2cf2ef64cc1432a4a0601d475e72 (diff)
downloadgem5-49507982685b4e807e612ff176fb67901415a2ce.tar.xz
X86: Implement tlb invalidation and make it happen some of the times it should.
--HG-- extra : convert_revision : 376516d33cd539fa526c834ef2b2c33069af3040
-rw-r--r--src/arch/x86/miscregfile.cc15
-rw-r--r--src/arch/x86/tlb.cc17
-rw-r--r--src/arch/x86/tlb.hh13
3 files changed, 39 insertions, 6 deletions
diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc
index a6aed336f..71908098e 100644
--- a/src/arch/x86/miscregfile.cc
+++ b/src/arch/x86/miscregfile.cc
@@ -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;
diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc
index 704ab3027..1184bf9de 100644
--- a/src/arch/x86/tlb.cc
+++ b/src/arch/x86/tlb.cc
@@ -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
diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh
index d45f94520..93bbf2c9d 100644
--- a/src/arch/x86/tlb.hh
+++ b/src/arch/x86/tlb.hh
@@ -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);