se.py revision 10555:9f456b5cc474
17322Sgblack@eecs.umich.edu# Copyright (c) 2012-2013 ARM Limited
27322Sgblack@eecs.umich.edu# All rights reserved.
37322Sgblack@eecs.umich.edu#
47322Sgblack@eecs.umich.edu# The license below extends only to copyright in the software and shall
57322Sgblack@eecs.umich.edu# not be construed as granting a license to any other intellectual
67322Sgblack@eecs.umich.edu# property including but not limited to intellectual property relating
77322Sgblack@eecs.umich.edu# to a hardware implementation of the functionality of the software
87322Sgblack@eecs.umich.edu# licensed hereunder.  You may use the software subject to the license
97322Sgblack@eecs.umich.edu# terms below provided that you ensure that this notice is replicated
107322Sgblack@eecs.umich.edu# unmodified and in its entirety in all distributions of the software,
117322Sgblack@eecs.umich.edu# modified or unmodified, in source code or in binary form.
127322Sgblack@eecs.umich.edu#
137322Sgblack@eecs.umich.edu# Copyright (c) 2006-2008 The Regents of The University of Michigan
147322Sgblack@eecs.umich.edu# All rights reserved.
157322Sgblack@eecs.umich.edu#
167322Sgblack@eecs.umich.edu# Redistribution and use in source and binary forms, with or without
177322Sgblack@eecs.umich.edu# modification, are permitted provided that the following conditions are
187322Sgblack@eecs.umich.edu# met: redistributions of source code must retain the above copyright
197322Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer;
207322Sgblack@eecs.umich.edu# redistributions in binary form must reproduce the above copyright
217322Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the
227322Sgblack@eecs.umich.edu# documentation and/or other materials provided with the distribution;
237322Sgblack@eecs.umich.edu# neither the name of the copyright holders nor the names of its
247322Sgblack@eecs.umich.edu# contributors may be used to endorse or promote products derived from
257322Sgblack@eecs.umich.edu# this software without specific prior written permission.
267322Sgblack@eecs.umich.edu#
277322Sgblack@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
287322Sgblack@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
297322Sgblack@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
307322Sgblack@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
317322Sgblack@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
327322Sgblack@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
337322Sgblack@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
347322Sgblack@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
357322Sgblack@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
367322Sgblack@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
377322Sgblack@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
387322Sgblack@eecs.umich.edu#
397322Sgblack@eecs.umich.edu# Authors: Steve Reinhardt
407376Sgblack@eecs.umich.edu
417376Sgblack@eecs.umich.edu# Simple test script
427376Sgblack@eecs.umich.edu#
437376Sgblack@eecs.umich.edu# "m5 test.py"
447376Sgblack@eecs.umich.edu
457376Sgblack@eecs.umich.eduimport optparse
467376Sgblack@eecs.umich.eduimport sys
477376Sgblack@eecs.umich.eduimport os
487376Sgblack@eecs.umich.edu
497376Sgblack@eecs.umich.eduimport m5
507376Sgblack@eecs.umich.edufrom m5.defines import buildEnv
517376Sgblack@eecs.umich.edufrom m5.objects import *
527376Sgblack@eecs.umich.edufrom m5.util import addToPath, fatal
537376Sgblack@eecs.umich.edu
547376Sgblack@eecs.umich.eduaddToPath('../common')
557376Sgblack@eecs.umich.eduaddToPath('../ruby')
567376Sgblack@eecs.umich.edu
577376Sgblack@eecs.umich.eduimport Options
587376Sgblack@eecs.umich.eduimport Ruby
597376Sgblack@eecs.umich.eduimport Simulation
607376Sgblack@eecs.umich.eduimport CacheConfig
617376Sgblack@eecs.umich.eduimport MemConfig
627376Sgblack@eecs.umich.edufrom Caches import *
637376Sgblack@eecs.umich.edufrom cpu2000 import *
647376Sgblack@eecs.umich.edu
657376Sgblack@eecs.umich.edu# Check if KVM support has been enabled, we might need to do VM
667376Sgblack@eecs.umich.edu# configuration if that's the case.
677376Sgblack@eecs.umich.eduhave_kvm_support = 'BaseKvmCPU' in globals()
687376Sgblack@eecs.umich.edudef is_kvm_cpu(cpu_class):
697376Sgblack@eecs.umich.edu    return have_kvm_support and cpu_class != None and \
707376Sgblack@eecs.umich.edu        issubclass(cpu_class, BaseKvmCPU)
717376Sgblack@eecs.umich.edu
727376Sgblack@eecs.umich.edudef get_processes(options):
737376Sgblack@eecs.umich.edu    """Interprets provided options and returns a list of processes"""
747376Sgblack@eecs.umich.edu
757376Sgblack@eecs.umich.edu    multiprocesses = []
767376Sgblack@eecs.umich.edu    inputs = []
777376Sgblack@eecs.umich.edu    outputs = []
787376Sgblack@eecs.umich.edu    errouts = []
797376Sgblack@eecs.umich.edu    pargs = []
807376Sgblack@eecs.umich.edu
817376Sgblack@eecs.umich.edu    workloads = options.cmd.split(';')
827376Sgblack@eecs.umich.edu    if options.input != "":
837376Sgblack@eecs.umich.edu        inputs = options.input.split(';')
847376Sgblack@eecs.umich.edu    if options.output != "":
857376Sgblack@eecs.umich.edu        outputs = options.output.split(';')
867376Sgblack@eecs.umich.edu    if options.errout != "":
877376Sgblack@eecs.umich.edu        errouts = options.errout.split(';')
887376Sgblack@eecs.umich.edu    if options.options != "":
897376Sgblack@eecs.umich.edu        pargs = options.options.split(';')
907376Sgblack@eecs.umich.edu
917376Sgblack@eecs.umich.edu    idx = 0
927376Sgblack@eecs.umich.edu    for wrkld in workloads:
937376Sgblack@eecs.umich.edu        process = LiveProcess()
947376Sgblack@eecs.umich.edu        process.executable = wrkld
957376Sgblack@eecs.umich.edu        process.cwd = os.getcwd()
967376Sgblack@eecs.umich.edu
977376Sgblack@eecs.umich.edu        if len(pargs) > idx:
987376Sgblack@eecs.umich.edu            process.cmd = [wrkld] + pargs[idx].split()
997376Sgblack@eecs.umich.edu        else:
1007376Sgblack@eecs.umich.edu            process.cmd = [wrkld]
1017376Sgblack@eecs.umich.edu
1027376Sgblack@eecs.umich.edu        if len(inputs) > idx:
1037376Sgblack@eecs.umich.edu            process.input = inputs[idx]
1047376Sgblack@eecs.umich.edu        if len(outputs) > idx:
1057376Sgblack@eecs.umich.edu            process.output = outputs[idx]
1067376Sgblack@eecs.umich.edu        if len(errouts) > idx:
1077376Sgblack@eecs.umich.edu            process.errout = errouts[idx]
1087376Sgblack@eecs.umich.edu
1097376Sgblack@eecs.umich.edu        multiprocesses.append(process)
1107376Sgblack@eecs.umich.edu        idx += 1
1117376Sgblack@eecs.umich.edu
1127376Sgblack@eecs.umich.edu    if options.smt:
1137376Sgblack@eecs.umich.edu        assert(options.cpu_type == "detailed" or options.cpu_type == "inorder")
1147376Sgblack@eecs.umich.edu        return multiprocesses, idx
1157376Sgblack@eecs.umich.edu    else:
1167376Sgblack@eecs.umich.edu        return multiprocesses, 1
1177376Sgblack@eecs.umich.edu
1187376Sgblack@eecs.umich.edu
1197376Sgblack@eecs.umich.eduparser = optparse.OptionParser()
1207376Sgblack@eecs.umich.eduOptions.addCommonOptions(parser)
1217376Sgblack@eecs.umich.eduOptions.addSEOptions(parser)
1227376Sgblack@eecs.umich.edu
1237376Sgblack@eecs.umich.eduif '--ruby' in sys.argv:
1247376Sgblack@eecs.umich.edu    Ruby.define_options(parser)
1257376Sgblack@eecs.umich.edu
1267376Sgblack@eecs.umich.edu(options, args) = parser.parse_args()
1277376Sgblack@eecs.umich.edu
1287376Sgblack@eecs.umich.eduif args:
1297376Sgblack@eecs.umich.edu    print "Error: script doesn't take any positional arguments"
1307376Sgblack@eecs.umich.edu    sys.exit(1)
1317376Sgblack@eecs.umich.edu
1327376Sgblack@eecs.umich.edumultiprocesses = []
1337376Sgblack@eecs.umich.edunumThreads = 1
1347376Sgblack@eecs.umich.edu
1357376Sgblack@eecs.umich.eduif options.bench:
1367376Sgblack@eecs.umich.edu    apps = options.bench.split("-")
1377376Sgblack@eecs.umich.edu    if len(apps) != options.num_cpus:
1387376Sgblack@eecs.umich.edu        print "number of benchmarks not equal to set num_cpus!"
1397376Sgblack@eecs.umich.edu        sys.exit(1)
1407376Sgblack@eecs.umich.edu
1417376Sgblack@eecs.umich.edu    for app in apps:
1427376Sgblack@eecs.umich.edu        try:
1437376Sgblack@eecs.umich.edu            if buildEnv['TARGET_ISA'] == 'alpha':
1447376Sgblack@eecs.umich.edu                exec("workload = %s('alpha', 'tru64', '%s')" % (
1457376Sgblack@eecs.umich.edu                        app, options.spec_input))
1467376Sgblack@eecs.umich.edu            elif buildEnv['TARGET_ISA'] == 'arm':
1477376Sgblack@eecs.umich.edu                exec("workload = %s('arm_%s', 'linux', '%s')" % (
1487376Sgblack@eecs.umich.edu                        app, options.arm_iset, options.spec_input))
1497376Sgblack@eecs.umich.edu            else:
1507376Sgblack@eecs.umich.edu                exec("workload = %s(buildEnv['TARGET_ISA', 'linux', '%s')" % (
1517376Sgblack@eecs.umich.edu                        app, options.spec_input))
1527376Sgblack@eecs.umich.edu            multiprocesses.append(workload.makeLiveProcess())
1537376Sgblack@eecs.umich.edu        except:
1547376Sgblack@eecs.umich.edu            print >>sys.stderr, "Unable to find workload for %s: %s" % (
1557376Sgblack@eecs.umich.edu                    buildEnv['TARGET_ISA'], app)
1567376Sgblack@eecs.umich.edu            sys.exit(1)
1577376Sgblack@eecs.umich.eduelif options.cmd:
1587376Sgblack@eecs.umich.edu    multiprocesses, numThreads = get_processes(options)
1597376Sgblack@eecs.umich.eduelse:
1607376Sgblack@eecs.umich.edu    print >> sys.stderr, "No workload specified. Exiting!\n"
1617376Sgblack@eecs.umich.edu    sys.exit(1)
1627376Sgblack@eecs.umich.edu
1637376Sgblack@eecs.umich.edu
1647376Sgblack@eecs.umich.edu(CPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options)
1657376Sgblack@eecs.umich.eduCPUClass.numThreads = numThreads
1667376Sgblack@eecs.umich.edu
1677376Sgblack@eecs.umich.edu# Check -- do not allow SMT with multiple CPUs
1687376Sgblack@eecs.umich.eduif options.smt and options.num_cpus > 1:
1697376Sgblack@eecs.umich.edu    fatal("You cannot use SMT with multiple CPUs!")
1707376Sgblack@eecs.umich.edu
1717376Sgblack@eecs.umich.edunp = options.num_cpus
1727376Sgblack@eecs.umich.edusystem = System(cpu = [CPUClass(cpu_id=i) for i in xrange(np)],
1737376Sgblack@eecs.umich.edu                mem_mode = test_mem_mode,
1747376Sgblack@eecs.umich.edu                mem_ranges = [AddrRange(options.mem_size)],
1757376Sgblack@eecs.umich.edu                cache_line_size = options.cacheline_size)
1767376Sgblack@eecs.umich.edu
1777376Sgblack@eecs.umich.edu# Create a top-level voltage domain
1787376Sgblack@eecs.umich.edusystem.voltage_domain = VoltageDomain(voltage = options.sys_voltage)
1797376Sgblack@eecs.umich.edu
1807376Sgblack@eecs.umich.edu# Create a source clock for the system and set the clock period
1817376Sgblack@eecs.umich.edusystem.clk_domain = SrcClockDomain(clock =  options.sys_clock,
1827376Sgblack@eecs.umich.edu                                   voltage_domain = system.voltage_domain)
1837376Sgblack@eecs.umich.edu
1847376Sgblack@eecs.umich.edu# Create a CPU voltage domain
1857376Sgblack@eecs.umich.edusystem.cpu_voltage_domain = VoltageDomain()
1867376Sgblack@eecs.umich.edu
1877376Sgblack@eecs.umich.edu# Create a separate clock domain for the CPUs
1887322Sgblack@eecs.umich.edusystem.cpu_clk_domain = SrcClockDomain(clock = options.cpu_clock,
1897322Sgblack@eecs.umich.edu                                       voltage_domain =
1907322Sgblack@eecs.umich.edu                                       system.cpu_voltage_domain)
1917322Sgblack@eecs.umich.edu
1927322Sgblack@eecs.umich.edu# All cpus belong to a common cpu_clk_domain, therefore running at a common
1937322Sgblack@eecs.umich.edu# frequency.
1947396Sgblack@eecs.umich.edufor cpu in system.cpu:
1957322Sgblack@eecs.umich.edu    cpu.clk_domain = system.cpu_clk_domain
1967322Sgblack@eecs.umich.edu
1977396Sgblack@eecs.umich.eduif is_kvm_cpu(CPUClass) or is_kvm_cpu(FutureClass):
1987396Sgblack@eecs.umich.edu    if buildEnv['TARGET_ISA'] == 'x86':
1997322Sgblack@eecs.umich.edu        system.vm = KvmVM()
2007324Sgblack@eecs.umich.edu        for process in multiprocesses:
2017396Sgblack@eecs.umich.edu            process.useArchPT = True
2027324Sgblack@eecs.umich.edu            process.kvmInSE = True
2037324Sgblack@eecs.umich.edu    else:
2047396Sgblack@eecs.umich.edu        fatal("KvmCPU can only be used in SE mode with x86")
2057396Sgblack@eecs.umich.edu
2067324Sgblack@eecs.umich.edu# Sanity check
2077333Sgblack@eecs.umich.eduif options.fastmem:
2087392Sgblack@eecs.umich.edu    if CPUClass != AtomicSimpleCPU:
2097396Sgblack@eecs.umich.edu        fatal("Fastmem can only be used with atomic CPU!")
2107392Sgblack@eecs.umich.edu    if (options.caches or options.l2cache):
2117392Sgblack@eecs.umich.edu        fatal("You cannot use fastmem in combination with caches!")
2127396Sgblack@eecs.umich.edu
2137396Sgblack@eecs.umich.eduif options.simpoint_profile:
2147392Sgblack@eecs.umich.edu    if not options.fastmem:
2157392Sgblack@eecs.umich.edu        # Atomic CPU checked with fastmem option already
2167333Sgblack@eecs.umich.edu        fatal("SimPoint generation should be done with atomic cpu and fastmem")
2177333Sgblack@eecs.umich.edu    if np > 1:
2187333Sgblack@eecs.umich.edu        fatal("SimPoint generation not supported with more than one CPUs")
2197396Sgblack@eecs.umich.edu
2207333Sgblack@eecs.umich.edufor i in xrange(np):
2217333Sgblack@eecs.umich.edu    if options.smt:
2227396Sgblack@eecs.umich.edu        system.cpu[i].workload = multiprocesses
2237396Sgblack@eecs.umich.edu    elif len(multiprocesses) == 1:
2247333Sgblack@eecs.umich.edu        system.cpu[i].workload = multiprocesses[0]
2257333Sgblack@eecs.umich.edu    else:
2267333Sgblack@eecs.umich.edu        system.cpu[i].workload = multiprocesses[i]
2277333Sgblack@eecs.umich.edu
2287333Sgblack@eecs.umich.edu    if options.fastmem:
2297333Sgblack@eecs.umich.edu        system.cpu[i].fastmem = True
2307396Sgblack@eecs.umich.edu
2317333Sgblack@eecs.umich.edu    if options.simpoint_profile:
2327333Sgblack@eecs.umich.edu        system.cpu[i].addSimPointProbe(options.simpoint_interval)
2337396Sgblack@eecs.umich.edu
2347396Sgblack@eecs.umich.edu    if options.checker:
2357333Sgblack@eecs.umich.edu        system.cpu[i].addCheckerCpu()
2367333Sgblack@eecs.umich.edu
2377333Sgblack@eecs.umich.edu    system.cpu[i].createThreads()
2387333Sgblack@eecs.umich.edu
2397333Sgblack@eecs.umich.eduif options.ruby:
2407333Sgblack@eecs.umich.edu    if not (options.cpu_type == "detailed" or options.cpu_type == "timing"):
2417333Sgblack@eecs.umich.edu        print >> sys.stderr, "Ruby requires TimingSimpleCPU or O3CPU!!"
2427333Sgblack@eecs.umich.edu        sys.exit(1)
2437396Sgblack@eecs.umich.edu
2447333Sgblack@eecs.umich.edu    Ruby.create_system(options, False, system)
2457333Sgblack@eecs.umich.edu    assert(options.num_cpus == len(system.ruby._cpu_ports))
2467396Sgblack@eecs.umich.edu
2477396Sgblack@eecs.umich.edu    system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock,
2487333Sgblack@eecs.umich.edu                                        voltage_domain = system.voltage_domain)
2497333Sgblack@eecs.umich.edu    for i in xrange(np):
2507333Sgblack@eecs.umich.edu        ruby_port = system.ruby._cpu_ports[i]
2517333Sgblack@eecs.umich.edu
2527333Sgblack@eecs.umich.edu        # Create the interrupt controller and connect its ports to Ruby
2537396Sgblack@eecs.umich.edu        # Note that the interrupt controller is always present but only
2547333Sgblack@eecs.umich.edu        # in x86 does it have message ports that need to be connected
2557333Sgblack@eecs.umich.edu        system.cpu[i].createInterruptController()
2567396Sgblack@eecs.umich.edu
2577396Sgblack@eecs.umich.edu        # Connect the cpu's cache ports to Ruby
2587333Sgblack@eecs.umich.edu        system.cpu[i].icache_port = ruby_port.slave
2597333Sgblack@eecs.umich.edu        system.cpu[i].dcache_port = ruby_port.slave
2607333Sgblack@eecs.umich.edu        if buildEnv['TARGET_ISA'] == 'x86':
2617333Sgblack@eecs.umich.edu            system.cpu[i].interrupts.pio = ruby_port.master
2627333Sgblack@eecs.umich.edu            system.cpu[i].interrupts.int_master = ruby_port.slave
2637333Sgblack@eecs.umich.edu            system.cpu[i].interrupts.int_slave = ruby_port.master
2647396Sgblack@eecs.umich.edu            system.cpu[i].itb.walker.port = ruby_port.slave
2657333Sgblack@eecs.umich.edu            system.cpu[i].dtb.walker.port = ruby_port.slave
2667333Sgblack@eecs.umich.eduelse:
2677396Sgblack@eecs.umich.edu    MemClass = Simulation.setMemClass(options)
2687396Sgblack@eecs.umich.edu    system.membus = CoherentXBar()
2697333Sgblack@eecs.umich.edu    system.system_port = system.membus.slave
2707333Sgblack@eecs.umich.edu    CacheConfig.config_cache(options, system)
2717333Sgblack@eecs.umich.edu    MemConfig.config_mem(options, system)
2727333Sgblack@eecs.umich.edu
2737333Sgblack@eecs.umich.eduroot = Root(full_system = False, system = system)
2747333Sgblack@eecs.umich.eduSimulation.run(options, root, system, FutureClass)
2757333Sgblack@eecs.umich.edu