testers: move testers to a new directory
authorBrad Beckmann <Brad.Beckmann@amd.com>
Tue, 24 Aug 2010 19:07:22 +0000 (12:07 -0700)
committerBrad Beckmann <Brad.Beckmann@amd.com>
Tue, 24 Aug 2010 19:07:22 +0000 (12:07 -0700)
This patch moves the testers to a new subdirectory under src/cpu and includes
the necessary fixes to work with latest m5 initialization patches.

--HG--
rename : configs/example/determ_test.py => configs/example/ruby_direct_test.py
rename : src/cpu/directedtest/DirectedGenerator.cc => src/cpu/testers/directedtest/DirectedGenerator.cc
rename : src/cpu/directedtest/DirectedGenerator.hh => src/cpu/testers/directedtest/DirectedGenerator.hh
rename : src/cpu/directedtest/InvalidateGenerator.cc => src/cpu/testers/directedtest/InvalidateGenerator.cc
rename : src/cpu/directedtest/InvalidateGenerator.hh => src/cpu/testers/directedtest/InvalidateGenerator.hh
rename : src/cpu/directedtest/RubyDirectedTester.cc => src/cpu/testers/directedtest/RubyDirectedTester.cc
rename : src/cpu/directedtest/RubyDirectedTester.hh => src/cpu/testers/directedtest/RubyDirectedTester.hh
rename : src/cpu/directedtest/RubyDirectedTester.py => src/cpu/testers/directedtest/RubyDirectedTester.py
rename : src/cpu/directedtest/SConscript => src/cpu/testers/directedtest/SConscript
rename : src/cpu/directedtest/SeriesRequestGenerator.cc => src/cpu/testers/directedtest/SeriesRequestGenerator.cc
rename : src/cpu/directedtest/SeriesRequestGenerator.hh => src/cpu/testers/directedtest/SeriesRequestGenerator.hh
rename : src/cpu/memtest/MemTest.py => src/cpu/testers/memtest/MemTest.py
rename : src/cpu/memtest/SConscript => src/cpu/testers/memtest/SConscript
rename : src/cpu/memtest/memtest.cc => src/cpu/testers/memtest/memtest.cc
rename : src/cpu/memtest/memtest.hh => src/cpu/testers/memtest/memtest.hh
rename : src/cpu/rubytest/Check.cc => src/cpu/testers/rubytest/Check.cc
rename : src/cpu/rubytest/Check.hh => src/cpu/testers/rubytest/Check.hh
rename : src/cpu/rubytest/CheckTable.cc => src/cpu/testers/rubytest/CheckTable.cc
rename : src/cpu/rubytest/CheckTable.hh => src/cpu/testers/rubytest/CheckTable.hh
rename : src/cpu/rubytest/RubyTester.cc => src/cpu/testers/rubytest/RubyTester.cc
rename : src/cpu/rubytest/RubyTester.hh => src/cpu/testers/rubytest/RubyTester.hh
rename : src/cpu/rubytest/RubyTester.py => src/cpu/testers/rubytest/RubyTester.py
rename : src/cpu/rubytest/SConscript => src/cpu/testers/rubytest/SConscript

51 files changed:
configs/example/determ_test.py [deleted file]
configs/example/memtest-ruby.py
configs/example/ruby_direct_test.py [new file with mode: 0644]
configs/example/rubytest.py
configs/ruby/MOESI_hammer.py
src/cpu/directedtest/DirectedGenerator.cc [deleted file]
src/cpu/directedtest/DirectedGenerator.hh [deleted file]
src/cpu/directedtest/InvalidateGenerator.cc [deleted file]
src/cpu/directedtest/InvalidateGenerator.hh [deleted file]
src/cpu/directedtest/RubyDirectedTester.cc [deleted file]
src/cpu/directedtest/RubyDirectedTester.hh [deleted file]
src/cpu/directedtest/RubyDirectedTester.py [deleted file]
src/cpu/directedtest/SConscript [deleted file]
src/cpu/directedtest/SeriesRequestGenerator.cc [deleted file]
src/cpu/directedtest/SeriesRequestGenerator.hh [deleted file]
src/cpu/memtest/MemTest.py [deleted file]
src/cpu/memtest/SConscript [deleted file]
src/cpu/memtest/memtest.cc [deleted file]
src/cpu/memtest/memtest.hh [deleted file]
src/cpu/rubytest/Check.cc [deleted file]
src/cpu/rubytest/Check.hh [deleted file]
src/cpu/rubytest/CheckTable.cc [deleted file]
src/cpu/rubytest/CheckTable.hh [deleted file]
src/cpu/rubytest/RubyTester.cc [deleted file]
src/cpu/rubytest/RubyTester.hh [deleted file]
src/cpu/rubytest/RubyTester.py [deleted file]
src/cpu/rubytest/SConscript [deleted file]
src/cpu/testers/directedtest/DirectedGenerator.cc [new file with mode: 0644]
src/cpu/testers/directedtest/DirectedGenerator.hh [new file with mode: 0644]
src/cpu/testers/directedtest/InvalidateGenerator.cc [new file with mode: 0644]
src/cpu/testers/directedtest/InvalidateGenerator.hh [new file with mode: 0644]
src/cpu/testers/directedtest/RubyDirectedTester.cc [new file with mode: 0644]
src/cpu/testers/directedtest/RubyDirectedTester.hh [new file with mode: 0644]
src/cpu/testers/directedtest/RubyDirectedTester.py [new file with mode: 0644]
src/cpu/testers/directedtest/SConscript [new file with mode: 0644]
src/cpu/testers/directedtest/SeriesRequestGenerator.cc [new file with mode: 0644]
src/cpu/testers/directedtest/SeriesRequestGenerator.hh [new file with mode: 0644]
src/cpu/testers/memtest/MemTest.py [new file with mode: 0644]
src/cpu/testers/memtest/SConscript [new file with mode: 0644]
src/cpu/testers/memtest/memtest.cc [new file with mode: 0644]
src/cpu/testers/memtest/memtest.hh [new file with mode: 0644]
src/cpu/testers/rubytest/Check.cc [new file with mode: 0644]
src/cpu/testers/rubytest/Check.hh [new file with mode: 0644]
src/cpu/testers/rubytest/CheckTable.cc [new file with mode: 0644]
src/cpu/testers/rubytest/CheckTable.hh [new file with mode: 0644]
src/cpu/testers/rubytest/RubyTester.cc [new file with mode: 0644]
src/cpu/testers/rubytest/RubyTester.hh [new file with mode: 0644]
src/cpu/testers/rubytest/RubyTester.py [new file with mode: 0644]
src/cpu/testers/rubytest/SConscript [new file with mode: 0644]
src/mem/ruby/system/RubyPort.cc
src/mem/ruby/system/Sequencer.cc

diff --git a/configs/example/determ_test.py b/configs/example/determ_test.py
deleted file mode 100644 (file)
index 77712ff..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-# Copyright (c) 2006-2007 The Regents of The University of Michigan
-# Copyright (c) 2009 Advanced Micro Devices, Inc.
-# 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: Ron Dreslinski
-#          Brad Beckmann
-
-import m5
-from m5.objects import *
-from m5.defines import buildEnv
-from m5.util import addToPath
-import os, optparse, sys
-addToPath('../common')
-addToPath('../ruby')
-
-import Ruby
-
-if buildEnv['FULL_SYSTEM']:
-    panic("This script requires system-emulation mode (*_SE).")
-
-# Get paths we might need.  It's expected this file is in m5/configs/example.
-config_path = os.path.dirname(os.path.abspath(__file__))
-config_root = os.path.dirname(config_path)
-m5_root = os.path.dirname(config_root)
-
-parser = optparse.OptionParser()
-
-parser.add_option("-l", "--requests", metavar="N", default=100,
-                  help="Stop after N requests")
-parser.add_option("-f", "--wakeup_freq", metavar="N", default=10,
-                  help="Wakeup every N cycles")
-parser.add_option("--test-type", type="string", default="SeriesGetx",
-                  help="SeriesGetx|SeriesGets|Invalidate")
-
-#
-# Add the ruby specific and protocol specific options
-#
-Ruby.define_options(parser)
-
-execfile(os.path.join(config_root, "common", "Options.py"))
-
-(options, args) = parser.parse_args()
-
-if args:
-     print "Error: script doesn't take any positional arguments"
-     sys.exit(1)
-
-#
-# Select the directed generator
-#
-if options.test_type == "SeriesGetx":
-    generator = SeriesRequestGenerator(num_cpus = options.num_cpus,
-                                             issue_writes = True)
-elif options.test_type == "SeriesGets":
-    generator = SeriesRequestGenerator(num_cpus = options.num_cpus,
-                                             issue_writes = False)
-elif options.test_type == "Invalidate":
-    generator = InvalidateGenerator(num_cpus = options.num_cpus)
-else:
-    print "Error: unknown directed generator"
-    sys.exit(1)
-
-#
-# Create the M5 system.  Note that the PhysicalMemory Object isn't
-# actually used by the rubytester, but is included to support the
-# M5 memory size == Ruby memory size checks
-#
-system = System(physmem = PhysicalMemory())
-
-#
-# Create the ruby random tester
-#
-system.tester = RubyDirectedTester(requests_to_complete = \
-                                   options.requests,
-                                 generator = generator)
-
-system.ruby = Ruby.create_system(options, system)
-
-assert(options.num_cpus == len(system.ruby.cpu_ruby_ports))
-
-for ruby_port in system.ruby.cpu_ruby_ports:
-    #
-    # Tie the ruby tester ports to the ruby cpu ports
-    #
-    system.tester.cpuPort = ruby_port.port
-
-# -----------------------
-# run simulation
-# -----------------------
-
-root = Root( system = system )
-root.system.mem_mode = 'timing'
-
-# Not much point in this being higher than the L1 latency
-m5.ticks.setGlobalFrequency('1ns')
-
-# instantiate configuration
-m5.instantiate()
-
-# simulate until program terminates
-exit_event = m5.simulate(options.maxtick)
-
-print 'Exiting @ tick', m5.curTick(), 'because', exit_event.getCause()
index d2e9c137eb088d0915825f447dfd9aeefc7f96a1..e32e0c1143966fd31aeced610afdb873c71d9fac 100644 (file)
@@ -104,17 +104,21 @@ system = System(cpu = cpus,
                 funcmem = PhysicalMemory(),
                 physmem = PhysicalMemory())
 
-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) ]
+if options.num_dmas > 0:
+    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.dma_devices = dmas
+else:
+    dmas = []
 
 system.ruby = Ruby.create_system(options, \
-                                 system.physmem, \
-                                 dma_devices = system.dmas)
+                                 system, \
+                                 dma_devices = dmas)
 
 #
 # The tester is most effective when randomization is turned on and
@@ -131,7 +135,7 @@ for (i, cpu) in enumerate(cpus):
     cpu.test = system.ruby.cpu_ruby_ports[i].port
     cpu.functional = system.funcmem.port
 
-for (i, dma) in enumerate(system.dmas):
+for (i, dma) in enumerate(dmas):
     #
     # Tie the dma memtester ports to the correct functional port
     # Note that the test port has already been connected to the dma_sequencer
diff --git a/configs/example/ruby_direct_test.py b/configs/example/ruby_direct_test.py
new file mode 100644 (file)
index 0000000..e744c35
--- /dev/null
@@ -0,0 +1,126 @@
+# Copyright (c) 2006-2007 The Regents of The University of Michigan
+# Copyright (c) 2009 Advanced Micro Devices, Inc.
+# 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: Ron Dreslinski
+#          Brad Beckmann
+
+import m5
+from m5.objects import *
+from m5.defines import buildEnv
+from m5.util import addToPath
+import os, optparse, sys
+addToPath('../common')
+addToPath('../ruby')
+
+import Ruby
+
+if buildEnv['FULL_SYSTEM']:
+    panic("This script requires system-emulation mode (*_SE).")
+
+# Get paths we might need.  It's expected this file is in m5/configs/example.
+config_path = os.path.dirname(os.path.abspath(__file__))
+config_root = os.path.dirname(config_path)
+m5_root = os.path.dirname(config_root)
+
+parser = optparse.OptionParser()
+
+parser.add_option("-l", "--requests", metavar="N", default=100,
+                  help="Stop after N requests")
+parser.add_option("-f", "--wakeup_freq", metavar="N", default=10,
+                  help="Wakeup every N cycles")
+parser.add_option("--test-type", type="string", default="SeriesGetx",
+                  help="SeriesGetx|SeriesGets|Invalidate")
+
+#
+# Add the ruby specific and protocol specific options
+#
+Ruby.define_options(parser)
+
+execfile(os.path.join(config_root, "common", "Options.py"))
+
+(options, args) = parser.parse_args()
+
+if args:
+     print "Error: script doesn't take any positional arguments"
+     sys.exit(1)
+
+#
+# Select the direct test generator
+#
+if options.test_type == "SeriesGetx":
+    generator = SeriesRequestGenerator(num_cpus = options.num_cpus,
+                                             issue_writes = True)
+elif options.test_type == "SeriesGets":
+    generator = SeriesRequestGenerator(num_cpus = options.num_cpus,
+                                             issue_writes = False)
+elif options.test_type == "Invalidate":
+    generator = InvalidateGenerator(num_cpus = options.num_cpus)
+else:
+    print "Error: unknown direct test generator"
+    sys.exit(1)
+
+#
+# Create the M5 system.  Note that the PhysicalMemory Object isn't
+# actually used by the rubytester, but is included to support the
+# M5 memory size == Ruby memory size checks
+#
+system = System(physmem = PhysicalMemory())
+
+#
+# Create the ruby random tester
+#
+system.tester = RubyDirectedTester(requests_to_complete = \
+                                   options.requests,
+                                   generator = generator)
+
+system.ruby = Ruby.create_system(options, system)
+
+assert(options.num_cpus == len(system.ruby.cpu_ruby_ports))
+
+for ruby_port in system.ruby.cpu_ruby_ports:
+    #
+    # Tie the ruby tester ports to the ruby cpu ports
+    #
+    system.tester.cpuPort = ruby_port.port
+
+# -----------------------
+# run simulation
+# -----------------------
+
+root = Root( system = system )
+root.system.mem_mode = 'timing'
+
+# Not much point in this being higher than the L1 latency
+m5.ticks.setGlobalFrequency('1ns')
+
+# instantiate configuration
+m5.instantiate()
+
+# simulate until program terminates
+exit_event = m5.simulate(options.maxtick)
+
+print 'Exiting @ tick', m5.curTick(), 'because', exit_event.getCause()
index a4daf6b823aa2c4a740f91af37034dab00dafa31..ddd6a53af67b5eb1902ff605552778df6d53e28f 100644 (file)
@@ -90,7 +90,7 @@ tester = RubyTester(checks_to_complete = options.checks,
 # actually used by the rubytester, but is included to support the
 # M5 memory size == Ruby memory size checks
 #
-system = System(physmem = PhysicalMemory())
+system = System(tester = tester, physmem = PhysicalMemory())
 
 system.ruby = Ruby.create_system(options, system)
 
index 3cd33f9816679329d4d4a618014e2a437df51ad0..d1c1cc2b097598b03aacba31e07f1b971dc7c2a6 100644 (file)
@@ -186,10 +186,9 @@ def create_system(options, system, piobus, dma_devices):
 
         exec("system.dma_cntrl%d = dma_cntrl" % i)
         if dma_device.type == 'MemTest':
-            system.dma_cntrl.dma_sequencer.port = dma_device.test
+            exec("system.dma_cntrl%d.dma_sequencer.port = dma_device.test" % i)
         else:
-            system.dma_cntrl.dma_sequencer.port = dma_device.dma
-        dma_cntrl.dma_sequencer.port = dma_device.dma
+            exec("system.dma_cntrl%d.dma_sequencer.port = dma_device.dma" % i)
         dma_cntrl_nodes.append(dma_cntrl)
 
         if options.recycle_latency:
diff --git a/src/cpu/directedtest/DirectedGenerator.cc b/src/cpu/directedtest/DirectedGenerator.cc
deleted file mode 100644 (file)
index 6361cbf..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * Copyright (c) 2009-2010 Advanced Micro Devices, Inc.
- * 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.
- */
-
-#include "cpu/directedtest/DirectedGenerator.hh"
-
-DirectedGenerator::DirectedGenerator(const Params *p)
-    : SimObject(p)
-{
-    m_num_cpus = p->num_cpus;
-    m_directed_tester = NULL;
-}
-
-void 
-DirectedGenerator::setDirectedTester(RubyDirectedTester* directed_tester)
-{
-    assert(m_directed_tester == NULL);
-    m_directed_tester = directed_tester;
-}
diff --git a/src/cpu/directedtest/DirectedGenerator.hh b/src/cpu/directedtest/DirectedGenerator.hh
deleted file mode 100644 (file)
index baef09e..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * 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.
- */
-
-#ifndef __CPU_DIRECTEDTEST_DIRECTEDGENERATOR_HH__
-#define __CPU_DIRECTEDTEST_DIRECTEDGENERATOR_HH__
-
-#include "cpu/directedtest/DirectedGenerator.hh"
-#include "cpu/directedtest/RubyDirectedTester.hh"
-#include "params/DirectedGenerator.hh"
-#include "sim/sim_object.hh"
-
-class DirectedGenerator : public SimObject 
-{
-  public:
-    typedef DirectedGeneratorParams Params;
-    DirectedGenerator(const Params *p);
-    
-    virtual ~DirectedGenerator() {}
-    
-    virtual bool initiate() = 0;
-    virtual void performCallback(uint proc, Addr address) = 0;
-    
-    void setDirectedTester(RubyDirectedTester* directed_tester);
-    
-  protected:
-    int m_num_cpus;
-    RubyDirectedTester* m_directed_tester;
-};
-
-#endif //__CPU_DIRECTEDTEST_DIRECTEDGENERATOR_HH__
-
diff --git a/src/cpu/directedtest/InvalidateGenerator.cc b/src/cpu/directedtest/InvalidateGenerator.cc
deleted file mode 100644 (file)
index 5a0a3cc..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * Copyright (c) 2009-2010 Advanced Micro Devices, Inc.
- * 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.
- */
-
-#include "cpu/directedtest/RubyDirectedTester.hh"
-#include "cpu/directedtest/DirectedGenerator.hh"
-#include "cpu/directedtest/InvalidateGenerator.hh"
-
-InvalidateGenerator::InvalidateGenerator(const Params *p)
-    : DirectedGenerator(p)
-{
-    //
-    // First, issue loads to bring the block into S state
-    //
-    m_status = InvalidateGeneratorStatus_Load_Waiting;
-    m_active_read_node = 0;
-    m_active_inv_node = 0;
-    m_address = 0x0;
-    m_addr_increment_size = p->addr_increment_size;
-}
-
-InvalidateGenerator::~InvalidateGenerator()
-{
-}
-
-bool
-InvalidateGenerator::initiate()
-{
-    RubyDirectedTester::CpuPort* port;
-    Request::Flags flags;
-    PacketPtr pkt;
-    Packet::Command cmd;
-
-    // For simplicity, requests are assumed to be 1 byte-sized
-    Request *req = new Request(m_address, 1, flags);
-
-    //
-    // Based on the current state, issue a load or a store
-    //
-    if (m_status == InvalidateGeneratorStatus_Load_Waiting) {
-        DPRINTF(DirectedTest, "initiating read\n");
-        cmd = MemCmd::ReadReq;
-        port = safe_cast<RubyDirectedTester::CpuPort*>(m_directed_tester->
-                                               getCpuPort(m_active_read_node));
-        pkt = new Packet(req, cmd, m_active_read_node);
-    } else if (m_status == InvalidateGeneratorStatus_Inv_Waiting) {
-        DPRINTF(DirectedTest, "initiating invalidating write\n");
-        cmd = MemCmd::WriteReq;
-        port = safe_cast<RubyDirectedTester::CpuPort*>(m_directed_tester->
-                                               getCpuPort(m_active_inv_node));
-        pkt = new Packet(req, cmd, m_active_inv_node);
-    } else {
-        panic("initiate was unexpectedly called\n");
-    }
-    uint8_t* dummyData = new uint8_t;
-    *dummyData = 0;
-    pkt->dataDynamic(dummyData);
-
-    if (port->sendTiming(pkt)) {
-        DPRINTF(DirectedTest, "initiating request - successful\n");
-        if (m_status == InvalidateGeneratorStatus_Load_Waiting) {
-            m_status = InvalidateGeneratorStatus_Load_Pending;
-        } else {
-            m_status = InvalidateGeneratorStatus_Inv_Pending;
-        }
-        return true;
-    } else {
-        // If the packet did not issue, must delete
-        // Note: No need to delete the data, the packet destructor
-        // will delete it
-        delete pkt->req;
-        delete pkt;
-
-        DPRINTF(DirectedTest, "failed to issue request - sequencer not ready\n");
-        return false;
-    }
-}
-
-void 
-InvalidateGenerator::performCallback(uint proc, Addr address)
-{
-    assert(m_address == address);  
-
-    if (m_status == InvalidateGeneratorStatus_Load_Pending) {
-        assert(m_active_read_node == proc);
-        m_active_read_node++;
-        //
-        // Once all cpus have the block in S state, issue the invalidate
-        //
-        if (m_active_read_node == m_num_cpus) {
-            m_status = InvalidateGeneratorStatus_Inv_Waiting;
-            m_active_read_node = 0;
-        } else {
-            m_status = InvalidateGeneratorStatus_Load_Waiting;
-        }
-    } else if (m_status == InvalidateGeneratorStatus_Inv_Pending) {
-        assert(m_active_inv_node == proc);
-        m_active_inv_node++;
-        if (m_active_inv_node == m_num_cpus) {
-            m_address += m_addr_increment_size;
-            m_active_inv_node = 0;
-        }
-        //
-        // Invalidate completed, send that info to the tester and restart
-        // the cycle
-        //
-        m_directed_tester->incrementCycleCompletions();
-        m_status = InvalidateGeneratorStatus_Load_Waiting;
-    } 
-    
-}
-
-InvalidateGenerator *
-InvalidateGeneratorParams::create()
-{
-    return new InvalidateGenerator(this);
-}
diff --git a/src/cpu/directedtest/InvalidateGenerator.hh b/src/cpu/directedtest/InvalidateGenerator.hh
deleted file mode 100644 (file)
index f9f2ed5..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * 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.
- */
-
-//
-// This Directed Generator generates GETX requests for all nodes in the 
-// system.  The GETX requests are generated one at a time in round-robin fashion
-// 0...1...2...etc.
-//
-
-#ifndef __CPU_DIRECTEDTEST_INVALIDATEGENERATOR_HH__
-#define __CPU_DIRECTEDTEST_INVALIDATEGENERATOR_HH__
-
-#include "cpu/directedtest/RubyDirectedTester.hh"
-#include "cpu/directedtest/DirectedGenerator.hh"
-#include "mem/protocol/InvalidateGeneratorStatus.hh"
-#include "params/InvalidateGenerator.hh"
-
-class InvalidateGenerator : public DirectedGenerator 
-{
-  public:
-    typedef InvalidateGeneratorParams Params;
-    InvalidateGenerator(const Params *p);
-    
-    ~InvalidateGenerator();
-    
-    bool initiate();
-    void performCallback(uint proc, Addr address);
-    
-  private:
-    InvalidateGeneratorStatus m_status;
-    Addr m_address;
-    uint m_active_read_node;
-    uint m_active_inv_node;
-    uint m_addr_increment_size;
-};
-
-#endif //__CPU_DIRECTEDTEST_INVALIDATEGENERATOR_HH__
-
diff --git a/src/cpu/directedtest/RubyDirectedTester.cc b/src/cpu/directedtest/RubyDirectedTester.cc
deleted file mode 100644 (file)
index 8f27062..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * Copyright (c) 2009-2010 Advanced Micro Devices, Inc.
- * 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.
- */
-
-#include "cpu/directedtest/RubyDirectedTester.hh"
-#include "cpu/directedtest/DirectedGenerator.hh"
-#include "mem/ruby/eventqueue/RubyEventQueue.hh"
-#include "sim/sim_exit.hh"
-
-RubyDirectedTester::RubyDirectedTester(const Params *p)
-  : MemObject(p), directedStartEvent(this),
-    m_requests_to_complete(p->requests_to_complete),
-    generator(p->generator)
-{
-    m_requests_completed = 0;
-
-    // add the check start event to the event queue
-    schedule(directedStartEvent, 1);
-}
-
-RubyDirectedTester::~RubyDirectedTester()
-{
-    for (int i = 0; i < ports.size(); i++)
-        delete ports[i];
-}
-
-void
-RubyDirectedTester::init()
-{
-    assert(ports.size() > 0);
-    generator->setDirectedTester(this);
-}
-
-Port *
-RubyDirectedTester::getPort(const std::string &if_name, int idx)
-{
-    if (if_name != "cpuPort") {
-        panic("RubyDirectedTester::getPort: unknown port %s requested", if_name);
-    }
-
-    if (idx >= (int)ports.size()) {
-        ports.resize(idx + 1);
-    }
-
-    if (ports[idx] != NULL) {
-        panic("RubyDirectedTester::getPort: port %d already assigned", idx);
-    }
-
-    CpuPort *port = new CpuPort(csprintf("%s-port%d", name(), idx), this, idx);
-
-    ports[idx] = port;
-    return port;
-}
-
-Tick
-RubyDirectedTester::CpuPort::recvAtomic(PacketPtr pkt)
-{
-    panic("RubyDirectedTester::CpuPort::recvAtomic() not implemented!\n");
-    return 0;
-}
-
-bool
-RubyDirectedTester::CpuPort::recvTiming(PacketPtr pkt)
-{
-    tester->hitCallback(idx, pkt->getAddr());
-    
-    //
-    // Now that the tester has completed, delete the packet, then return
-    //
-    delete pkt->req;
-    delete pkt;
-    return true;
-}
-
-Port*
-RubyDirectedTester::getCpuPort(int idx)
-{
-    assert(idx >= 0 && idx < ports.size());
-
-    return ports[idx];
-}
-
-void
-RubyDirectedTester::hitCallback(NodeID proc, Addr addr)
-{
-    DPRINTF(DirectedTest,
-            "completed request for proc: %d addr: 0x%x\n",
-            proc,
-            addr);
-
-    generator->performCallback(proc, addr);    
-    schedule(directedStartEvent, curTick);
-}
-
-void
-RubyDirectedTester::wakeup()
-{
-    if (m_requests_completed < m_requests_to_complete) {
-        if (!generator->initiate()) {
-            schedule(directedStartEvent, curTick + 1);
-        }
-    } else {
-        exitSimLoop("Ruby DirectedTester completed");
-    }
-}
-
-RubyDirectedTester *
-RubyDirectedTesterParams::create()
-{
-    return new RubyDirectedTester(this);
-}
diff --git a/src/cpu/directedtest/RubyDirectedTester.hh b/src/cpu/directedtest/RubyDirectedTester.hh
deleted file mode 100644 (file)
index bd3989c..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * Copyright (c) 2009-2010 Advanced Micro Devices, Inc.
- * 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.
- */
-
-#ifndef __CPU_DIRECTEDTEST_RUBYDIRECTEDTESTER_HH__
-#define __CPU_DIRECTEDTEST_RUBYDIRECTEDTESTER_HH__
-
-#include <iostream>
-#include <vector>
-#include <string>
-
-#include "mem/mem_object.hh"
-#include "mem/packet.hh"
-#include "mem/ruby/common/DataBlock.hh"
-#include "mem/ruby/common/Global.hh"
-#include "mem/ruby/common/SubBlock.hh"
-#include "mem/ruby/system/RubyPort.hh"
-#include "params/RubyDirectedTester.hh"
-
-class DirectedGenerator;
-
-class RubyDirectedTester : public MemObject
-{
-  public:
-    class CpuPort : public SimpleTimingPort
-    {
-      private:
-        RubyDirectedTester *tester;
-
-      public:
-        CpuPort(const std::string &_name, RubyDirectedTester *_tester, uint _idx)
-            : SimpleTimingPort(_name, _tester), tester(_tester), idx(_idx)
-        {}
-
-        uint idx;
-
-      protected:
-        virtual bool recvTiming(PacketPtr pkt);
-        virtual Tick recvAtomic(PacketPtr pkt);
-    };
-
-    typedef RubyDirectedTesterParams Params;
-    RubyDirectedTester(const Params *p);
-    ~RubyDirectedTester();
-
-    virtual Port *getPort(const std::string &if_name, int idx = -1);
-
-    Port* getCpuPort(int idx);
-
-    virtual void init();
-
-    void wakeup();
-
-    void incrementCycleCompletions() { m_requests_completed++; }
-
-    void printStats(std::ostream& out) const {}
-    void clearStats() {}
-    void printConfig(std::ostream& out) const {}
-
-    void print(std::ostream& out) const;
-
-  protected:
-    class DirectedStartEvent : public Event
-    {
-      private:
-        RubyDirectedTester *tester;
-
-      public:
-        DirectedStartEvent(RubyDirectedTester *_tester)
-            : Event(CPU_Tick_Pri), tester(_tester)
-        {}
-        void process() { tester->wakeup(); }
-        virtual const char *description() const { return "Directed tick"; }
-    };
-
-    DirectedStartEvent directedStartEvent;
-
-  private:
-    void hitCallback(NodeID proc, Addr addr);
-
-    void checkForDeadlock();
-
-    // Private copy constructor and assignment operator
-    RubyDirectedTester(const RubyDirectedTester& obj);
-    RubyDirectedTester& operator=(const RubyDirectedTester& obj);
-
-    uint64 m_requests_completed;
-    std::vector<CpuPort*> ports;
-    uint64 m_requests_to_complete;
-    DirectedGenerator* generator;
-};
-
-#endif // __CPU_DIRECTEDTEST_RUBYDIRECTEDTESTER_HH__
diff --git a/src/cpu/directedtest/RubyDirectedTester.py b/src/cpu/directedtest/RubyDirectedTester.py
deleted file mode 100644 (file)
index af19705..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (c) 2010 Advanced Micro Devices, Inc.
-# 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: Brad Beckmann
-
-from m5.SimObject import SimObject
-from MemObject import MemObject
-from m5.params import *
-from m5.proxy import *
-
-class DirectedGenerator(SimObject):
-    type = 'DirectedGenerator'
-    abstract = True
-    num_cpus = Param.Int("num of cpus")
-
-class SeriesRequestGenerator(DirectedGenerator):
-    type = 'SeriesRequestGenerator'
-    addr_increment_size = Param.Int(64, "address increment size")
-    issue_writes = Param.Bool(True, "issue writes if true, otherwise reads")
-
-class InvalidateGenerator(DirectedGenerator):
-    type = 'InvalidateGenerator'
-    addr_increment_size = Param.Int(64, "address increment size")
-
-class RubyDirectedTester(MemObject):
-    type = 'RubyDirectedTester'
-    cpuPort = VectorPort("the cpu ports")
-    requests_to_complete = Param.Int("checks to complete")
-    generator = Param.DirectedGenerator("the request generator")
diff --git a/src/cpu/directedtest/SConscript b/src/cpu/directedtest/SConscript
deleted file mode 100644 (file)
index 1afa159..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- mode:python -*-
-
-# Copyright (c) 2006 The Regents of The University of Michigan
-# Copyright (c) 2009-2010 Advanced Micro Devices, Inc.
-# 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.
-#
-
-Import('*')
-
-#
-# Currently the ruby testser relies on Ruby specific objects (SubBlock, etc.)
-# When this dependency is removed, the ruby tester should be compiled
-# independently from Ruby
-#
-if not env['RUBY']:
-    Return()
-
-SimObject('RubyDirectedTester.py')
-
-Source('RubyDirectedTester.cc')
-Source('DirectedGenerator.cc')
-Source('SeriesRequestGenerator.cc')
-Source('InvalidateGenerator.cc')
-
-TraceFlag('DirectedTest')
diff --git a/src/cpu/directedtest/SeriesRequestGenerator.cc b/src/cpu/directedtest/SeriesRequestGenerator.cc
deleted file mode 100644 (file)
index a880cdc..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * Copyright (c) 2009-2010 Advanced Micro Devices, Inc.
- * 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.
- */
-
-#include "cpu/directedtest/RubyDirectedTester.hh"
-#include "cpu/directedtest/DirectedGenerator.hh"
-#include "cpu/directedtest/SeriesRequestGenerator.hh"
-
-SeriesRequestGenerator::SeriesRequestGenerator(const Params *p)
-    : DirectedGenerator(p)
-{
-    m_status = SeriesRequestGeneratorStatus_Thinking;
-    m_active_node = 0;
-    m_address = 0x0;
-    m_addr_increment_size = p->addr_increment_size;
-    m_issue_writes = p->issue_writes;
-}
-
-SeriesRequestGenerator::~SeriesRequestGenerator()
-{
-}
-
-bool
-SeriesRequestGenerator::initiate()
-{
-    DPRINTF(DirectedTest, "initiating request\n");
-    assert(m_status == SeriesRequestGeneratorStatus_Thinking);
-
-    RubyDirectedTester::CpuPort* port =
-        safe_cast<RubyDirectedTester::CpuPort*>(m_directed_tester->
-                                              getCpuPort(m_active_node));
-
-    Request::Flags flags;
-
-    // For simplicity, requests are assumed to be 1 byte-sized
-    Request *req = new Request(m_address, 1, flags);
-
-    Packet::Command cmd;
-    if (m_issue_writes) {
-        cmd = MemCmd::WriteReq;
-    } else {
-        cmd = MemCmd::ReadReq;
-    }
-    PacketPtr pkt = new Packet(req, cmd, m_active_node);
-    uint8_t* dummyData = new uint8_t;
-    *dummyData = 0;
-    pkt->dataDynamic(dummyData);
-
-    if (port->sendTiming(pkt)) {
-        DPRINTF(DirectedTest, "initiating request - successful\n");
-        m_status = SeriesRequestGeneratorStatus_Request_Pending;
-        return true;
-    } else {
-        // If the packet did not issue, must delete
-        // Note: No need to delete the data, the packet destructor
-        // will delete it
-        delete pkt->req;
-        delete pkt;
-
-        DPRINTF(DirectedTest, "failed to initiate request - sequencer not ready\n");
-        return false;
-    }
-}
-
-void 
-SeriesRequestGenerator::performCallback(uint proc, Addr address)
-{
-    assert(m_active_node == proc);
-    assert(m_address == address);  
-    assert(m_status == SeriesRequestGeneratorStatus_Request_Pending);
-
-    m_status = SeriesRequestGeneratorStatus_Thinking;
-    m_active_node++;
-    if (m_active_node == m_num_cpus) {
-        //
-        // Cycle of requests completed, increment cycle completions and restart
-        // at cpu zero
-        //
-        m_directed_tester->incrementCycleCompletions();
-        m_address += m_addr_increment_size;
-        m_active_node = 0;
-    }
-}
-
-SeriesRequestGenerator *
-SeriesRequestGeneratorParams::create()
-{
-    return new SeriesRequestGenerator(this);
-}
diff --git a/src/cpu/directedtest/SeriesRequestGenerator.hh b/src/cpu/directedtest/SeriesRequestGenerator.hh
deleted file mode 100644 (file)
index 443bd4f..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * 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.
- */
-
-//
-// This Deterministic Generator generates GETX requests for all nodes in the 
-// system.  The GETX requests are generated one at a time in round-robin fashion
-// 0...1...2...etc.
-//
-
-#ifndef __CPU_DIRECTEDTEST_SERIESREQUESTGENERATOR_HH__
-#define __CPU_DIRECTEDTEST_SERIESREQUESTGENERATOR_HH__
-
-#include "cpu/directedtest/RubyDirectedTester.hh"
-#include "cpu/directedtest/DirectedGenerator.hh"
-#include "mem/protocol/SeriesRequestGeneratorStatus.hh"
-#include "params/SeriesRequestGenerator.hh"
-
-class SeriesRequestGenerator : public DirectedGenerator 
-{
-  public:
-    typedef SeriesRequestGeneratorParams Params;
-    SeriesRequestGenerator(const Params *p);
-    
-    ~SeriesRequestGenerator();
-    
-    bool initiate();
-    void performCallback(uint proc, Addr address);
-    
-  private:
-    SeriesRequestGeneratorStatus m_status;
-    Addr m_address;
-    uint m_active_node;
-    uint m_addr_increment_size;
-    bool m_issue_writes;
-};
-
-#endif //__CPU_DIRECTEDTEST_SERIESREQUESTGENERATOR_HH__
-
diff --git a/src/cpu/memtest/MemTest.py b/src/cpu/memtest/MemTest.py
deleted file mode 100644 (file)
index 957de80..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (c) 2005-2007 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: Nathan Binkert
-
-from MemObject import MemObject
-from m5.params import *
-from m5.proxy import *
-
-class MemTest(MemObject):
-    type = 'MemTest'
-    max_loads = Param.Counter(0, "number of loads to execute")
-    atomic = Param.Bool(False, "Execute tester in atomic mode? (or timing)\n")
-    memory_size = Param.Int(65536, "memory size")
-    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")
-    percent_uncacheable = Param.Percent(10,
-        "target uncacheable percentage")
-    progress_interval = Param.Counter(1000000,
-        "progress report interval (in accesses)")
-    trace_addr = Param.Addr(0, "address to trace")
-
-    test = Port("Port to the memory system to test")
-    functional = Port("Port to the functional memory used for verification")
diff --git a/src/cpu/memtest/SConscript b/src/cpu/memtest/SConscript
deleted file mode 100644 (file)
index 61aa096..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-# -*- mode:python -*-
-
-# 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: Nathan Binkert
-
-Import('*')
-
-#if 'O3CPU' in env['CPU_MODELS']:
-SimObject('MemTest.py')
-
-Source('memtest.cc')
-
-TraceFlag('MemTest')
diff --git a/src/cpu/memtest/memtest.cc b/src/cpu/memtest/memtest.cc
deleted file mode 100644 (file)
index 7b3ed31..0000000
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Copyright (c) 2002-2005 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: Erik Hallnor
- *          Steve Reinhardt
- */
-
-// FIX ME: make trackBlkAddr use blocksize from actual cache, not hard coded
-
-#include <iomanip>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/misc.hh"
-#include "base/statistics.hh"
-#include "cpu/memtest/memtest.hh"
-#include "mem/mem_object.hh"
-#include "mem/port.hh"
-#include "mem/packet.hh"
-#include "mem/request.hh"
-#include "sim/sim_events.hh"
-#include "sim/stats.hh"
-
-using namespace std;
-
-int TESTER_ALLOCATOR=0;
-
-bool
-MemTest::CpuPort::recvTiming(PacketPtr pkt)
-{
-    if (pkt->isResponse()) {
-        memtest->completeRequest(pkt);
-    } else {
-        // must be snoop upcall
-        assert(pkt->isRequest());
-        assert(pkt->getDest() == Packet::Broadcast);
-    }
-    return true;
-}
-
-Tick
-MemTest::CpuPort::recvAtomic(PacketPtr pkt)
-{
-    // must be snoop upcall
-    assert(pkt->isRequest());
-    assert(pkt->getDest() == Packet::Broadcast);
-    return curTick;
-}
-
-void
-MemTest::CpuPort::recvFunctional(PacketPtr pkt)
-{
-    //Do nothing if we see one come through
-//    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;
-}
-
-void
-MemTest::CpuPort::recvStatusChange(Status status)
-{
-    if (status == RangeChange) {
-        if (!snoopRangeSent) {
-            snoopRangeSent = true;
-            sendStatusChange(Port::RangeChange);
-        }
-        return;
-    }
-
-    panic("MemTest doesn't expect recvStatusChange callback!");
-}
-
-void
-MemTest::CpuPort::recvRetry()
-{
-    memtest->doRetry();
-}
-
-void
-MemTest::sendPkt(PacketPtr pkt) {
-    if (atomic) {
-        cachePort.sendAtomic(pkt);
-        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;
-        }
-    }
-
-}
-
-MemTest::MemTest(const Params *p)
-    : MemObject(p),
-      tickEvent(this),
-      cachePort("test", this),
-      funcPort("functional", this),
-      retryPkt(NULL),
-//      mainMem(main_mem),
-//      checkMem(check_mem),
-      size(p->memory_size),
-      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),
-      percentDestUnaligned(p->percent_dest_unaligned),
-      maxLoads(p->max_loads),
-      atomic(p->atomic)
-{
-    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;
-
-    id = TESTER_ALLOCATOR++;
-
-    // Needs to be masked off once we know the block size.
-    traceBlockAddr = p->trace_addr;
-    baseAddr1 = 0x100000;
-    baseAddr2 = 0x400000;
-    uncacheAddr = 0x800000;
-
-    // set up counters
-    noResponseCycles = 0;
-    numReads = 0;
-    schedule(tickEvent, 0);
-
-    accessRetry = false;
-    dmaOutstanding = false;
-}
-
-Port *
-MemTest::getPort(const std::string &if_name, int idx)
-{
-    if (if_name == "functional")
-        return &funcPort;
-    else if (if_name == "test")
-        return &cachePort;
-    else
-        panic("No Such Port\n");
-}
-
-void
-MemTest::init()
-{
-    // By the time init() is called, the ports should be hooked up.
-    blockSize = cachePort.peerBlockSize();
-    blockAddrMask = blockSize - 1;
-    traceBlockAddr = blockAddr(traceBlockAddr);
-
-    // initial memory contents for both physical memory and functional
-    // memory should be 0; no need to initialize them.
-}
-
-
-void
-MemTest::completeRequest(PacketPtr pkt)
-{
-    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()));
-
-    MemTestSenderState *state =
-        dynamic_cast<MemTestSenderState *>(pkt->senderState);
-
-    uint8_t *data = state->data;
-    uint8_t *pkt_data = pkt->getPtr<uint8_t>();
-
-    //Remove the address from the list of outstanding
-    std::set<unsigned>::iterator removeAddr =
-        outstandingAddrs.find(req->getPaddr());
-    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);
-        }
-
-        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++;
-    }
-
-    noResponseCycles = 0;
-    delete state;
-    delete [] data;
-    delete pkt->req;
-    delete pkt;
-}
-
-void
-MemTest::regStats()
-{
-    using namespace Stats;
-
-    numReadsStat
-        .name(name() + ".num_reads")
-        .desc("number of read accesses completed")
-        ;
-
-    numWritesStat
-        .name(name() + ".num_writes")
-        .desc("number of write accesses completed")
-        ;
-
-    numCopiesStat
-        .name(name() + ".num_copies")
-        .desc("number of copy accesses completed")
-        ;
-}
-
-void
-MemTest::tick()
-{
-    if (!tickEvent.scheduled())
-        schedule(tickEvent, curTick + ticks(1));
-
-    if (++noResponseCycles >= 500000) {
-        if (issueDmas) {
-            cerr << "DMA tester ";
-        }
-        cerr << name() << ": deadlocked at cycle " << curTick << endl;
-        fatal("");
-    }
-
-    if (accessRetry || (issueDmas && dmaOutstanding)) {
-        DPRINTF(MemTest, "MemTester waiting on accessRetry or DMA response\n");
-        return;
-    }
-
-    //make new request
-    unsigned cmd = random() % 100;
-    unsigned offset = random() % size;
-    unsigned base = random() % 2;
-    uint64_t data = random();
-    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
-    //to offset within the blks
-    offset = blockAddr(offset);
-    offset += id;
-    access_size = 0;
-    dma_access_size = 0;
-
-    Request *req = new Request();
-    Request::Flags flags;
-    Addr paddr;
-
-    if (uncacheable) {
-        flags.set(Request::UNCACHEABLE);
-        paddr = uncacheAddr + offset;
-    } else  {
-        paddr = ((base) ? baseAddr1 : baseAddr2) + offset;
-    }
-    bool probe = (random() % 100 < percentFunctional) && !uncacheable;
-
-    if (issueDmas) {
-        paddr &= ~((1 << dma_access_size) - 1);
-        req->setPhys(paddr, 1 << dma_access_size, flags);
-        req->setThreadContext(id,0);
-    } else {
-        paddr &= ~((1 << access_size) - 1);
-        req->setPhys(paddr, 1 << access_size, flags);
-        req->setThreadContext(id,0);
-    }
-    assert(req->getSize() == 1);
-
-    uint8_t *result = new uint8_t[8];
-
-    if (cmd < percentReads) {
-        // read
-
-        // For now we only allow one outstanding request per address
-        // per tester This means we assume CPU does write forwarding
-        // to reads that alias something in the cpu store buffer.
-        if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) {
-            delete [] result;
-            delete req;
-            return;
-        }
-
-        outstandingAddrs.insert(paddr);
-
-        // ***** NOTE FOR RON: I'm not sure how to access checkMem. - Kevin
-        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);
-
-        PacketPtr pkt = new Packet(req, MemCmd::ReadReq, Packet::Broadcast);
-        pkt->setSrc(0);
-        pkt->dataDynamicArray(new uint8_t[req->getSize()]);
-        MemTestSenderState *state = new MemTestSenderState(result);
-        pkt->senderState = state;
-
-        if (probe) {
-            cachePort.sendFunctional(pkt);
-            completeRequest(pkt);
-        } else {
-            sendPkt(pkt);
-        }
-    } else {
-        // write
-
-        // For now we only allow one outstanding request per addreess
-        // per tester.  This means we assume CPU does write forwarding
-        // to reads that alias something in the cpu store buffer.
-        if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) {
-            delete [] result;
-            delete req;
-            return;
-        }
-
-        outstandingAddrs.insert(paddr);
-
-        DPRINTF(MemTest, "initiating write at address %x (blk %x) value %x\n",
-                req->getPaddr(), blockAddr(req->getPaddr()), data & 0xff);
-
-        PacketPtr pkt = new Packet(req, MemCmd::WriteReq, Packet::Broadcast);
-        pkt->setSrc(0);
-        uint8_t *pkt_data = new uint8_t[req->getSize()];
-        pkt->dataDynamicArray(pkt_data);
-        memcpy(pkt_data, &data, req->getSize());
-        MemTestSenderState *state = new MemTestSenderState(result);
-        pkt->senderState = state;
-
-        funcPort.writeBlob(req->getPaddr(), pkt_data, req->getSize());
-
-        if (probe) {
-            cachePort.sendFunctional(pkt);
-            completeRequest(pkt);
-        } else {
-            sendPkt(pkt);
-        }
-    }
-}
-
-void
-MemTest::doRetry()
-{
-    if (cachePort.sendTiming(retryPkt)) {
-        DPRINTF(MemTest, "accessRetry setting to false\n");
-        accessRetry = false;
-        retryPkt = NULL;
-    }
-}
-
-
-void
-MemTest::printAddr(Addr a)
-{
-    cachePort.printAddr(a);
-}
-
-
-MemTest *
-MemTestParams::create()
-{
-    return new MemTest(this);
-}
diff --git a/src/cpu/memtest/memtest.hh b/src/cpu/memtest/memtest.hh
deleted file mode 100644 (file)
index bb71da3..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (c) 2002-2005 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: Erik Hallnor
- *          Steve Reinhardt
- */
-
-#ifndef __CPU_MEMTEST_MEMTEST_HH__
-#define __CPU_MEMTEST_MEMTEST_HH__
-
-#include <set>
-
-#include "base/statistics.hh"
-#include "base/fast_alloc.hh"
-#include "params/MemTest.hh"
-#include "sim/eventq.hh"
-#include "sim/sim_exit.hh"
-#include "sim/sim_object.hh"
-#include "sim/stats.hh"
-#include "mem/mem_object.hh"
-#include "mem/port.hh"
-
-class Packet;
-class MemTest : public MemObject
-{
-  public:
-    typedef MemTestParams Params;
-    MemTest(const Params *p);
-
-    virtual void init();
-
-    // register statistics
-    virtual void regStats();
-
-    inline Tick ticks(int numCycles) const { return numCycles; }
-
-    // main simulation loop (one cycle)
-    void tick();
-
-    virtual Port *getPort(const std::string &if_name, int idx = -1);
-
-    /**
-     * Print state of address in memory system via PrintReq (for
-     * debugging).
-     */
-    void printAddr(Addr a);
-
-  protected:
-    class TickEvent : public Event
-    {
-      private:
-        MemTest *cpu;
-
-      public:
-        TickEvent(MemTest *c) : Event(CPU_Tick_Pri), cpu(c) {}
-        void process() { cpu->tick(); }
-        virtual const char *description() const { return "MemTest tick"; }
-    };
-
-    TickEvent tickEvent;
-
-    class CpuPort : public Port
-    {
-        MemTest *memtest;
-
-      public:
-
-        CpuPort(const std::string &_name, MemTest *_memtest)
-            : Port(_name, _memtest), memtest(_memtest)
-        { }
-
-        bool snoopRangeSent;
-
-      protected:
-
-        virtual bool recvTiming(PacketPtr pkt);
-
-        virtual Tick recvAtomic(PacketPtr pkt);
-
-        virtual void recvFunctional(PacketPtr pkt);
-
-        virtual void recvStatusChange(Status status);
-
-        virtual void recvRetry();
-
-        virtual void getDeviceAddressRanges(AddrRangeList &resp,
-                                            bool &snoop)
-        { resp.clear(); snoop = false; }
-    };
-
-    CpuPort cachePort;
-    CpuPort funcPort;
-
-    bool snoopRangeSent;
-
-    class MemTestSenderState : public Packet::SenderState, public FastAlloc
-    {
-      public:
-        /** Constructor. */
-        MemTestSenderState(uint8_t *_data)
-            : data(_data)
-        { }
-
-        // Hold onto data pointer
-        uint8_t *data;
-    };
-
-    PacketPtr retryPkt;
-
-    bool accessRetry;
-    
-    //
-    // The dmaOustanding flag enforces only one dma at a time
-    //
-    bool dmaOutstanding;
-
-    unsigned size;              // size of testing memory region
-
-    unsigned percentReads;      // target percentage of read accesses
-    unsigned percentFunctional; // target percentage of functional accesses
-    unsigned percentUncacheable;
-
-    bool issueDmas;
-
-    int id;
-
-    std::set<unsigned> outstandingAddrs;
-
-    unsigned blockSize;
-
-    Addr blockAddrMask;
-
-    Addr blockAddr(Addr addr)
-    {
-        return (addr & ~blockAddrMask);
-    }
-
-    Addr traceBlockAddr;
-
-    Addr baseAddr1;             // fix this to option
-    Addr baseAddr2;             // fix this to option
-    Addr uncacheAddr;
-
-    unsigned progressInterval;  // frequency of progress reports
-    Tick nextProgressMessage;   // access # for next progress report
-
-    unsigned percentSourceUnaligned;
-    unsigned percentDestUnaligned;
-
-    Tick noResponseCycles;
-
-    uint64_t numReads;
-    uint64_t maxLoads;
-
-    bool atomic;
-
-    Stats::Scalar numReadsStat;
-    Stats::Scalar numWritesStat;
-    Stats::Scalar numCopiesStat;
-
-    // called by MemCompleteEvent::process()
-    void completeRequest(PacketPtr pkt);
-
-    void sendPkt(PacketPtr pkt);
-
-    void doRetry();
-
-    friend class MemCompleteEvent;
-};
-
-#endif // __CPU_MEMTEST_MEMTEST_HH__
-
-
-
diff --git a/src/cpu/rubytest/Check.cc b/src/cpu/rubytest/Check.cc
deleted file mode 100644 (file)
index 33927ea..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * Copyright (c) 2009 Advanced Micro Devices, Inc.
- * 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.
- */
-
-#include "cpu/rubytest/Check.hh"
-#include "mem/ruby/common/SubBlock.hh"
-#include "mem/ruby/system/Sequencer.hh"
-#include "mem/ruby/system/System.hh"
-
-typedef RubyTester::SenderState SenderState;
-
-Check::Check(const Address& address, const Address& pc,
-             int _num_cpu_sequencers, RubyTester* _tester)
-    : m_num_cpu_sequencers(_num_cpu_sequencers), m_tester_ptr(_tester)
-{
-    m_status = TesterStatus_Idle;
-
-    pickValue();
-    pickInitiatingNode();
-    changeAddress(address);
-    m_pc = pc;
-    m_access_mode = AccessModeType(random() % AccessModeType_NUM);
-    m_store_count = 0;
-}
-
-void
-Check::initiate()
-{
-    DPRINTF(RubyTest, "initiating\n");
-    debugPrint();
-
-    // currently no protocols support prefetches
-    if (false && (random() & 0xf) == 0) {
-        initiatePrefetch(); // Prefetch from random processor
-    }
-
-    if (m_status == TesterStatus_Idle) {
-        initiateAction();
-    } else if (m_status == TesterStatus_Ready) {
-        initiateCheck();
-    } else {
-        // Pending - do nothing
-        DPRINTF(RubyTest,
-                "initiating action/check - failed: action/check is pending\n");
-    }
-}
-
-void
-Check::initiatePrefetch()
-{
-    DPRINTF(RubyTest, "initiating prefetch\n");
-
-    int index = random() % m_num_cpu_sequencers;
-    RubyTester::CpuPort* port =
-        safe_cast<RubyTester::CpuPort*>(m_tester_ptr->getCpuPort(index));
-
-    Request::Flags flags;
-    flags.set(Request::PREFETCH);
-
-    Packet::Command cmd;
-
-    // 1 in 8 chance this will be an exclusive prefetch
-    if ((random() & 0x7) != 0) {
-        cmd = MemCmd::ReadReq;
-
-        // 50% chance that the request will be an instruction fetch
-        if ((random() & 0x1) == 0) {
-            flags.set(Request::INST_FETCH);
-        }
-    } else {
-        cmd = MemCmd::WriteReq;
-        flags.set(Request::PF_EXCLUSIVE);
-    }
-
-    // Prefetches are assumed to be 0 sized
-    Request *req = new Request(m_address.getAddress(), 0, flags, curTick,
-                               m_pc.getAddress());
-
-    PacketPtr pkt = new Packet(req, cmd, port->idx);
-
-    // push the subblock onto the sender state.  The sequencer will
-    // update the subblock on the return
-    pkt->senderState =
-        new SenderState(m_address, req->getSize(), pkt->senderState);
-
-    if (port->sendTiming(pkt)) {
-        DPRINTF(RubyTest, "successfully initiated prefetch.\n");
-    } else {
-        // If the packet did not issue, must delete
-        SenderState* senderState =  safe_cast<SenderState*>(pkt->senderState);
-        pkt->senderState = senderState->saved;
-        delete senderState;
-        delete pkt->req;
-        delete pkt;
-
-        DPRINTF(RubyTest,
-                "prefetch initiation failed because Port was busy.\n");
-    }
-}
-
-void
-Check::initiateAction()
-{
-    DPRINTF(RubyTest, "initiating Action\n");
-    assert(m_status == TesterStatus_Idle);
-
-    int index = random() % m_num_cpu_sequencers;
-    RubyTester::CpuPort* port =
-        safe_cast<RubyTester::CpuPort*>(m_tester_ptr->getCpuPort(index));
-
-    Request::Flags flags;
-
-    // Create the particular address for the next byte to be written
-    Address writeAddr(m_address.getAddress() + m_store_count);
-
-    // Stores are assumed to be 1 byte-sized
-    Request *req = new Request(writeAddr.getAddress(), 1, flags, curTick,
-                               m_pc.getAddress());
-
-    Packet::Command cmd;
-
-    // 1 out of 8 chance, issue an atomic rather than a write
-    // if ((random() & 0x7) == 0) {
-    //     cmd = MemCmd::SwapReq;
-    // } else {
-    cmd = MemCmd::WriteReq;
-    // }
-
-    PacketPtr pkt = new Packet(req, cmd, port->idx);
-    uint8_t* writeData = new uint8_t;
-    *writeData = m_value + m_store_count;
-    pkt->dataDynamic(writeData);
-
-    DPRINTF(RubyTest, "data 0x%x check 0x%x\n",
-            *(pkt->getPtr<uint8_t>()), *writeData);
-
-    // push the subblock onto the sender state.  The sequencer will
-    // update the subblock on the return
-    pkt->senderState =
-        new SenderState(writeAddr, req->getSize(), pkt->senderState);
-
-    if (port->sendTiming(pkt)) {
-        DPRINTF(RubyTest, "initiating action - successful\n");
-        DPRINTF(RubyTest, "status before action update: %s\n",
-                (TesterStatus_to_string(m_status)).c_str());
-        m_status = TesterStatus_Action_Pending;
-    } else {
-        // If the packet did not issue, must delete
-        // Note: No need to delete the data, the packet destructor
-        // will delete it
-        SenderState* senderState = safe_cast<SenderState*>(pkt->senderState);
-        pkt->senderState = senderState->saved;
-        delete senderState;
-        delete pkt->req;
-        delete pkt;
-
-        DPRINTF(RubyTest, "failed to initiate action - sequencer not ready\n");
-    }
-
-    DPRINTF(RubyTest, "status after action update: %s\n",
-            (TesterStatus_to_string(m_status)).c_str());
-}
-
-void
-Check::initiateCheck()
-{
-    DPRINTF(RubyTest, "Initiating Check\n");
-    assert(m_status == TesterStatus_Ready);
-
-    int index = random() % m_num_cpu_sequencers;
-    RubyTester::CpuPort* port =
-        safe_cast<RubyTester::CpuPort*>(m_tester_ptr->getCpuPort(index));
-
-    Request::Flags flags;
-
-    // 50% chance that the request will be an instruction fetch
-    if ((random() & 0x1) == 0) {
-        flags.set(Request::INST_FETCH);
-    }
-
-    // Checks are sized depending on the number of bytes written
-    Request *req = new Request(m_address.getAddress(), CHECK_SIZE, flags,
-                               curTick, m_pc.getAddress());
-
-    PacketPtr pkt = new Packet(req, MemCmd::ReadReq, port->idx);
-    uint8_t* dataArray = new uint8_t[CHECK_SIZE];
-    pkt->dataDynamicArray(dataArray);
-
-    // push the subblock onto the sender state.  The sequencer will
-    // update the subblock on the return
-    pkt->senderState =
-        new SenderState(m_address, req->getSize(), pkt->senderState);
-
-    if (port->sendTiming(pkt)) {
-        DPRINTF(RubyTest, "initiating check - successful\n");
-        DPRINTF(RubyTest, "status before check update: %s\n",
-                TesterStatus_to_string(m_status).c_str());
-        m_status = TesterStatus_Check_Pending;
-    } else {
-        // If the packet did not issue, must delete
-        // Note: No need to delete the data, the packet destructor
-        // will delete it
-        SenderState* senderState = safe_cast<SenderState*>(pkt->senderState);
-        pkt->senderState = senderState->saved;
-        delete senderState;
-        delete pkt->req;
-        delete pkt;
-
-        DPRINTF(RubyTest, "failed to initiate check - cpu port not ready\n");
-    }
-
-    DPRINTF(RubyTest, "status after check update: %s\n",
-            TesterStatus_to_string(m_status).c_str());
-}
-
-void
-Check::performCallback(NodeID proc, SubBlock* data)
-{
-    Address address = data->getAddress();
-
-    // This isn't exactly right since we now have multi-byte checks
-    //  assert(getAddress() == address);
-
-    assert(getAddress().getLineAddress() == address.getLineAddress());
-    assert(data != NULL);
-
-    DPRINTF(RubyTest, "RubyTester Callback\n");
-    debugPrint();
-
-    if (m_status == TesterStatus_Action_Pending) {
-        DPRINTF(RubyTest, "Action callback write value: %d, currently %d\n",
-                (m_value + m_store_count), data->getByte(0));
-        // Perform store one byte at a time
-        data->setByte(0, (m_value + m_store_count));
-        m_store_count++;
-        if (m_store_count == CHECK_SIZE) {
-            m_status = TesterStatus_Ready;
-        } else {
-            m_status = TesterStatus_Idle;
-        }
-        DPRINTF(RubyTest, "Action callback return data now %d\n",
-                data->getByte(0));
-    } else if (m_status == TesterStatus_Check_Pending) {
-        DPRINTF(RubyTest, "Check callback\n");
-        // Perform load/check
-        for (int byte_number=0; byte_number<CHECK_SIZE; byte_number++) {
-            if (uint8(m_value + byte_number) != data->getByte(byte_number)) {
-                WARN_EXPR(proc);
-                WARN_EXPR(address);
-                WARN_EXPR(data);
-                WARN_EXPR(byte_number);
-                WARN_EXPR((int)m_value + byte_number);
-                WARN_EXPR((int)data->getByte(byte_number));
-                WARN_EXPR(*this);
-                WARN_EXPR(g_eventQueue_ptr->getTime());
-                ERROR_MSG("Action/check failure");
-            }
-        }
-        DPRINTF(RubyTest, "Action/check success\n");
-        debugPrint();
-
-        // successful check complete, increment complete
-        m_tester_ptr->incrementCheckCompletions();
-
-        m_status = TesterStatus_Idle;
-        pickValue();
-
-    } else {
-        WARN_EXPR(*this);
-        WARN_EXPR(proc);
-        WARN_EXPR(data);
-        WARN_EXPR(m_status);
-        WARN_EXPR(g_eventQueue_ptr->getTime());
-        ERROR_MSG("Unexpected TesterStatus");
-    }
-
-    DPRINTF(RubyTest, "proc: %d, Address: 0x%x\n", proc,
-            getAddress().getLineAddress());
-    DPRINTF(RubyTest, "Callback done\n");
-    debugPrint();
-}
-
-void
-Check::changeAddress(const Address& address)
-{
-    assert(m_status == TesterStatus_Idle || m_status == TesterStatus_Ready);
-    m_status = TesterStatus_Idle;
-    m_address = address;
-    m_store_count = 0;
-}
-
-void
-Check::pickValue()
-{
-    assert(m_status == TesterStatus_Idle);
-    m_status = TesterStatus_Idle;
-    m_value = random() & 0xff; // One byte
-    m_store_count = 0;
-}
-
-void
-Check::pickInitiatingNode()
-{
-    assert(m_status == TesterStatus_Idle || m_status == TesterStatus_Ready);
-    m_status = TesterStatus_Idle;
-    m_initiatingNode = (random() % m_num_cpu_sequencers);
-    DPRINTF(RubyTest, "picked initiating node %d\n", m_initiatingNode);
-    m_store_count = 0;
-}
-
-void
-Check::print(std::ostream& out) const
-{
-    out << "["
-        << m_address << ", value: "
-        << (int)m_value << ", status: "
-        << m_status << ", initiating node: "
-        << m_initiatingNode << ", store_count: "
-        << m_store_count
-        << "]" << std::flush;
-}
-
-void
-Check::debugPrint()
-{
-    DPRINTF(RubyTest,
-        "[%#x, value: %d, status: %s, initiating node: %d, store_count: %d]\n",
-        m_address.getAddress(), (int)m_value,
-        TesterStatus_to_string(m_status).c_str(),
-        m_initiatingNode, m_store_count);
-}
diff --git a/src/cpu/rubytest/Check.hh b/src/cpu/rubytest/Check.hh
deleted file mode 100644 (file)
index 6d41dfc..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * Copyright (c) 2009 Advanced Micro Devices, Inc.
- * 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.
- */
-
-#ifndef __CPU_RUBYTEST_CHECK_HH__
-#define __CPU_RUBYTEST_CHECK_HH__
-
-#include <iostream>
-
-#include "cpu/rubytest/RubyTester.hh"
-#include "mem/protocol/AccessModeType.hh"
-#include "mem/protocol/TesterStatus.hh"
-#include "mem/ruby/common/Address.hh"
-#include "mem/ruby/common/Global.hh"
-#include "mem/ruby/system/NodeID.hh"
-
-class SubBlock;
-
-const int CHECK_SIZE_BITS = 2;
-const int CHECK_SIZE = (1 << CHECK_SIZE_BITS);
-
-class Check
-{
-  public:
-    Check(const Address& address, const Address& pc, int _num_cpu_sequencer,
-          RubyTester* _tester);
-
-    void initiate(); // Does Action or Check or nether
-    void performCallback(NodeID proc, SubBlock* data);
-    const Address& getAddress() { return m_address; }
-    void changeAddress(const Address& address);
-
-    void print(std::ostream& out) const;
-
-  private:
-    void initiatePrefetch();
-    void initiateAction();
-    void initiateCheck();
-
-    void pickValue();
-    void pickInitiatingNode();
-
-    void debugPrint();
-
-    TesterStatus m_status;
-    uint8 m_value;
-    int m_store_count;
-    NodeID m_initiatingNode;
-    Address m_address;
-    Address m_pc;
-    AccessModeType m_access_mode;
-    int m_num_cpu_sequencers;
-    RubyTester* m_tester_ptr;
-};
-
-inline std::ostream&
-operator<<(std::ostream& out, const Check& obj)
-{
-    obj.print(out);
-    out << std::flush;
-    return out;
-}
-
-#endif // __CPU_RUBYTEST_CHECK_HH__
diff --git a/src/cpu/rubytest/CheckTable.cc b/src/cpu/rubytest/CheckTable.cc
deleted file mode 100644 (file)
index 1c34447..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * Copyright (c) 2009 Advanced Micro Devices, Inc.
- * 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.
- */
-
-#include "base/intmath.hh"
-#include "cpu/rubytest/Check.hh"
-#include "cpu/rubytest/CheckTable.hh"
-#include "cpu/rubytest/CheckTable.hh"
-
-CheckTable::CheckTable(int _num_cpu_sequencers, RubyTester* _tester)
-    : m_num_cpu_sequencers(_num_cpu_sequencers), m_tester_ptr(_tester)
-{
-    physical_address_t physical = 0;
-    Address address;
-
-    const int size1 = 32;
-    const int size2 = 100;
-
-    // The first set is to get some false sharing
-    physical = 1000;
-    for (int i = 0; i < size1; i++) {
-        // Setup linear addresses
-        address.setAddress(physical);
-        addCheck(address);
-        physical += CHECK_SIZE;
-    }
-
-    // The next two sets are to get some limited false sharing and
-    // cache conflicts
-    physical = 1000;
-    for (int i = 0; i < size2; i++) {
-        // Setup linear addresses
-        address.setAddress(physical);
-        addCheck(address);
-        physical += 256;
-    }
-
-    physical = 1000 + CHECK_SIZE;
-    for (int i = 0; i < size2; i++) {
-        // Setup linear addresses
-        address.setAddress(physical);
-        addCheck(address);
-        physical += 256;
-    }
-}
-
-CheckTable::~CheckTable()
-{
-    int size = m_check_vector.size();
-    for (int i = 0; i < size; i++)
-        delete m_check_vector[i];
-}
-
-void
-CheckTable::addCheck(const Address& address)
-{
-    if (floorLog2(CHECK_SIZE) != 0) {
-        if (address.bitSelect(0, CHECK_SIZE_BITS - 1) != 0) {
-            ERROR_MSG("Check not aligned");
-        }
-    }
-
-    for (int i = 0; i < CHECK_SIZE; i++) {
-        if (m_lookup_map.count(Address(address.getAddress()+i))) {
-            // A mapping for this byte already existed, discard the
-            // entire check
-            return;
-        }
-    }
-
-    Check* check_ptr = new Check(address, Address(100 + m_check_vector.size()),
-                                 m_num_cpu_sequencers, m_tester_ptr);
-    for (int i = 0; i < CHECK_SIZE; i++) {
-        // Insert it once per byte
-        m_lookup_map[Address(address.getAddress() + i)] = check_ptr;
-    }
-    m_check_vector.push_back(check_ptr);
-}
-
-Check*
-CheckTable::getRandomCheck()
-{
-    return m_check_vector[random() % m_check_vector.size()];
-}
-
-Check*
-CheckTable::getCheck(const Address& address)
-{
-    DEBUG_MSG(TESTER_COMP, MedPrio, "Looking for check by address");
-    DEBUG_EXPR(TESTER_COMP, MedPrio, address);
-
-    m5::hash_map<Address, Check*>::iterator i = m_lookup_map.find(address);
-
-    if (i == m_lookup_map.end())
-        return NULL;
-
-    Check* check = i->second;
-    assert(check != NULL);
-    return check;
-}
-
-void
-CheckTable::print(std::ostream& out) const
-{
-}
diff --git a/src/cpu/rubytest/CheckTable.hh b/src/cpu/rubytest/CheckTable.hh
deleted file mode 100644 (file)
index 5a4ead3..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * Copyright (c) 2009 Advanced Micro Devices, Inc.
- * 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.
- */
-
-#ifndef __CPU_RUBYTEST_CHECKTABLE_HH__
-#define __CPU_RUBYTEST_CHECKTABLE_HH__
-
-#include <iostream>
-#include <vector>
-
-#include "base/hashmap.hh"
-#include "mem/ruby/common/Address.hh"
-#include "mem/ruby/common/Global.hh"
-
-class Check;
-class RubyTester;
-
-class CheckTable
-{
-  public:
-    CheckTable(int _num_cpu_sequencers, RubyTester* _tester);
-    ~CheckTable();
-
-    Check* getRandomCheck();
-    Check* getCheck(const Address& address);
-
-    //  bool isPresent(const Address& address) const;
-    //  void removeCheckFromTable(const Address& address);
-    //  bool isTableFull() const;
-    // Need a method to select a check or retrieve a check
-
-    void print(std::ostream& out) const;
-
-  private:
-    void addCheck(const Address& address);
-
-    // Private copy constructor and assignment operator
-    CheckTable(const CheckTable& obj);
-    CheckTable& operator=(const CheckTable& obj);
-
-    std::vector<Check*> m_check_vector;
-    m5::hash_map<Address, Check*> m_lookup_map;
-
-    int m_num_cpu_sequencers;
-    RubyTester* m_tester_ptr;
-};
-
-inline std::ostream&
-operator<<(std::ostream& out, const CheckTable& obj)
-{
-    obj.print(out);
-    out << std::flush;
-    return out;
-}
-
-#endif // __CPU_RUBYTEST_CHECKTABLE_HH__
diff --git a/src/cpu/rubytest/RubyTester.cc b/src/cpu/rubytest/RubyTester.cc
deleted file mode 100644 (file)
index 036e511..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * Copyright (c) 2009 Advanced Micro Devices, Inc.
- * 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.
- */
-
-#include "cpu/rubytest/Check.hh"
-#include "cpu/rubytest/RubyTester.hh"
-#include "mem/ruby/common/Global.hh"
-#include "mem/ruby/common/SubBlock.hh"
-#include "mem/ruby/eventqueue/RubyEventQueue.hh"
-#include "mem/ruby/system/System.hh"
-#include "sim/sim_exit.hh"
-
-RubyTester::RubyTester(const Params *p)
-  : MemObject(p), checkStartEvent(this),
-    m_checks_to_complete(p->checks_to_complete),
-    m_deadlock_threshold(p->deadlock_threshold),
-    m_wakeup_frequency(p->wakeup_frequency)
-{
-    m_checks_completed = 0;
-
-    // add the check start event to the event queue
-    schedule(checkStartEvent, 1);
-}
-
-RubyTester::~RubyTester()
-{
-    delete m_checkTable_ptr;
-    for (int i = 0; i < ports.size(); i++)
-        delete ports[i];
-}
-
-void
-RubyTester::init()
-{
-    assert(ports.size() > 0);
-
-    m_last_progress_vector.resize(ports.size());
-    for (int i = 0; i < m_last_progress_vector.size(); i++) {
-        m_last_progress_vector[i] = 0;
-    }
-
-    m_num_cpu_sequencers = ports.size();
-
-    m_checkTable_ptr = new CheckTable(m_num_cpu_sequencers, this);
-}
-
-Port *
-RubyTester::getPort(const std::string &if_name, int idx)
-{
-    if (if_name != "cpuPort") {
-        panic("RubyTester::getPort: unknown port %s requested", if_name);
-    }
-
-    if (idx >= (int)ports.size()) {
-        ports.resize(idx + 1);
-    }
-
-    if (ports[idx] != NULL) {
-        panic("RubyTester::getPort: port %d already assigned", idx);
-    }
-
-    CpuPort *port = new CpuPort(csprintf("%s-port%d", name(), idx), this, idx);
-
-    ports[idx] = port;
-    return port;
-}
-
-Tick
-RubyTester::CpuPort::recvAtomic(PacketPtr pkt)
-{
-    panic("RubyTester::CpuPort::recvAtomic() not implemented!\n");
-    return 0;
-}
-
-bool
-RubyTester::CpuPort::recvTiming(PacketPtr pkt)
-{
-    // retrieve the subblock and call hitCallback
-    RubyTester::SenderState* senderState =
-        safe_cast<RubyTester::SenderState*>(pkt->senderState);
-    SubBlock* subblock = senderState->subBlock;
-    assert(subblock != NULL);
-
-    // pop the sender state from the packet
-    pkt->senderState = senderState->saved;
-
-    tester->hitCallback(idx, subblock);
-
-    // Now that the tester has completed, delete the senderState
-    // (includes sublock) and the packet, then return
-    delete senderState;
-    delete pkt->req;
-    delete pkt;
-    return true;
-}
-
-Port*
-RubyTester::getCpuPort(int idx)
-{
-    assert(idx >= 0 && idx < ports.size());
-
-    return ports[idx];
-}
-
-void
-RubyTester::hitCallback(NodeID proc, SubBlock* data)
-{
-    // Mark that we made progress
-    m_last_progress_vector[proc] = g_eventQueue_ptr->getTime();
-
-    DPRINTF(RubyTest, "completed request for proc: %d\n", proc);
-    DPRINTF(RubyTest, "addr: 0x%x, size: %d, data: ",
-            data->getAddress(), data->getSize());
-    for (int byte = 0; byte < data->getSize(); byte++) {
-        DPRINTF(RubyTest, "%d", data->getByte(byte));
-    }
-    DPRINTF(RubyTest, "\n");
-
-    // This tells us our store has 'completed' or for a load gives us
-    // back the data to make the check
-    Check* check_ptr = m_checkTable_ptr->getCheck(data->getAddress());
-    assert(check_ptr != NULL);
-    check_ptr->performCallback(proc, data);
-}
-
-void
-RubyTester::wakeup()
-{
-    if (m_checks_completed < m_checks_to_complete) {
-        // Try to perform an action or check
-        Check* check_ptr = m_checkTable_ptr->getRandomCheck();
-        assert(check_ptr != NULL);
-        check_ptr->initiate();
-
-        checkForDeadlock();
-
-        schedule(checkStartEvent, curTick + m_wakeup_frequency);
-    } else {
-        exitSimLoop("Ruby Tester completed");
-    }
-}
-
-void
-RubyTester::checkForDeadlock()
-{
-    int size = m_last_progress_vector.size();
-    Time current_time = g_eventQueue_ptr->getTime();
-    for (int processor = 0; processor < size; processor++) {
-        if ((current_time - m_last_progress_vector[processor]) >
-                m_deadlock_threshold) {
-            WARN_EXPR(current_time);
-            WARN_EXPR(m_last_progress_vector[processor]);
-            WARN_EXPR(current_time - m_last_progress_vector[processor]);
-            WARN_EXPR(processor);
-            ERROR_MSG("Deadlock detected.");
-        }
-    }
-}
-
-void
-RubyTester::print(std::ostream& out) const
-{
-    out << "[RubyTester]" << std::endl;
-}
-
-RubyTester *
-RubyTesterParams::create()
-{
-    return new RubyTester(this);
-}
diff --git a/src/cpu/rubytest/RubyTester.hh b/src/cpu/rubytest/RubyTester.hh
deleted file mode 100644 (file)
index 2726a50..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * Copyright (c) 2009 Advanced Micro Devices, Inc.
- * 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.
- */
-
-#ifndef __CPU_RUBYTEST_RUBYTESTER_HH__
-#define __CPU_RUBYTEST_RUBYTESTER_HH__
-
-#include <iostream>
-#include <vector>
-#include <string>
-
-#include "cpu/rubytest/CheckTable.hh"
-#include "mem/mem_object.hh"
-#include "mem/packet.hh"
-#include "mem/ruby/common/DataBlock.hh"
-#include "mem/ruby/common/Global.hh"
-#include "mem/ruby/common/SubBlock.hh"
-#include "mem/ruby/system/RubyPort.hh"
-#include "params/RubyTester.hh"
-
-class RubyTester : public MemObject
-{
-  public:
-    class CpuPort : public SimpleTimingPort
-    {
-      private:
-        RubyTester *tester;
-
-      public:
-        CpuPort(const std::string &_name, RubyTester *_tester, int _idx)
-            : SimpleTimingPort(_name, _tester), tester(_tester), idx(_idx)
-        {}
-
-        int idx;
-
-      protected:
-        virtual bool recvTiming(PacketPtr pkt);
-        virtual Tick recvAtomic(PacketPtr pkt);
-    };
-
-    struct SenderState : public Packet::SenderState
-    {
-        SubBlock* subBlock;
-        Packet::SenderState *saved;
-
-        SenderState(Address addr, int size,
-                    Packet::SenderState *sender_state = NULL)
-            : saved(sender_state)
-        {
-            subBlock = new SubBlock(addr, size);
-        }
-
-        ~SenderState()
-        {
-            delete subBlock;
-        }
-    };
-
-    typedef RubyTesterParams Params;
-    RubyTester(const Params *p);
-    ~RubyTester();
-
-    virtual Port *getPort(const std::string &if_name, int idx = -1);
-
-    Port* getCpuPort(int idx);
-
-    virtual void init();
-
-    void wakeup();
-
-    void incrementCheckCompletions() { m_checks_completed++; }
-
-    void printStats(std::ostream& out) const {}
-    void clearStats() {}
-    void printConfig(std::ostream& out) const {}
-
-    void print(std::ostream& out) const;
-
-  protected:
-    class CheckStartEvent : public Event
-    {
-      private:
-        RubyTester *tester;
-
-      public:
-        CheckStartEvent(RubyTester *_tester)
-            : Event(CPU_Tick_Pri), tester(_tester)
-        {}
-        void process() { tester->wakeup(); }
-        virtual const char *description() const { return "RubyTester tick"; }
-    };
-
-    CheckStartEvent checkStartEvent;
-
-  private:
-    void hitCallback(NodeID proc, SubBlock* data);
-
-    void checkForDeadlock();
-
-    // Private copy constructor and assignment operator
-    RubyTester(const RubyTester& obj);
-    RubyTester& operator=(const RubyTester& obj);
-
-    CheckTable* m_checkTable_ptr;
-    std::vector<Time> m_last_progress_vector;
-
-    uint64 m_checks_completed;
-    std::vector<CpuPort*> ports;
-    uint64 m_checks_to_complete;
-    int m_deadlock_threshold;
-    int m_num_cpu_sequencers;
-    int m_wakeup_frequency;
-};
-
-inline std::ostream&
-operator<<(std::ostream& out, const RubyTester& obj)
-{
-    obj.print(out);
-    out << std::flush;
-    return out;
-}
-
-#endif // __CPU_RUBYTEST_RUBYTESTER_HH__
diff --git a/src/cpu/rubytest/RubyTester.py b/src/cpu/rubytest/RubyTester.py
deleted file mode 100644 (file)
index af37d2f..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (c) 2005-2007 The Regents of The University of Michigan
-# Copyright (c) 2009 Advanced Micro Devices, Inc.
-# 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.
-#
-
-from MemObject import MemObject
-from m5.params import *
-from m5.proxy import *
-
-class RubyTester(MemObject):
-    type = 'RubyTester'
-    cpuPort = VectorPort("the cpu ports")
-    checks_to_complete = Param.Int(100, "checks to complete")
-    deadlock_threshold = Param.Int(50000, "how often to check for deadlock")
-    wakeup_frequency = Param.Int(10, "number of cycles between wakeups")
diff --git a/src/cpu/rubytest/SConscript b/src/cpu/rubytest/SConscript
deleted file mode 100644 (file)
index 9352dd7..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-# -*- mode:python -*-
-
-# Copyright (c) 2006 The Regents of The University of Michigan
-# Copyright (c) 2009 Advanced Micro Devices, Inc.
-# 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.
-#
-
-Import('*')
-
-#
-# Currently the ruby testser relies on Ruby specific objects (SubBlock, etc.)
-# When this dependency is removed, the ruby tester should be compiled
-# independently from Ruby
-#
-if not env['RUBY']:
-    Return()
-
-SimObject('RubyTester.py')
-
-Source('RubyTester.cc')
-Source('Check.cc')
-Source('CheckTable.cc')
-
-TraceFlag('RubyTest')
diff --git a/src/cpu/testers/directedtest/DirectedGenerator.cc b/src/cpu/testers/directedtest/DirectedGenerator.cc
new file mode 100644 (file)
index 0000000..68ea554
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009-2010 Advanced Micro Devices, Inc.
+ * 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.
+ */
+
+#include "cpu/testers/directedtest/DirectedGenerator.hh"
+
+DirectedGenerator::DirectedGenerator(const Params *p)
+    : SimObject(p)
+{
+    m_num_cpus = p->num_cpus;
+    m_directed_tester = NULL;
+}
+
+void 
+DirectedGenerator::setDirectedTester(RubyDirectedTester* directed_tester)
+{
+    assert(m_directed_tester == NULL);
+    m_directed_tester = directed_tester;
+}
diff --git a/src/cpu/testers/directedtest/DirectedGenerator.hh b/src/cpu/testers/directedtest/DirectedGenerator.hh
new file mode 100644 (file)
index 0000000..904dcf3
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+#ifndef __CPU_DIRECTEDTEST_DIRECTEDGENERATOR_HH__
+#define __CPU_DIRECTEDTEST_DIRECTEDGENERATOR_HH__
+
+#include "cpu/testers/directedtest/DirectedGenerator.hh"
+#include "cpu/testers/directedtest/RubyDirectedTester.hh"
+#include "params/DirectedGenerator.hh"
+#include "sim/sim_object.hh"
+
+class DirectedGenerator : public SimObject 
+{
+  public:
+    typedef DirectedGeneratorParams Params;
+    DirectedGenerator(const Params *p);
+    
+    virtual ~DirectedGenerator() {}
+    
+    virtual bool initiate() = 0;
+    virtual void performCallback(uint proc, Addr address) = 0;
+    
+    void setDirectedTester(RubyDirectedTester* directed_tester);
+    
+  protected:
+    int m_num_cpus;
+    RubyDirectedTester* m_directed_tester;
+};
+
+#endif //__CPU_DIRECTEDTEST_DIRECTEDGENERATOR_HH__
+
diff --git a/src/cpu/testers/directedtest/InvalidateGenerator.cc b/src/cpu/testers/directedtest/InvalidateGenerator.cc
new file mode 100644 (file)
index 0000000..724702d
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009-2010 Advanced Micro Devices, Inc.
+ * 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.
+ */
+
+#include "cpu/testers/directedtest/RubyDirectedTester.hh"
+#include "cpu/testers/directedtest/DirectedGenerator.hh"
+#include "cpu/testers/directedtest/InvalidateGenerator.hh"
+
+InvalidateGenerator::InvalidateGenerator(const Params *p)
+    : DirectedGenerator(p)
+{
+    //
+    // First, issue loads to bring the block into S state
+    //
+    m_status = InvalidateGeneratorStatus_Load_Waiting;
+    m_active_read_node = 0;
+    m_active_inv_node = 0;
+    m_address = 0x0;
+    m_addr_increment_size = p->addr_increment_size;
+}
+
+InvalidateGenerator::~InvalidateGenerator()
+{
+}
+
+bool
+InvalidateGenerator::initiate()
+{
+    RubyDirectedTester::CpuPort* port;
+    Request::Flags flags;
+    PacketPtr pkt;
+    Packet::Command cmd;
+
+    // For simplicity, requests are assumed to be 1 byte-sized
+    Request *req = new Request(m_address, 1, flags);
+
+    //
+    // Based on the current state, issue a load or a store
+    //
+    if (m_status == InvalidateGeneratorStatus_Load_Waiting) {
+        DPRINTF(DirectedTest, "initiating read\n");
+        cmd = MemCmd::ReadReq;
+        port = safe_cast<RubyDirectedTester::CpuPort*>(m_directed_tester->
+                                               getCpuPort(m_active_read_node));
+        pkt = new Packet(req, cmd, m_active_read_node);
+    } else if (m_status == InvalidateGeneratorStatus_Inv_Waiting) {
+        DPRINTF(DirectedTest, "initiating invalidating write\n");
+        cmd = MemCmd::WriteReq;
+        port = safe_cast<RubyDirectedTester::CpuPort*>(m_directed_tester->
+                                               getCpuPort(m_active_inv_node));
+        pkt = new Packet(req, cmd, m_active_inv_node);
+    } else {
+        panic("initiate was unexpectedly called\n");
+    }
+    uint8_t* dummyData = new uint8_t;
+    *dummyData = 0;
+    pkt->dataDynamic(dummyData);
+
+    if (port->sendTiming(pkt)) {
+        DPRINTF(DirectedTest, "initiating request - successful\n");
+        if (m_status == InvalidateGeneratorStatus_Load_Waiting) {
+            m_status = InvalidateGeneratorStatus_Load_Pending;
+        } else {
+            m_status = InvalidateGeneratorStatus_Inv_Pending;
+        }
+        return true;
+    } else {
+        // If the packet did not issue, must delete
+        // Note: No need to delete the data, the packet destructor
+        // will delete it
+        delete pkt->req;
+        delete pkt;
+
+        DPRINTF(DirectedTest, "failed to issue request - sequencer not ready\n");
+        return false;
+    }
+}
+
+void 
+InvalidateGenerator::performCallback(uint proc, Addr address)
+{
+    assert(m_address == address);  
+
+    if (m_status == InvalidateGeneratorStatus_Load_Pending) {
+        assert(m_active_read_node == proc);
+        m_active_read_node++;
+        //
+        // Once all cpus have the block in S state, issue the invalidate
+        //
+        if (m_active_read_node == m_num_cpus) {
+            m_status = InvalidateGeneratorStatus_Inv_Waiting;
+            m_active_read_node = 0;
+        } else {
+            m_status = InvalidateGeneratorStatus_Load_Waiting;
+        }
+    } else if (m_status == InvalidateGeneratorStatus_Inv_Pending) {
+        assert(m_active_inv_node == proc);
+        m_active_inv_node++;
+        if (m_active_inv_node == m_num_cpus) {
+            m_address += m_addr_increment_size;
+            m_active_inv_node = 0;
+        }
+        //
+        // Invalidate completed, send that info to the tester and restart
+        // the cycle
+        //
+        m_directed_tester->incrementCycleCompletions();
+        m_status = InvalidateGeneratorStatus_Load_Waiting;
+    } 
+    
+}
+
+InvalidateGenerator *
+InvalidateGeneratorParams::create()
+{
+    return new InvalidateGenerator(this);
+}
diff --git a/src/cpu/testers/directedtest/InvalidateGenerator.hh b/src/cpu/testers/directedtest/InvalidateGenerator.hh
new file mode 100644 (file)
index 0000000..ab68c85
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+//
+// This Directed Generator generates GETX requests for all nodes in the 
+// system.  The GETX requests are generated one at a time in round-robin fashion
+// 0...1...2...etc.
+//
+
+#ifndef __CPU_DIRECTEDTEST_INVALIDATEGENERATOR_HH__
+#define __CPU_DIRECTEDTEST_INVALIDATEGENERATOR_HH__
+
+#include "cpu/testers/directedtest/RubyDirectedTester.hh"
+#include "cpu/testers/directedtest/DirectedGenerator.hh"
+#include "mem/protocol/InvalidateGeneratorStatus.hh"
+#include "params/InvalidateGenerator.hh"
+
+class InvalidateGenerator : public DirectedGenerator 
+{
+  public:
+    typedef InvalidateGeneratorParams Params;
+    InvalidateGenerator(const Params *p);
+    
+    ~InvalidateGenerator();
+    
+    bool initiate();
+    void performCallback(uint proc, Addr address);
+    
+  private:
+    InvalidateGeneratorStatus m_status;
+    Addr m_address;
+    uint m_active_read_node;
+    uint m_active_inv_node;
+    uint m_addr_increment_size;
+};
+
+#endif //__CPU_DIRECTEDTEST_INVALIDATEGENERATOR_HH__
+
diff --git a/src/cpu/testers/directedtest/RubyDirectedTester.cc b/src/cpu/testers/directedtest/RubyDirectedTester.cc
new file mode 100644 (file)
index 0000000..56352d1
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009-2010 Advanced Micro Devices, Inc.
+ * 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.
+ */
+
+#include "cpu/testers/directedtest/DirectedGenerator.hh"
+#include "cpu/testers/directedtest/RubyDirectedTester.hh"
+#include "mem/ruby/eventqueue/RubyEventQueue.hh"
+#include "sim/sim_exit.hh"
+
+RubyDirectedTester::RubyDirectedTester(const Params *p)
+  : MemObject(p), directedStartEvent(this),
+    m_requests_to_complete(p->requests_to_complete),
+    generator(p->generator)
+{
+    m_requests_completed = 0;
+
+    // add the check start event to the event queue
+    schedule(directedStartEvent, 1);
+}
+
+RubyDirectedTester::~RubyDirectedTester()
+{
+    for (int i = 0; i < ports.size(); i++)
+        delete ports[i];
+}
+
+void
+RubyDirectedTester::init()
+{
+    assert(ports.size() > 0);
+    generator->setDirectedTester(this);
+}
+
+Port *
+RubyDirectedTester::getPort(const std::string &if_name, int idx)
+{
+    if (if_name != "cpuPort") {
+        panic("RubyDirectedTester::getPort: unknown port %s requested", if_name);
+    }
+
+    if (idx >= (int)ports.size()) {
+        ports.resize(idx + 1);
+    }
+
+    if (ports[idx] != NULL) {
+        panic("RubyDirectedTester::getPort: port %d already assigned", idx);
+    }
+
+    CpuPort *port = new CpuPort(csprintf("%s-port%d", name(), idx), this, idx);
+
+    ports[idx] = port;
+    return port;
+}
+
+Tick
+RubyDirectedTester::CpuPort::recvAtomic(PacketPtr pkt)
+{
+    panic("RubyDirectedTester::CpuPort::recvAtomic() not implemented!\n");
+    return 0;
+}
+
+bool
+RubyDirectedTester::CpuPort::recvTiming(PacketPtr pkt)
+{
+    tester->hitCallback(idx, pkt->getAddr());
+    
+    //
+    // Now that the tester has completed, delete the packet, then return
+    //
+    delete pkt->req;
+    delete pkt;
+    return true;
+}
+
+Port*
+RubyDirectedTester::getCpuPort(int idx)
+{
+    assert(idx >= 0 && idx < ports.size());
+
+    return ports[idx];
+}
+
+void
+RubyDirectedTester::hitCallback(NodeID proc, Addr addr)
+{
+    DPRINTF(DirectedTest,
+            "completed request for proc: %d addr: 0x%x\n",
+            proc,
+            addr);
+
+    generator->performCallback(proc, addr);    
+    schedule(directedStartEvent, curTick);
+}
+
+void
+RubyDirectedTester::wakeup()
+{
+    if (m_requests_completed < m_requests_to_complete) {
+        if (!generator->initiate()) {
+            schedule(directedStartEvent, curTick + 1);
+        }
+    } else {
+        exitSimLoop("Ruby DirectedTester completed");
+    }
+}
+
+RubyDirectedTester *
+RubyDirectedTesterParams::create()
+{
+    return new RubyDirectedTester(this);
+}
diff --git a/src/cpu/testers/directedtest/RubyDirectedTester.hh b/src/cpu/testers/directedtest/RubyDirectedTester.hh
new file mode 100644 (file)
index 0000000..bd3989c
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009-2010 Advanced Micro Devices, Inc.
+ * 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.
+ */
+
+#ifndef __CPU_DIRECTEDTEST_RUBYDIRECTEDTESTER_HH__
+#define __CPU_DIRECTEDTEST_RUBYDIRECTEDTESTER_HH__
+
+#include <iostream>
+#include <vector>
+#include <string>
+
+#include "mem/mem_object.hh"
+#include "mem/packet.hh"
+#include "mem/ruby/common/DataBlock.hh"
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/common/SubBlock.hh"
+#include "mem/ruby/system/RubyPort.hh"
+#include "params/RubyDirectedTester.hh"
+
+class DirectedGenerator;
+
+class RubyDirectedTester : public MemObject
+{
+  public:
+    class CpuPort : public SimpleTimingPort
+    {
+      private:
+        RubyDirectedTester *tester;
+
+      public:
+        CpuPort(const std::string &_name, RubyDirectedTester *_tester, uint _idx)
+            : SimpleTimingPort(_name, _tester), tester(_tester), idx(_idx)
+        {}
+
+        uint idx;
+
+      protected:
+        virtual bool recvTiming(PacketPtr pkt);
+        virtual Tick recvAtomic(PacketPtr pkt);
+    };
+
+    typedef RubyDirectedTesterParams Params;
+    RubyDirectedTester(const Params *p);
+    ~RubyDirectedTester();
+
+    virtual Port *getPort(const std::string &if_name, int idx = -1);
+
+    Port* getCpuPort(int idx);
+
+    virtual void init();
+
+    void wakeup();
+
+    void incrementCycleCompletions() { m_requests_completed++; }
+
+    void printStats(std::ostream& out) const {}
+    void clearStats() {}
+    void printConfig(std::ostream& out) const {}
+
+    void print(std::ostream& out) const;
+
+  protected:
+    class DirectedStartEvent : public Event
+    {
+      private:
+        RubyDirectedTester *tester;
+
+      public:
+        DirectedStartEvent(RubyDirectedTester *_tester)
+            : Event(CPU_Tick_Pri), tester(_tester)
+        {}
+        void process() { tester->wakeup(); }
+        virtual const char *description() const { return "Directed tick"; }
+    };
+
+    DirectedStartEvent directedStartEvent;
+
+  private:
+    void hitCallback(NodeID proc, Addr addr);
+
+    void checkForDeadlock();
+
+    // Private copy constructor and assignment operator
+    RubyDirectedTester(const RubyDirectedTester& obj);
+    RubyDirectedTester& operator=(const RubyDirectedTester& obj);
+
+    uint64 m_requests_completed;
+    std::vector<CpuPort*> ports;
+    uint64 m_requests_to_complete;
+    DirectedGenerator* generator;
+};
+
+#endif // __CPU_DIRECTEDTEST_RUBYDIRECTEDTESTER_HH__
diff --git a/src/cpu/testers/directedtest/RubyDirectedTester.py b/src/cpu/testers/directedtest/RubyDirectedTester.py
new file mode 100644 (file)
index 0000000..af19705
--- /dev/null
@@ -0,0 +1,52 @@
+# Copyright (c) 2010 Advanced Micro Devices, Inc.
+# 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: Brad Beckmann
+
+from m5.SimObject import SimObject
+from MemObject import MemObject
+from m5.params import *
+from m5.proxy import *
+
+class DirectedGenerator(SimObject):
+    type = 'DirectedGenerator'
+    abstract = True
+    num_cpus = Param.Int("num of cpus")
+
+class SeriesRequestGenerator(DirectedGenerator):
+    type = 'SeriesRequestGenerator'
+    addr_increment_size = Param.Int(64, "address increment size")
+    issue_writes = Param.Bool(True, "issue writes if true, otherwise reads")
+
+class InvalidateGenerator(DirectedGenerator):
+    type = 'InvalidateGenerator'
+    addr_increment_size = Param.Int(64, "address increment size")
+
+class RubyDirectedTester(MemObject):
+    type = 'RubyDirectedTester'
+    cpuPort = VectorPort("the cpu ports")
+    requests_to_complete = Param.Int("checks to complete")
+    generator = Param.DirectedGenerator("the request generator")
diff --git a/src/cpu/testers/directedtest/SConscript b/src/cpu/testers/directedtest/SConscript
new file mode 100644 (file)
index 0000000..1afa159
--- /dev/null
@@ -0,0 +1,48 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2006 The Regents of The University of Michigan
+# Copyright (c) 2009-2010 Advanced Micro Devices, Inc.
+# 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.
+#
+
+Import('*')
+
+#
+# Currently the ruby testser relies on Ruby specific objects (SubBlock, etc.)
+# When this dependency is removed, the ruby tester should be compiled
+# independently from Ruby
+#
+if not env['RUBY']:
+    Return()
+
+SimObject('RubyDirectedTester.py')
+
+Source('RubyDirectedTester.cc')
+Source('DirectedGenerator.cc')
+Source('SeriesRequestGenerator.cc')
+Source('InvalidateGenerator.cc')
+
+TraceFlag('DirectedTest')
diff --git a/src/cpu/testers/directedtest/SeriesRequestGenerator.cc b/src/cpu/testers/directedtest/SeriesRequestGenerator.cc
new file mode 100644 (file)
index 0000000..5b6395f
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009-2010 Advanced Micro Devices, Inc.
+ * 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.
+ */
+
+#include "cpu/testers/directedtest/DirectedGenerator.hh"
+#include "cpu/testers/directedtest/RubyDirectedTester.hh"
+#include "cpu/testers/directedtest/SeriesRequestGenerator.hh"
+
+SeriesRequestGenerator::SeriesRequestGenerator(const Params *p)
+    : DirectedGenerator(p)
+{
+    m_status = SeriesRequestGeneratorStatus_Thinking;
+    m_active_node = 0;
+    m_address = 0x0;
+    m_addr_increment_size = p->addr_increment_size;
+    m_issue_writes = p->issue_writes;
+}
+
+SeriesRequestGenerator::~SeriesRequestGenerator()
+{
+}
+
+bool
+SeriesRequestGenerator::initiate()
+{
+    DPRINTF(DirectedTest, "initiating request\n");
+    assert(m_status == SeriesRequestGeneratorStatus_Thinking);
+
+    RubyDirectedTester::CpuPort* port =
+        safe_cast<RubyDirectedTester::CpuPort*>(m_directed_tester->
+                                              getCpuPort(m_active_node));
+
+    Request::Flags flags;
+
+    // For simplicity, requests are assumed to be 1 byte-sized
+    Request *req = new Request(m_address, 1, flags);
+
+    Packet::Command cmd;
+    if (m_issue_writes) {
+        cmd = MemCmd::WriteReq;
+    } else {
+        cmd = MemCmd::ReadReq;
+    }
+    PacketPtr pkt = new Packet(req, cmd, m_active_node);
+    uint8_t* dummyData = new uint8_t;
+    *dummyData = 0;
+    pkt->dataDynamic(dummyData);
+
+    if (port->sendTiming(pkt)) {
+        DPRINTF(DirectedTest, "initiating request - successful\n");
+        m_status = SeriesRequestGeneratorStatus_Request_Pending;
+        return true;
+    } else {
+        // If the packet did not issue, must delete
+        // Note: No need to delete the data, the packet destructor
+        // will delete it
+        delete pkt->req;
+        delete pkt;
+
+        DPRINTF(DirectedTest, "failed to initiate request - sequencer not ready\n");
+        return false;
+    }
+}
+
+void 
+SeriesRequestGenerator::performCallback(uint proc, Addr address)
+{
+    assert(m_active_node == proc);
+    assert(m_address == address);  
+    assert(m_status == SeriesRequestGeneratorStatus_Request_Pending);
+
+    m_status = SeriesRequestGeneratorStatus_Thinking;
+    m_active_node++;
+    if (m_active_node == m_num_cpus) {
+        //
+        // Cycle of requests completed, increment cycle completions and restart
+        // at cpu zero
+        //
+        m_directed_tester->incrementCycleCompletions();
+        m_address += m_addr_increment_size;
+        m_active_node = 0;
+    }
+}
+
+SeriesRequestGenerator *
+SeriesRequestGeneratorParams::create()
+{
+    return new SeriesRequestGenerator(this);
+}
diff --git a/src/cpu/testers/directedtest/SeriesRequestGenerator.hh b/src/cpu/testers/directedtest/SeriesRequestGenerator.hh
new file mode 100644 (file)
index 0000000..97b632a
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+//
+// This Deterministic Generator generates GETX requests for all nodes in the 
+// system.  The GETX requests are generated one at a time in round-robin fashion
+// 0...1...2...etc.
+//
+
+#ifndef __CPU_DIRECTEDTEST_SERIESREQUESTGENERATOR_HH__
+#define __CPU_DIRECTEDTEST_SERIESREQUESTGENERATOR_HH__
+
+#include "cpu/testers/directedtest/DirectedGenerator.hh"
+#include "cpu/testers/directedtest/RubyDirectedTester.hh"
+#include "mem/protocol/SeriesRequestGeneratorStatus.hh"
+#include "params/SeriesRequestGenerator.hh"
+
+class SeriesRequestGenerator : public DirectedGenerator 
+{
+  public:
+    typedef SeriesRequestGeneratorParams Params;
+    SeriesRequestGenerator(const Params *p);
+    
+    ~SeriesRequestGenerator();
+    
+    bool initiate();
+    void performCallback(uint proc, Addr address);
+    
+  private:
+    SeriesRequestGeneratorStatus m_status;
+    Addr m_address;
+    uint m_active_node;
+    uint m_addr_increment_size;
+    bool m_issue_writes;
+};
+
+#endif //__CPU_DIRECTEDTEST_SERIESREQUESTGENERATOR_HH__
+
diff --git a/src/cpu/testers/memtest/MemTest.py b/src/cpu/testers/memtest/MemTest.py
new file mode 100644 (file)
index 0000000..957de80
--- /dev/null
@@ -0,0 +1,52 @@
+# Copyright (c) 2005-2007 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: Nathan Binkert
+
+from MemObject import MemObject
+from m5.params import *
+from m5.proxy import *
+
+class MemTest(MemObject):
+    type = 'MemTest'
+    max_loads = Param.Counter(0, "number of loads to execute")
+    atomic = Param.Bool(False, "Execute tester in atomic mode? (or timing)\n")
+    memory_size = Param.Int(65536, "memory size")
+    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")
+    percent_uncacheable = Param.Percent(10,
+        "target uncacheable percentage")
+    progress_interval = Param.Counter(1000000,
+        "progress report interval (in accesses)")
+    trace_addr = Param.Addr(0, "address to trace")
+
+    test = Port("Port to the memory system to test")
+    functional = Port("Port to the functional memory used for verification")
diff --git a/src/cpu/testers/memtest/SConscript b/src/cpu/testers/memtest/SConscript
new file mode 100644 (file)
index 0000000..61aa096
--- /dev/null
@@ -0,0 +1,38 @@
+# -*- mode:python -*-
+
+# 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: Nathan Binkert
+
+Import('*')
+
+#if 'O3CPU' in env['CPU_MODELS']:
+SimObject('MemTest.py')
+
+Source('memtest.cc')
+
+TraceFlag('MemTest')
diff --git a/src/cpu/testers/memtest/memtest.cc b/src/cpu/testers/memtest/memtest.cc
new file mode 100644 (file)
index 0000000..7a8e4cc
--- /dev/null
@@ -0,0 +1,434 @@
+/*
+ * Copyright (c) 2002-2005 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: Erik Hallnor
+ *          Steve Reinhardt
+ */
+
+// FIX ME: make trackBlkAddr use blocksize from actual cache, not hard coded
+
+#include <iomanip>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "base/misc.hh"
+#include "base/statistics.hh"
+#include "cpu/testers/memtest/memtest.hh"
+#include "mem/mem_object.hh"
+#include "mem/port.hh"
+#include "mem/packet.hh"
+#include "mem/request.hh"
+#include "sim/sim_events.hh"
+#include "sim/stats.hh"
+
+using namespace std;
+
+int TESTER_ALLOCATOR=0;
+
+bool
+MemTest::CpuPort::recvTiming(PacketPtr pkt)
+{
+    if (pkt->isResponse()) {
+        memtest->completeRequest(pkt);
+    } else {
+        // must be snoop upcall
+        assert(pkt->isRequest());
+        assert(pkt->getDest() == Packet::Broadcast);
+    }
+    return true;
+}
+
+Tick
+MemTest::CpuPort::recvAtomic(PacketPtr pkt)
+{
+    // must be snoop upcall
+    assert(pkt->isRequest());
+    assert(pkt->getDest() == Packet::Broadcast);
+    return curTick;
+}
+
+void
+MemTest::CpuPort::recvFunctional(PacketPtr pkt)
+{
+    //Do nothing if we see one come through
+//    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;
+}
+
+void
+MemTest::CpuPort::recvStatusChange(Status status)
+{
+    if (status == RangeChange) {
+        if (!snoopRangeSent) {
+            snoopRangeSent = true;
+            sendStatusChange(Port::RangeChange);
+        }
+        return;
+    }
+
+    panic("MemTest doesn't expect recvStatusChange callback!");
+}
+
+void
+MemTest::CpuPort::recvRetry()
+{
+    memtest->doRetry();
+}
+
+void
+MemTest::sendPkt(PacketPtr pkt) {
+    if (atomic) {
+        cachePort.sendAtomic(pkt);
+        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;
+        }
+    }
+
+}
+
+MemTest::MemTest(const Params *p)
+    : MemObject(p),
+      tickEvent(this),
+      cachePort("test", this),
+      funcPort("functional", this),
+      retryPkt(NULL),
+//      mainMem(main_mem),
+//      checkMem(check_mem),
+      size(p->memory_size),
+      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),
+      percentDestUnaligned(p->percent_dest_unaligned),
+      maxLoads(p->max_loads),
+      atomic(p->atomic)
+{
+    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;
+
+    id = TESTER_ALLOCATOR++;
+
+    // Needs to be masked off once we know the block size.
+    traceBlockAddr = p->trace_addr;
+    baseAddr1 = 0x100000;
+    baseAddr2 = 0x400000;
+    uncacheAddr = 0x800000;
+
+    // set up counters
+    noResponseCycles = 0;
+    numReads = 0;
+    schedule(tickEvent, 0);
+
+    accessRetry = false;
+    dmaOutstanding = false;
+}
+
+Port *
+MemTest::getPort(const std::string &if_name, int idx)
+{
+    if (if_name == "functional")
+        return &funcPort;
+    else if (if_name == "test")
+        return &cachePort;
+    else
+        panic("No Such Port\n");
+}
+
+void
+MemTest::init()
+{
+    // By the time init() is called, the ports should be hooked up.
+    blockSize = cachePort.peerBlockSize();
+    blockAddrMask = blockSize - 1;
+    traceBlockAddr = blockAddr(traceBlockAddr);
+
+    // initial memory contents for both physical memory and functional
+    // memory should be 0; no need to initialize them.
+}
+
+
+void
+MemTest::completeRequest(PacketPtr pkt)
+{
+    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()));
+
+    MemTestSenderState *state =
+        dynamic_cast<MemTestSenderState *>(pkt->senderState);
+
+    uint8_t *data = state->data;
+    uint8_t *pkt_data = pkt->getPtr<uint8_t>();
+
+    //Remove the address from the list of outstanding
+    std::set<unsigned>::iterator removeAddr =
+        outstandingAddrs.find(req->getPaddr());
+    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);
+        }
+
+        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++;
+    }
+
+    noResponseCycles = 0;
+    delete state;
+    delete [] data;
+    delete pkt->req;
+    delete pkt;
+}
+
+void
+MemTest::regStats()
+{
+    using namespace Stats;
+
+    numReadsStat
+        .name(name() + ".num_reads")
+        .desc("number of read accesses completed")
+        ;
+
+    numWritesStat
+        .name(name() + ".num_writes")
+        .desc("number of write accesses completed")
+        ;
+
+    numCopiesStat
+        .name(name() + ".num_copies")
+        .desc("number of copy accesses completed")
+        ;
+}
+
+void
+MemTest::tick()
+{
+    if (!tickEvent.scheduled())
+        schedule(tickEvent, curTick + ticks(1));
+
+    if (++noResponseCycles >= 500000) {
+        if (issueDmas) {
+            cerr << "DMA tester ";
+        }
+        cerr << name() << ": deadlocked at cycle " << curTick << endl;
+        fatal("");
+    }
+
+    if (accessRetry || (issueDmas && dmaOutstanding)) {
+        DPRINTF(MemTest, "MemTester waiting on accessRetry or DMA response\n");
+        return;
+    }
+
+    //make new request
+    unsigned cmd = random() % 100;
+    unsigned offset = random() % size;
+    unsigned base = random() % 2;
+    uint64_t data = random();
+    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
+    //to offset within the blks
+    offset = blockAddr(offset);
+    offset += id;
+    access_size = 0;
+    dma_access_size = 0;
+
+    Request *req = new Request();
+    Request::Flags flags;
+    Addr paddr;
+
+    if (uncacheable) {
+        flags.set(Request::UNCACHEABLE);
+        paddr = uncacheAddr + offset;
+    } else  {
+        paddr = ((base) ? baseAddr1 : baseAddr2) + offset;
+    }
+    bool probe = (random() % 100 < percentFunctional) && !uncacheable;
+
+    if (issueDmas) {
+        paddr &= ~((1 << dma_access_size) - 1);
+        req->setPhys(paddr, 1 << dma_access_size, flags);
+        req->setThreadContext(id,0);
+    } else {
+        paddr &= ~((1 << access_size) - 1);
+        req->setPhys(paddr, 1 << access_size, flags);
+        req->setThreadContext(id,0);
+    }
+    assert(req->getSize() == 1);
+
+    uint8_t *result = new uint8_t[8];
+
+    if (cmd < percentReads) {
+        // read
+
+        // For now we only allow one outstanding request per address
+        // per tester This means we assume CPU does write forwarding
+        // to reads that alias something in the cpu store buffer.
+        if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) {
+            delete [] result;
+            delete req;
+            return;
+        }
+
+        outstandingAddrs.insert(paddr);
+
+        // ***** NOTE FOR RON: I'm not sure how to access checkMem. - Kevin
+        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);
+
+        PacketPtr pkt = new Packet(req, MemCmd::ReadReq, Packet::Broadcast);
+        pkt->setSrc(0);
+        pkt->dataDynamicArray(new uint8_t[req->getSize()]);
+        MemTestSenderState *state = new MemTestSenderState(result);
+        pkt->senderState = state;
+
+        if (probe) {
+            cachePort.sendFunctional(pkt);
+            completeRequest(pkt);
+        } else {
+            sendPkt(pkt);
+        }
+    } else {
+        // write
+
+        // For now we only allow one outstanding request per addreess
+        // per tester.  This means we assume CPU does write forwarding
+        // to reads that alias something in the cpu store buffer.
+        if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) {
+            delete [] result;
+            delete req;
+            return;
+        }
+
+        outstandingAddrs.insert(paddr);
+
+        DPRINTF(MemTest, "initiating write at address %x (blk %x) value %x\n",
+                req->getPaddr(), blockAddr(req->getPaddr()), data & 0xff);
+
+        PacketPtr pkt = new Packet(req, MemCmd::WriteReq, Packet::Broadcast);
+        pkt->setSrc(0);
+        uint8_t *pkt_data = new uint8_t[req->getSize()];
+        pkt->dataDynamicArray(pkt_data);
+        memcpy(pkt_data, &data, req->getSize());
+        MemTestSenderState *state = new MemTestSenderState(result);
+        pkt->senderState = state;
+
+        funcPort.writeBlob(req->getPaddr(), pkt_data, req->getSize());
+
+        if (probe) {
+            cachePort.sendFunctional(pkt);
+            completeRequest(pkt);
+        } else {
+            sendPkt(pkt);
+        }
+    }
+}
+
+void
+MemTest::doRetry()
+{
+    if (cachePort.sendTiming(retryPkt)) {
+        DPRINTF(MemTest, "accessRetry setting to false\n");
+        accessRetry = false;
+        retryPkt = NULL;
+    }
+}
+
+
+void
+MemTest::printAddr(Addr a)
+{
+    cachePort.printAddr(a);
+}
+
+
+MemTest *
+MemTestParams::create()
+{
+    return new MemTest(this);
+}
diff --git a/src/cpu/testers/memtest/memtest.hh b/src/cpu/testers/memtest/memtest.hh
new file mode 100644 (file)
index 0000000..bb71da3
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2002-2005 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: Erik Hallnor
+ *          Steve Reinhardt
+ */
+
+#ifndef __CPU_MEMTEST_MEMTEST_HH__
+#define __CPU_MEMTEST_MEMTEST_HH__
+
+#include <set>
+
+#include "base/statistics.hh"
+#include "base/fast_alloc.hh"
+#include "params/MemTest.hh"
+#include "sim/eventq.hh"
+#include "sim/sim_exit.hh"
+#include "sim/sim_object.hh"
+#include "sim/stats.hh"
+#include "mem/mem_object.hh"
+#include "mem/port.hh"
+
+class Packet;
+class MemTest : public MemObject
+{
+  public:
+    typedef MemTestParams Params;
+    MemTest(const Params *p);
+
+    virtual void init();
+
+    // register statistics
+    virtual void regStats();
+
+    inline Tick ticks(int numCycles) const { return numCycles; }
+
+    // main simulation loop (one cycle)
+    void tick();
+
+    virtual Port *getPort(const std::string &if_name, int idx = -1);
+
+    /**
+     * Print state of address in memory system via PrintReq (for
+     * debugging).
+     */
+    void printAddr(Addr a);
+
+  protected:
+    class TickEvent : public Event
+    {
+      private:
+        MemTest *cpu;
+
+      public:
+        TickEvent(MemTest *c) : Event(CPU_Tick_Pri), cpu(c) {}
+        void process() { cpu->tick(); }
+        virtual const char *description() const { return "MemTest tick"; }
+    };
+
+    TickEvent tickEvent;
+
+    class CpuPort : public Port
+    {
+        MemTest *memtest;
+
+      public:
+
+        CpuPort(const std::string &_name, MemTest *_memtest)
+            : Port(_name, _memtest), memtest(_memtest)
+        { }
+
+        bool snoopRangeSent;
+
+      protected:
+
+        virtual bool recvTiming(PacketPtr pkt);
+
+        virtual Tick recvAtomic(PacketPtr pkt);
+
+        virtual void recvFunctional(PacketPtr pkt);
+
+        virtual void recvStatusChange(Status status);
+
+        virtual void recvRetry();
+
+        virtual void getDeviceAddressRanges(AddrRangeList &resp,
+                                            bool &snoop)
+        { resp.clear(); snoop = false; }
+    };
+
+    CpuPort cachePort;
+    CpuPort funcPort;
+
+    bool snoopRangeSent;
+
+    class MemTestSenderState : public Packet::SenderState, public FastAlloc
+    {
+      public:
+        /** Constructor. */
+        MemTestSenderState(uint8_t *_data)
+            : data(_data)
+        { }
+
+        // Hold onto data pointer
+        uint8_t *data;
+    };
+
+    PacketPtr retryPkt;
+
+    bool accessRetry;
+    
+    //
+    // The dmaOustanding flag enforces only one dma at a time
+    //
+    bool dmaOutstanding;
+
+    unsigned size;              // size of testing memory region
+
+    unsigned percentReads;      // target percentage of read accesses
+    unsigned percentFunctional; // target percentage of functional accesses
+    unsigned percentUncacheable;
+
+    bool issueDmas;
+
+    int id;
+
+    std::set<unsigned> outstandingAddrs;
+
+    unsigned blockSize;
+
+    Addr blockAddrMask;
+
+    Addr blockAddr(Addr addr)
+    {
+        return (addr & ~blockAddrMask);
+    }
+
+    Addr traceBlockAddr;
+
+    Addr baseAddr1;             // fix this to option
+    Addr baseAddr2;             // fix this to option
+    Addr uncacheAddr;
+
+    unsigned progressInterval;  // frequency of progress reports
+    Tick nextProgressMessage;   // access # for next progress report
+
+    unsigned percentSourceUnaligned;
+    unsigned percentDestUnaligned;
+
+    Tick noResponseCycles;
+
+    uint64_t numReads;
+    uint64_t maxLoads;
+
+    bool atomic;
+
+    Stats::Scalar numReadsStat;
+    Stats::Scalar numWritesStat;
+    Stats::Scalar numCopiesStat;
+
+    // called by MemCompleteEvent::process()
+    void completeRequest(PacketPtr pkt);
+
+    void sendPkt(PacketPtr pkt);
+
+    void doRetry();
+
+    friend class MemCompleteEvent;
+};
+
+#endif // __CPU_MEMTEST_MEMTEST_HH__
+
+
+
diff --git a/src/cpu/testers/rubytest/Check.cc b/src/cpu/testers/rubytest/Check.cc
new file mode 100644 (file)
index 0000000..9ace655
--- /dev/null
@@ -0,0 +1,356 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009 Advanced Micro Devices, Inc.
+ * 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.
+ */
+
+#include "cpu/testers/rubytest/Check.hh"
+#include "mem/ruby/common/SubBlock.hh"
+#include "mem/ruby/system/Sequencer.hh"
+#include "mem/ruby/system/System.hh"
+
+typedef RubyTester::SenderState SenderState;
+
+Check::Check(const Address& address, const Address& pc,
+             int _num_cpu_sequencers, RubyTester* _tester)
+    : m_num_cpu_sequencers(_num_cpu_sequencers), m_tester_ptr(_tester)
+{
+    m_status = TesterStatus_Idle;
+
+    pickValue();
+    pickInitiatingNode();
+    changeAddress(address);
+    m_pc = pc;
+    m_access_mode = AccessModeType(random() % AccessModeType_NUM);
+    m_store_count = 0;
+}
+
+void
+Check::initiate()
+{
+    DPRINTF(RubyTest, "initiating\n");
+    debugPrint();
+
+    // currently no protocols support prefetches
+    if (false && (random() & 0xf) == 0) {
+        initiatePrefetch(); // Prefetch from random processor
+    }
+
+    if (m_status == TesterStatus_Idle) {
+        initiateAction();
+    } else if (m_status == TesterStatus_Ready) {
+        initiateCheck();
+    } else {
+        // Pending - do nothing
+        DPRINTF(RubyTest,
+                "initiating action/check - failed: action/check is pending\n");
+    }
+}
+
+void
+Check::initiatePrefetch()
+{
+    DPRINTF(RubyTest, "initiating prefetch\n");
+
+    int index = random() % m_num_cpu_sequencers;
+    RubyTester::CpuPort* port =
+        safe_cast<RubyTester::CpuPort*>(m_tester_ptr->getCpuPort(index));
+
+    Request::Flags flags;
+    flags.set(Request::PREFETCH);
+
+    Packet::Command cmd;
+
+    // 1 in 8 chance this will be an exclusive prefetch
+    if ((random() & 0x7) != 0) {
+        cmd = MemCmd::ReadReq;
+
+        // 50% chance that the request will be an instruction fetch
+        if ((random() & 0x1) == 0) {
+            flags.set(Request::INST_FETCH);
+        }
+    } else {
+        cmd = MemCmd::WriteReq;
+        flags.set(Request::PF_EXCLUSIVE);
+    }
+
+    // Prefetches are assumed to be 0 sized
+    Request *req = new Request(m_address.getAddress(), 0, flags, curTick,
+                               m_pc.getAddress());
+
+    PacketPtr pkt = new Packet(req, cmd, port->idx);
+
+    // push the subblock onto the sender state.  The sequencer will
+    // update the subblock on the return
+    pkt->senderState =
+        new SenderState(m_address, req->getSize(), pkt->senderState);
+
+    if (port->sendTiming(pkt)) {
+        DPRINTF(RubyTest, "successfully initiated prefetch.\n");
+    } else {
+        // If the packet did not issue, must delete
+        SenderState* senderState =  safe_cast<SenderState*>(pkt->senderState);
+        pkt->senderState = senderState->saved;
+        delete senderState;
+        delete pkt->req;
+        delete pkt;
+
+        DPRINTF(RubyTest,
+                "prefetch initiation failed because Port was busy.\n");
+    }
+}
+
+void
+Check::initiateAction()
+{
+    DPRINTF(RubyTest, "initiating Action\n");
+    assert(m_status == TesterStatus_Idle);
+
+    int index = random() % m_num_cpu_sequencers;
+    RubyTester::CpuPort* port =
+        safe_cast<RubyTester::CpuPort*>(m_tester_ptr->getCpuPort(index));
+
+    Request::Flags flags;
+
+    // Create the particular address for the next byte to be written
+    Address writeAddr(m_address.getAddress() + m_store_count);
+
+    // Stores are assumed to be 1 byte-sized
+    Request *req = new Request(writeAddr.getAddress(), 1, flags, curTick,
+                               m_pc.getAddress());
+
+    Packet::Command cmd;
+
+    // 1 out of 8 chance, issue an atomic rather than a write
+    // if ((random() & 0x7) == 0) {
+    //     cmd = MemCmd::SwapReq;
+    // } else {
+    cmd = MemCmd::WriteReq;
+    // }
+
+    PacketPtr pkt = new Packet(req, cmd, port->idx);
+    uint8_t* writeData = new uint8_t;
+    *writeData = m_value + m_store_count;
+    pkt->dataDynamic(writeData);
+
+    DPRINTF(RubyTest, "data 0x%x check 0x%x\n",
+            *(pkt->getPtr<uint8_t>()), *writeData);
+
+    // push the subblock onto the sender state.  The sequencer will
+    // update the subblock on the return
+    pkt->senderState =
+        new SenderState(writeAddr, req->getSize(), pkt->senderState);
+
+    if (port->sendTiming(pkt)) {
+        DPRINTF(RubyTest, "initiating action - successful\n");
+        DPRINTF(RubyTest, "status before action update: %s\n",
+                (TesterStatus_to_string(m_status)).c_str());
+        m_status = TesterStatus_Action_Pending;
+    } else {
+        // If the packet did not issue, must delete
+        // Note: No need to delete the data, the packet destructor
+        // will delete it
+        SenderState* senderState = safe_cast<SenderState*>(pkt->senderState);
+        pkt->senderState = senderState->saved;
+        delete senderState;
+        delete pkt->req;
+        delete pkt;
+
+        DPRINTF(RubyTest, "failed to initiate action - sequencer not ready\n");
+    }
+
+    DPRINTF(RubyTest, "status after action update: %s\n",
+            (TesterStatus_to_string(m_status)).c_str());
+}
+
+void
+Check::initiateCheck()
+{
+    DPRINTF(RubyTest, "Initiating Check\n");
+    assert(m_status == TesterStatus_Ready);
+
+    int index = random() % m_num_cpu_sequencers;
+    RubyTester::CpuPort* port =
+        safe_cast<RubyTester::CpuPort*>(m_tester_ptr->getCpuPort(index));
+
+    Request::Flags flags;
+
+    // 50% chance that the request will be an instruction fetch
+    if ((random() & 0x1) == 0) {
+        flags.set(Request::INST_FETCH);
+    }
+
+    // Checks are sized depending on the number of bytes written
+    Request *req = new Request(m_address.getAddress(), CHECK_SIZE, flags,
+                               curTick, m_pc.getAddress());
+
+    PacketPtr pkt = new Packet(req, MemCmd::ReadReq, port->idx);
+    uint8_t* dataArray = new uint8_t[CHECK_SIZE];
+    pkt->dataDynamicArray(dataArray);
+
+    // push the subblock onto the sender state.  The sequencer will
+    // update the subblock on the return
+    pkt->senderState =
+        new SenderState(m_address, req->getSize(), pkt->senderState);
+
+    if (port->sendTiming(pkt)) {
+        DPRINTF(RubyTest, "initiating check - successful\n");
+        DPRINTF(RubyTest, "status before check update: %s\n",
+                TesterStatus_to_string(m_status).c_str());
+        m_status = TesterStatus_Check_Pending;
+    } else {
+        // If the packet did not issue, must delete
+        // Note: No need to delete the data, the packet destructor
+        // will delete it
+        SenderState* senderState = safe_cast<SenderState*>(pkt->senderState);
+        pkt->senderState = senderState->saved;
+        delete senderState;
+        delete pkt->req;
+        delete pkt;
+
+        DPRINTF(RubyTest, "failed to initiate check - cpu port not ready\n");
+    }
+
+    DPRINTF(RubyTest, "status after check update: %s\n",
+            TesterStatus_to_string(m_status).c_str());
+}
+
+void
+Check::performCallback(NodeID proc, SubBlock* data)
+{
+    Address address = data->getAddress();
+
+    // This isn't exactly right since we now have multi-byte checks
+    //  assert(getAddress() == address);
+
+    assert(getAddress().getLineAddress() == address.getLineAddress());
+    assert(data != NULL);
+
+    DPRINTF(RubyTest, "RubyTester Callback\n");
+    debugPrint();
+
+    if (m_status == TesterStatus_Action_Pending) {
+        DPRINTF(RubyTest, "Action callback write value: %d, currently %d\n",
+                (m_value + m_store_count), data->getByte(0));
+        // Perform store one byte at a time
+        data->setByte(0, (m_value + m_store_count));
+        m_store_count++;
+        if (m_store_count == CHECK_SIZE) {
+            m_status = TesterStatus_Ready;
+        } else {
+            m_status = TesterStatus_Idle;
+        }
+        DPRINTF(RubyTest, "Action callback return data now %d\n",
+                data->getByte(0));
+    } else if (m_status == TesterStatus_Check_Pending) {
+        DPRINTF(RubyTest, "Check callback\n");
+        // Perform load/check
+        for (int byte_number=0; byte_number<CHECK_SIZE; byte_number++) {
+            if (uint8(m_value + byte_number) != data->getByte(byte_number)) {
+                WARN_EXPR(proc);
+                WARN_EXPR(address);
+                WARN_EXPR(data);
+                WARN_EXPR(byte_number);
+                WARN_EXPR((int)m_value + byte_number);
+                WARN_EXPR((int)data->getByte(byte_number));
+                WARN_EXPR(*this);
+                WARN_EXPR(g_eventQueue_ptr->getTime());
+                ERROR_MSG("Action/check failure");
+            }
+        }
+        DPRINTF(RubyTest, "Action/check success\n");
+        debugPrint();
+
+        // successful check complete, increment complete
+        m_tester_ptr->incrementCheckCompletions();
+
+        m_status = TesterStatus_Idle;
+        pickValue();
+
+    } else {
+        WARN_EXPR(*this);
+        WARN_EXPR(proc);
+        WARN_EXPR(data);
+        WARN_EXPR(m_status);
+        WARN_EXPR(g_eventQueue_ptr->getTime());
+        ERROR_MSG("Unexpected TesterStatus");
+    }
+
+    DPRINTF(RubyTest, "proc: %d, Address: 0x%x\n", proc,
+            getAddress().getLineAddress());
+    DPRINTF(RubyTest, "Callback done\n");
+    debugPrint();
+}
+
+void
+Check::changeAddress(const Address& address)
+{
+    assert(m_status == TesterStatus_Idle || m_status == TesterStatus_Ready);
+    m_status = TesterStatus_Idle;
+    m_address = address;
+    m_store_count = 0;
+}
+
+void
+Check::pickValue()
+{
+    assert(m_status == TesterStatus_Idle);
+    m_status = TesterStatus_Idle;
+    m_value = random() & 0xff; // One byte
+    m_store_count = 0;
+}
+
+void
+Check::pickInitiatingNode()
+{
+    assert(m_status == TesterStatus_Idle || m_status == TesterStatus_Ready);
+    m_status = TesterStatus_Idle;
+    m_initiatingNode = (random() % m_num_cpu_sequencers);
+    DPRINTF(RubyTest, "picked initiating node %d\n", m_initiatingNode);
+    m_store_count = 0;
+}
+
+void
+Check::print(std::ostream& out) const
+{
+    out << "["
+        << m_address << ", value: "
+        << (int)m_value << ", status: "
+        << m_status << ", initiating node: "
+        << m_initiatingNode << ", store_count: "
+        << m_store_count
+        << "]" << std::flush;
+}
+
+void
+Check::debugPrint()
+{
+    DPRINTF(RubyTest,
+        "[%#x, value: %d, status: %s, initiating node: %d, store_count: %d]\n",
+        m_address.getAddress(), (int)m_value,
+        TesterStatus_to_string(m_status).c_str(),
+        m_initiatingNode, m_store_count);
+}
diff --git a/src/cpu/testers/rubytest/Check.hh b/src/cpu/testers/rubytest/Check.hh
new file mode 100644 (file)
index 0000000..1ce795a
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009 Advanced Micro Devices, Inc.
+ * 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.
+ */
+
+#ifndef __CPU_RUBYTEST_CHECK_HH__
+#define __CPU_RUBYTEST_CHECK_HH__
+
+#include <iostream>
+
+#include "cpu/testers/rubytest/RubyTester.hh"
+#include "mem/protocol/AccessModeType.hh"
+#include "mem/protocol/TesterStatus.hh"
+#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/system/NodeID.hh"
+
+class SubBlock;
+
+const int CHECK_SIZE_BITS = 2;
+const int CHECK_SIZE = (1 << CHECK_SIZE_BITS);
+
+class Check
+{
+  public:
+    Check(const Address& address, const Address& pc, int _num_cpu_sequencer,
+          RubyTester* _tester);
+
+    void initiate(); // Does Action or Check or nether
+    void performCallback(NodeID proc, SubBlock* data);
+    const Address& getAddress() { return m_address; }
+    void changeAddress(const Address& address);
+
+    void print(std::ostream& out) const;
+
+  private:
+    void initiatePrefetch();
+    void initiateAction();
+    void initiateCheck();
+
+    void pickValue();
+    void pickInitiatingNode();
+
+    void debugPrint();
+
+    TesterStatus m_status;
+    uint8 m_value;
+    int m_store_count;
+    NodeID m_initiatingNode;
+    Address m_address;
+    Address m_pc;
+    AccessModeType m_access_mode;
+    int m_num_cpu_sequencers;
+    RubyTester* m_tester_ptr;
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, const Check& obj)
+{
+    obj.print(out);
+    out << std::flush;
+    return out;
+}
+
+#endif // __CPU_RUBYTEST_CHECK_HH__
diff --git a/src/cpu/testers/rubytest/CheckTable.cc b/src/cpu/testers/rubytest/CheckTable.cc
new file mode 100644 (file)
index 0000000..728ad03
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009 Advanced Micro Devices, Inc.
+ * 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.
+ */
+
+#include "base/intmath.hh"
+#include "cpu/testers/rubytest/Check.hh"
+#include "cpu/testers/rubytest/CheckTable.hh"
+#include "cpu/testers/rubytest/CheckTable.hh"
+
+CheckTable::CheckTable(int _num_cpu_sequencers, RubyTester* _tester)
+    : m_num_cpu_sequencers(_num_cpu_sequencers), m_tester_ptr(_tester)
+{
+    physical_address_t physical = 0;
+    Address address;
+
+    const int size1 = 32;
+    const int size2 = 100;
+
+    // The first set is to get some false sharing
+    physical = 1000;
+    for (int i = 0; i < size1; i++) {
+        // Setup linear addresses
+        address.setAddress(physical);
+        addCheck(address);
+        physical += CHECK_SIZE;
+    }
+
+    // The next two sets are to get some limited false sharing and
+    // cache conflicts
+    physical = 1000;
+    for (int i = 0; i < size2; i++) {
+        // Setup linear addresses
+        address.setAddress(physical);
+        addCheck(address);
+        physical += 256;
+    }
+
+    physical = 1000 + CHECK_SIZE;
+    for (int i = 0; i < size2; i++) {
+        // Setup linear addresses
+        address.setAddress(physical);
+        addCheck(address);
+        physical += 256;
+    }
+}
+
+CheckTable::~CheckTable()
+{
+    int size = m_check_vector.size();
+    for (int i = 0; i < size; i++)
+        delete m_check_vector[i];
+}
+
+void
+CheckTable::addCheck(const Address& address)
+{
+    if (floorLog2(CHECK_SIZE) != 0) {
+        if (address.bitSelect(0, CHECK_SIZE_BITS - 1) != 0) {
+            ERROR_MSG("Check not aligned");
+        }
+    }
+
+    for (int i = 0; i < CHECK_SIZE; i++) {
+        if (m_lookup_map.count(Address(address.getAddress()+i))) {
+            // A mapping for this byte already existed, discard the
+            // entire check
+            return;
+        }
+    }
+
+    Check* check_ptr = new Check(address, Address(100 + m_check_vector.size()),
+                                 m_num_cpu_sequencers, m_tester_ptr);
+    for (int i = 0; i < CHECK_SIZE; i++) {
+        // Insert it once per byte
+        m_lookup_map[Address(address.getAddress() + i)] = check_ptr;
+    }
+    m_check_vector.push_back(check_ptr);
+}
+
+Check*
+CheckTable::getRandomCheck()
+{
+    return m_check_vector[random() % m_check_vector.size()];
+}
+
+Check*
+CheckTable::getCheck(const Address& address)
+{
+    DEBUG_MSG(TESTER_COMP, MedPrio, "Looking for check by address");
+    DEBUG_EXPR(TESTER_COMP, MedPrio, address);
+
+    m5::hash_map<Address, Check*>::iterator i = m_lookup_map.find(address);
+
+    if (i == m_lookup_map.end())
+        return NULL;
+
+    Check* check = i->second;
+    assert(check != NULL);
+    return check;
+}
+
+void
+CheckTable::print(std::ostream& out) const
+{
+}
diff --git a/src/cpu/testers/rubytest/CheckTable.hh b/src/cpu/testers/rubytest/CheckTable.hh
new file mode 100644 (file)
index 0000000..5a4ead3
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009 Advanced Micro Devices, Inc.
+ * 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.
+ */
+
+#ifndef __CPU_RUBYTEST_CHECKTABLE_HH__
+#define __CPU_RUBYTEST_CHECKTABLE_HH__
+
+#include <iostream>
+#include <vector>
+
+#include "base/hashmap.hh"
+#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/common/Global.hh"
+
+class Check;
+class RubyTester;
+
+class CheckTable
+{
+  public:
+    CheckTable(int _num_cpu_sequencers, RubyTester* _tester);
+    ~CheckTable();
+
+    Check* getRandomCheck();
+    Check* getCheck(const Address& address);
+
+    //  bool isPresent(const Address& address) const;
+    //  void removeCheckFromTable(const Address& address);
+    //  bool isTableFull() const;
+    // Need a method to select a check or retrieve a check
+
+    void print(std::ostream& out) const;
+
+  private:
+    void addCheck(const Address& address);
+
+    // Private copy constructor and assignment operator
+    CheckTable(const CheckTable& obj);
+    CheckTable& operator=(const CheckTable& obj);
+
+    std::vector<Check*> m_check_vector;
+    m5::hash_map<Address, Check*> m_lookup_map;
+
+    int m_num_cpu_sequencers;
+    RubyTester* m_tester_ptr;
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, const CheckTable& obj)
+{
+    obj.print(out);
+    out << std::flush;
+    return out;
+}
+
+#endif // __CPU_RUBYTEST_CHECKTABLE_HH__
diff --git a/src/cpu/testers/rubytest/RubyTester.cc b/src/cpu/testers/rubytest/RubyTester.cc
new file mode 100644 (file)
index 0000000..516d6ae
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009 Advanced Micro Devices, Inc.
+ * 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.
+ */
+
+#include "cpu/testers/rubytest/Check.hh"
+#include "cpu/testers/rubytest/RubyTester.hh"
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/common/SubBlock.hh"
+#include "mem/ruby/eventqueue/RubyEventQueue.hh"
+#include "mem/ruby/system/System.hh"
+#include "sim/sim_exit.hh"
+
+RubyTester::RubyTester(const Params *p)
+  : MemObject(p), checkStartEvent(this),
+    m_checks_to_complete(p->checks_to_complete),
+    m_deadlock_threshold(p->deadlock_threshold),
+    m_wakeup_frequency(p->wakeup_frequency)
+{
+    m_checks_completed = 0;
+
+    // add the check start event to the event queue
+    schedule(checkStartEvent, 1);
+}
+
+RubyTester::~RubyTester()
+{
+    delete m_checkTable_ptr;
+    for (int i = 0; i < ports.size(); i++)
+        delete ports[i];
+}
+
+void
+RubyTester::init()
+{
+    assert(ports.size() > 0);
+
+    m_last_progress_vector.resize(ports.size());
+    for (int i = 0; i < m_last_progress_vector.size(); i++) {
+        m_last_progress_vector[i] = 0;
+    }
+
+    m_num_cpu_sequencers = ports.size();
+
+    m_checkTable_ptr = new CheckTable(m_num_cpu_sequencers, this);
+}
+
+Port *
+RubyTester::getPort(const std::string &if_name, int idx)
+{
+    if (if_name != "cpuPort") {
+        panic("RubyTester::getPort: unknown port %s requested", if_name);
+    }
+
+    if (idx >= (int)ports.size()) {
+        ports.resize(idx + 1);
+    }
+
+    if (ports[idx] != NULL) {
+        panic("RubyTester::getPort: port %d already assigned", idx);
+    }
+
+    CpuPort *port = new CpuPort(csprintf("%s-port%d", name(), idx), this, idx);
+
+    ports[idx] = port;
+    return port;
+}
+
+Tick
+RubyTester::CpuPort::recvAtomic(PacketPtr pkt)
+{
+    panic("RubyTester::CpuPort::recvAtomic() not implemented!\n");
+    return 0;
+}
+
+bool
+RubyTester::CpuPort::recvTiming(PacketPtr pkt)
+{
+    // retrieve the subblock and call hitCallback
+    RubyTester::SenderState* senderState =
+        safe_cast<RubyTester::SenderState*>(pkt->senderState);
+    SubBlock* subblock = senderState->subBlock;
+    assert(subblock != NULL);
+
+    // pop the sender state from the packet
+    pkt->senderState = senderState->saved;
+
+    tester->hitCallback(idx, subblock);
+
+    // Now that the tester has completed, delete the senderState
+    // (includes sublock) and the packet, then return
+    delete senderState;
+    delete pkt->req;
+    delete pkt;
+    return true;
+}
+
+Port*
+RubyTester::getCpuPort(int idx)
+{
+    assert(idx >= 0 && idx < ports.size());
+
+    return ports[idx];
+}
+
+void
+RubyTester::hitCallback(NodeID proc, SubBlock* data)
+{
+    // Mark that we made progress
+    m_last_progress_vector[proc] = g_eventQueue_ptr->getTime();
+
+    DPRINTF(RubyTest, "completed request for proc: %d\n", proc);
+    DPRINTF(RubyTest, "addr: 0x%x, size: %d, data: ",
+            data->getAddress(), data->getSize());
+    for (int byte = 0; byte < data->getSize(); byte++) {
+        DPRINTF(RubyTest, "%d", data->getByte(byte));
+    }
+    DPRINTF(RubyTest, "\n");
+
+    // This tells us our store has 'completed' or for a load gives us
+    // back the data to make the check
+    Check* check_ptr = m_checkTable_ptr->getCheck(data->getAddress());
+    assert(check_ptr != NULL);
+    check_ptr->performCallback(proc, data);
+}
+
+void
+RubyTester::wakeup()
+{
+    if (m_checks_completed < m_checks_to_complete) {
+        // Try to perform an action or check
+        Check* check_ptr = m_checkTable_ptr->getRandomCheck();
+        assert(check_ptr != NULL);
+        check_ptr->initiate();
+
+        checkForDeadlock();
+
+        schedule(checkStartEvent, curTick + m_wakeup_frequency);
+    } else {
+        exitSimLoop("Ruby Tester completed");
+    }
+}
+
+void
+RubyTester::checkForDeadlock()
+{
+    int size = m_last_progress_vector.size();
+    Time current_time = g_eventQueue_ptr->getTime();
+    for (int processor = 0; processor < size; processor++) {
+        if ((current_time - m_last_progress_vector[processor]) >
+                m_deadlock_threshold) {
+            WARN_EXPR(current_time);
+            WARN_EXPR(m_last_progress_vector[processor]);
+            WARN_EXPR(current_time - m_last_progress_vector[processor]);
+            WARN_EXPR(processor);
+            ERROR_MSG("Deadlock detected.");
+        }
+    }
+}
+
+void
+RubyTester::print(std::ostream& out) const
+{
+    out << "[RubyTester]" << std::endl;
+}
+
+RubyTester *
+RubyTesterParams::create()
+{
+    return new RubyTester(this);
+}
diff --git a/src/cpu/testers/rubytest/RubyTester.hh b/src/cpu/testers/rubytest/RubyTester.hh
new file mode 100644 (file)
index 0000000..53341bc
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009 Advanced Micro Devices, Inc.
+ * 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.
+ */
+
+#ifndef __CPU_RUBYTEST_RUBYTESTER_HH__
+#define __CPU_RUBYTEST_RUBYTESTER_HH__
+
+#include <iostream>
+#include <vector>
+#include <string>
+
+#include "cpu/testers/rubytest/CheckTable.hh"
+#include "mem/mem_object.hh"
+#include "mem/packet.hh"
+#include "mem/ruby/common/DataBlock.hh"
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/common/SubBlock.hh"
+#include "mem/ruby/system/RubyPort.hh"
+#include "params/RubyTester.hh"
+
+class RubyTester : public MemObject
+{
+  public:
+    class CpuPort : public SimpleTimingPort
+    {
+      private:
+        RubyTester *tester;
+
+      public:
+        CpuPort(const std::string &_name, RubyTester *_tester, int _idx)
+            : SimpleTimingPort(_name, _tester), tester(_tester), idx(_idx)
+        {}
+
+        int idx;
+
+      protected:
+        virtual bool recvTiming(PacketPtr pkt);
+        virtual Tick recvAtomic(PacketPtr pkt);
+    };
+
+    struct SenderState : public Packet::SenderState
+    {
+        SubBlock* subBlock;
+        Packet::SenderState *saved;
+
+        SenderState(Address addr, int size,
+                    Packet::SenderState *sender_state = NULL)
+            : saved(sender_state)
+        {
+            subBlock = new SubBlock(addr, size);
+        }
+
+        ~SenderState()
+        {
+            delete subBlock;
+        }
+    };
+
+    typedef RubyTesterParams Params;
+    RubyTester(const Params *p);
+    ~RubyTester();
+
+    virtual Port *getPort(const std::string &if_name, int idx = -1);
+
+    Port* getCpuPort(int idx);
+
+    virtual void init();
+
+    void wakeup();
+
+    void incrementCheckCompletions() { m_checks_completed++; }
+
+    void printStats(std::ostream& out) const {}
+    void clearStats() {}
+    void printConfig(std::ostream& out) const {}
+
+    void print(std::ostream& out) const;
+
+  protected:
+    class CheckStartEvent : public Event
+    {
+      private:
+        RubyTester *tester;
+
+      public:
+        CheckStartEvent(RubyTester *_tester)
+            : Event(CPU_Tick_Pri), tester(_tester)
+        {}
+        void process() { tester->wakeup(); }
+        virtual const char *description() const { return "RubyTester tick"; }
+    };
+
+    CheckStartEvent checkStartEvent;
+
+  private:
+    void hitCallback(NodeID proc, SubBlock* data);
+
+    void checkForDeadlock();
+
+    // Private copy constructor and assignment operator
+    RubyTester(const RubyTester& obj);
+    RubyTester& operator=(const RubyTester& obj);
+
+    CheckTable* m_checkTable_ptr;
+    std::vector<Time> m_last_progress_vector;
+
+    uint64 m_checks_completed;
+    std::vector<CpuPort*> ports;
+    uint64 m_checks_to_complete;
+    int m_deadlock_threshold;
+    int m_num_cpu_sequencers;
+    int m_wakeup_frequency;
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, const RubyTester& obj)
+{
+    obj.print(out);
+    out << std::flush;
+    return out;
+}
+
+#endif // __CPU_RUBYTEST_RUBYTESTER_HH__
diff --git a/src/cpu/testers/rubytest/RubyTester.py b/src/cpu/testers/rubytest/RubyTester.py
new file mode 100644 (file)
index 0000000..af37d2f
--- /dev/null
@@ -0,0 +1,38 @@
+# Copyright (c) 2005-2007 The Regents of The University of Michigan
+# Copyright (c) 2009 Advanced Micro Devices, Inc.
+# 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.
+#
+
+from MemObject import MemObject
+from m5.params import *
+from m5.proxy import *
+
+class RubyTester(MemObject):
+    type = 'RubyTester'
+    cpuPort = VectorPort("the cpu ports")
+    checks_to_complete = Param.Int(100, "checks to complete")
+    deadlock_threshold = Param.Int(50000, "how often to check for deadlock")
+    wakeup_frequency = Param.Int(10, "number of cycles between wakeups")
diff --git a/src/cpu/testers/rubytest/SConscript b/src/cpu/testers/rubytest/SConscript
new file mode 100644 (file)
index 0000000..9352dd7
--- /dev/null
@@ -0,0 +1,47 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2006 The Regents of The University of Michigan
+# Copyright (c) 2009 Advanced Micro Devices, Inc.
+# 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.
+#
+
+Import('*')
+
+#
+# Currently the ruby testser relies on Ruby specific objects (SubBlock, etc.)
+# When this dependency is removed, the ruby tester should be compiled
+# independently from Ruby
+#
+if not env['RUBY']:
+    Return()
+
+SimObject('RubyTester.py')
+
+Source('RubyTester.cc')
+Source('Check.cc')
+Source('CheckTable.cc')
+
+TraceFlag('RubyTest')
index 46bef49c6b61d8224fbf65180052b65a8b44b886..f707af36fb86a9845b2505b00151240d616d30c3 100644 (file)
@@ -26,7 +26,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "cpu/rubytest/RubyTester.hh"
+#include "cpu/testers/rubytest/RubyTester.hh"
 #include "mem/physical.hh"
 #include "mem/ruby/slicc_interface/AbstractController.hh"
 #include "mem/ruby/system/RubyPort.hh"
index 74b6355e8c93eb9aa84ee56c7981dfda0deb9ee0..dd30835da90c742be939dc189bb06ca7c35b8547 100644 (file)
@@ -27,7 +27,7 @@
  */
 
 #include "base/str.hh"
-#include "cpu/rubytest/RubyTester.hh"
+#include "cpu/testers/rubytest/RubyTester.hh"
 #include "mem/protocol/CacheMsg.hh"
 #include "mem/protocol/Protocol.hh"
 #include "mem/protocol/Protocol.hh"