diff options
Diffstat (limited to 'configs/common')
-rw-r--r-- | configs/common/FSConfig.py | 47 | ||||
-rw-r--r-- | configs/common/MemConfig.py | 125 | ||||
-rw-r--r-- | configs/common/Options.py | 23 | ||||
-rw-r--r-- | configs/common/Simulation.py | 6 |
4 files changed, 178 insertions, 23 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 |