changeset 90c5eb6a5e66 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=90c5eb6a5e66
description:
        memtest: Memtester support for DMA

        This patch adds DMA testing to the Memtester and is inherits many 
changes from
        Polina's old tester_dma_extension patch.  Since Ruby does not work in 
atomic
        mode, the atomic mode options are removed.

diffstat:

 configs/example/memtest-ruby.py     |  59 ++++++++++++++++++++++--------------
 configs/ruby/MESI_CMP_directory.py  |   4 ++
 configs/ruby/MI_example.py          |   4 ++
 configs/ruby/MOESI_CMP_directory.py |   4 ++
 configs/ruby/MOESI_CMP_token.py     |   4 ++
 configs/ruby/MOESI_hammer.py        |   4 ++
 src/cpu/memtest/MemTest.py          |   1 +
 src/cpu/memtest/memtest.cc          |  52 ++++++++++++++++++++++++++-----
 src/cpu/memtest/memtest.hh          |   7 ++++
 src/mem/ruby/system/DMASequencer.cc |   6 +++
 src/mem/ruby/system/SConscript      |   1 +
 11 files changed, 114 insertions(+), 32 deletions(-)

diffs (truncated from 395 to 300 lines):

diff -r e660ab620115 -r 90c5eb6a5e66 configs/example/memtest-ruby.py
--- a/configs/example/memtest-ruby.py   Fri Aug 20 11:46:12 2010 -0700
+++ b/configs/example/memtest-ruby.py   Fri Aug 20 11:46:12 2010 -0700
@@ -48,25 +48,13 @@
 
 parser = optparse.OptionParser()
 
-parser.add_option("-a", "--atomic", action="store_true",
-                  help="Use atomic (non-timing) mode")
-parser.add_option("-b", "--blocking", action="store_true",
-                  help="Use blocking caches")
 parser.add_option("-l", "--maxloads", metavar="N", default=0,
                   help="Stop after N loads")
-parser.add_option("-f", "--functional", type="int", default=0,
-                  metavar="PCT",
-                  help="Target percentage of functional accesses "
-                  "[default: %default]")
-parser.add_option("-u", "--uncacheable", type="int", default=0,
-                  metavar="PCT",
-                  help="Target percentage of uncacheable accesses "
-                  "[default: %default]")
-
 parser.add_option("--progress", type="int", default=1000,
                   metavar="NLOADS",
                   help="Progress message interval "
                   "[default: %default]")
+parser.add_option("--num-dmas", type="int", default=0, help="# of dma testers")
 
 #
 # Add the ruby specific and protocol specific options
@@ -101,36 +89,61 @@
            % (options.num_cpus, block_size)
      sys.exit(1)
 
-cpus = [ MemTest(atomic=options.atomic, max_loads=options.maxloads, \
-                 percent_functional=options.functional, \
-                 percent_uncacheable=options.uncacheable, \
-                 progress_interval=options.progress) \
+#
+# Currently ruby does not support atomic, functional, or uncacheable accesses
+#
+cpus = [ MemTest(atomic = False, \
+                 max_loads = options.maxloads, \
+                 issue_dmas = False, \
+                 percent_functional = 0, \
+                 percent_uncacheable = 0, \
+                 progress_interval = options.progress) \
          for i in xrange(options.num_cpus) ]
 
 system = System(cpu = cpus,
                 funcmem = PhysicalMemory(),
                 physmem = PhysicalMemory())
 
-system.ruby = Ruby.create_system(options, system)
+system.dmas = [ MemTest(atomic = False, \
+                        max_loads = options.maxloads, \
+                        issue_dmas = True, \
+                        percent_functional = 0, \
+                        percent_uncacheable = 0, \
+                        progress_interval = options.progress) \
+                for i in xrange(options.num_dmas) ]
 
+system.ruby = Ruby.create_system(options, \
+                                 system.physmem, \
+                                 dma_devices = system.dmas)
+
+#
+# The tester is most effective when randomization is turned on and
+# artifical delay is randomly inserted on messages
+#
+system.ruby.randomization = True
+ 
 assert(len(cpus) == len(system.ruby.cpu_ruby_ports))
 
 for (i, cpu) in enumerate(cpus):
     #
-    # Tie the memtester ports to the correct system ports
+    # Tie the cpu memtester ports to the correct system ports
     #
     cpu.test = system.ruby.cpu_ruby_ports[i].port
     cpu.functional = system.funcmem.port
 
+for (i, dma) in enumerate(system.dmas):
+    #
+    # Tie the dma memtester ports to the correct functional port
+    # Note that the test port has already been connected to the dma_sequencer
+    #
+    dma.functional = system.funcmem.port
+
 # -----------------------
 # run simulation
 # -----------------------
 
 root = Root( system = system )
-if options.atomic:
-    root.system.mem_mode = 'atomic'
-else:
-    root.system.mem_mode = 'timing'
+root.system.mem_mode = 'timing'
 
 # Not much point in this being higher than the L1 latency
 m5.ticks.setGlobalFrequency('1ns')
diff -r e660ab620115 -r 90c5eb6a5e66 configs/ruby/MESI_CMP_directory.py
--- a/configs/ruby/MESI_CMP_directory.py        Fri Aug 20 11:46:12 2010 -0700
+++ b/configs/ruby/MESI_CMP_directory.py        Fri Aug 20 11:46:12 2010 -0700
@@ -153,6 +153,10 @@
 
         dma_cntrl.dma_sequencer.port = dma_device.dma
         exec("system.dma_cntrl%d = dma_cntrl" % i)
+        if dma_device.type == 'MemTest':
+            system.dma_cntrl.dma_sequencer.port = dma_device.test
+        else:
+            system.dma_cntrl.dma_sequencer.port = dma_device.dma
         dma_cntrl_nodes.append(dma_cntrl)
 
     all_cntrls = l1_cntrl_nodes + \
diff -r e660ab620115 -r 90c5eb6a5e66 configs/ruby/MI_example.py
--- a/configs/ruby/MI_example.py        Fri Aug 20 11:46:12 2010 -0700
+++ b/configs/ruby/MI_example.py        Fri Aug 20 11:46:12 2010 -0700
@@ -132,6 +132,10 @@
                                    dma_sequencer = dma_seq)
 
         exec("system.dma_cntrl%d = dma_cntrl" % i)
+        if dma_device.type == 'MemTest':
+            system.dma_cntrl.dma_sequencer.port = dma_device.test
+        else:
+            system.dma_cntrl.dma_sequencer.port = dma_device.dma
         dma_cntrl.dma_sequencer.port = dma_device.dma
         dma_cntrl_nodes.append(dma_cntrl)
 
diff -r e660ab620115 -r 90c5eb6a5e66 configs/ruby/MOESI_CMP_directory.py
--- a/configs/ruby/MOESI_CMP_directory.py       Fri Aug 20 11:46:12 2010 -0700
+++ b/configs/ruby/MOESI_CMP_directory.py       Fri Aug 20 11:46:12 2010 -0700
@@ -151,6 +151,10 @@
                                    dma_sequencer = dma_seq)
 
         exec("system.dma_cntrl%d = dma_cntrl" % i)
+        if dma_device.type == 'MemTest':
+            system.dma_cntrl.dma_sequencer.port = dma_device.test
+        else:
+            system.dma_cntrl.dma_sequencer.port = dma_device.dma
         dma_cntrl.dma_sequencer.port = dma_device.dma
         dma_cntrl_nodes.append(dma_cntrl)
 
diff -r e660ab620115 -r 90c5eb6a5e66 configs/ruby/MOESI_CMP_token.py
--- a/configs/ruby/MOESI_CMP_token.py   Fri Aug 20 11:46:12 2010 -0700
+++ b/configs/ruby/MOESI_CMP_token.py   Fri Aug 20 11:46:12 2010 -0700
@@ -173,6 +173,10 @@
                                    dma_sequencer = dma_seq)
 
         exec("system.dma_cntrl%d = dma_cntrl" % i)
+        if dma_device.type == 'MemTest':
+            system.dma_cntrl.dma_sequencer.port = dma_device.test
+        else:
+            system.dma_cntrl.dma_sequencer.port = dma_device.dma
         dma_cntrl.dma_sequencer.port = dma_device.dma
         dma_cntrl_nodes.append(dma_cntrl)
 
diff -r e660ab620115 -r 90c5eb6a5e66 configs/ruby/MOESI_hammer.py
--- a/configs/ruby/MOESI_hammer.py      Fri Aug 20 11:46:12 2010 -0700
+++ b/configs/ruby/MOESI_hammer.py      Fri Aug 20 11:46:12 2010 -0700
@@ -139,6 +139,10 @@
                                    dma_sequencer = dma_seq)
 
         exec("system.dma_cntrl%d = dma_cntrl" % i)
+        if dma_device.type == 'MemTest':
+            system.dma_cntrl.dma_sequencer.port = dma_device.test
+        else:
+            system.dma_cntrl.dma_sequencer.port = dma_device.dma
         dma_cntrl.dma_sequencer.port = dma_device.dma
         dma_cntrl_nodes.append(dma_cntrl)
 
diff -r e660ab620115 -r 90c5eb6a5e66 src/cpu/memtest/MemTest.py
--- a/src/cpu/memtest/MemTest.py        Fri Aug 20 11:46:12 2010 -0700
+++ b/src/cpu/memtest/MemTest.py        Fri Aug 20 11:46:12 2010 -0700
@@ -38,6 +38,7 @@
     percent_dest_unaligned = Param.Percent(50,
         "percent of copy dest address that are unaligned")
     percent_reads = Param.Percent(65, "target read percentage")
+    issue_dmas = Param.Bool(False, "this memtester should issue dma requests")
     percent_source_unaligned = Param.Percent(50,
         "percent of copy source address that are unaligned")
     percent_functional = Param.Percent(50, "percent of access that are 
functional")
diff -r e660ab620115 -r 90c5eb6a5e66 src/cpu/memtest/memtest.cc
--- a/src/cpu/memtest/memtest.cc        Fri Aug 20 11:46:12 2010 -0700
+++ b/src/cpu/memtest/memtest.cc        Fri Aug 20 11:46:12 2010 -0700
@@ -109,8 +109,20 @@
         completeRequest(pkt);
     }
     else if (!cachePort.sendTiming(pkt)) {
+        DPRINTF(MemTest, "accessRetry setting to true\n");
+
+        //
+        // dma requests should never be retried
+        //
+        if (issueDmas) {
+            panic("Nacked DMA requests are not supported\n");
+        }
         accessRetry = true;
         retryPkt = pkt;
+    } else {
+        if (issueDmas) {
+            dmaOutstanding = true;
+        }
     }
 
 }
@@ -127,6 +139,7 @@
       percentReads(p->percent_reads),
       percentFunctional(p->percent_functional),
       percentUncacheable(p->percent_uncacheable),
+      issueDmas(p->issue_dmas),
       progressInterval(p->progress_interval),
       nextProgressMessage(p->progress_interval),
       percentSourceUnaligned(p->percent_source_unaligned),
@@ -134,6 +147,7 @@
       maxLoads(p->max_loads),
       atomic(p->atomic)
 {
+ 
     vector<string> cmd;
     cmd.push_back("/bin/ls");
     vector<string> null_vec;
@@ -143,6 +157,8 @@
     cachePort.snoopRangeSent = false;
     funcPort.snoopRangeSent = true;
 
+    id = TESTER_ALLOCATOR++;
+
     // Needs to be masked off once we know the block size.
     traceBlockAddr = p->trace_addr;
     baseAddr1 = 0x100000;
@@ -154,9 +170,8 @@
     numReads = 0;
     schedule(tickEvent, 0);
 
-    id = TESTER_ALLOCATOR++;
-
     accessRetry = false;
+    dmaOutstanding = false;
 }
 
 Port *
@@ -188,6 +203,10 @@
 {
     Request *req = pkt->req;
 
+    if (issueDmas) {
+        dmaOutstanding = false;
+    }
+
     DPRINTF(MemTest, "completing %s at address %x (blk %x)\n",
             pkt->isWrite() ? "write" : "read",
             req->getPaddr(), blockAddr(req->getPaddr()));
@@ -265,11 +284,15 @@
         schedule(tickEvent, curTick + ticks(1));
 
     if (++noResponseCycles >= 500000) {
+        if (issueDmas) {
+            cerr << "DMA tester ";
+        }
         cerr << name() << ": deadlocked at cycle " << curTick << endl;
         fatal("");
     }
 
-    if (accessRetry) {
+    if (accessRetry || (issueDmas && dmaOutstanding)) {
+        DPRINTF(MemTest, "MemTester waiting on accessRetry or DMA response\n");
         return;
     }
 
@@ -281,6 +304,8 @@
     unsigned access_size = random() % 4;
     bool uncacheable = (random() % 100) < percentUncacheable;
 
+    unsigned dma_access_size = random() % 4; 
+
     //If we aren't doing copies, use id as offset, and do a false sharing
     //mem tester
     //We can eliminate the lower bits of the offset, and then use the id
@@ -288,6 +313,7 @@
     offset = blockAddr(offset);
     offset += id;
     access_size = 0;
+    dma_access_size = 0;
 
     Request *req = new Request();
     Request::Flags flags;
@@ -296,14 +322,21 @@
     if (uncacheable) {
         flags.set(Request::UNCACHEABLE);
         paddr = uncacheAddr + offset;
-    } else {
+    } else  {
         paddr = ((base) ? baseAddr1 : baseAddr2) + offset;
     }
     bool probe = (random() % 100 < percentFunctional) && !uncacheable;
 
-    paddr &= ~((1 << access_size) - 1);
-    req->setPhys(paddr, 1 << access_size, flags);
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to