diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2007-11-12 14:39:07 -0800 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2007-11-12 14:39:07 -0800 |
commit | 49507982685b4e807e612ff176fb67901415a2ce (patch) | |
tree | 5f056c6d333f78cc8f0e071eddb238d15216e756 | |
parent | f1f5dd79bf8c2cf2ef64cc1432a4a0601d475e72 (diff) | |
download | gem5-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.cc | 15 | ||||
-rw-r--r-- | src/arch/x86/tlb.cc | 17 | ||||
-rw-r--r-- | src/arch/x86/tlb.hh | 13 |
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); |