From: Andreas Sandberg Date: Fri, 4 Dec 2015 00:19:05 +0000 (+0000) Subject: arm, config: Automatically discover available platforms X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6a05179e13a2ac8e72feb4bd00647013940d814e;p=gem5.git arm, config: Automatically discover available platforms Add support for automatically discover available platforms. The Python-side uses functionality similar to what we use when auto-detecting available CPU models. The machine IDs have been updated to match the platform configurations. If there isn't a matching machine ID, the configuration scripts default to -1 which Linux uses for device tree only platforms. --- diff --git a/configs/common/FSConfig.py b/configs/common/FSConfig.py index 7dd2e05fd..e449efbd5 100644 --- a/configs/common/FSConfig.py +++ b/configs/common/FSConfig.py @@ -42,6 +42,7 @@ from m5.objects import * from Benchmarks import * from m5.util import * +import PlatformConfig # Populate to reflect supported os types per target ISA os_types = { 'alpha' : [ 'linux' ], @@ -207,6 +208,20 @@ def makeArmSystem(mem_mode, machine_type, num_cpus=1, mdesc=None, external_memory=""): assert machine_type + default_dtbs = { + "RealViewEB": None, + "RealViewPBX": None, + "VExpress_EMM": "vexpress.aarch32.ll_20131205.0-gem5.%dcpu.dtb" % num_cpus, + "VExpress_EMM64": "vexpress.aarch64.20140821.dtb", + } + + default_kernels = { + "RealViewEB": "vmlinux.arm.smp.fb.2.6.38.8", + "RealViewPBX": "vmlinux.arm.smp.fb.2.6.38.8", + "VExpress_EMM": "vmlinux.aarch32.ll_20131205.0-gem5", + "VExpress_EMM64": "vmlinux.aarch64.20140821", + } + if bare_metal: self = ArmSystem() else: @@ -226,24 +241,23 @@ def makeArmSystem(mem_mode, machine_type, num_cpus=1, mdesc=None, self.mem_mode = mem_mode - if machine_type == "RealView_PBX": - self.realview = RealViewPBX() - elif machine_type == "RealView_EB": - self.realview = RealViewEB() - elif machine_type == "VExpress_EMM": - self.realview = VExpress_EMM() - if not dtb_filename: - dtb_filename = 'vexpress.aarch32.ll_20131205.0-gem5.%dcpu.dtb' % num_cpus - elif machine_type == "VExpress_EMM64": - self.realview = VExpress_EMM64() + platform_class = PlatformConfig.get(machine_type) + # Resolve the real platform name, the original machine_type + # variable might have been an alias. + machine_type = platform_class.__name__ + self.realview = platform_class() + + if not dtb_filename and not bare_metal: + try: + dtb_filename = default_dtbs[machine_type] + except KeyError: + fatal("No DTB specified and no default DTB known for '%s'" % \ + machine_type) + + if isinstance(self.realview, VExpress_EMM64): if os.path.split(mdesc.disk())[-1] == 'linux-aarch32-ael.img': print "Selected 64-bit ARM architecture, updating default disk image..." mdesc.diskname = 'linaro-minimal-aarch64.img' - if not dtb_filename: - dtb_filename = 'vexpress.aarch64.20140821.dtb' - else: - print "Unknown Machine Type" - sys.exit(1) self.cf0 = CowIdeDisk(driveID='master') self.cf0.childImage(mdesc.disk()) @@ -278,16 +292,15 @@ def makeArmSystem(mem_mode, machine_type, num_cpus=1, mdesc=None, # EOT character on UART will end the simulation self.realview.uart.end_on_eot = True else: - if machine_type == "VExpress_EMM64": - self.kernel = binary('vmlinux.aarch64.20140821') - elif machine_type == "VExpress_EMM": - self.kernel = binary('vmlinux.aarch32.ll_20131205.0-gem5') - else: - self.kernel = binary('vmlinux.arm.smp.fb.2.6.38.8') + if machine_type in default_kernels: + self.kernel = binary(default_kernels[machine_type]) if dtb_filename: self.dtb_filename = binary(dtb_filename) - self.machine_type = machine_type + + self.machine_type = machine_type if machine_type in ArmMachineType.map \ + else "DTOnly" + # Ensure that writes to the UART actually go out early in the boot if not cmdline: cmdline = 'earlyprintk=pl011,0x1c090000 console=ttyAMA0 ' + \ diff --git a/configs/common/Options.py b/configs/common/Options.py index 1922f78a6..f4cf9fbd6 100644 --- a/configs/common/Options.py +++ b/configs/common/Options.py @@ -45,6 +45,7 @@ from Benchmarks import * import CpuConfig import MemConfig +import PlatformConfig from FSConfig import os_types @@ -56,6 +57,10 @@ def _listMemTypes(option, opt, value, parser): MemConfig.print_mem_list() sys.exit(0) +def _listPlatformTypes(option, opt, value, parser): + PlatformConfig.print_platform_list() + sys.exit(0) + def addCommonOptions(parser): # system options parser.add_option("--list-cpu-types", @@ -263,8 +268,12 @@ def addFSOptions(parser): if buildEnv['TARGET_ISA'] == "arm": parser.add_option("--bare-metal", action="store_true", help="Provide the raw system without the linux specific bits") + parser.add_option("--list-machine-types", + action="callback", callback=_listPlatformTypes, + help="List available platform types") parser.add_option("--machine-type", action="store", type="choice", - choices=ArmMachineType.map.keys(), default="VExpress_EMM") + choices=PlatformConfig.platform_names(), + default="VExpress_EMM") parser.add_option("--dtb-filename", action="store", type="string", help="Specifies device tree blob file to use with device-tree-"\ "enabled kernels") diff --git a/configs/common/PlatformConfig.py b/configs/common/PlatformConfig.py new file mode 100644 index 000000000..636e6d8ac --- /dev/null +++ b/configs/common/PlatformConfig.py @@ -0,0 +1,109 @@ +# Copyright (c) 2012, 2015 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 + +import m5.objects +import inspect +import sys +from textwrap import TextWrapper + +# Dictionary of mapping names of real CPU models to classes. +_platform_classes = {} + +# Platform aliases. The platforms listed here might not be compiled, +# we make sure they exist before we add them to the platform list. +_platform_aliases_all = [ + ("RealView_EB", "RealViewEB"), + ("RealView_PBX", "RealViewPBX"), + ] + +# Filtered list of aliases. Only aliases for existing platforms exist +# in this list. +_platform_aliases = {} + +def is_platform_class(cls): + """Determine if a class is a Platform 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.Platform) and \ + not cls.abstract + except TypeError: + return False + +def get(name): + """Get a platform class from a user provided class name.""" + + real_name = _platform_aliases.get(name, name) + + try: + return _platform_classes[real_name] + except KeyError: + print "%s is not a valid Platform model." % (name,) + sys.exit(1) + +def print_platform_list(): + """Print a list of available Platform classes including their aliases.""" + + print "Available Platform classes:" + doc_wrapper = TextWrapper(initial_indent="\t\t", subsequent_indent="\t\t") + for name, cls in _platform_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 _platform_aliases: + print "\Platform aliases:" + for alias, target in _platform_aliases.items(): + print "\t%s => %s" % (alias, target) + +def platform_names(): + """Return a list of valid Platform names.""" + return _platform_classes.keys() + _platform_aliases.keys() + +# Add all Platforms in the object hierarchy. +for name, cls in inspect.getmembers(m5.objects, is_platform_class): + _platform_classes[name] = cls + +for alias, target in _platform_aliases_all: + if target in _platform_classes: + _platform_aliases[alias] = target diff --git a/src/arch/arm/ArmSystem.py b/src/arch/arm/ArmSystem.py index 1e5acc4e6..9bb939c5e 100644 --- a/src/arch/arm/ArmSystem.py +++ b/src/arch/arm/ArmSystem.py @@ -40,10 +40,13 @@ from m5.params import * from System import System class ArmMachineType(Enum): - map = {'RealView_EB' : 827, - 'RealView_PBX' : 1901, - 'VExpress_EMM' : 2272, - 'VExpress_EMM64' : 2272} + map = { + 'RealViewEB' : 827, + 'RealViewPBX' : 1901, + 'VExpress_EMM' : 2272, + 'VExpress_EMM64' : 2272, + 'DTOnly' : -1, + } class ArmSystem(System): type = 'ArmSystem'