do a linear search for matching tlb entries instead of using map because you could...
authorAli Saidi <saidi@eecs.umich.edu>
Wed, 17 Jan 2007 22:59:22 +0000 (17:59 -0500)
committerAli Saidi <saidi@eecs.umich.edu>
Wed, 17 Jan 2007 22:59:22 +0000 (17:59 -0500)
fix for lookup table to keep it consistant with tlb on a replace of a specific entry

--HG--
extra : convert_revision : 5a14fbcdcfc13156c63fa41ddeca474660143b32

src/arch/sparc/tlb.cc

index e8b0a933b3b78475b26926459ebf3dc7b1d2e861..f64bad1690893571c76ff0a6b17e42189986a5e1 100644 (file)
@@ -81,21 +81,44 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real,
 
     MapIter i;
     TlbEntry *new_entry = NULL;
-    TlbRange tr;
+//    TlbRange tr;
     int x;
 
     cacheValid = false;
-    tr.va = va;
/*   tr.va = va;
     tr.size = PTE.size() - 1;
     tr.contextId = context_id;
     tr.partitionId = partition_id;
     tr.real = real;
-
+*/
 
     DPRINTF(TLB, "TLB: Inserting TLB Entry; va=%#x pa=%#x pid=%d cid=%d r=%d entryid=%d\n",
             va, PTE.paddr(), partition_id, context_id, (int)real, entry);
 
     // Demap any entry that conflicts
+    for (x = 0; x < size; x++) {
+        if (tlb[x].range.real == real &&
+            tlb[x].range.partitionId == partition_id &&
+            tlb[x].range.va < va + PTE.size() - 1 &&
+            tlb[x].range.va + tlb[x].range.size >= va &&
+            (real || tlb[x].range.contextId == context_id ))
+        {
+            if (tlb[x].valid) {
+                freeList.push_front(&tlb[x]);
+                DPRINTF(TLB, "TLB: Conflicting entry %#X , deleting it\n", x);
+
+                tlb[x].valid = false;
+                if (tlb[x].used) {
+                    tlb[x].used = false;
+                    usedEntries--;
+                }
+                lookupTable.erase(tlb[x].range);
+            }
+        }
+    }
+
+
+/*
     i = lookupTable.find(tr);
     if (i != lookupTable.end()) {
         i->second->valid = false;
@@ -108,7 +131,7 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real,
                 i->second);
         lookupTable.erase(i);
     }
-
+*/
 
     if (entry != -1) {
         assert(entry < size && entry >= 0);
@@ -127,7 +150,6 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real,
             } while (tlb[x].pte.locked());
             lastReplaced = x;
             new_entry = &tlb[x];
-            lookupTable.erase(new_entry->range);
         }
         /*
         for (x = 0; x < size; x++) {
@@ -142,10 +164,15 @@ insertAllLocked:
     // Update the last ently if their all locked
     if (!new_entry) {
         new_entry = &tlb[size-1];
-        lookupTable.erase(new_entry->range);
     }
 
     freeList.remove(new_entry);
+    if (new_entry->valid && new_entry->used)
+        usedEntries--;
+
+    lookupTable.erase(new_entry->range);
+
+
     DPRINTF(TLB, "Using entry: %#X\n", new_entry);
 
     assert(PTE.valid());
@@ -315,10 +342,12 @@ TLB::invalidateAll()
     cacheValid = false;
 
     freeList.clear();
+    lookupTable.clear();
     for (x = 0; x < size; x++) {
         if (tlb[x].valid == true)
             freeList.push_back(&tlb[x]);
         tlb[x].valid = false;
+        tlb[x].used = false;
     }
     usedEntries = 0;
 }