diff options
author | Vincentius Robby <acolyte@umich.edu> | 2007-08-04 14:25:35 -0400 |
---|---|---|
committer | Vincentius Robby <acolyte@umich.edu> | 2007-08-04 14:25:35 -0400 |
commit | 2898d768271a4a32b16a0ee01f884544bda490bd (patch) | |
tree | 12207c7756a5bae2dc4f28b2aad3f8b7c2ab30f4 | |
parent | acac5580f211809927f58d99f6dfd034a8dacd30 (diff) | |
download | gem5-2898d768271a4a32b16a0ee01f884544bda490bd.tar.xz |
alpha: Implement a cache for recently used page table entries
--HG--
extra : convert_revision : 1bb80d71fa91e500a68390e5dc17464ce7136fba
-rw-r--r-- | src/arch/alpha/tlb.cc | 38 | ||||
-rw-r--r-- | src/arch/alpha/tlb.hh | 4 |
2 files changed, 31 insertions, 11 deletions
diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc index 214b2579f..205b81baf 100644 --- a/src/arch/alpha/tlb.cc +++ b/src/arch/alpha/tlb.cc @@ -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()); diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh index ea5ba5539..20f0037fd 100644 --- a/src/arch/alpha/tlb.hh +++ b/src/arch/alpha/tlb.hh @@ -88,6 +88,10 @@ namespace AlphaISA // Checkpointing virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); + + // Most recently used page table entries + PTE *PTECache[2]; + inline void flushCache() { memset(PTECache, 0, 2 * sizeof(PTE*)); } }; class ITB : public TLB |