configs,tests: use Sequencer port connect methods
[gem5.git] / configs / example / fs.py
index 19a2bd358ed1f11e75375e24e6d4997463cebd89..1cd53db14c483d8a81f94793be999a7c8626a35e 100644 (file)
@@ -1,4 +1,5 @@
-# Copyright (c) 2010-2013 ARM Limited
+# Copyright (c) 2010-2013, 2016, 2019-2020 ARM Limited
+# Copyright (c) 2020 Barkhausen Institut
 # All rights reserved.
 #
 # The license below extends only to copyright in the software and shall
@@ -37,9 +38,9 @@
 # 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: Ali Saidi
-#          Brad Beckmann
+
+from __future__ import print_function
+from __future__ import absolute_import
 
 import optparse
 import sys
@@ -47,44 +48,62 @@ import sys
 import m5
 from m5.defines import buildEnv
 from m5.objects import *
-from m5.util import addToPath, fatal
-
-addToPath('../common')
-addToPath('../ruby')
-
-import Ruby
-
-from FSConfig import *
-from SysPaths import *
-from Benchmarks import *
-import Simulation
-import CacheConfig
-import MemConfig
-from Caches import *
-import Options
-
-
-# Check if KVM support has been enabled, we might need to do VM
-# configuration if that's the case.
-have_kvm_support = 'BaseKvmCPU' in globals()
-def is_kvm_cpu(cpu_class):
-    return have_kvm_support and cpu_class != None and \
-        issubclass(cpu_class, BaseKvmCPU)
+from m5.util import addToPath, fatal, warn
+from m5.util.fdthelper import *
+
+addToPath('../')
+
+from ruby import Ruby
+
+from common.FSConfig import *
+from common.SysPaths import *
+from common.Benchmarks import *
+from common import Simulation
+from common import CacheConfig
+from common import CpuConfig
+from common import MemConfig
+from common import ObjectList
+from common.Caches import *
+from common import Options
+
+def cmd_line_template():
+    if options.command_line and options.command_line_file:
+        print("Error: --command-line and --command-line-file are "
+              "mutually exclusive")
+        sys.exit(1)
+    if options.command_line:
+        return options.command_line
+    if options.command_line_file:
+        return open(options.command_line_file).read().strip()
+    return None
 
 def build_test_system(np):
-    if buildEnv['TARGET_ISA'] == "alpha":
-        test_sys = makeLinuxAlphaSystem(test_mem_mode, bm[0], options.ruby)
-    elif buildEnv['TARGET_ISA'] == "mips":
-        test_sys = makeLinuxMipsSystem(test_mem_mode, bm[0])
+    cmdline = cmd_line_template()
+    if buildEnv['TARGET_ISA'] == "mips":
+        test_sys = makeLinuxMipsSystem(test_mem_mode, bm[0], cmdline=cmdline)
     elif buildEnv['TARGET_ISA'] == "sparc":
-        test_sys = makeSparcSystem(test_mem_mode, bm[0])
+        test_sys = makeSparcSystem(test_mem_mode, bm[0], cmdline=cmdline)
+    elif buildEnv['TARGET_ISA'] == "riscv":
+        test_sys = makeBareMetalRiscvSystem(test_mem_mode, bm[0],
+                                            cmdline=cmdline)
     elif buildEnv['TARGET_ISA'] == "x86":
-        test_sys = makeLinuxX86System(test_mem_mode, options.num_cpus, bm[0],
-                options.ruby)
+        test_sys = makeLinuxX86System(test_mem_mode, np, bm[0], options.ruby,
+                                      cmdline=cmdline)
     elif buildEnv['TARGET_ISA'] == "arm":
-        test_sys = makeArmSystem(test_mem_mode, options.machine_type,
-                                 options.num_cpus, bm[0], options.dtb_filename,
-                                 bare_metal=options.bare_metal)
+        test_sys = makeArmSystem(
+            test_mem_mode,
+            options.machine_type,
+            np,
+            bm[0],
+            options.dtb_filename,
+            bare_metal=options.bare_metal,
+            cmdline=cmdline,
+            external_memory=options.external_memory_system,
+            ruby=options.ruby,
+            security=options.enable_security_extensions,
+            vio_9p=options.vio_9p,
+            bootloader=options.bootloader,
+        )
         if options.enable_context_switch_stats_dump:
             test_sys.enable_context_switch_stats_dump = True
     else:
@@ -108,8 +127,10 @@ def build_test_system(np):
                                              voltage_domain =
                                              test_sys.cpu_voltage_domain)
 
-    if options.kernel is not None:
-        test_sys.kernel = binary(options.kernel)
+    if buildEnv['TARGET_ISA'] == 'riscv':
+        test_sys.workload.bootloader = options.kernel
+    elif options.kernel is not None:
+        test_sys.workload.object_file = binary(options.kernel)
 
     if options.script is not None:
         test_sys.readfile = options.script
@@ -124,23 +145,25 @@ def build_test_system(np):
 
     # For now, assign all the CPUs to the same clock domain
     test_sys.cpu = [TestCPUClass(clk_domain=test_sys.cpu_clk_domain, cpu_id=i)
-                    for i in xrange(np)]
+                    for i in range(np)]
 
-    if is_kvm_cpu(TestCPUClass) or is_kvm_cpu(FutureClass):
-        test_sys.vm = KvmVM()
+    if ObjectList.is_kvm_cpu(TestCPUClass) or \
+        ObjectList.is_kvm_cpu(FutureClass):
+        test_sys.kvm_vm = KvmVM()
 
     if options.ruby:
-        # Check for timing mode because ruby does not support atomic accesses
-        if not (options.cpu_type == "detailed" or options.cpu_type == "timing"):
-            print >> sys.stderr, "Ruby requires TimingSimpleCPU or O3CPU!!"
-            sys.exit(1)
-
-        Ruby.create_system(options, test_sys, test_sys.iobus, test_sys._dma_ports)
+        bootmem = getattr(test_sys, '_bootmem', None)
+        Ruby.create_system(options, True, test_sys, test_sys.iobus,
+                           test_sys._dma_ports, bootmem)
 
         # Create a seperate clock domain for Ruby
         test_sys.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock,
                                         voltage_domain = test_sys.voltage_domain)
 
+        # 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
+
         for (i, cpu) in enumerate(test_sys.cpu):
             #
             # Tie the cpu ports to the correct ruby system ports
@@ -149,24 +172,7 @@ def build_test_system(np):
             cpu.createThreads()
             cpu.createInterruptController()
 
-            cpu.icache_port = test_sys.ruby._cpu_ports[i].slave
-            cpu.dcache_port = test_sys.ruby._cpu_ports[i].slave
-
-            if buildEnv['TARGET_ISA'] == "x86":
-                cpu.itb.walker.port = test_sys.ruby._cpu_ports[i].slave
-                cpu.dtb.walker.port = test_sys.ruby._cpu_ports[i].slave
-
-                cpu.interrupts.pio = test_sys.ruby._cpu_ports[i].master
-                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
+            test_sys.ruby._cpu_ports[i].connectCpuPorts(cpu)
 
     else:
         if options.caches or options.l2cache:
@@ -174,26 +180,47 @@ def build_test_system(np):
             test_sys.iocache = IOCache(addr_ranges = test_sys.mem_ranges)
             test_sys.iocache.cpu_side = test_sys.iobus.master
             test_sys.iocache.mem_side = test_sys.membus.slave
-        else:
+        elif not options.external_memory_system:
             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
 
         # Sanity check
-        if options.fastmem:
-            if TestCPUClass != AtomicSimpleCPU:
-                fatal("Fastmem can only be used with atomic CPU!")
-            if (options.caches or options.l2cache):
-                fatal("You cannot use fastmem in combination with caches!")
-
-        for i in xrange(np):
-            if options.fastmem:
-                test_sys.cpu[i].fastmem = True
+        if options.simpoint_profile:
+            if not ObjectList.is_noncaching_cpu(TestCPUClass):
+                fatal("SimPoint generation should be done with atomic cpu")
+            if np > 1:
+                fatal("SimPoint generation not supported with more than one CPUs")
+
+        for i in range(np):
+            if options.simpoint_profile:
+                test_sys.cpu[i].addSimPointProbe(options.simpoint_interval)
             if options.checker:
                 test_sys.cpu[i].addCheckerCpu()
+            if not ObjectList.is_kvm_cpu(TestCPUClass):
+                if options.bp_type:
+                    bpClass = ObjectList.bp_list.get(options.bp_type)
+                    test_sys.cpu[i].branchPred = bpClass()
+                if options.indirect_bp_type:
+                    IndirectBPClass = ObjectList.indirect_bp_list.get(
+                        options.indirect_bp_type)
+                    test_sys.cpu[i].branchPred.indirectBranchPred = \
+                        IndirectBPClass()
             test_sys.cpu[i].createThreads()
 
+        # If elastic tracing is enabled when not restoring from checkpoint and
+        # when not fast forwarding using the atomic cpu, then check that the
+        # TestCPUClass is DerivO3CPU or inherits from DerivO3CPU. If the check
+        # passes then attach the elastic trace probe.
+        # If restoring from checkpoint or fast forwarding, the code that does this for
+        # FutureCPUClass is in the Simulation module. If the check passes then the
+        # elastic trace probe is attached to the switch CPUs.
+        if options.elastic_trace_en and options.checkpoint_restore == None and \
+            not options.fast_forward:
+            CpuConfig.config_etrace(TestCPUClass, test_sys.cpu, options)
+
         CacheConfig.config_cache(options, test_sys)
+
         MemConfig.config_mem(options, test_sys)
 
     return test_sys
@@ -205,16 +232,17 @@ def build_drive_system(np):
     drive_mem_mode = 'atomic'
     DriveMemClass = SimpleMemory
 
-    if buildEnv['TARGET_ISA'] == 'alpha':
-        drive_sys = makeLinuxAlphaSystem(drive_mem_mode, bm[1])
-    elif buildEnv['TARGET_ISA'] == 'mips':
-        drive_sys = makeLinuxMipsSystem(drive_mem_mode, bm[1])
+    cmdline = cmd_line_template()
+    if buildEnv['TARGET_ISA'] == 'mips':
+        drive_sys = makeLinuxMipsSystem(drive_mem_mode, bm[1], cmdline=cmdline)
     elif buildEnv['TARGET_ISA'] == 'sparc':
-        drive_sys = makeSparcSystem(drive_mem_mode, bm[1])
+        drive_sys = makeSparcSystem(drive_mem_mode, bm[1], cmdline=cmdline)
     elif buildEnv['TARGET_ISA'] == 'x86':
-        drive_sys = makeLinuxX86System(drive_mem_mode, np, bm[1])
+        drive_sys = makeLinuxX86System(drive_mem_mode, np, bm[1],
+                                       cmdline=cmdline)
     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, np,
+                                  bm[1], options.dtb_filename, cmdline=cmdline)
 
     # Create a top-level voltage domain
     drive_sys.voltage_domain = VoltageDomain(voltage = options.sys_voltage)
@@ -236,13 +264,11 @@ def build_drive_system(np):
     drive_sys.cpu.createThreads()
     drive_sys.cpu.createInterruptController()
     drive_sys.cpu.connectAllPorts(drive_sys.membus)
-    if options.fastmem:
-        drive_sys.cpu.fastmem = True
     if options.kernel is not None:
-        drive_sys.kernel = binary(options.kernel)
+        drive_sys.workload.object_file = binary(options.kernel)
 
-    if is_kvm_cpu(DriveCPUClass):
-        drive_sys.vm = KvmVM()
+    if ObjectList.is_kvm_cpu(DriveCPUClass):
+        drive_sys.kvm_vm = KvmVM()
 
     drive_sys.iobridge = Bridge(delay='50ns',
                                 ranges = drive_sys.mem_ranges)
@@ -253,7 +279,7 @@ def build_drive_system(np):
     # memory bus
     drive_sys.mem_ctrls = [DriveMemClass(range = r)
                            for r in drive_sys.mem_ranges]
-    for i in xrange(len(drive_sys.mem_ctrls)):
+    for i in range(len(drive_sys.mem_ctrls)):
         drive_sys.mem_ctrls[i].port = drive_sys.membus.master
 
     drive_sys.init_param = options.init_param
@@ -272,7 +298,7 @@ if '--ruby' in sys.argv:
 (options, args) = parser.parse_args()
 
 if args:
-    print "Error: script doesn't take any positional arguments"
+    print("Error: script doesn't take any positional arguments")
     sys.exit(1)
 
 # system under test can be any CPU
@@ -285,15 +311,18 @@ if options.benchmark:
     try:
         bm = Benchmarks[options.benchmark]
     except KeyError:
-        print "Error benchmark %s has not been defined." % options.benchmark
-        print "Valid benchmarks are: %s" % DefinedBenchmarks
+        print("Error benchmark %s has not been defined." % options.benchmark)
+        print("Valid benchmarks are: %s" % DefinedBenchmarks)
         sys.exit(1)
 else:
     if options.dual:
-        bm = [SysConfig(disk=options.disk_image, mem=options.mem_size),
-              SysConfig(disk=options.disk_image, mem=options.mem_size)]
+        bm = [SysConfig(disks=options.disk_image, rootdev=options.root_device,
+                        mem=options.mem_size, os_type=options.os_type),
+              SysConfig(disks=options.disk_image, rootdev=options.root_device,
+                        mem=options.mem_size, os_type=options.os_type)]
     else:
-        bm = [SysConfig(disk=options.disk_image, mem=options.mem_size)]
+        bm = [SysConfig(disks=options.disk_image, rootdev=options.root_device,
+                        mem=options.mem_size, os_type=options.os_type)]
 
 np = options.num_cpus
 
@@ -301,10 +330,22 @@ test_sys = build_test_system(np)
 if len(bm) == 2:
     drive_sys = build_drive_system(np)
     root = makeDualRoot(True, test_sys, drive_sys, options.etherdump)
+elif len(bm) == 1 and options.dist:
+    # This system is part of a dist-gem5 simulation
+    root = makeDistRoot(test_sys,
+                        options.dist_rank,
+                        options.dist_size,
+                        options.dist_server_name,
+                        options.dist_server_port,
+                        options.dist_sync_repeat,
+                        options.dist_sync_start,
+                        options.ethernet_linkspeed,
+                        options.ethernet_linkdelay,
+                        options.etherdump);
 elif len(bm) == 1:
     root = Root(full_system=True, system=test_sys)
 else:
-    print "Error I don't know how to create more than 2 systems."
+    print("Error I don't know how to create more than 2 systems.")
     sys.exit(1)
 
 if options.timesync:
@@ -313,5 +354,23 @@ if options.timesync:
 if options.frame_capture:
     VncServer.frame_capture = True
 
+if buildEnv['TARGET_ISA'] == "arm" and not options.bare_metal \
+        and not options.dtb_filename:
+    if options.machine_type not in ["VExpress_GEM5",
+                                    "VExpress_GEM5_V1",
+                                    "VExpress_GEM5_V2",
+                                    "VExpress_GEM5_Foundation"]:
+        warn("Can only correctly generate a dtb for VExpress_GEM5_* " \
+             "platforms, unless custom hardware models have been equipped "\
+             "with generation functionality.")
+
+    # Generate a Device Tree
+    for sysname in ('system', 'testsys', 'drivesys'):
+        if hasattr(root, sysname):
+            sys = getattr(root, sysname)
+            sys.workload.dtb_filename = \
+                os.path.join(m5.options.outdir, '%s.dtb' % sysname)
+            sys.generateDtb(sys.workload.dtb_filename)
+
 Simulation.setWorkCountOptions(test_sys, options)
 Simulation.run(options, root, test_sys, FutureClass)