diff options
Diffstat (limited to 'src/arch')
-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 |