summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorVincentius Robby <acolyte@umich.edu>2007-08-04 14:25:35 -0400
committerVincentius Robby <acolyte@umich.edu>2007-08-04 14:25:35 -0400
commit2898d768271a4a32b16a0ee01f884544bda490bd (patch)
tree12207c7756a5bae2dc4f28b2aad3f8b7c2ab30f4 /src/arch
parentacac5580f211809927f58d99f6dfd034a8dacd30 (diff)
downloadgem5-2898d768271a4a32b16a0ee01f884544bda490bd.tar.xz
alpha: Implement a cache for recently used page table entries
--HG-- extra : convert_revision : 1bb80d71fa91e500a68390e5dc17464ce7136fba
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/alpha/tlb.cc38
-rw-r--r--src/arch/alpha/tlb.hh4
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 &section);
+
+ // Most recently used page table entries
+ PTE *PTECache[2];
+ inline void flushCache() { memset(PTECache, 0, 2 * sizeof(PTE*)); }
};
class ITB : public TLB