summaryrefslogtreecommitdiff
path: root/src/arch/alpha
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/alpha')
-rw-r--r--src/arch/alpha/tlb.cc49
-rw-r--r--src/arch/alpha/tlb.hh16
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 &section);
+
+ // 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);
};
}