ruby: single physical memory in fs mode

Both ruby and the system used to maintain memory copies.  With the changes
carried for programmed io accesses, only one single memory is required for
fs simulations.  This patch sets the copy of memory that used to reside
with the system to null, so that no space is allocated, but address checks
can still be carried out.  All the memory accesses now source and sink values
to the memory maintained by ruby.
This commit is contained in:
Nilay Vaish 2014-11-06 05:41:44 -06:00
parent 8ccfd9defa
commit 95a0b18431
25 changed files with 155 additions and 98 deletions

View file

@ -135,7 +135,10 @@ def build_test_system(np):
print >> sys.stderr, "Ruby requires TimingSimpleCPU or O3CPU!!"
sys.exit(1)
Ruby.create_system(options, test_sys, test_sys.iobus, test_sys._dma_ports)
Ruby.create_system(options, True, test_sys, test_sys.iobus,
test_sys._dma_ports)
test_sys.physmem = [SimpleMemory(range = r, null = True)
for r in test_sys.mem_ranges]
# Create a seperate clock domain for Ruby
test_sys.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock,
@ -160,13 +163,9 @@ def build_test_system(np):
cpu.interrupts.int_master = test_sys.ruby._cpu_ports[i].slave
cpu.interrupts.int_slave = test_sys.ruby._cpu_ports[i].master
test_sys.ruby._cpu_ports[i].access_phys_mem = True
# Create the appropriate memory controllers
# and connect them to the IO bus
test_sys.mem_ctrls = [TestMemClass(range = r) for r in test_sys.mem_ranges]
for i in xrange(len(test_sys.mem_ctrls)):
test_sys.mem_ctrls[i].port = test_sys.iobus.master
# Connect the ruby io port to the PIO bus,
# assuming that there is just one such port.
test_sys.iobus.master = test_sys.ruby._io_port.slave
else:
if options.caches or options.l2cache:

View file

@ -109,7 +109,7 @@ system.cpu = RubyDirectedTester(requests_to_complete = \
options.requests,
generator = generator)
Ruby.create_system(options, system)
Ruby.create_system(options, False, system)
# Since Ruby runs at an independent frequency, create a seperate clock
system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock,

View file

@ -128,7 +128,7 @@ else:
dma_ports = []
for (i, dma) in enumerate(dmas):
dma_ports.append(dma.test)
Ruby.create_system(options, system, dma_ports = dma_ports)
Ruby.create_system(options, False, system, dma_ports = dma_ports)
# Create a top-level voltage domain and clock domain
system.voltage_domain = VoltageDomain(voltage = options.sys_voltage)
@ -159,12 +159,6 @@ for (i, cpu) in enumerate(cpus):
#
system.ruby._cpu_ports[i].deadlock_threshold = 5000000
#
# Ruby doesn't need the backing image of memory when running with
# the tester.
#
system.ruby._cpu_ports[i].access_phys_mem = False
for (i, dma) in enumerate(dmas):
#
# Tie the dma memtester ports to the correct functional port

View file

@ -113,7 +113,7 @@ system.voltage_domain = VoltageDomain(voltage = options.sys_voltage)
system.clk_domain = SrcClockDomain(clock = options.sys_clock,
voltage_domain = system.voltage_domain)
Ruby.create_system(options, system)
Ruby.create_system(options, False, system)
# Create a seperate clock domain for Ruby
system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock,
@ -125,8 +125,6 @@ for ruby_port in system.ruby._cpu_ports:
# Tie the cpu test ports to the ruby cpu port
#
cpus[i].test = ruby_port.slave
ruby_port.access_phys_mem = False
i += 1
# -----------------------

View file

@ -106,7 +106,7 @@ system.voltage_domain = VoltageDomain(voltage = options.sys_voltage)
system.clk_domain = SrcClockDomain(clock = options.sys_clock,
voltage_domain = system.voltage_domain)
Ruby.create_system(options, system)
Ruby.create_system(options, False, system)
# Create a seperate clock domain for Ruby
system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock,
@ -137,12 +137,6 @@ for ruby_port in system.ruby._cpu_ports:
#
ruby_port.using_ruby_tester = True
#
# Ruby doesn't need the backing image of memory when running with
# the tester.
#
ruby_port.access_phys_mem = False
# -----------------------
# run simulation
# -----------------------

View file

@ -231,7 +231,7 @@ if options.ruby:
system.physmem = SimpleMemory(range=AddrRange(options.mem_size),
null = True)
options.use_map = True
Ruby.create_system(options, system)
Ruby.create_system(options, False, system)
assert(options.num_cpus == len(system.ruby._cpu_ports))
system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock,

View file

@ -56,7 +56,7 @@ def define_options(parser):
caches private to clusters")
return
def create_system(options, system, dma_ports, ruby_system):
def create_system(options, full_system, system, dma_ports, ruby_system):
if buildEnv['PROTOCOL'] != 'MESI_Three_Level':
fatal("This script requires the MESI_Three_Level protocol to be built.")
@ -231,5 +231,20 @@ def create_system(options, system, dma_ports, ruby_system):
dir_cntrl_nodes + \
dma_cntrl_nodes
# Create the io controller and the sequencer
if full_system:
io_seq = DMASequencer(version=len(dma_ports), ruby_system=ruby_system)
ruby_system._io_port = io_seq
io_controller = DMA_Controller(version = len(dma_ports),
dma_sequencer = io_seq,
ruby_system = ruby_system)
ruby_system.io_controller = io_controller
# Connect the dma controller to the network
io_controller.responseFromDir = ruby_system.network.master
io_controller.requestToDir = ruby_system.network.slave
all_cntrls = all_cntrls + [io_controller]
topology = create_topology(all_cntrls, options)
return (cpu_sequencers, dir_cntrl_nodes, topology)

View file

@ -48,7 +48,7 @@ class L2Cache(RubyCache):
def define_options(parser):
return
def create_system(options, system, dma_ports, ruby_system):
def create_system(options, full_system, system, dma_ports, ruby_system):
if buildEnv['PROTOCOL'] != 'MESI_Two_Level':
fatal("This script requires the MESI_Two_Level protocol to be built.")
@ -196,7 +196,8 @@ def create_system(options, system, dma_ports, ruby_system):
for i, dma_port in enumerate(dma_ports):
# Create the Ruby objects associated with the dma controller
dma_seq = DMASequencer(version = i,
ruby_system = ruby_system)
ruby_system = ruby_system,
slave = dma_port)
dma_cntrl = DMA_Controller(version = i,
dma_sequencer = dma_seq,
@ -204,19 +205,31 @@ def create_system(options, system, dma_ports, ruby_system):
ruby_system = ruby_system)
exec("ruby_system.dma_cntrl%d = dma_cntrl" % i)
exec("ruby_system.dma_cntrl%d.dma_sequencer.slave = dma_port" % i)
dma_cntrl_nodes.append(dma_cntrl)
# Connect the dma controller to the network
dma_cntrl.responseFromDir = ruby_system.network.master
dma_cntrl.requestToDir = ruby_system.network.slave
all_cntrls = l1_cntrl_nodes + \
l2_cntrl_nodes + \
dir_cntrl_nodes + \
dma_cntrl_nodes
topology = create_topology(all_cntrls, options)
# Create the io controller and the sequencer
if full_system:
io_seq = DMASequencer(version=len(dma_ports), ruby_system=ruby_system)
ruby_system._io_port = io_seq
io_controller = DMA_Controller(version = len(dma_ports),
dma_sequencer = io_seq,
ruby_system = ruby_system)
ruby_system.io_controller = io_controller
# Connect the dma controller to the network
io_controller.responseFromDir = ruby_system.network.master
io_controller.requestToDir = ruby_system.network.slave
all_cntrls = all_cntrls + [io_controller]
topology = create_topology(all_cntrls, options)
return (cpu_sequencers, dir_cntrl_nodes, topology)

View file

@ -42,7 +42,7 @@ class Cache(RubyCache):
def define_options(parser):
return
def create_system(options, system, dma_ports, ruby_system):
def create_system(options, full_system, system, dma_ports, ruby_system):
if buildEnv['PROTOCOL'] != 'MI_example':
panic("This script requires the MI_example protocol to be built.")
@ -173,7 +173,22 @@ def create_system(options, system, dma_ports, ruby_system):
dma_cntrl.requestToDir = ruby_system.network.master
dma_cntrl.responseFromDir = ruby_system.network.slave
all_cntrls = l1_cntrl_nodes + dir_cntrl_nodes + dma_cntrl_nodes
# Create the io controller and the sequencer
if full_system:
io_seq = DMASequencer(version=len(dma_ports), ruby_system=ruby_system)
ruby_system._io_port = io_seq
io_controller = DMA_Controller(version = len(dma_ports),
dma_sequencer = io_seq,
ruby_system = ruby_system)
ruby_system.io_controller = io_controller
# Connect the dma controller to the network
io_controller.responseFromDir = ruby_system.network.master
io_controller.requestToDir = ruby_system.network.slave
all_cntrls = all_cntrls + [io_controller]
topology = create_topology(all_cntrls, options)
return (cpu_sequencers, dir_cntrl_nodes, topology)

View file

@ -48,7 +48,7 @@ class L2Cache(RubyCache):
def define_options(parser):
return
def create_system(options, system, dma_ports, ruby_system):
def create_system(options, full_system, system, dma_ports, ruby_system):
if buildEnv['PROTOCOL'] != 'MOESI_CMP_directory':
panic("This script requires the MOESI_CMP_directory protocol to be built.")
@ -192,7 +192,8 @@ def create_system(options, system, dma_ports, ruby_system):
# Create the Ruby objects associated with the dma controller
#
dma_seq = DMASequencer(version = i,
ruby_system = ruby_system)
ruby_system = ruby_system,
slave = dma_port)
dma_cntrl = DMA_Controller(version = i,
dma_sequencer = dma_seq,
@ -200,14 +201,35 @@ def create_system(options, system, dma_ports, ruby_system):
ruby_system = ruby_system)
exec("ruby_system.dma_cntrl%d = dma_cntrl" % i)
exec("ruby_system.dma_cntrl%d.dma_sequencer.slave = dma_port" % i)
dma_cntrl_nodes.append(dma_cntrl)
# Connect the dma controller to the network
dma_cntrl.responseFromDir = ruby_system.network.master
dma_cntrl.reqToDir = ruby_system.network.slave
dma_cntrl.respToDir = ruby_system.network.slave
all_cntrls = l1_cntrl_nodes + \
l2_cntrl_nodes + \
dir_cntrl_nodes + \
dma_cntrl_nodes
# Create the io controller and the sequencer
if full_system:
io_seq = DMASequencer(version=len(dma_ports), ruby_system=ruby_system)
ruby_system._io_port = io_seq
io_controller = DMA_Controller(version = len(dma_ports),
dma_sequencer = io_seq,
ruby_system = ruby_system)
ruby_system.io_controller = io_controller
# Connect the dma controller to the network
io_controller.responseFromDir = ruby_system.network.master
io_controller.reqToDir = ruby_system.network.slave
io_controller.respToDir = ruby_system.network.slave
all_cntrls = all_cntrls + [io_controller]
topology = create_topology(all_cntrls, options)
return (cpu_sequencers, dir_cntrl_nodes, topology)

View file

@ -55,7 +55,7 @@ def define_options(parser):
parser.add_option("--allow-atomic-migration", action="store_true",
help="allow migratory sharing for atomic only accessed blocks")
def create_system(options, system, dma_ports, ruby_system):
def create_system(options, full_system, system, dma_ports, ruby_system):
if buildEnv['PROTOCOL'] != 'MOESI_CMP_token':
panic("This script requires the MOESI_CMP_token protocol to be built.")
@ -222,7 +222,8 @@ def create_system(options, system, dma_ports, ruby_system):
# Create the Ruby objects associated with the dma controller
#
dma_seq = DMASequencer(version = i,
ruby_system = ruby_system)
ruby_system = ruby_system,
slave = dma_port)
dma_cntrl = DMA_Controller(version = i,
dma_sequencer = dma_seq,
@ -230,14 +231,32 @@ def create_system(options, system, dma_ports, ruby_system):
ruby_system = ruby_system)
exec("ruby_system.dma_cntrl%d = dma_cntrl" % i)
exec("ruby_system.dma_cntrl%d.dma_sequencer.slave = dma_port" % i)
dma_cntrl_nodes.append(dma_cntrl)
# Connect the dma controller to the network
dma_cntrl.responseFromDir = ruby_system.network.master
dma_cntrl.reqToDirectory = ruby_system.network.slave
all_cntrls = l1_cntrl_nodes + \
l2_cntrl_nodes + \
dir_cntrl_nodes + \
dma_cntrl_nodes
topology = create_topology(all_cntrls, options)
# Create the io controller and the sequencer
if full_system:
io_seq = DMASequencer(version=len(dma_ports), ruby_system=ruby_system)
ruby_system._io_port = io_seq
io_controller = DMA_Controller(version = len(dma_ports),
dma_sequencer = io_seq,
ruby_system = ruby_system)
ruby_system.io_controller = io_controller
# Connect the dma controller to the network
io_controller.responseFromDir = ruby_system.network.master
io_controller.reqToDirectory = ruby_system.network.slave
all_cntrls = all_cntrls + [io_controller]
topology = create_topology(all_cntrls, options)
return (cpu_sequencers, dir_cntrl_nodes, topology)

View file

@ -59,7 +59,7 @@ def define_options(parser):
parser.add_option("--dir-on", action="store_true",
help="Hammer: enable Full-bit Directory")
def create_system(options, system, dma_ports, ruby_system):
def create_system(options, full_system, system, dma_ports, ruby_system):
if buildEnv['PROTOCOL'] != 'MOESI_hammer':
panic("This script requires the MOESI_hammer protocol to be built.")
@ -224,7 +224,8 @@ def create_system(options, system, dma_ports, ruby_system):
# Create the Ruby objects associated with the dma controller
#
dma_seq = DMASequencer(version = i,
ruby_system = ruby_system)
ruby_system = ruby_system,
slave = dma_port)
dma_cntrl = DMA_Controller(version = i,
dma_sequencer = dma_seq,
@ -232,7 +233,6 @@ def create_system(options, system, dma_ports, ruby_system):
ruby_system = ruby_system)
exec("ruby_system.dma_cntrl%d = dma_cntrl" % i)
exec("ruby_system.dma_cntrl%d.dma_sequencer.slave = dma_port" % i)
dma_cntrl_nodes.append(dma_cntrl)
if options.recycle_latency:
@ -242,7 +242,22 @@ def create_system(options, system, dma_ports, ruby_system):
dma_cntrl.responseFromDir = ruby_system.network.master
dma_cntrl.requestToDir = ruby_system.network.slave
all_cntrls = l1_cntrl_nodes + dir_cntrl_nodes + dma_cntrl_nodes
# Create the io controller and the sequencer
if full_system:
io_seq = DMASequencer(version=len(dma_ports), ruby_system=ruby_system)
ruby_system._io_port = io_seq
io_controller = DMA_Controller(version = len(dma_ports),
dma_sequencer = io_seq,
ruby_system = ruby_system)
ruby_system.io_controller = io_controller
# Connect the dma controller to the network
io_controller.responseFromDir = ruby_system.network.master
io_controller.requestToDir = ruby_system.network.slave
all_cntrls = all_cntrls + [io_controller]
topology = create_topology(all_cntrls, options)
return (cpu_sequencers, dir_cntrl_nodes, topology)

View file

@ -42,7 +42,7 @@ class Cache(RubyCache):
def define_options(parser):
return
def create_system(options, system, dma_ports, ruby_system):
def create_system(options, full_system, system, dma_ports, ruby_system):
if buildEnv['PROTOCOL'] != 'Network_test':
panic("This script requires the Network_test protocol to be built.")

View file

@ -101,7 +101,7 @@ def create_topology(controllers, options):
topology = eval("Topo.%s(controllers)" % options.topology)
return topology
def create_system(options, system, piobus = None, dma_ports = []):
def create_system(options, full_system, system, piobus = None, dma_ports = []):
system.ruby = RubySystem(no_mem_vec = options.use_map)
ruby = system.ruby
@ -137,7 +137,8 @@ def create_system(options, system, piobus = None, dma_ports = []):
exec "import %s" % protocol
try:
(cpu_sequencers, dir_cntrls, topology) = \
eval("%s.create_system(options, system, dma_ports, ruby)"
eval("%s.create_system(options, full_system, system, dma_ports,\
ruby)"
% protocol)
except:
print "Error: could not create sytem for ruby protocol %s" % protocol

View file

@ -49,11 +49,6 @@ machine(DMA, "DMA Controller")
Ack, desc="DMA write to memory completed";
}
structure(DMASequencer, external="yes") {
void ackCallback();
void dataCallback(DataBlock);
}
MessageBuffer mandatoryQueue, ordered="false";
State cur_state;

View file

@ -62,11 +62,6 @@ machine(DMA, "DMA Controller")
DataBlock DataBlk, desc="Data";
}
structure(DMASequencer, external = "yes") {
void ackCallback();
void dataCallback(DataBlock);
}
structure(TBETable, external = "yes") {
TBE lookup(Address);
void allocate(Address);

View file

@ -51,11 +51,6 @@ machine(DMA, "DMA Controller")
Ack, desc="DMA write to memory completed";
}
structure(DMASequencer, external="yes") {
void ackCallback();
void dataCallback(DataBlock);
}
MessageBuffer mandatoryQueue, ordered="false";
State cur_state;

View file

@ -40,9 +40,8 @@
DMASequencer::DMASequencer(const Params *p)
: MemObject(p), m_version(p->version), m_controller(NULL),
m_mandatory_q_ptr(NULL), m_usingRubyTester(p->using_ruby_tester),
slave_port(csprintf("%s.slave", name()), this, access_phys_mem, 0),
drainManager(NULL), system(p->system), retry(false),
access_phys_mem(p->access_phys_mem)
slave_port(csprintf("%s.slave", name()), this, 0),
drainManager(NULL), system(p->system), retry(false)
{
assert(m_version != -1);
}
@ -56,6 +55,8 @@ DMASequencer::init()
m_mandatory_q_ptr->setSender(this);
m_is_busy = false;
m_data_block_mask = ~ (~0 << RubySystem::getBlockSizeBits());
slave_port.sendRangeChange();
}
BaseSlavePort &
@ -72,9 +73,8 @@ DMASequencer::getSlavePort(const std::string &if_name, PortID idx)
}
DMASequencer::MemSlavePort::MemSlavePort(const std::string &_name,
DMASequencer *_port, bool _access_phys_mem, PortID id)
: QueuedSlavePort(_name, _port, queue, id), queue(*_port, *this),
access_phys_mem(_access_phys_mem)
DMASequencer *_port, PortID id)
: QueuedSlavePort(_name, _port, queue, id), queue(*_port, *this)
{
DPRINTF(RubyDma, "Created slave memport on ruby sequencer %s\n", _name);
}
@ -202,28 +202,21 @@ void
DMASequencer::MemSlavePort::hitCallback(PacketPtr pkt)
{
bool needsResponse = pkt->needsResponse();
bool accessPhysMem = access_phys_mem;
assert(!pkt->isLLSC());
assert(!pkt->isFlush());
DPRINTF(RubyDma, "Hit callback needs response %d\n", needsResponse);
if (accessPhysMem) {
DMASequencer *seq = static_cast<DMASequencer *>(&owner);
seq->system->getPhysMem().access(pkt);
} else if (needsResponse) {
pkt->makeResponse();
}
// turn packet around to go back to requester if response expected
if (needsResponse) {
pkt->makeResponse();
DPRINTF(RubyDma, "Sending packet back over port\n");
// send next cycle
schedTimingResp(pkt, curTick() + g_system_ptr->clockPeriod());
} else {
delete pkt;
}
DPRINTF(RubyDma, "Hit callback done!\n");
}

View file

@ -66,11 +66,10 @@ class DMASequencer : public MemObject
{
private:
SlavePacketQueue queue;
bool access_phys_mem;
public:
MemSlavePort(const std::string &_name, DMASequencer *_port,
bool _access_phys_mem, PortID id);
PortID id);
void hitCallback(PacketPtr pkt);
void evictionCallback(const Address& address);
@ -140,8 +139,6 @@ class DMASequencer : public MemObject
System* system;
bool retry;
bool access_phys_mem;
bool m_is_busy;
uint64_t m_data_block_mask;
DMARequest active_request;

View file

@ -73,12 +73,9 @@ class RubySequencer(RubyPort):
class DMASequencer(MemObject):
type = 'DMASequencer'
cxx_header = "mem/ruby/system/DMASequencer.hh"
version = Param.Int(0, "")
slave = SlavePort("Device slave port")
using_ruby_tester = Param.Bool(False, "")
access_phys_mem = Param.Bool(True,
"should the dma atomically update phys_mem")
ruby_system = Param.RubySystem(Parent.any, "")
system = Param.System(Parent.any, "system object")

View file

@ -98,7 +98,7 @@ for cpu in cpus:
system.mem_ranges = AddrRange('256MB')
Ruby.create_system(options, system)
Ruby.create_system(options, False, system)
# Create a separate clock domain for Ruby
system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock,

View file

@ -68,12 +68,16 @@ system.cpu_clk_domain = SrcClockDomain(clock = '2GHz',
system.cpu = [TimingSimpleCPU(cpu_id=i, clk_domain = system.cpu_clk_domain)
for i in xrange(options.num_cpus)]
Ruby.create_system(options, system, system.iobus, system._dma_ports)
Ruby.create_system(options, True, system, system.iobus, system._dma_ports)
# Create a seperate clock domain for Ruby
system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock,
voltage_domain = system.voltage_domain)
# Connect the ruby io port to the PIO bus,
# assuming that there is just one such port.
system.iobus.master = system.ruby._io_port.slave
for (i, cpu) in enumerate(system.cpu):
# create the interrupt controller
cpu.createInterruptController()
@ -82,17 +86,13 @@ for (i, cpu) in enumerate(system.cpu):
cpu.dcache_port = system.ruby._cpu_ports[i].slave
cpu.itb.walker.port = system.ruby._cpu_ports[i].slave
cpu.dtb.walker.port = system.ruby._cpu_ports[i].slave
cpu.interrupts.pio = system.ruby._cpu_ports[i].master
cpu.interrupts.int_master = system.ruby._cpu_ports[i].slave
cpu.interrupts.int_slave = system.ruby._cpu_ports[i].master
# Set access_phys_mem to True for ruby port
system.ruby._cpu_ports[i].access_phys_mem = True
system.physmem = [DDR3_1600_x64(range = r)
system.physmem = [SimpleMemory(range = r, null = True)
for r in system.mem_ranges]
for i in xrange(len(system.physmem)):
system.physmem[i].port = system.iobus.master
root = Root(full_system = True, system = system)
m5.ticks.setGlobalFrequency('1THz')

View file

@ -89,7 +89,7 @@ system.clk_domain = SrcClockDomain(clock = '1GHz',
system.mem_ranges = AddrRange('256MB')
Ruby.create_system(options, system)
Ruby.create_system(options, False, system)
# Create a separate clock domain for Ruby
system.ruby.clk_domain = SrcClockDomain(clock = '1GHz',

View file

@ -78,7 +78,7 @@ system = System(cpu = cpus, physmem = SimpleMemory(),
# CPUs frequency
system.cpu.clk_domain = SrcClockDomain(clock = '2GHz')
Ruby.create_system(options, system)
Ruby.create_system(options, False, system)
# Create a separate clock domain for Ruby
system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock)

View file

@ -79,7 +79,7 @@ system.cpu.clk_domain = SrcClockDomain(clock = '2GHz',
voltage_domain = system.voltage_domain)
system.mem_ranges = AddrRange('256MB')
Ruby.create_system(options, system)
Ruby.create_system(options, False, system)
# Create a separate clock for Ruby
system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock,