Ruby: Add support for functional accesses
[gem5.git] / src / cpu / testers / memtest / memtest.cc
index 7a8e4cc525f8aa5a4856d65d2ef462615b1fc175..ef23825cd37a8b47996bebfa2996de5b71a0a43c 100644 (file)
 #include "base/misc.hh"
 #include "base/statistics.hh"
 #include "cpu/testers/memtest/memtest.hh"
+#include "debug/MemTest.hh"
 #include "mem/mem_object.hh"
-#include "mem/port.hh"
 #include "mem/packet.hh"
+#include "mem/port.hh"
 #include "mem/request.hh"
 #include "sim/sim_events.hh"
 #include "sim/stats.hh"
@@ -69,14 +70,14 @@ MemTest::CpuPort::recvAtomic(PacketPtr pkt)
     // must be snoop upcall
     assert(pkt->isRequest());
     assert(pkt->getDest() == Packet::Broadcast);
-    return curTick;
+    return curTick();
 }
 
 void
 MemTest::CpuPort::recvFunctional(PacketPtr pkt)
 {
     //Do nothing if we see one come through
-//    if (curTick != 0)//Supress warning durring initialization
+//    if (curTick() != 0)//Supress warning durring initialization
 //        warn("Functional Writes not implemented in MemTester\n");
     //Need to find any response values that intersect and update
     return;
@@ -145,15 +146,9 @@ MemTest::MemTest(const Params *p)
       percentSourceUnaligned(p->percent_source_unaligned),
       percentDestUnaligned(p->percent_dest_unaligned),
       maxLoads(p->max_loads),
-      atomic(p->atomic)
+      atomic(p->atomic),
+      suppress_func_warnings(p->suppress_func_warnings)
 {
-    vector<string> cmd;
-    cmd.push_back("/bin/ls");
-    vector<string> null_vec;
-    //  thread = new SimpleThread(NULL, 0, NULL, 0, mainMem);
-    curTick = 0;
-
     cachePort.snoopRangeSent = false;
     funcPort.snoopRangeSent = true;
 
@@ -168,6 +163,7 @@ MemTest::MemTest(const Params *p)
     // set up counters
     noResponseCycles = 0;
     numReads = 0;
+    numWrites = 0;
     schedule(tickEvent, 0);
 
     accessRetry = false;
@@ -207,9 +203,10 @@ MemTest::completeRequest(PacketPtr pkt)
         dmaOutstanding = false;
     }
 
-    DPRINTF(MemTest, "completing %s at address %x (blk %x)\n",
+    DPRINTF(MemTest, "completing %s at address %x (blk %x) %s\n",
             pkt->isWrite() ? "write" : "read",
-            req->getPaddr(), blockAddr(req->getPaddr()));
+            req->getPaddr(), blockAddr(req->getPaddr()),
+            pkt->isError() ? "error" : "success");
 
     MemTestSenderState *state =
         dynamic_cast<MemTestSenderState *>(pkt->senderState);
@@ -223,30 +220,37 @@ MemTest::completeRequest(PacketPtr pkt)
     assert(removeAddr != outstandingAddrs.end());
     outstandingAddrs.erase(removeAddr);
 
-    assert(pkt->isResponse());
-
-    if (pkt->isRead()) {
-        if (memcmp(pkt_data, data, pkt->getSize()) != 0) {
-            panic("%s: read of %x (blk %x) @ cycle %d "
-                  "returns %x, expected %x\n", name(),
-                  req->getPaddr(), blockAddr(req->getPaddr()), curTick,
-                  *pkt_data, *data);
+    if (pkt->isError()) {
+        if (!suppress_func_warnings) {
+          warn("Functional Access failed for %x at %x\n",
+               pkt->isWrite() ? "write" : "read", req->getPaddr());
         }
-
-        numReads++;
-        numReadsStat++;
-
-        if (numReads == (uint64_t)nextProgressMessage) {
-            ccprintf(cerr, "%s: completed %d read accesses @%d\n",
-                     name(), numReads, curTick);
-            nextProgressMessage += progressInterval;
-        }
-
-        if (maxLoads != 0 && numReads >= maxLoads)
-            exitSimLoop("maximum number of loads reached");
     } else {
-        assert(pkt->isWrite());
-        numWritesStat++;
+        if (pkt->isRead()) {
+            if (memcmp(pkt_data, data, pkt->getSize()) != 0) {
+                panic("%s: read of %x (blk %x) @ cycle %d "
+                      "returns %x, expected %x\n", name(),
+                      req->getPaddr(), blockAddr(req->getPaddr()), curTick(),
+                      *pkt_data, *data);
+            }
+
+            numReads++;
+            numReadsStat++;
+
+            if (numReads == (uint64_t)nextProgressMessage) {
+                ccprintf(cerr, "%s: completed %d read, %d write accesses @%d\n",
+                         name(), numReads, numWrites, curTick());
+                nextProgressMessage += progressInterval;
+            }
+
+            if (maxLoads != 0 && numReads >= maxLoads)
+                exitSimLoop("maximum number of loads reached");
+        } else {
+            assert(pkt->isWrite());
+            funcPort.writeBlob(req->getPaddr(), pkt_data, req->getSize());
+            numWrites++;
+            numWritesStat++;
+        }
     }
 
     noResponseCycles = 0;
@@ -281,13 +285,13 @@ void
 MemTest::tick()
 {
     if (!tickEvent.scheduled())
-        schedule(tickEvent, curTick + ticks(1));
+        schedule(tickEvent, curTick() + ticks(1));
 
     if (++noResponseCycles >= 500000) {
         if (issueDmas) {
             cerr << "DMA tester ";
         }
-        cerr << name() << ": deadlocked at cycle " << curTick << endl;
+        cerr << name() << ": deadlocked at cycle " << curTick() << endl;
         fatal("");
     }
 
@@ -325,7 +329,7 @@ MemTest::tick()
     } else  {
         paddr = ((base) ? baseAddr1 : baseAddr2) + offset;
     }
-    bool probe = (random() % 100 < percentFunctional) && !uncacheable;
+    bool do_functional = (random() % 100 < percentFunctional) && !uncacheable;
 
     if (issueDmas) {
         paddr &= ~((1 << dma_access_size) - 1);
@@ -358,8 +362,9 @@ MemTest::tick()
         funcPort.readBlob(req->getPaddr(), result, req->getSize());
 
         DPRINTF(MemTest,
-                "id %d initiating read at address %x (blk %x) expecting %x\n",
-                id, req->getPaddr(), blockAddr(req->getPaddr()), *result);
+                "id %d initiating %sread at addr %x (blk %x) expecting %x\n",
+                id, do_functional ? "functional " : "", req->getPaddr(),
+                blockAddr(req->getPaddr()), *result);
 
         PacketPtr pkt = new Packet(req, MemCmd::ReadReq, Packet::Broadcast);
         pkt->setSrc(0);
@@ -367,7 +372,9 @@ MemTest::tick()
         MemTestSenderState *state = new MemTestSenderState(result);
         pkt->senderState = state;
 
-        if (probe) {
+        if (do_functional) {
+            assert(pkt->needsResponse());
+            pkt->setSuppressFuncError();
             cachePort.sendFunctional(pkt);
             completeRequest(pkt);
         } else {
@@ -387,8 +394,9 @@ MemTest::tick()
 
         outstandingAddrs.insert(paddr);
 
-        DPRINTF(MemTest, "initiating write at address %x (blk %x) value %x\n",
-                req->getPaddr(), blockAddr(req->getPaddr()), data & 0xff);
+        DPRINTF(MemTest, "initiating %swrite at addr %x (blk %x) value %x\n",
+                do_functional ? "functional " : "", req->getPaddr(),
+                blockAddr(req->getPaddr()), data & 0xff);
 
         PacketPtr pkt = new Packet(req, MemCmd::WriteReq, Packet::Broadcast);
         pkt->setSrc(0);
@@ -398,9 +406,8 @@ MemTest::tick()
         MemTestSenderState *state = new MemTestSenderState(result);
         pkt->senderState = state;
 
-        funcPort.writeBlob(req->getPaddr(), pkt_data, req->getSize());
-
-        if (probe) {
+        if (do_functional) {
+            pkt->setSuppressFuncError();
             cachePort.sendFunctional(pkt);
             completeRequest(pkt);
         } else {