Fix bugs in tlbmap (and thus rangemap since the code is nearly identical)
authorAli Saidi <saidi@eecs.umich.edu>
Tue, 12 Dec 2006 22:55:27 +0000 (17:55 -0500)
committerAli Saidi <saidi@eecs.umich.edu>
Tue, 12 Dec 2006 22:55:27 +0000 (17:55 -0500)
Deal with block initializing stores (by doing nothing, at some point we might want to do the write hint 64 like thing)
Fix tcc instruction igoner in legion-lock stuff to be correct in all cases
Have console interrupts warn rather than panicing until we figure out what to do with interrupts

src/arch/sparc/miscregfile.cc:
src/arch/sparc/miscregfile.hh:
    add a magic miscreg which reads all the bits the tlb needs in one go
src/arch/sparc/tlb.cc:
    initialized the context type and id to reasonable values and handle block init stores
src/arch/sparc/tlb_map.hh:
    fix bug in tlb map code
src/base/range_map.hh:
    fix bug in rangemap code and add range_multimap
    (these are probably useful for bus range stuff)
src/cpu/exetrace.cc:
    fixup tcc ignore code to be correct
src/dev/sparc/t1000.cc:
    make console interrupt stuff warn instead of panicing until we get interrupt stuff figured out
src/unittest/rangemaptest.cc:
    fix up the rangemap unit test to catch the missing case

--HG--
extra : convert_revision : 70604a8b5d0553aa0b0bd7649f775a0cfa8267a5

src/arch/sparc/miscregfile.cc
src/arch/sparc/miscregfile.hh
src/arch/sparc/tlb.cc
src/arch/sparc/tlb_map.hh
src/base/range_map.hh
src/cpu/exetrace.cc
src/dev/sparc/t1000.cc
src/unittest/rangemaptest.cc
src/unittest/rangemaptest2.cc [new file with mode: 0644]

index fd20a14c113e4ab40d098a8095af5cc680711645..dbcd91925054fd177429d0a39e33ec1f0911b820 100644 (file)
@@ -129,6 +129,26 @@ void MiscRegFile::clear()
 MiscReg MiscRegFile::readReg(int miscReg)
 {
     switch (miscReg) {
+      case MISCREG_TLB_DATA:
+        /* Package up all the data for the tlb:
+         * 6666555555555544444444443333333333222222222211111111110000000000
+         * 3210987654321098765432109876543210987654321098765432109876543210
+         *   secContext   | priContext    |             |tl|partid|  |||||^hpriv
+         *                                                           ||||^red
+         *                                                           |||^priv
+         *                                                           ||^am
+         *                                                           |^lsuim
+         *                                                           ^lsudm
+         */
+        return bits((uint64_t)hpstate,2,2) |
+               bits((uint64_t)hpstate,5,5) << 1 |
+               bits((uint64_t)pstate,3,2) << 2 |
+               bits((uint64_t)lsuCtrlReg,3,2) << 4 |
+               bits((uint64_t)partId,7,0) << 8 |
+               bits((uint64_t)tl,2,0) << 16 |
+               (uint64_t)priContext << 32 |
+               (uint64_t)secContext << 48;
+
       case MISCREG_Y:
         return y;
       case MISCREG_CCR:
index d09005795b7c9ec6b954566edd3093bcbe9a1241..c879fd357cd2a356874925be65a5b324aab3b7ea 100644 (file)
@@ -137,6 +137,8 @@ namespace SparcISA
         MISCREG_QUEUE_NRES_ERROR_HEAD,
         MISCREG_QUEUE_NRES_ERROR_TAIL,
 
+        /* All the data for the TLB packed up in one register. */
+        MISCREG_TLB_DATA,
         MISCREG_NUMMISCREGS
     };
 
index b0fc562aced64b03678601407314580b6429582a..bc5527f2fc07b8135fa8bb2c2f2051b9e4175545 100644 (file)
@@ -446,8 +446,8 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
     bool real = false;
     Addr vaddr = req->getVaddr();
     Addr size = req->getSize();
-    ContextType ct;
-    int context;
+    ContextType ct = Primary;
+    int context = 0;
     ASI asi;
 
     TlbEntry *e;
@@ -508,6 +508,9 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
             panic("Block ASIs not supported\n");
         if (AsiIsNoFault(asi))
             panic("No Fault ASIs not supported\n");
+        if (write && asi == ASI_LDTX_P)
+            // block init store (like write hint64)
+            goto continueDtbFlow;
         if (AsiIsTwin(asi))
             panic("Twin ASIs not supported\n");
         if (AsiIsPartialStore(asi))
index 226ef23a1b33017bb8ca71cd93d2ee845e09b0a5..688daf5b91bb035013e28ab991a7a6388459700b 100644 (file)
@@ -53,8 +53,15 @@ class TlbMap
         i = tree.upper_bound(r);
 
         if (i == tree.begin())
-            // Nothing could match, so return end()
-            return tree.end();
+            if (r.real == i->first.real &&
+                r.partitionId == i->first.partitionId &&
+                i->first.va < r.va + r.size &&
+                i->first.va+i->first.size >= r.va &&
+                (r.real || r.contextId == i->first.contextId))
+                return i;
+            else
+                // Nothing could match, so return end()
+                return tree.end();
 
         i--;
 
index 17ecb929003b7b44e196d672e56fbc23dea9de53..6d345073907b9aafcb1d2c5cf24c73a043cf25e8 100644 (file)
@@ -52,9 +52,13 @@ class range_map
 
         i = tree.upper_bound(r);
 
-        if (i == tree.begin())
-            // Nothing could match, so return end()
-            return tree.end();
+        if (i == tree.begin()) {
+            if (i->first.start <= r.end && i->first.end >= r.start)
+                return i;
+            else
+                // Nothing could match, so return end()
+                return tree.end();
+        }
 
         i--;
 
@@ -126,4 +130,117 @@ class range_map
 };
 
 
+template <class T,class V>
+class range_multimap
+{
+  private:
+    typedef std::multimap<Range<T>,V> RangeMap;
+    RangeMap tree;
+
+  public:
+    typedef typename RangeMap::iterator iterator;
+
+    template <class U>
+    std::pair<iterator,iterator> find(const Range<U> &r)
+    {
+        iterator i;
+        iterator j;
+
+        i = tree.lower_bound(r);
+
+        if (i == tree.begin()) {
+          if (i->first.start <= r.end && i->first.end >= r.start)
+                return std::make_pair<iterator, iterator>(i,i);
+          else
+            // Nothing could match, so return end()
+            return std::make_pair<iterator, iterator>(tree.end(), tree.end());
+        }
+        i--;
+
+        if (i->first.start <= r.end && i->first.end >= r.start) {
+            // we have at least one match
+            j = i;
+
+            i--;
+            while (i->first.start <= r.end && i->first.end >=
+                    r.start) {
+                if (i == tree.begin())
+                    break;
+                i--;
+            }
+            if (i == tree.begin() && i->first.start <= r.end && i->first.end >=
+                                        r.start)
+                return std::make_pair<iterator, iterator>(i,j);
+            i++;
+            return std::make_pair<iterator, iterator>(i,j);
+
+        }
+
+        return std::make_pair<iterator, iterator>(tree.end(), tree.end());
+    }
+
+    template <class U>
+    bool intersect(const Range<U> &r)
+    {
+        std::pair<iterator,iterator> p;
+        p = find(r);
+        if (p.first != tree.end())
+            return true;
+        return false;
+    }
+
+
+    template <class U,class W>
+    iterator insert(const Range<U> &r, const W d)
+    {
+        std::pair<iterator,iterator> p;
+        p = find(r);
+        if (p.first->first.start == r.start && p.first->first.end == r.end ||
+                p.first == tree.end())
+            return tree.insert(std::make_pair<Range<T>,V>(r, d));
+        else
+            return tree.end();
+    }
+
+    size_t erase(T k)
+    {
+        return tree.erase(k);
+    }
+
+    void erase(iterator p)
+    {
+        tree.erase(p);
+    }
+
+    void erase(iterator p, iterator q)
+    {
+        tree.erase(p,q);
+    }
+
+    void clear()
+    {
+        tree.erase(tree.begin(), tree.end());
+    }
+
+    iterator begin()
+    {
+        return tree.begin();
+    }
+
+    iterator end()
+    {
+        return tree.end();
+    }
+
+    size_t size()
+    {
+        return tree.size();
+    }
+
+    bool empty()
+    {
+        return tree.empty();
+    }
+};
+
 #endif //__BASE_RANGE_MAP_HH__
index 7c4c037ceb7b3244dcc395fa525e2b918d22fb42..316716540db94f90f72171f6b8118f8bc62cc18f 100644 (file)
@@ -399,7 +399,7 @@ Trace::InstRecord::dump(ostream &outs)
                             diffCcr || diffTl || diffGl || diffAsi || diffPil ||
                             diffCwp || diffCansave || diffCanrestore ||
                             diffOtherwin || diffCleanwin)
-                        && !((staticInst->machInst & 0xE1F80000) == 0xE1F80000)) {
+                        && !((staticInst->machInst & 0xC1F80000) == 0x81D00000)) {
                         outs << "Differences found between M5 and Legion:";
                         if (diffPC)
                             outs << " [PC]";
@@ -575,7 +575,7 @@ Trace::InstRecord::dump(ostream &outs)
                         thread->getDTBPtr()->dumpAll();
 
                         diffcount++;
-                        if (diffcount > 3)
+                        if (diffcount > 2)
                             fatal("Differences found between Legion and M5\n");
                     }
 
index 5fc7870845671bc10f5b20548d815ffaec24758e..4a8de77a570f723725f02faba09c68cc4dddf98b 100644 (file)
@@ -62,13 +62,15 @@ T1000::intrFrequency()
 void
 T1000::postConsoleInt()
 {
-    panic("Need implementation\n");
+    warn_once("Don't know what interrupt to post for console.\n");
+    //panic("Need implementation\n");
 }
 
 void
 T1000::clearConsoleInt()
 {
-    panic("Need implementation\n");
+    warn_once("Don't know what interrupt to clear for console.\n");
+    //panic("Need implementation\n");
 }
 
 void
index 6fd99c927bf5d76ebc3762d4b72c00ba570de191..983a41520ffcb5500fa549c647b48b702686273f 100644 (file)
@@ -41,7 +41,7 @@ int main()
 
     range_map<Addr,int>::iterator i;
 
-    i = r.insert(RangeIn<Addr>(0,40),5);
+    i = r.insert(RangeIn<Addr>(10,40),5);
     assert(i != r.end());
     i = r.insert(RangeIn<Addr>(60,90),3);
     assert(i != r.end());
@@ -52,6 +52,17 @@ int main()
 
     i = r.find(RangeIn(55,55));
     assert(i == r.end());
+
+    i = r.insert(RangeIn<Addr>(0,12),1);
+    assert(i == r.end());
+
+    i = r.insert(RangeIn<Addr>(0,9),1);
+    assert(i != r.end());
+
+    i = r.find(RangeIn(20,30));
+    assert(i != r.end());
+    cout << i->first << " " << i->second << endl;
+
 }
 
 
diff --git a/src/unittest/rangemaptest2.cc b/src/unittest/rangemaptest2.cc
new file mode 100644 (file)
index 0000000..b253dbe
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ali Saidi
+ */
+
+#include <iostream>
+#include <cassert>
+#include "sim/host.hh"
+#include "base/range_map.hh"
+
+using namespace std;
+
+int main()
+{
+    range_multimap<Addr,int> r;
+
+    range_multimap<Addr,int>::iterator i;
+    std::pair<range_multimap<Addr,int>::iterator,range_multimap<Addr,int>::iterator>
+        jk;
+
+    i = r.insert(RangeIn<Addr>(10,40),5);
+    assert(i != r.end());
+    i = r.insert(RangeIn<Addr>(10,40),6);
+    assert(i != r.end());
+    i = r.insert(RangeIn<Addr>(60,90),3);
+    assert(i != r.end());
+
+    jk = r.find(RangeIn(20,30));
+    assert(jk.first != r.end());
+    cout << jk.first->first << " " << jk.first->second << endl;
+    cout << jk.second->first << " " << jk.second->second << endl;
+
+    i = r.insert(RangeIn<Addr>(0,3),5);
+    assert(i != r.end());
+
+    for( i = r.begin(); i != r.end(); i++)
+        cout << i->first << " " << i->second << endl;
+
+    jk = r.find(RangeIn(20,30));
+    assert(jk.first != r.end());
+    cout << jk.first->first << " " << jk.first->second << endl;
+    cout << jk.second->first << " " << jk.second->second << endl;
+
+
+}
+
+
+
+
+
+
+
+