summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configs/common/FSConfig.py47
-rw-r--r--configs/common/MemConfig.py125
-rw-r--r--configs/common/Options.py23
-rw-r--r--configs/common/Simulation.py6
-rw-r--r--configs/example/fs.py30
-rw-r--r--configs/example/se.py4
-rw-r--r--tests/configs/alpha_generic.py2
-rw-r--r--tests/configs/arm_generic.py1
-rw-r--r--tests/configs/pc-simple-timing-ruby.py2
-rw-r--r--tests/configs/twosys-tsunami-simple-atomic.py4
-rw-r--r--tests/configs/x86_generic.py1
11 files changed, 206 insertions, 39 deletions
diff --git a/configs/common/FSConfig.py b/configs/common/FSConfig.py
index 3a7a50839..0d46dcde2 100644
--- a/configs/common/FSConfig.py
+++ b/configs/common/FSConfig.py
@@ -55,7 +55,7 @@ class MemBus(CoherentBus):
default = Self.badaddr_responder.pio
-def makeLinuxAlphaSystem(mem_mode, mdesc = None):
+def makeLinuxAlphaSystem(mem_mode, MemClass, mdesc = None):
IO_address_space_base = 0x80000000000
class BaseTsunami(Tsunami):
ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0)
@@ -73,7 +73,7 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None):
# base address (including the PCI config space)
self.bridge = Bridge(delay='50ns',
ranges = [AddrRange(IO_address_space_base, Addr.max)])
- self.physmem = SimpleDDR3(range = AddrRange(mdesc.mem()))
+ self.physmem = MemClass(range = AddrRange(mdesc.mem()))
self.mem_ranges = [self.physmem.range]
self.bridge.master = self.iobus.slave
self.bridge.slave = self.membus.master
@@ -104,13 +104,13 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None):
return self
-def makeLinuxAlphaRubySystem(mem_mode, mdesc = None):
+def makeLinuxAlphaRubySystem(mem_mode, MemClass, 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)
- physmem = SimpleDDR3(range = AddrRange(mdesc.mem()))
+ physmem = MemClass(range = AddrRange(mdesc.mem()))
self = LinuxAlphaSystem(physmem = physmem)
self.mem_ranges = [self.physmem.range]
if not mdesc:
@@ -157,7 +157,7 @@ def makeLinuxAlphaRubySystem(mem_mode, mdesc = None):
return self
-def makeSparcSystem(mem_mode, mdesc = None):
+def makeSparcSystem(mem_mode, MemClass, mdesc = None):
# Constants from iob.cc and uart8250.cc
iob_man_addr = 0x9800000000
uart_pio_size = 8
@@ -180,10 +180,10 @@ def makeSparcSystem(mem_mode, mdesc = None):
self.t1000 = T1000()
self.t1000.attachOnChipIO(self.membus)
self.t1000.attachIO(self.iobus)
- self.physmem = SimpleDDR3(range = AddrRange(Addr('1MB'), size = '64MB'),
- zero = True)
- self.physmem2 = SimpleDDR3(range = AddrRange(Addr('2GB'), size ='256MB'),
- zero = True)
+ self.physmem = MemClass(range = AddrRange(Addr('1MB'), size = '64MB'),
+ zero = True)
+ self.physmem2 = MemClass(range = AddrRange(Addr('2GB'), size ='256MB'),
+ zero = True)
self.mem_ranges = [self.physmem.range, self.physmem2.range]
self.bridge.master = self.iobus.slave
self.bridge.slave = self.membus.master
@@ -227,8 +227,8 @@ def makeSparcSystem(mem_mode, mdesc = None):
return self
-def makeArmSystem(mem_mode, machine_type, mdesc = None, dtb_filename = None,
- bare_metal=False):
+def makeArmSystem(mem_mode, machine_type, MemClass, mdesc = None,
+ dtb_filename = None, bare_metal=False):
assert machine_type
if bare_metal:
@@ -275,8 +275,8 @@ def makeArmSystem(mem_mode, machine_type, mdesc = None, dtb_filename = None,
if bare_metal:
# EOT character on UART will end the simulation
self.realview.uart.end_on_eot = True
- self.physmem = SimpleDDR3(range = AddrRange(Addr(mdesc.mem())),
- zero = True)
+ self.physmem = MemClass(range = AddrRange(Addr(mdesc.mem())),
+ zero = True)
self.mem_ranges = [self.physmem.range]
else:
self.kernel = binary('vmlinux.arm.smp.fb.2.6.38.8')
@@ -292,10 +292,9 @@ def makeArmSystem(mem_mode, machine_type, mdesc = None, dtb_filename = None,
boot_flags = 'earlyprintk console=ttyAMA0 lpj=19988480 norandmaps ' + \
'rw loglevel=8 mem=%s root=/dev/sda1' % mdesc.mem()
- self.physmem = SimpleDDR3(range =
- AddrRange(self.realview.mem_start_addr,
- size = mdesc.mem()),
- conf_table_reported = True)
+ self.physmem = MemClass(range = AddrRange(self.realview.mem_start_addr,
+ size = mdesc.mem()),
+ conf_table_reported = True)
self.mem_ranges = [self.physmem.range]
self.realview.setupBootLoader(self.membus, self, binary)
self.gic_cpu_addr = self.realview.gic.cpu_addr
@@ -317,7 +316,7 @@ def makeArmSystem(mem_mode, machine_type, mdesc = None, dtb_filename = None,
return self
-def makeLinuxMipsSystem(mem_mode, mdesc = None):
+def makeLinuxMipsSystem(mem_mode, MemClass, mdesc = None):
class BaseMalta(Malta):
ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0)
ide = IdeController(disks=[Parent.disk0, Parent.disk2],
@@ -331,7 +330,7 @@ def makeLinuxMipsSystem(mem_mode, mdesc = None):
self.iobus = NoncoherentBus()
self.membus = MemBus()
self.bridge = Bridge(delay='50ns')
- self.physmem = SimpleDDR3(range = AddrRange('1GB'))
+ self.physmem = MemClass(range = AddrRange('1GB'))
self.mem_ranges = [self.physmem.range]
self.bridge.master = self.iobus.slave
self.bridge.slave = self.membus.master
@@ -425,7 +424,8 @@ def connectX86RubySystem(x86_sys):
x86_sys.pc.attachIO(x86_sys.piobus, x86_sys._dma_ports)
-def makeX86System(mem_mode, numCPUs = 1, mdesc = None, self = None, Ruby = False):
+def makeX86System(mem_mode, MemClass, numCPUs = 1, mdesc = None, self = None,
+ Ruby = False):
if self == None:
self = X86System()
@@ -437,7 +437,7 @@ def makeX86System(mem_mode, numCPUs = 1, mdesc = None, self = None, Ruby = False
self.mem_mode = mem_mode
# Physical memory
- self.physmem = SimpleDDR3(range = AddrRange(mdesc.mem()))
+ self.physmem = MemClass(range = AddrRange(mdesc.mem()))
self.mem_ranges = [self.physmem.range]
# Platform
@@ -521,11 +521,12 @@ def makeX86System(mem_mode, numCPUs = 1, mdesc = None, self = None, Ruby = False
self.intel_mp_table.base_entries = base_entries
self.intel_mp_table.ext_entries = ext_entries
-def makeLinuxX86System(mem_mode, numCPUs = 1, mdesc = None, Ruby = False):
+def makeLinuxX86System(mem_mode, MemClass, numCPUs = 1, mdesc = None,
+ Ruby = False):
self = LinuxX86System()
# Build up the x86 system and then specialize it for Linux
- makeX86System(mem_mode, numCPUs, mdesc, self, Ruby)
+ makeX86System(mem_mode, MemClass, numCPUs, mdesc, self, Ruby)
# We assume below that there's at least 1MB of memory. We'll require 2
# just to avoid corner cases.
diff --git a/configs/common/MemConfig.py b/configs/common/MemConfig.py
new file mode 100644
index 000000000..4e772c3ea
--- /dev/null
+++ b/configs/common/MemConfig.py
@@ -0,0 +1,125 @@
+# Copyright (c) 2013 ARM Limited
+# All rights reserved.
+#
+# The license below extends only to copyright in the software and shall
+# not be construed as granting a license to any other intellectual
+# property including but not limited to intellectual property relating
+# to a hardware implementation of the functionality of the software
+# licensed hereunder. You may use the software subject to the license
+# terms below provided that you ensure that this notice is replicated
+# unmodified and in its entirety in all distributions of the software,
+# modified or unmodified, in source code or in binary form.
+#
+# 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: Andreas Sandberg
+# Andreas Hansson
+
+import m5.objects
+import inspect
+import sys
+from textwrap import TextWrapper
+
+# Dictionary of mapping names of real memory controller models to
+# classes.
+_mem_classes = {}
+
+# Memory aliases. We make sure they exist before we add them to the
+# fina; list. A target may be specified as a tuple, in which case the
+# first available memory controller model in the tuple will be used.
+_mem_aliases_all = [
+ ("simple_mem", "SimpleMemory"),
+ ("ddr3-1600", "SimpleDDR3"),
+ ("lpddr2_s4-1066", "SimpleLPDDR2_S4"),
+ ("wio-200", "SimpleWideIO"),
+ ]
+
+# Filtered list of aliases. Only aliases for existing memory
+# controllers exist in this list.
+_mem_aliases = {}
+
+
+def is_mem_class(cls):
+ """Determine if a class is a memory controller that can be instantiated"""
+
+ # We can't use the normal inspect.isclass because the ParamFactory
+ # and ProxyFactory classes have a tendency to confuse it.
+ try:
+ return issubclass(cls, m5.objects.AbstractMemory) and \
+ not cls.abstract
+ except TypeError:
+ return False
+
+def get(name):
+ """Get a memory class from a user provided class name or alias."""
+
+ real_name = _mem_aliases.get(name, name)
+
+ try:
+ mem_class = _mem_classes[real_name]
+ return mem_class
+ except KeyError:
+ print "%s is not a valid memory controller." % (name,)
+ sys.exit(1)
+
+def print_mem_list():
+ """Print a list of available memory classes including their aliases."""
+
+ print "Available memory classes:"
+ doc_wrapper = TextWrapper(initial_indent="\t\t", subsequent_indent="\t\t")
+ for name, cls in _mem_classes.items():
+ print "\t%s" % name
+
+ # Try to extract the class documentation from the class help
+ # string.
+ doc = inspect.getdoc(cls)
+ if doc:
+ for line in doc_wrapper.wrap(doc):
+ print line
+
+ if _mem_aliases:
+ print "\nMemory aliases:"
+ for alias, target in _mem_aliases.items():
+ print "\t%s => %s" % (alias, target)
+
+def mem_names():
+ """Return a list of valid memory names."""
+ return _mem_classes.keys() + _mem_aliases.keys()
+
+# Add all memory controllers in the object hierarchy.
+for name, cls in inspect.getmembers(m5.objects, is_mem_class):
+ _mem_classes[name] = cls
+
+for alias, target in _mem_aliases_all:
+ if isinstance(target, tuple):
+ # Some aliases contain a list of memory controller models
+ # sorted in priority order. Use the first target that's
+ # available.
+ for t in target:
+ if t in _mem_classes:
+ _mem_aliases[alias] = t
+ break
+ elif target in _mem_classes:
+ # Normal alias
+ _mem_aliases[alias] = target
diff --git a/configs/common/Options.py b/configs/common/Options.py
index 474da94f4..e651e96ec 100644
--- a/configs/common/Options.py
+++ b/configs/common/Options.py
@@ -1,3 +1,15 @@
+# Copyright (c) 2013 ARM Limited
+# All rights reserved.
+#
+# The license below extends only to copyright in the software and shall
+# not be construed as granting a license to any other intellectual
+# property including but not limited to intellectual property relating
+# to a hardware implementation of the functionality of the software
+# licensed hereunder. You may use the software subject to the license
+# terms below provided that you ensure that this notice is replicated
+# unmodified and in its entirety in all distributions of the software,
+# modified or unmodified, in source code or in binary form.
+#
# Copyright (c) 2006-2008 The Regents of The University of Michigan
# All rights reserved.
#
@@ -32,11 +44,16 @@ from m5.objects import *
from Benchmarks import *
import CpuConfig
+import MemConfig
def _listCpuTypes(option, opt, value, parser):
CpuConfig.print_cpu_list()
sys.exit(0)
+def _listMemTypes(option, opt, value, parser):
+ MemConfig.print_mem_list()
+ sys.exit(0)
+
def addCommonOptions(parser):
# system options
parser.add_option("--list-cpu-types",
@@ -45,6 +62,12 @@ def addCommonOptions(parser):
parser.add_option("--cpu-type", type="choice", default="atomic",
choices=CpuConfig.cpu_names(),
help = "type of cpu to run with")
+ parser.add_option("--list-mem-types",
+ action="callback", callback=_listMemTypes,
+ help="List available memory types")
+ parser.add_option("--mem-type", type="choice", default="simple_mem",
+ choices=MemConfig.mem_names(),
+ help = "type of memory to use")
parser.add_option("--checker", action="store_true");
parser.add_option("-n", "--num-cpus", type="int", default=1)
parser.add_option("--caches", action="store_true")
diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py
index cecf030ad..27b1a510a 100644
--- a/configs/common/Simulation.py
+++ b/configs/common/Simulation.py
@@ -44,6 +44,7 @@ from os import getcwd
from os.path import join as joinpath
import CpuConfig
+import MemConfig
import m5
from m5.defines import buildEnv
@@ -84,6 +85,11 @@ def setCPUClass(options):
return (TmpClass, test_mem_mode, CPUClass)
+def setMemClass(options):
+ """Returns a memory controller class."""
+
+ return MemConfig.get(options.mem_type)
+
def setWorkCountOptions(system, options):
if options.work_item_id != None:
system.work_item_id = options.work_item_id
diff --git a/configs/example/fs.py b/configs/example/fs.py
index 1f8e2d3a7..4fedf12db 100644
--- a/configs/example/fs.py
+++ b/configs/example/fs.py
@@ -84,6 +84,11 @@ def is_kvm_cpu(cpu_class):
TestCPUClass.clock = options.clock
DriveCPUClass.clock = options.clock
+# Match the memories with the CPUs, the driver system always simple,
+# and based on the options for the test system
+DriveMemClass = SimpleMemory
+TestMemClass = Simulation.setMemClass(options)
+
if options.benchmark:
try:
bm = Benchmarks[options.benchmark]
@@ -100,16 +105,18 @@ else:
np = options.num_cpus
if buildEnv['TARGET_ISA'] == "alpha":
- test_sys = makeLinuxAlphaSystem(test_mem_mode, bm[0])
+ test_sys = makeLinuxAlphaSystem(test_mem_mode, TestMemClass, bm[0])
elif buildEnv['TARGET_ISA'] == "mips":
- test_sys = makeLinuxMipsSystem(test_mem_mode, bm[0])
+ test_sys = makeLinuxMipsSystem(test_mem_mode, TestMemClass, bm[0])
elif buildEnv['TARGET_ISA'] == "sparc":
- test_sys = makeSparcSystem(test_mem_mode, bm[0])
+ test_sys = makeSparcSystem(test_mem_mode, TestMemClass, bm[0])
elif buildEnv['TARGET_ISA'] == "x86":
- test_sys = makeLinuxX86System(test_mem_mode, options.num_cpus, bm[0])
+ test_sys = makeLinuxX86System(test_mem_mode, TestMemClass,
+ options.num_cpus, bm[0])
elif buildEnv['TARGET_ISA'] == "arm":
- test_sys = makeArmSystem(test_mem_mode, options.machine_type, bm[0],
- options.dtb_filename, bare_metal=options.bare_metal)
+ test_sys = makeArmSystem(test_mem_mode, options.machine_type,
+ TestMemClass, bm[0], options.dtb_filename,
+ bare_metal=options.bare_metal)
else:
fatal("Incapable of building %s full system!", buildEnv['TARGET_ISA'])
@@ -154,15 +161,16 @@ CacheConfig.config_cache(options, test_sys)
if len(bm) == 2:
if buildEnv['TARGET_ISA'] == 'alpha':
- drive_sys = makeLinuxAlphaSystem(drive_mem_mode, bm[1])
+ drive_sys = makeLinuxAlphaSystem(drive_mem_mode, DriveMemClass, bm[1])
elif buildEnv['TARGET_ISA'] == 'mips':
- drive_sys = makeLinuxMipsSystem(drive_mem_mode, bm[1])
+ drive_sys = makeLinuxMipsSystem(drive_mem_mode, DriveMemClass, bm[1])
elif buildEnv['TARGET_ISA'] == 'sparc':
- drive_sys = makeSparcSystem(drive_mem_mode, bm[1])
+ drive_sys = makeSparcSystem(drive_mem_mode, DriveMemClass, bm[1])
elif buildEnv['TARGET_ISA'] == 'x86':
- drive_sys = makeX86System(drive_mem_mode, np, bm[1])
+ drive_sys = makeX86System(drive_mem_mode, DriveMemClass, np, bm[1])
elif buildEnv['TARGET_ISA'] == 'arm':
- drive_sys = makeArmSystem(drive_mem_mode, options.machine_type, bm[1])
+ drive_sys = makeArmSystem(drive_mem_mode, options.machine_type,
+ DriveMemClass, bm[1])
drive_sys.cpu = DriveCPUClass(cpu_id=0)
drive_sys.cpu.createThreads()
diff --git a/configs/example/se.py b/configs/example/se.py
index a5f0204fd..6878742c8 100644
--- a/configs/example/se.py
+++ b/configs/example/se.py
@@ -150,13 +150,15 @@ else:
CPUClass.clock = options.clock
CPUClass.numThreads = numThreads
+MemClass = Simulation.setMemClass(options)
+
# Check -- do not allow SMT with multiple CPUs
if options.smt and options.num_cpus > 1:
fatal("You cannot use SMT with multiple CPUs!")
np = options.num_cpus
system = System(cpu = [CPUClass(cpu_id=i) for i in xrange(np)],
- physmem = SimpleMemory(range=AddrRange("512MB")),
+ physmem = MemClass(range=AddrRange("512MB")),
membus = CoherentBus(), mem_mode = test_mem_mode)
# Sanity check
diff --git a/tests/configs/alpha_generic.py b/tests/configs/alpha_generic.py
index a4ebba54d..5060eae39 100644
--- a/tests/configs/alpha_generic.py
+++ b/tests/configs/alpha_generic.py
@@ -59,7 +59,7 @@ class LinuxAlphaSystemBuilder(object):
pass
def create_system(self):
- system = FSConfig.makeLinuxAlphaSystem(self.mem_mode)
+ system = FSConfig.makeLinuxAlphaSystem(self.mem_mode, SimpleDDR3)
self.init_system(system)
return system
diff --git a/tests/configs/arm_generic.py b/tests/configs/arm_generic.py
index 1b0e8ee8b..e6c56041b 100644
--- a/tests/configs/arm_generic.py
+++ b/tests/configs/arm_generic.py
@@ -61,6 +61,7 @@ class LinuxArmSystemBuilder(object):
def create_system(self):
system = FSConfig.makeArmSystem(self.mem_mode,
self.machine_type,
+ SimpleDDR3,
None, False)
# We typically want the simulator to panic if the kernel
diff --git a/tests/configs/pc-simple-timing-ruby.py b/tests/configs/pc-simple-timing-ruby.py
index 23a0bb3d0..6413133c2 100644
--- a/tests/configs/pc-simple-timing-ruby.py
+++ b/tests/configs/pc-simple-timing-ruby.py
@@ -55,7 +55,7 @@ options.num_cpus = 2
#the system
mdesc = SysConfig(disk = 'linux-x86.img')
-system = FSConfig.makeLinuxX86System('timing', options.num_cpus,
+system = FSConfig.makeLinuxX86System('timing', SimpleDDR3, options.num_cpus,
mdesc=mdesc, Ruby=True)
system.kernel = FSConfig.binary('x86_64-vmlinux-2.6.22.9.smp')
system.cpu = [TimingSimpleCPU(cpu_id=i) for i in xrange(options.num_cpus)]
diff --git a/tests/configs/twosys-tsunami-simple-atomic.py b/tests/configs/twosys-tsunami-simple-atomic.py
index dbfcaaafe..89d497008 100644
--- a/tests/configs/twosys-tsunami-simple-atomic.py
+++ b/tests/configs/twosys-tsunami-simple-atomic.py
@@ -32,7 +32,7 @@ m5.util.addToPath('../configs/common')
from FSConfig import *
from Benchmarks import *
-test_sys = makeLinuxAlphaSystem('atomic',
+test_sys = makeLinuxAlphaSystem('atomic', SimpleDDR3,
SysConfig('netperf-stream-client.rcS'))
test_sys.cpu = AtomicSimpleCPU(cpu_id=0)
# create the interrupt controller
@@ -46,7 +46,7 @@ test_sys.iobridge = Bridge(delay='50ns', ranges = test_sys.mem_ranges)
test_sys.iobridge.slave = test_sys.iobus.master
test_sys.iobridge.master = test_sys.membus.slave
-drive_sys = makeLinuxAlphaSystem('atomic',
+drive_sys = makeLinuxAlphaSystem('atomic', SimpleDDR3,
SysConfig('netperf-server.rcS'))
drive_sys.cpu = AtomicSimpleCPU(cpu_id=0)
# create the interrupt controller
diff --git a/tests/configs/x86_generic.py b/tests/configs/x86_generic.py
index b9f8f7122..e9e7bff63 100644
--- a/tests/configs/x86_generic.py
+++ b/tests/configs/x86_generic.py
@@ -58,6 +58,7 @@ class LinuxX86SystemBuilder(object):
def create_system(self):
mdesc = SysConfig(disk = 'linux-x86.img')
system = FSConfig.makeLinuxX86System(self.mem_mode,
+ SimpleDDR3,
numCPUs=self.num_cpus,
mdesc=mdesc)
system.kernel = FSConfig.binary('x86_64-vmlinux-2.6.22.9')