se.py revision 13684:076506a21535
1# Copyright (c) 2012-2013 ARM Limited
2# All rights reserved.
3#
4# The license below extends only to copyright in the software and shall
5# not be construed as granting a license to any other intellectual
6# property including but not limited to intellectual property relating
7# to a hardware implementation of the functionality of the software
8# licensed hereunder.  You may use the software subject to the license
9# terms below provided that you ensure that this notice is replicated
10# unmodified and in its entirety in all distributions of the software,
11# modified or unmodified, in source code or in binary form.
12#
13# Copyright (c) 2006-2008 The Regents of The University of Michigan
14# All rights reserved.
15#
16# Redistribution and use in source and binary forms, with or without
17# modification, are permitted provided that the following conditions are
18# met: redistributions of source code must retain the above copyright
19# notice, this list of conditions and the following disclaimer;
20# redistributions in binary form must reproduce the above copyright
21# notice, this list of conditions and the following disclaimer in the
22# documentation and/or other materials provided with the distribution;
23# neither the name of the copyright holders nor the names of its
24# contributors may be used to endorse or promote products derived from
25# this software without specific prior written permission.
26#
27# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38#
39# Authors: Steve Reinhardt
40
41# Simple test script
42#
43# "m5 test.py"
44
45from __future__ import print_function
46
47import optparse
48import sys
49import os
50
51import m5
52from m5.defines import buildEnv
53from m5.objects import *
54from m5.util import addToPath, fatal, warn
55
56addToPath('../')
57
58from ruby import Ruby
59
60from common import Options
61from common import Simulation
62from common import CacheConfig
63from common import CpuConfig
64from common import BPConfig
65from common import MemConfig
66from common.Caches import *
67from common.cpu2000 import *
68
69def get_processes(options):
70    """Interprets provided options and returns a list of processes"""
71
72    multiprocesses = []
73    inputs = []
74    outputs = []
75    errouts = []
76    pargs = []
77
78    workloads = options.cmd.split(';')
79    if options.input != "":
80        inputs = options.input.split(';')
81    if options.output != "":
82        outputs = options.output.split(';')
83    if options.errout != "":
84        errouts = options.errout.split(';')
85    if options.options != "":
86        pargs = options.options.split(';')
87
88    idx = 0
89    for wrkld in workloads:
90        process = Process(pid = 100 + idx)
91        process.executable = wrkld
92        process.cwd = os.getcwd()
93
94        if options.env:
95            with open(options.env, 'r') as f:
96                process.env = [line.rstrip() for line in f]
97
98        if len(pargs) > idx:
99            process.cmd = [wrkld] + pargs[idx].split()
100        else:
101            process.cmd = [wrkld]
102
103        if len(inputs) > idx:
104            process.input = inputs[idx]
105        if len(outputs) > idx:
106            process.output = outputs[idx]
107        if len(errouts) > idx:
108            process.errout = errouts[idx]
109
110        multiprocesses.append(process)
111        idx += 1
112
113    if options.smt:
114        assert(options.cpu_type == "DerivO3CPU")
115        return multiprocesses, idx
116    else:
117        return multiprocesses, 1
118
119
120parser = optparse.OptionParser()
121Options.addCommonOptions(parser)
122Options.addSEOptions(parser)
123
124if '--ruby' in sys.argv:
125    Ruby.define_options(parser)
126
127(options, args) = parser.parse_args()
128
129if args:
130    print("Error: script doesn't take any positional arguments")
131    sys.exit(1)
132
133multiprocesses = []
134numThreads = 1
135
136if options.bench:
137    apps = options.bench.split("-")
138    if len(apps) != options.num_cpus:
139        print("number of benchmarks not equal to set num_cpus!")
140        sys.exit(1)
141
142    for app in apps:
143        try:
144            if buildEnv['TARGET_ISA'] == 'alpha':
145                exec("workload = %s('alpha', 'tru64', '%s')" % (
146                        app, options.spec_input))
147            elif buildEnv['TARGET_ISA'] == 'arm':
148                exec("workload = %s('arm_%s', 'linux', '%s')" % (
149                        app, options.arm_iset, options.spec_input))
150            else:
151                exec("workload = %s(buildEnv['TARGET_ISA', 'linux', '%s')" % (
152                        app, options.spec_input))
153            multiprocesses.append(workload.makeProcess())
154        except:
155            print("Unable to find workload for %s: %s" %
156                  (buildEnv['TARGET_ISA'], app),
157                  file=sys.stderr)
158            sys.exit(1)
159elif options.cmd:
160    multiprocesses, numThreads = get_processes(options)
161else:
162    print("No workload specified. Exiting!\n", file=sys.stderr)
163    sys.exit(1)
164
165
166(CPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options)
167CPUClass.numThreads = numThreads
168
169# Check -- do not allow SMT with multiple CPUs
170if options.smt and options.num_cpus > 1:
171    fatal("You cannot use SMT with multiple CPUs!")
172
173np = options.num_cpus
174system = System(cpu = [CPUClass(cpu_id=i) for i in xrange(np)],
175                mem_mode = test_mem_mode,
176                mem_ranges = [AddrRange(options.mem_size)],
177                cache_line_size = options.cacheline_size)
178
179if numThreads > 1:
180    system.multi_thread = True
181
182# Create a top-level voltage domain
183system.voltage_domain = VoltageDomain(voltage = options.sys_voltage)
184
185# Create a source clock for the system and set the clock period
186system.clk_domain = SrcClockDomain(clock =  options.sys_clock,
187                                   voltage_domain = system.voltage_domain)
188
189# Create a CPU voltage domain
190system.cpu_voltage_domain = VoltageDomain()
191
192# Create a separate clock domain for the CPUs
193system.cpu_clk_domain = SrcClockDomain(clock = options.cpu_clock,
194                                       voltage_domain =
195                                       system.cpu_voltage_domain)
196
197# If elastic tracing is enabled, then configure the cpu and attach the elastic
198# trace probe
199if options.elastic_trace_en:
200    CpuConfig.config_etrace(CPUClass, system.cpu, options)
201
202# All cpus belong to a common cpu_clk_domain, therefore running at a common
203# frequency.
204for cpu in system.cpu:
205    cpu.clk_domain = system.cpu_clk_domain
206
207if CpuConfig.is_kvm_cpu(CPUClass) or CpuConfig.is_kvm_cpu(FutureClass):
208    if buildEnv['TARGET_ISA'] == 'x86':
209        system.kvm_vm = KvmVM()
210        for process in multiprocesses:
211            process.useArchPT = True
212            process.kvmInSE = True
213    else:
214        fatal("KvmCPU can only be used in SE mode with x86")
215
216# Sanity check
217if options.simpoint_profile:
218    if not CpuConfig.is_noncaching_cpu(CPUClass):
219        fatal("SimPoint/BPProbe should be done with an atomic cpu")
220    if np > 1:
221        fatal("SimPoint generation not supported with more than one CPUs")
222
223for i in xrange(np):
224    if options.smt:
225        system.cpu[i].workload = multiprocesses
226    elif len(multiprocesses) == 1:
227        system.cpu[i].workload = multiprocesses[0]
228    else:
229        system.cpu[i].workload = multiprocesses[i]
230
231    if options.simpoint_profile:
232        system.cpu[i].addSimPointProbe(options.simpoint_interval)
233
234    if options.checker:
235        system.cpu[i].addCheckerCpu()
236
237    if options.bp_type:
238        bpClass = BPConfig.get(options.bp_type)
239        system.cpu[i].branchPred = bpClass()
240
241    system.cpu[i].createThreads()
242
243if options.ruby:
244    Ruby.create_system(options, False, system)
245    assert(options.num_cpus == len(system.ruby._cpu_ports))
246
247    system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock,
248                                        voltage_domain = system.voltage_domain)
249    for i in xrange(np):
250        ruby_port = system.ruby._cpu_ports[i]
251
252        # Create the interrupt controller and connect its ports to Ruby
253        # Note that the interrupt controller is always present but only
254        # in x86 does it have message ports that need to be connected
255        system.cpu[i].createInterruptController()
256
257        # Connect the cpu's cache ports to Ruby
258        system.cpu[i].icache_port = ruby_port.slave
259        system.cpu[i].dcache_port = ruby_port.slave
260        if buildEnv['TARGET_ISA'] == 'x86':
261            system.cpu[i].interrupts[0].pio = ruby_port.master
262            system.cpu[i].interrupts[0].int_master = ruby_port.slave
263            system.cpu[i].interrupts[0].int_slave = ruby_port.master
264            system.cpu[i].itb.walker.port = ruby_port.slave
265            system.cpu[i].dtb.walker.port = ruby_port.slave
266else:
267    MemClass = Simulation.setMemClass(options)
268    system.membus = SystemXBar()
269    system.system_port = system.membus.slave
270    CacheConfig.config_cache(options, system)
271    MemConfig.config_mem(options, system)
272
273root = Root(full_system = False, system = system)
274Simulation.run(options, root, system, FutureClass)
275