diff options
author | Nathan Binkert <nate@binkert.org> | 2007-08-12 09:56:37 -0700 |
---|---|---|
committer | Nathan Binkert <nate@binkert.org> | 2007-08-12 09:56:37 -0700 |
commit | 64295b800fd67e9b9bb3eee0131511a71ddf1fdb (patch) | |
tree | ed1c759f11384dd2c263b43d7842be2922c5c39d /src/arch/alpha | |
parent | b92594dd90f54a892771989a8164148e6647c9ab (diff) | |
parent | ec4000e0e284834df0eb1db792074a1b11f21cc8 (diff) | |
download | gem5-64295b800fd67e9b9bb3eee0131511a71ddf1fdb.tar.xz |
merge
--HG--
extra : convert_revision : 5866eaa4008c4fa5da7fbb443132b8326955f71d
Diffstat (limited to 'src/arch/alpha')
-rw-r--r-- | src/arch/alpha/tlb.cc | 49 | ||||
-rw-r--r-- | src/arch/alpha/tlb.hh | 16 |
2 files changed, 48 insertions, 17 deletions
diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc index 214b2579f..f701c423d 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() @@ -74,23 +75,39 @@ TLB::~TLB() // look up an entry in the TLB PTE * -TLB::lookup(Addr vpn, uint8_t asn) const +TLB::lookup(Addr vpn, uint8_t asn) { // 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]) { + if (vpn == PTECache[0]->tag && + (PTECache[0]->asma || PTECache[0]->asn == asn)) + retval = PTECache[0]; + else if (PTECache[1]) { + if (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]; + } + } - ++i; + if (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 = updateCache(pte); + break; + } + + ++i; + } } } @@ -142,6 +159,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 +196,7 @@ TLB::flushAll() { DPRINTF(TLB, "flushAll\n"); memset(table, 0, sizeof(PTE[size])); + flushCache(); lookupTable.clear(); nlu = 0; } @@ -185,6 +204,7 @@ TLB::flushAll() void TLB::flushProcesses() { + flushCache(); PageTable::iterator i = lookupTable.begin(); PageTable::iterator end = lookupTable.end(); while (i != end) { @@ -208,6 +228,7 @@ TLB::flushProcesses() void TLB::flushAddr(Addr addr, uint8_t asn) { + flushCache(); VAddr vaddr = addr; PageTable::iterator i = lookupTable.find(vaddr.vpn()); @@ -291,7 +312,7 @@ ITB::regStats() Fault -ITB::translate(RequestPtr &req, ThreadContext *tc) const +ITB::translate(RequestPtr &req, ThreadContext *tc) { //If this is a pal pc, then set PHYSICAL if(FULL_SYSTEM && PcPAL(req->getPC())) @@ -453,7 +474,7 @@ DTB::regStats() } Fault -DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) const +DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) { Addr pc = tc->readPC(); diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh index ea5ba5539..a4255f3c5 100644 --- a/src/arch/alpha/tlb.hh +++ b/src/arch/alpha/tlb.hh @@ -61,7 +61,7 @@ namespace AlphaISA int nlu; // not last used entry (for replacement) void nextnlu() { if (++nlu >= size) nlu = 0; } - PTE *lookup(Addr vpn, uint8_t asn) const; + PTE *lookup(Addr vpn, uint8_t asn); public: TLB(const std::string &name, int size); @@ -88,6 +88,16 @@ 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[3]; + inline void flushCache() { memset(PTECache, 0, 3 * sizeof(PTE*)); } + inline PTE* updateCache(PTE *pte) { + PTECache[2] = PTECache[1]; + PTECache[1] = PTECache[0]; + PTECache[0] = pte; + return pte; + } }; class ITB : public TLB @@ -102,7 +112,7 @@ namespace AlphaISA ITB(const std::string &name, int size); virtual void regStats(); - Fault translate(RequestPtr &req, ThreadContext *tc) const; + Fault translate(RequestPtr &req, ThreadContext *tc); }; class DTB : public TLB @@ -125,7 +135,7 @@ namespace AlphaISA DTB(const std::string &name, int size); virtual void regStats(); - Fault translate(RequestPtr &req, ThreadContext *tc, bool write) const; + Fault translate(RequestPtr &req, ThreadContext *tc, bool write); }; } |