ARM: Decode neon memory instructions.
[gem5.git] / src / arch / alpha / tlb.cc
index be02293d60fb5f0cf598595dcd836fa9542632e3..b578741d9316a2818973598454c0593b68381e32 100644 (file)
@@ -39,7 +39,6 @@
 #include "base/inifile.hh"
 #include "base/str.hh"
 #include "base/trace.hh"
-#include "config/alpha_tlaser.hh"
 #include "cpu/thread_context.hh"
 
 using namespace std;
@@ -72,6 +71,90 @@ TLB::~TLB()
         delete [] table;
 }
 
+void
+TLB::regStats()
+{
+    fetch_hits
+        .name(name() + ".fetch_hits")
+        .desc("ITB hits");
+    fetch_misses
+        .name(name() + ".fetch_misses")
+        .desc("ITB misses");
+    fetch_acv
+        .name(name() + ".fetch_acv")
+        .desc("ITB acv");
+    fetch_accesses
+        .name(name() + ".fetch_accesses")
+        .desc("ITB accesses");
+
+    fetch_accesses = fetch_hits + fetch_misses;
+
+    read_hits
+        .name(name() + ".read_hits")
+        .desc("DTB read hits")
+        ;
+
+    read_misses
+        .name(name() + ".read_misses")
+        .desc("DTB read misses")
+        ;
+
+    read_acv
+        .name(name() + ".read_acv")
+        .desc("DTB read access violations")
+        ;
+
+    read_accesses
+        .name(name() + ".read_accesses")
+        .desc("DTB read accesses")
+        ;
+
+    write_hits
+        .name(name() + ".write_hits")
+        .desc("DTB write hits")
+        ;
+
+    write_misses
+        .name(name() + ".write_misses")
+        .desc("DTB write misses")
+        ;
+
+    write_acv
+        .name(name() + ".write_acv")
+        .desc("DTB write access violations")
+        ;
+
+    write_accesses
+        .name(name() + ".write_accesses")
+        .desc("DTB write accesses")
+        ;
+
+    data_hits
+        .name(name() + ".data_hits")
+        .desc("DTB hits")
+        ;
+
+    data_misses
+        .name(name() + ".data_misses")
+        .desc("DTB misses")
+        ;
+
+    data_acv
+        .name(name() + ".data_acv")
+        .desc("DTB access violations")
+        ;
+
+    data_accesses
+        .name(name() + ".data_accesses")
+        .desc("DTB accesses")
+        ;
+
+    data_hits = read_hits + write_hits;
+    data_misses = read_misses + write_misses;
+    data_acv = read_acv + write_acv;
+    data_accesses = read_accesses + write_accesses;
+}
+
 // look up an entry in the TLB
 TlbEntry *
 TLB::lookup(Addr vpn, uint8_t asn)
@@ -131,12 +214,7 @@ TLB::checkCacheability(RequestPtr &req, bool itb)
      */
 
 
-#if ALPHA_TLASER
-    if (req->getPaddr() & PAddrUncachedBit39)
-#else
-    if (req->getPaddr() & PAddrUncachedBit43)
-#endif
-    {
+    if (req->getPaddr() & PAddrUncachedBit43) {
         // IPR memory space not implemented
         if (PAddrIprSpace(req->getPaddr())) {
             return new UnimpFault("IPR memory space not implemented!");
@@ -144,11 +222,9 @@ TLB::checkCacheability(RequestPtr &req, bool itb)
             // mark request as uncacheable
             req->setFlags(Request::UNCACHEABLE);
 
-#if !ALPHA_TLASER
             // Clear bits 42:35 of the physical address (10-2 in
             // Tsunami manual)
             req->setPaddr(req->getPaddr() & PAddrUncachedMask);
-#endif
         }
         // We shouldn't be able to read from an uncachable address in Alpha as
         // we don't have a ROM and we don't want to try to fetch from a device 
@@ -288,36 +364,8 @@ TLB::unserialize(Checkpoint *cp, const string &section)
     }
 }
 
-///////////////////////////////////////////////////////////////////////
-//
-//  Alpha ITB
-//
-ITB::ITB(const Params *p)
-    : TLB(p)
-{}
-
-
-void
-ITB::regStats()
-{
-    hits
-        .name(name() + ".hits")
-        .desc("ITB hits");
-    misses
-        .name(name() + ".misses")
-        .desc("ITB misses");
-    acv
-        .name(name() + ".acv")
-        .desc("ITB acv");
-    accesses
-        .name(name() + ".accesses")
-        .desc("ITB accesses");
-
-    accesses = hits + misses;
-}
-
 Fault
-ITB::translate(RequestPtr &req, ThreadContext *tc)
+TLB::translateInst(RequestPtr req, ThreadContext *tc)
 {
     //If this is a pal pc, then set PHYSICAL
     if (FULL_SYSTEM && PcPAL(req->getPC()))
@@ -326,7 +374,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
     if (PcPAL(req->getPC())) {
         // strip off PAL PC marker (lsb is 1)
         req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask);
-        hits++;
+        fetch_hits++;
         return NoFault;
     }
 
@@ -335,37 +383,28 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
     } else {
         // verify that this is a good virtual address
         if (!validVirtualAddress(req->getVaddr())) {
-            acv++;
+            fetch_acv++;
             return new ItbAcvFault(req->getVaddr());
         }
 
 
         // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13> for EV5
         // VA<47:41> == 0x7e, VA<40:13> maps directly to PA<40:13> for EV6
-#if ALPHA_TLASER
-        if ((MCSR_SP(tc->readMiscRegNoEffect(IPR_MCSR)) & 2) &&
-            VAddrSpaceEV5(req->getVaddr()) == 2)
-#else
-        if (VAddrSpaceEV6(req->getVaddr()) == 0x7e)
-#endif
-        {
+        if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) {
             // only valid in kernel mode
             if (ICM_CM(tc->readMiscRegNoEffect(IPR_ICM)) !=
                 mode_kernel) {
-                acv++;
+                fetch_acv++;
                 return new ItbAcvFault(req->getVaddr());
             }
 
             req->setPaddr(req->getVaddr() & PAddrImplMask);
 
-#if !ALPHA_TLASER
             // sign extend the physical address properly
             if (req->getPaddr() & PAddrUncachedBit40)
                 req->setPaddr(req->getPaddr() | ULL(0xf0000000000));
             else
                 req->setPaddr(req->getPaddr() & ULL(0xffffffffff));
-#endif
-
         } else {
             // not a physical address: need to look up pte
             int asn = DTB_ASN_ASN(tc->readMiscRegNoEffect(IPR_DTB_ASN));
@@ -373,7 +412,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
                               asn);
 
             if (!entry) {
-                misses++;
+                fetch_misses++;
                 return new ItbPageFault(req->getVaddr());
             }
 
@@ -385,11 +424,11 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
             if (!(entry->xre &
                   (1 << ICM_CM(tc->readMiscRegNoEffect(IPR_ICM))))) {
                 // instruction access fault
-                acv++;
+                fetch_acv++;
                 return new ItbAcvFault(req->getVaddr());
             }
 
-            hits++;
+            fetch_hits++;
         }
     }
 
@@ -401,85 +440,8 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
 
 }
 
-///////////////////////////////////////////////////////////////////////
-//
-//  Alpha DTB
-//
-DTB::DTB(const Params *p)
-     : TLB(p)
-{}
-
-void
-DTB::regStats()
-{
-    read_hits
-        .name(name() + ".read_hits")
-        .desc("DTB read hits")
-        ;
-
-    read_misses
-        .name(name() + ".read_misses")
-        .desc("DTB read misses")
-        ;
-
-    read_acv
-        .name(name() + ".read_acv")
-        .desc("DTB read access violations")
-        ;
-
-    read_accesses
-        .name(name() + ".read_accesses")
-        .desc("DTB read accesses")
-        ;
-
-    write_hits
-        .name(name() + ".write_hits")
-        .desc("DTB write hits")
-        ;
-
-    write_misses
-        .name(name() + ".write_misses")
-        .desc("DTB write misses")
-        ;
-
-    write_acv
-        .name(name() + ".write_acv")
-        .desc("DTB write access violations")
-        ;
-
-    write_accesses
-        .name(name() + ".write_accesses")
-        .desc("DTB write accesses")
-        ;
-
-    hits
-        .name(name() + ".hits")
-        .desc("DTB hits")
-        ;
-
-    misses
-        .name(name() + ".misses")
-        .desc("DTB misses")
-        ;
-
-    acv
-        .name(name() + ".acv")
-        .desc("DTB access violations")
-        ;
-
-    accesses
-        .name(name() + ".accesses")
-        .desc("DTB accesses")
-        ;
-
-    hits = read_hits + write_hits;
-    misses = read_misses + write_misses;
-    acv = read_acv + write_acv;
-    accesses = read_accesses + write_accesses;
-}
-
 Fault
-DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
+TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
 {
     Addr pc = tc->readPC();
 
@@ -490,7 +452,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
      * Check for alignment faults
      */
     if (req->getVaddr() & (req->getSize() - 1)) {
-        DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(),
+        DPRINTF(TLB, "Alignment Fault on %#x, size = %d\n", req->getVaddr(),
                 req->getSize());
         uint64_t flags = write ? MM_STAT_WR_MASK : 0;
         return new DtbAlignmentFault(req->getVaddr(), req->getFlags(), flags);
@@ -516,13 +478,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
         }
 
         // Check for "superpage" mapping
-#if ALPHA_TLASER
-        if ((MCSR_SP(tc->readMiscRegNoEffect(IPR_MCSR)) & 2) &&
-            VAddrSpaceEV5(req->getVaddr()) == 2)
-#else
-        if (VAddrSpaceEV6(req->getVaddr()) == 0x7e)
-#endif
-        {
+        if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) {
             // only valid in kernel mode
             if (DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)) !=
                 mode_kernel) {
@@ -536,14 +492,11 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
 
             req->setPaddr(req->getVaddr() & PAddrImplMask);
 
-#if !ALPHA_TLASER
             // sign extend the physical address properly
             if (req->getPaddr() & PAddrUncachedBit40)
                 req->setPaddr(req->getPaddr() | ULL(0xf0000000000));
             else
                 req->setPaddr(req->getPaddr() & ULL(0xffffffffff));
-#endif
-
         } else {
             if (write)
                 write_accesses++;
@@ -627,16 +580,27 @@ TLB::index(bool advance)
     return *entry;
 }
 
-/* end namespace AlphaISA */ }
+Fault
+TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
+{
+    if (mode == Execute)
+        return translateInst(req, tc);
+    else
+        return translateData(req, tc, mode == Write);
+}
 
-AlphaISA::ITB *
-AlphaITBParams::create()
+void
+TLB::translateTiming(RequestPtr req, ThreadContext *tc,
+        Translation *translation, Mode mode)
 {
-    return new AlphaISA::ITB(this);
+    assert(translation);
+    translation->finish(translateAtomic(req, tc, mode), req, tc, mode);
 }
 
-AlphaISA::DTB *
-AlphaDTBParams::create()
+/* end namespace AlphaISA */ }
+
+AlphaISA::TLB *
+AlphaTLBParams::create()
 {
-    return new AlphaISA::DTB(this);
+    return new AlphaISA::TLB(this);
 }