summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configs/common/FSConfig.py23
-rw-r--r--configs/common/Options.py4
-rw-r--r--configs/example/ruby_fs.py100
-rw-r--r--configs/ruby/MOESI_hammer.py50
-rw-r--r--configs/ruby/Ruby.py13
-rw-r--r--src/mem/ruby/system/RubyPort.cc55
-rw-r--r--src/mem/ruby/system/RubyPort.hh6
-rw-r--r--src/mem/ruby/system/Sequencer.cc2
-rw-r--r--src/mem/ruby/system/Sequencer.py3
9 files changed, 106 insertions, 150 deletions
diff --git a/configs/common/FSConfig.py b/configs/common/FSConfig.py
index cf4c9b6f5..f1c905fd8 100644
--- a/configs/common/FSConfig.py
+++ b/configs/common/FSConfig.py
@@ -79,14 +79,14 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None):
return self
-def makeLinuxAlphaRubySystem(mem_mode, rubymem, mdesc = None):
+def makeLinuxAlphaRubySystem(mem_mode, phys_mem, mdesc = None):
class BaseTsunami(Tsunami):
ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0)
ide = IdeController(disks=[Parent.disk0, Parent.disk2],
pci_func=0, pci_dev=0, pci_bus=0)
- self = LinuxAlphaSystem(physmem = rubymem)
+ self = LinuxAlphaSystem(physmem = phys_mem)
if not mdesc:
# generic system
mdesc = SysConfig()
@@ -94,7 +94,14 @@ def makeLinuxAlphaRubySystem(mem_mode, rubymem, mdesc = None):
# Create pio bus to connect all device pio ports to rubymem's pio port
self.piobus = Bus(bus_id=0)
-
+
+ #
+ # Pio functional accesses from devices need direct access to memory
+ # RubyPort currently does support functional accesses. Therefore provide
+ # the piobus a direct connection to physical memory
+ #
+ self.piobus.port = phys_mem.port
+
self.disk0 = CowIdeDisk(driveID='master')
self.disk2 = CowIdeDisk(driveID='master')
self.disk0.childImage(mdesc.disk())
@@ -104,13 +111,11 @@ def makeLinuxAlphaRubySystem(mem_mode, rubymem, mdesc = None):
self.tsunami.ide.pio = self.piobus.port
self.tsunami.ethernet.pio = self.piobus.port
- # connect the dma ports directly to ruby dma ports
- self.tsunami.ide.dma = self.physmem.dma_port
- self.tsunami.ethernet.dma = self.physmem.dma_port
+ #
+ # store the dma devices for later connection to dma ruby ports
+ #
+ self.dma_devices = [self.tsunami.ide, self.tsunami.ethernet]
- # connect the pio bus to rubymem
- self.physmem.pio_port = self.piobus.port
-
self.simple_disk = SimpleDisk(disk=RawDiskImage(image_file = mdesc.disk(),
read_only = True))
self.intrctrl = IntrControl()
diff --git a/configs/common/Options.py b/configs/common/Options.py
index d38943644..8b4fc2ce1 100644
--- a/configs/common/Options.py
+++ b/configs/common/Options.py
@@ -34,7 +34,9 @@ parser.add_option("-n", "--num-cpus", type="int", default=1)
parser.add_option("--caches", action="store_true")
parser.add_option("--l2cache", action="store_true")
parser.add_option("--fastmem", action="store_true")
-
+parser.add_option("--clock", action="store", type="string", default='1GHz')
+parser.add_option("--num-dirs", type="int", default=1)
+
# Run duration options
parser.add_option("-m", "--maxtick", type="int", default=m5.MaxTick,
metavar="T",
diff --git a/configs/example/ruby_fs.py b/configs/example/ruby_fs.py
index a4831f3bb..e30f40bd5 100644
--- a/configs/example/ruby_fs.py
+++ b/configs/example/ruby_fs.py
@@ -43,10 +43,10 @@ from m5.util import addToPath, panic
if not buildEnv['FULL_SYSTEM']:
panic("This script requires full-system mode (*_FS).")
-addToPath('../../tests/configs/')
addToPath('../common')
+addToPath('../ruby')
-import ruby_config
+import Ruby
from FSConfig import *
from SysPaths import *
@@ -72,12 +72,6 @@ parser.add_option("-i", "--input", default="", help="Read stdin from a file.")
parser.add_option("--output", default="", help="Redirect stdout to a file.")
parser.add_option("--errout", default="", help="Redirect stderr to a file.")
-# ruby options
-parser.add_option("--ruby-debug", action="store_true")
-parser.add_option("--ruby-debug-file", default="", help="Ruby debug out file (stdout if blank)")
-parser.add_option("--protocol", default="", help="Ruby protocol compiled into binary")
-
-
# ruby host memory experimentation
parser.add_option("--cache_size", type="int")
parser.add_option("--cache_assoc", type="int")
@@ -114,87 +108,25 @@ class CPUClass(TimingSimpleCPU): pass
test_mem_mode = 'timing'
FutureClass = None
-CPUClass.clock = '1GHz'
-
-#
-# Since we are running in timing mode, set the number of M5 ticks to ruby ticks
-# to the cpu clock frequency
-#
-M5_to_ruby_tick = '1000t'
-
-np = options.num_cpus
+CPUClass.clock = options.clock
-# check for max instruction count
-if options.max_inst:
- max_inst = options.max_inst
-else:
- max_inst = 0
-
-# set cache size
-if options.cache_size:
- cache_size = options.cache_size
-else:
- cache_size = 32768 # 32 kB is default
-
-# set cache assoc
-if options.cache_assoc:
- cache_assoc = options.cache_assoc
-else:
- cache_assoc = 8 # 8 is default
-
-# set map levels
-if options.map_levels:
- map_levels = options.map_levels
-else:
- map_levels = 4 # 4 levels is the default
-
-if options.protocol == "MOESI_hammer":
- ruby_config_file = "MOESI_hammer-homogeneous.rb"
-elif options.protocol == "MOESI_CMP_token":
- ruby_config_file = "TwoLevel_SplitL1UnifiedL2.rb"
-elif options.protocol == "MI_example":
- ruby_config_file = "MI_example-homogeneous.rb"
-else:
- print "Error: unsupported ruby protocol"
- sys.exit(1)
+physmem = PhysicalMemory()
-#
-# Currently, since ruby configuraiton is separate from m5, we need to manually
-# tell ruby that two dma ports are created by makeLinuxAlphaRubySystem().
-# Eventually, this will be fix with a unified configuration system.
-#
-rubymem = ruby_config.generate(ruby_config_file,
- np,
- np,
- 128,
- False,
- cache_size,
- cache_assoc,
- map_levels,
- 2,
- M5_to_ruby_tick)
-
-if options.ruby_debug == True:
- rubymem.debug = True
- rubymem.debug_file = options.ruby_debug_file
-
-system = makeLinuxAlphaRubySystem(test_mem_mode, rubymem, bm[0])
-
-system.cpu = [CPUClass(cpu_id=i) for i in xrange(np)]
-
-if options.l2cache:
- print "Error: -l2cache incompatible with ruby, must configure it ruby-style"
- sys.exit(1)
+system = makeLinuxAlphaRubySystem(test_mem_mode, physmem, bm[0])
-if options.caches:
- print "Error: -caches incompatible with ruby, must configure it ruby-style"
- sys.exit(1)
+system.ruby = Ruby.create_system(options,
+ physmem,
+ system.piobus,
+ system.dma_devices)
-for i in xrange(np):
- system.cpu[i].connectMemPorts(system.physmem)
+system.cpu = [CPUClass(cpu_id=i) for i in xrange(options.num_cpus)]
- if options.fastmem:
- system.cpu[i].physmem_port = system.physmem.port
+for (i, cpu) in enumerate(system.cpu):
+ #
+ # Tie the cpu ports to the correct ruby system ports
+ #
+ cpu.icache_port = system.ruby.cpu_ruby_ports[i].port
+ cpu.dcache_port = system.ruby.cpu_ruby_ports[i].port
root = Root(system = system)
diff --git a/configs/ruby/MOESI_hammer.py b/configs/ruby/MOESI_hammer.py
index 41c507503..f35ab20c4 100644
--- a/configs/ruby/MOESI_hammer.py
+++ b/configs/ruby/MOESI_hammer.py
@@ -49,12 +49,13 @@ class L2Cache(RubyCache):
latency = 15
size = 1048576
-def create_system(options, physmem):
+def create_system(options, phys_mem, piobus, dma_devices):
if buildEnv['PROTOCOL'] != 'MOESI_hammer':
panic("This script requires the MOESI_hammer protocol to be built.")
- sequencers = []
+ cpu_sequencers = []
+
#
# The ruby network creation expects the list of nodes in the system to be
# consistent with the NetDest list. Therefore the l1 controller nodes must be
@@ -68,11 +69,10 @@ def create_system(options, physmem):
# Must create the individual controllers before the network to ensure the
# controller constructors are called before the network constructor
#
- for i in range(options.num_cpus):
+
+ for i in xrange(options.num_cpus):
#
# First create the Ruby objects associated with this cpu
- # Eventually this code should go in a python file specific to the
- # MOESI_hammer protocol
#
l1i_profiler = CacheProfiler(description = ("l1i_%s_profiler" % i))
l1i_cache = L1Cache(cache_profiler = l1i_profiler)
@@ -85,33 +85,51 @@ def create_system(options, physmem):
cpu_seq = RubySequencer(icache = l1i_cache,
dcache = l1d_cache,
- funcmem_port = physmem.port)
+ physMemPort = phys_mem.port,
+ physmem = phys_mem)
+
+ if piobus != None:
+ cpu_seq.pio_port = piobus.port
l1_cntrl = L1Cache_Controller(version = i,
sequencer = cpu_seq,
L1IcacheMemory = l1i_cache,
L1DcacheMemory = l1d_cache,
L2cacheMemory = l2_cache)
+ #
+ # Add controllers and sequencers to the appropriate lists
+ #
+ cpu_sequencers.append(cpu_seq)
+ l1_cntrl_nodes.append(l1_cntrl)
+
+ for i in xrange(options.num_dirs):
+ #
+ # Create the Ruby objects associated with the directory controller
+ #
mem_cntrl = RubyMemoryControl(version = i)
dir_cntrl = Directory_Controller(version = i,
- directory = RubyDirectoryMemory(),
+ directory = \
+ RubyDirectoryMemory(version = i),
memBuffer = mem_cntrl)
- dma_cntrl = DMA_Controller(version = i,
- dma_sequencer = DMASequencer())
+ dir_cntrl_nodes.append(dir_cntrl)
+ for i, dma_device in enumerate(dma_devices):
#
- # Add controllers and sequencers to the appropriate lists
- # As noted above: Independent list are track to maintain the order of
- # nodes/controllers assumed by the ruby network
+ # Create the Ruby objects associated with the dma controller
#
- sequencers.append(cpu_seq)
- l1_cntrl_nodes.append(l1_cntrl)
- dir_cntrl_nodes.append(dir_cntrl)
+ dma_seq = DMASequencer(version = i,
+ physMemPort = phys_mem.port,
+ physmem = phys_mem)
+
+ dma_cntrl = DMA_Controller(version = i,
+ dma_sequencer = dma_seq)
+
+ dma_cntrl.dma_sequencer.port = dma_device.dma
dma_cntrl_nodes.append(dma_cntrl)
all_cntrls = l1_cntrl_nodes + dir_cntrl_nodes + dma_cntrl_nodes
- return (sequencers, dir_cntrl_nodes, all_cntrls)
+ return (cpu_sequencers, dir_cntrl_nodes, all_cntrls)
diff --git a/configs/ruby/Ruby.py b/configs/ruby/Ruby.py
index 415cb5545..4504bda85 100644
--- a/configs/ruby/Ruby.py
+++ b/configs/ruby/Ruby.py
@@ -34,13 +34,16 @@ from m5.util import addToPath
import MOESI_hammer
-def create_system(options, physmem):
+def create_system(options, physmem, piobus = None, dma_devices = []):
protocol = buildEnv['PROTOCOL']
if protocol == "MOESI_hammer":
- (sequencers, dir_cntrls, all_cntrls) = MOESI_hammer.create_system( \
- options, physmem)
+ (cpu_sequencers, dir_cntrls, all_cntrls) = \
+ MOESI_hammer.create_system(options, \
+ physmem, \
+ piobus, \
+ dma_devices)
else:
print "Error: unsupported ruby protocol"
sys.exit(1)
@@ -68,7 +71,7 @@ def create_system(options, physmem):
ranks_per_dimm = ranksPerDimm,
dimms_per_channel = dimmsPerChannel)
- ruby = RubySystem(clock = '1GHz',
+ ruby = RubySystem(clock = options.clock,
network = network,
profiler = ruby_profiler,
tracer = RubyTracer(),
@@ -77,6 +80,6 @@ def create_system(options, physmem):
protocol_trace = False),
mem_size_mb = mem_size_mb)
- ruby.cpu_ruby_ports = sequencers
+ ruby.cpu_ruby_ports = cpu_sequencers
return ruby
diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc
index d8fb6b470..692c9ea81 100644
--- a/src/mem/ruby/system/RubyPort.cc
+++ b/src/mem/ruby/system/RubyPort.cc
@@ -36,12 +36,13 @@ uint16_t RubyPort::m_num_ports = 0;
RubyPort::RequestMap RubyPort::pending_cpu_requests;
RubyPort::RubyPort(const Params *p)
- : MemObject(p),
- funcMemPort(csprintf("%s-funcmem_port", name()), this)
+ : MemObject(p)
{
m_version = p->version;
assert(m_version != -1);
+ physmem = p->physmem;
+
m_controller = NULL;
m_mandatory_q_ptr = NULL;
@@ -49,6 +50,7 @@ RubyPort::RubyPort(const Params *p)
m_request_cnt = 0;
m_hit_callback = ruby_hit_callback;
pio_port = NULL;
+ physMemPort = NULL;
assert(m_num_ports <= 2048); // see below for reason
}
@@ -73,8 +75,23 @@ RubyPort::getPort(const std::string &if_name, int idx)
this);
return pio_port;
- } else if (if_name == "funcmem_port") {
- return &funcMemPort;
+ } else if (if_name == "physMemPort") {
+ //
+ // RubyPort should only have one port to physical memory
+ //
+ assert (physMemPort == NULL);
+
+ physMemPort = new M5Port(csprintf("%s-physMemPort", name()),
+ this);
+
+ return physMemPort;
+ } else if (if_name == "functional") {
+ //
+ // Calls for the functional port only want to access functional memory.
+ // Therefore, directly pass these calls ports to physmem.
+ //
+ assert(physmem != NULL);
+ return physmem->getPort(if_name, idx);
}
return NULL;
}
@@ -248,11 +265,11 @@ RubyPort::M5Port::hitCallback(PacketPtr pkt)
DPRINTF(MemoryAccess, "Hit callback needs response %d\n",
needsResponse);
- ruby_port->funcMemPort.sendFunctional(pkt);
+ ruby_port->physMemPort->sendAtomic(pkt);
// turn packet around to go back to requester if response expected
if (needsResponse) {
- // recvAtomic() should already have turned packet into
+ // sendAtomic() should already have turned packet into
// atomic response
assert(pkt->isResponse());
DPRINTF(MemoryAccess, "Sending packet back over port\n");
@@ -282,7 +299,7 @@ RubyPort::M5Port::isPhysMemAddress(Addr addr)
{
AddrRangeList physMemAddrList;
bool snoop = false;
- ruby_port->funcMemPort.getPeerAddressRanges(physMemAddrList, snoop);
+ ruby_port->physMemPort->getPeerAddressRanges(physMemAddrList, snoop);
for(AddrRangeIter iter = physMemAddrList.begin();
iter != physMemAddrList.end();
iter++) {
@@ -292,29 +309,5 @@ RubyPort::M5Port::isPhysMemAddress(Addr addr)
return true;
}
}
- assert(isPioAddress(addr));
return false;
}
-
-bool
-RubyPort::M5Port::isPioAddress(Addr addr)
-{
- AddrRangeList pioAddrList;
- bool snoop = false;
- if (ruby_port->pio_port == NULL) {
- return false;
- }
-
- ruby_port->pio_port->getPeerAddressRanges(pioAddrList, snoop);
- for(AddrRangeIter iter = pioAddrList.begin();
- iter != pioAddrList.end();
- iter++) {
- if (addr >= iter->start && addr <= iter->end) {
- DPRINTF(MemoryAccess, "Pio request found in %#llx - %#llx range\n",
- iter->start, iter->end);
- return true;
- }
- }
- return false;
-}
-
diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh
index a03c4dce2..e57f663c9 100644
--- a/src/mem/ruby/system/RubyPort.hh
+++ b/src/mem/ruby/system/RubyPort.hh
@@ -36,6 +36,7 @@
#include "mem/mem_object.hh"
#include "mem/tport.hh"
+#include "mem/physical.hh"
#include "params/RubyPort.hh"
@@ -63,7 +64,6 @@ public:
virtual Tick recvAtomic(PacketPtr pkt);
private:
- bool isPioAddress(Addr addr);
bool isPhysMemAddress(Addr addr);
};
@@ -169,7 +169,9 @@ private:
static RequestMap pending_cpu_requests;
static void ruby_hit_callback(int64_t req_id);
- FunctionalPort funcMemPort;
+ M5Port* physMemPort;
+
+ PhysicalMemory* physmem;
};
#endif
diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc
index 23a6b44e2..00ae5364c 100644
--- a/src/mem/ruby/system/Sequencer.cc
+++ b/src/mem/ruby/system/Sequencer.cc
@@ -197,7 +197,7 @@ bool Sequencer::insertRequest(SequencerRequest* request) {
// See if we should schedule a deadlock check
if (deadlockCheckEvent.scheduled() == false) {
- schedule(deadlockCheckEvent, m_deadlock_threshold);
+ schedule(deadlockCheckEvent, m_deadlock_threshold + curTick);
}
Address line_addr(request->ruby_request.paddr);
diff --git a/src/mem/ruby/system/Sequencer.py b/src/mem/ruby/system/Sequencer.py
index 1333204a2..30cb9add0 100644
--- a/src/mem/ruby/system/Sequencer.py
+++ b/src/mem/ruby/system/Sequencer.py
@@ -8,6 +8,8 @@ class RubyPort(MemObject):
port = VectorPort("M5 port")
version = Param.Int(0, "")
pio_port = Port("Ruby_pio_port")
+ physmem = Param.PhysicalMemory("")
+ physMemPort = Port("port to physical memory")
class RubySequencer(RubyPort):
type = 'RubySequencer'
@@ -18,7 +20,6 @@ class RubySequencer(RubyPort):
"max requests (incl. prefetches) outstanding")
deadlock_threshold = Param.Int(500000,
"max outstanding cycles for a request before deadlock/livelock declared")
- funcmem_port = Port("port to functional memory")
class DMASequencer(RubyPort):
type = 'DMASequencer'