fs.py (10547:b61dc895269a) fs.py (10594:4fdc929c0aaa)
1# Copyright (c) 2010-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) 2012-2014 Mark D. Hill and David A. Wood
14# Copyright (c) 2009-2011 Advanced Micro Devices, Inc.
15# Copyright (c) 2006-2007 The Regents of The University of Michigan
16# All rights reserved.
17#
18# Redistribution and use in source and binary forms, with or without
19# modification, are permitted provided that the following conditions are
20# met: redistributions of source code must retain the above copyright
21# notice, this list of conditions and the following disclaimer;
22# redistributions in binary form must reproduce the above copyright
23# notice, this list of conditions and the following disclaimer in the
24# documentation and/or other materials provided with the distribution;
25# neither the name of the copyright holders nor the names of its
26# contributors may be used to endorse or promote products derived from
27# this software without specific prior written permission.
28#
29# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40#
41# Authors: Ali Saidi
42# Brad Beckmann
43
44import optparse
45import sys
46
47import m5
48from m5.defines import buildEnv
49from m5.objects import *
50from m5.util import addToPath, fatal
51
52addToPath('../common')
53addToPath('../ruby')
54
55import Ruby
56
57from FSConfig import *
58from SysPaths import *
59from Benchmarks import *
60import Simulation
61import CacheConfig
62import MemConfig
63from Caches import *
64import Options
65
66
67# Check if KVM support has been enabled, we might need to do VM
68# configuration if that's the case.
69have_kvm_support = 'BaseKvmCPU' in globals()
70def is_kvm_cpu(cpu_class):
71 return have_kvm_support and cpu_class != None and \
72 issubclass(cpu_class, BaseKvmCPU)
73
1# Copyright (c) 2010-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) 2012-2014 Mark D. Hill and David A. Wood
14# Copyright (c) 2009-2011 Advanced Micro Devices, Inc.
15# Copyright (c) 2006-2007 The Regents of The University of Michigan
16# All rights reserved.
17#
18# Redistribution and use in source and binary forms, with or without
19# modification, are permitted provided that the following conditions are
20# met: redistributions of source code must retain the above copyright
21# notice, this list of conditions and the following disclaimer;
22# redistributions in binary form must reproduce the above copyright
23# notice, this list of conditions and the following disclaimer in the
24# documentation and/or other materials provided with the distribution;
25# neither the name of the copyright holders nor the names of its
26# contributors may be used to endorse or promote products derived from
27# this software without specific prior written permission.
28#
29# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40#
41# Authors: Ali Saidi
42# Brad Beckmann
43
44import optparse
45import sys
46
47import m5
48from m5.defines import buildEnv
49from m5.objects import *
50from m5.util import addToPath, fatal
51
52addToPath('../common')
53addToPath('../ruby')
54
55import Ruby
56
57from FSConfig import *
58from SysPaths import *
59from Benchmarks import *
60import Simulation
61import CacheConfig
62import MemConfig
63from Caches import *
64import Options
65
66
67# Check if KVM support has been enabled, we might need to do VM
68# configuration if that's the case.
69have_kvm_support = 'BaseKvmCPU' in globals()
70def is_kvm_cpu(cpu_class):
71 return have_kvm_support and cpu_class != None and \
72 issubclass(cpu_class, BaseKvmCPU)
73
74def cmd_line_template():
75 if options.command_line and options.command_line_file:
76 print "Error: --command-line and --command-line-file are " \
77 "mutually exclusive"
78 sys.exit(1)
79 if options.command_line:
80 return options.command_line
81 if options.command_line_file:
82 return open(options.command_line_file).read().strip()
83 return None
84
74def build_test_system(np):
85def build_test_system(np):
86 cmdline = cmd_line_template()
75 if buildEnv['TARGET_ISA'] == "alpha":
87 if buildEnv['TARGET_ISA'] == "alpha":
76 test_sys = makeLinuxAlphaSystem(test_mem_mode, bm[0], options.ruby)
88 test_sys = makeLinuxAlphaSystem(test_mem_mode, bm[0], options.ruby,
89 cmdline=cmdline)
77 elif buildEnv['TARGET_ISA'] == "mips":
90 elif buildEnv['TARGET_ISA'] == "mips":
78 test_sys = makeLinuxMipsSystem(test_mem_mode, bm[0])
91 test_sys = makeLinuxMipsSystem(test_mem_mode, bm[0], cmdline=cmdline)
79 elif buildEnv['TARGET_ISA'] == "sparc":
92 elif buildEnv['TARGET_ISA'] == "sparc":
80 test_sys = makeSparcSystem(test_mem_mode, bm[0])
93 test_sys = makeSparcSystem(test_mem_mode, bm[0], cmdline=cmdline)
81 elif buildEnv['TARGET_ISA'] == "x86":
82 test_sys = makeLinuxX86System(test_mem_mode, options.num_cpus, bm[0],
94 elif buildEnv['TARGET_ISA'] == "x86":
95 test_sys = makeLinuxX86System(test_mem_mode, options.num_cpus, bm[0],
83 options.ruby)
96 options.ruby, cmdline=cmdline)
84 elif buildEnv['TARGET_ISA'] == "arm":
85 test_sys = makeArmSystem(test_mem_mode, options.machine_type,
86 options.num_cpus, bm[0], options.dtb_filename,
97 elif buildEnv['TARGET_ISA'] == "arm":
98 test_sys = makeArmSystem(test_mem_mode, options.machine_type,
99 options.num_cpus, bm[0], options.dtb_filename,
87 bare_metal=options.bare_metal)
100 bare_metal=options.bare_metal,
101 cmdline=cmdline)
88 if options.enable_context_switch_stats_dump:
89 test_sys.enable_context_switch_stats_dump = True
90 else:
91 fatal("Incapable of building %s full system!", buildEnv['TARGET_ISA'])
92
93 # Set the cache line size for the entire system
94 test_sys.cache_line_size = options.cacheline_size
95
96 # Create a top-level voltage domain
97 test_sys.voltage_domain = VoltageDomain(voltage = options.sys_voltage)
98
99 # Create a source clock for the system and set the clock period
100 test_sys.clk_domain = SrcClockDomain(clock = options.sys_clock,
101 voltage_domain = test_sys.voltage_domain)
102
103 # Create a CPU voltage domain
104 test_sys.cpu_voltage_domain = VoltageDomain()
105
106 # Create a source clock for the CPUs and set the clock period
107 test_sys.cpu_clk_domain = SrcClockDomain(clock = options.cpu_clock,
108 voltage_domain =
109 test_sys.cpu_voltage_domain)
110
111 if options.kernel is not None:
112 test_sys.kernel = binary(options.kernel)
113
114 if options.script is not None:
115 test_sys.readfile = options.script
116
117 if options.lpae:
118 test_sys.have_lpae = True
119
120 if options.virtualisation:
121 test_sys.have_virtualization = True
122
123 test_sys.init_param = options.init_param
124
125 # For now, assign all the CPUs to the same clock domain
126 test_sys.cpu = [TestCPUClass(clk_domain=test_sys.cpu_clk_domain, cpu_id=i)
127 for i in xrange(np)]
128
129 if is_kvm_cpu(TestCPUClass) or is_kvm_cpu(FutureClass):
130 test_sys.vm = KvmVM()
131
132 if options.ruby:
133 # Check for timing mode because ruby does not support atomic accesses
134 if not (options.cpu_type == "detailed" or options.cpu_type == "timing"):
135 print >> sys.stderr, "Ruby requires TimingSimpleCPU or O3CPU!!"
136 sys.exit(1)
137
138 Ruby.create_system(options, True, test_sys, test_sys.iobus,
139 test_sys._dma_ports)
140
141 # Create a seperate clock domain for Ruby
142 test_sys.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock,
143 voltage_domain = test_sys.voltage_domain)
144
145 # Connect the ruby io port to the PIO bus,
146 # assuming that there is just one such port.
147 test_sys.iobus.master = test_sys.ruby._io_port.slave
148
149 for (i, cpu) in enumerate(test_sys.cpu):
150 #
151 # Tie the cpu ports to the correct ruby system ports
152 #
153 cpu.clk_domain = test_sys.cpu_clk_domain
154 cpu.createThreads()
155 cpu.createInterruptController()
156
157 cpu.icache_port = test_sys.ruby._cpu_ports[i].slave
158 cpu.dcache_port = test_sys.ruby._cpu_ports[i].slave
159
160 if buildEnv['TARGET_ISA'] == "x86":
161 cpu.itb.walker.port = test_sys.ruby._cpu_ports[i].slave
162 cpu.dtb.walker.port = test_sys.ruby._cpu_ports[i].slave
163
164 cpu.interrupts.pio = test_sys.ruby._cpu_ports[i].master
165 cpu.interrupts.int_master = test_sys.ruby._cpu_ports[i].slave
166 cpu.interrupts.int_slave = test_sys.ruby._cpu_ports[i].master
167
168 else:
169 if options.caches or options.l2cache:
170 # By default the IOCache runs at the system clock
171 test_sys.iocache = IOCache(addr_ranges = test_sys.mem_ranges)
172 test_sys.iocache.cpu_side = test_sys.iobus.master
173 test_sys.iocache.mem_side = test_sys.membus.slave
174 else:
175 test_sys.iobridge = Bridge(delay='50ns', ranges = test_sys.mem_ranges)
176 test_sys.iobridge.slave = test_sys.iobus.master
177 test_sys.iobridge.master = test_sys.membus.slave
178
179 # Sanity check
180 if options.fastmem:
181 if TestCPUClass != AtomicSimpleCPU:
182 fatal("Fastmem can only be used with atomic CPU!")
183 if (options.caches or options.l2cache):
184 fatal("You cannot use fastmem in combination with caches!")
185
186 for i in xrange(np):
187 if options.fastmem:
188 test_sys.cpu[i].fastmem = True
189 if options.checker:
190 test_sys.cpu[i].addCheckerCpu()
191 test_sys.cpu[i].createThreads()
192
193 CacheConfig.config_cache(options, test_sys)
194 MemConfig.config_mem(options, test_sys)
195
196 return test_sys
197
198def build_drive_system(np):
199 # driver system CPU is always simple, so is the memory
200 # Note this is an assignment of a class, not an instance.
201 DriveCPUClass = AtomicSimpleCPU
202 drive_mem_mode = 'atomic'
203 DriveMemClass = SimpleMemory
204
102 if options.enable_context_switch_stats_dump:
103 test_sys.enable_context_switch_stats_dump = True
104 else:
105 fatal("Incapable of building %s full system!", buildEnv['TARGET_ISA'])
106
107 # Set the cache line size for the entire system
108 test_sys.cache_line_size = options.cacheline_size
109
110 # Create a top-level voltage domain
111 test_sys.voltage_domain = VoltageDomain(voltage = options.sys_voltage)
112
113 # Create a source clock for the system and set the clock period
114 test_sys.clk_domain = SrcClockDomain(clock = options.sys_clock,
115 voltage_domain = test_sys.voltage_domain)
116
117 # Create a CPU voltage domain
118 test_sys.cpu_voltage_domain = VoltageDomain()
119
120 # Create a source clock for the CPUs and set the clock period
121 test_sys.cpu_clk_domain = SrcClockDomain(clock = options.cpu_clock,
122 voltage_domain =
123 test_sys.cpu_voltage_domain)
124
125 if options.kernel is not None:
126 test_sys.kernel = binary(options.kernel)
127
128 if options.script is not None:
129 test_sys.readfile = options.script
130
131 if options.lpae:
132 test_sys.have_lpae = True
133
134 if options.virtualisation:
135 test_sys.have_virtualization = True
136
137 test_sys.init_param = options.init_param
138
139 # For now, assign all the CPUs to the same clock domain
140 test_sys.cpu = [TestCPUClass(clk_domain=test_sys.cpu_clk_domain, cpu_id=i)
141 for i in xrange(np)]
142
143 if is_kvm_cpu(TestCPUClass) or is_kvm_cpu(FutureClass):
144 test_sys.vm = KvmVM()
145
146 if options.ruby:
147 # Check for timing mode because ruby does not support atomic accesses
148 if not (options.cpu_type == "detailed" or options.cpu_type == "timing"):
149 print >> sys.stderr, "Ruby requires TimingSimpleCPU or O3CPU!!"
150 sys.exit(1)
151
152 Ruby.create_system(options, True, test_sys, test_sys.iobus,
153 test_sys._dma_ports)
154
155 # Create a seperate clock domain for Ruby
156 test_sys.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock,
157 voltage_domain = test_sys.voltage_domain)
158
159 # Connect the ruby io port to the PIO bus,
160 # assuming that there is just one such port.
161 test_sys.iobus.master = test_sys.ruby._io_port.slave
162
163 for (i, cpu) in enumerate(test_sys.cpu):
164 #
165 # Tie the cpu ports to the correct ruby system ports
166 #
167 cpu.clk_domain = test_sys.cpu_clk_domain
168 cpu.createThreads()
169 cpu.createInterruptController()
170
171 cpu.icache_port = test_sys.ruby._cpu_ports[i].slave
172 cpu.dcache_port = test_sys.ruby._cpu_ports[i].slave
173
174 if buildEnv['TARGET_ISA'] == "x86":
175 cpu.itb.walker.port = test_sys.ruby._cpu_ports[i].slave
176 cpu.dtb.walker.port = test_sys.ruby._cpu_ports[i].slave
177
178 cpu.interrupts.pio = test_sys.ruby._cpu_ports[i].master
179 cpu.interrupts.int_master = test_sys.ruby._cpu_ports[i].slave
180 cpu.interrupts.int_slave = test_sys.ruby._cpu_ports[i].master
181
182 else:
183 if options.caches or options.l2cache:
184 # By default the IOCache runs at the system clock
185 test_sys.iocache = IOCache(addr_ranges = test_sys.mem_ranges)
186 test_sys.iocache.cpu_side = test_sys.iobus.master
187 test_sys.iocache.mem_side = test_sys.membus.slave
188 else:
189 test_sys.iobridge = Bridge(delay='50ns', ranges = test_sys.mem_ranges)
190 test_sys.iobridge.slave = test_sys.iobus.master
191 test_sys.iobridge.master = test_sys.membus.slave
192
193 # Sanity check
194 if options.fastmem:
195 if TestCPUClass != AtomicSimpleCPU:
196 fatal("Fastmem can only be used with atomic CPU!")
197 if (options.caches or options.l2cache):
198 fatal("You cannot use fastmem in combination with caches!")
199
200 for i in xrange(np):
201 if options.fastmem:
202 test_sys.cpu[i].fastmem = True
203 if options.checker:
204 test_sys.cpu[i].addCheckerCpu()
205 test_sys.cpu[i].createThreads()
206
207 CacheConfig.config_cache(options, test_sys)
208 MemConfig.config_mem(options, test_sys)
209
210 return test_sys
211
212def build_drive_system(np):
213 # driver system CPU is always simple, so is the memory
214 # Note this is an assignment of a class, not an instance.
215 DriveCPUClass = AtomicSimpleCPU
216 drive_mem_mode = 'atomic'
217 DriveMemClass = SimpleMemory
218
219 cmdline = cmd_line_template()
205 if buildEnv['TARGET_ISA'] == 'alpha':
220 if buildEnv['TARGET_ISA'] == 'alpha':
206 drive_sys = makeLinuxAlphaSystem(drive_mem_mode, bm[1])
221 drive_sys = makeLinuxAlphaSystem(drive_mem_mode, bm[1], cmdline=cmdline)
207 elif buildEnv['TARGET_ISA'] == 'mips':
222 elif buildEnv['TARGET_ISA'] == 'mips':
208 drive_sys = makeLinuxMipsSystem(drive_mem_mode, bm[1])
223 drive_sys = makeLinuxMipsSystem(drive_mem_mode, bm[1], cmdline=cmdline)
209 elif buildEnv['TARGET_ISA'] == 'sparc':
224 elif buildEnv['TARGET_ISA'] == 'sparc':
210 drive_sys = makeSparcSystem(drive_mem_mode, bm[1])
225 drive_sys = makeSparcSystem(drive_mem_mode, bm[1], cmdline=cmdline)
211 elif buildEnv['TARGET_ISA'] == 'x86':
226 elif buildEnv['TARGET_ISA'] == 'x86':
212 drive_sys = makeLinuxX86System(drive_mem_mode, np, bm[1])
227 drive_sys = makeLinuxX86System(drive_mem_mode, np, bm[1],
228 cmdline=cmdline)
213 elif buildEnv['TARGET_ISA'] == 'arm':
229 elif buildEnv['TARGET_ISA'] == 'arm':
214 drive_sys = makeArmSystem(drive_mem_mode, options.machine_type, bm[1])
230 drive_sys = makeArmSystem(drive_mem_mode, options.machine_type, bm[1],
231 cmdline=cmdline)
215
216 # Create a top-level voltage domain
217 drive_sys.voltage_domain = VoltageDomain(voltage = options.sys_voltage)
218
219 # Create a source clock for the system and set the clock period
220 drive_sys.clk_domain = SrcClockDomain(clock = options.sys_clock,
221 voltage_domain = drive_sys.voltage_domain)
222
223 # Create a CPU voltage domain
224 drive_sys.cpu_voltage_domain = VoltageDomain()
225
226 # Create a source clock for the CPUs and set the clock period
227 drive_sys.cpu_clk_domain = SrcClockDomain(clock = options.cpu_clock,
228 voltage_domain =
229 drive_sys.cpu_voltage_domain)
230
231 drive_sys.cpu = DriveCPUClass(clk_domain=drive_sys.cpu_clk_domain,
232 cpu_id=0)
233 drive_sys.cpu.createThreads()
234 drive_sys.cpu.createInterruptController()
235 drive_sys.cpu.connectAllPorts(drive_sys.membus)
236 if options.fastmem:
237 drive_sys.cpu.fastmem = True
238 if options.kernel is not None:
239 drive_sys.kernel = binary(options.kernel)
240
241 if is_kvm_cpu(DriveCPUClass):
242 drive_sys.vm = KvmVM()
243
244 drive_sys.iobridge = Bridge(delay='50ns',
245 ranges = drive_sys.mem_ranges)
246 drive_sys.iobridge.slave = drive_sys.iobus.master
247 drive_sys.iobridge.master = drive_sys.membus.slave
248
249 # Create the appropriate memory controllers and connect them to the
250 # memory bus
251 drive_sys.mem_ctrls = [DriveMemClass(range = r)
252 for r in drive_sys.mem_ranges]
253 for i in xrange(len(drive_sys.mem_ctrls)):
254 drive_sys.mem_ctrls[i].port = drive_sys.membus.master
255
256 drive_sys.init_param = options.init_param
257
258 return drive_sys
259
260# Add options
261parser = optparse.OptionParser()
262Options.addCommonOptions(parser)
263Options.addFSOptions(parser)
264
265# Add the ruby specific and protocol specific options
266if '--ruby' in sys.argv:
267 Ruby.define_options(parser)
268
269(options, args) = parser.parse_args()
270
271if args:
272 print "Error: script doesn't take any positional arguments"
273 sys.exit(1)
274
275# system under test can be any CPU
276(TestCPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options)
277
278# Match the memories with the CPUs, based on the options for the test system
279TestMemClass = Simulation.setMemClass(options)
280
281if options.benchmark:
282 try:
283 bm = Benchmarks[options.benchmark]
284 except KeyError:
285 print "Error benchmark %s has not been defined." % options.benchmark
286 print "Valid benchmarks are: %s" % DefinedBenchmarks
287 sys.exit(1)
288else:
289 if options.dual:
290 bm = [SysConfig(disk=options.disk_image, mem=options.mem_size),
291 SysConfig(disk=options.disk_image, mem=options.mem_size)]
292 else:
293 bm = [SysConfig(disk=options.disk_image, mem=options.mem_size)]
294
295np = options.num_cpus
296
297test_sys = build_test_system(np)
298if len(bm) == 2:
299 drive_sys = build_drive_system(np)
300 root = makeDualRoot(True, test_sys, drive_sys, options.etherdump)
301elif len(bm) == 1:
302 root = Root(full_system=True, system=test_sys)
303else:
304 print "Error I don't know how to create more than 2 systems."
305 sys.exit(1)
306
307if options.timesync:
308 root.time_sync_enable = True
309
310if options.frame_capture:
311 VncServer.frame_capture = True
312
313Simulation.setWorkCountOptions(test_sys, options)
314Simulation.run(options, root, test_sys, FutureClass)
232
233 # Create a top-level voltage domain
234 drive_sys.voltage_domain = VoltageDomain(voltage = options.sys_voltage)
235
236 # Create a source clock for the system and set the clock period
237 drive_sys.clk_domain = SrcClockDomain(clock = options.sys_clock,
238 voltage_domain = drive_sys.voltage_domain)
239
240 # Create a CPU voltage domain
241 drive_sys.cpu_voltage_domain = VoltageDomain()
242
243 # Create a source clock for the CPUs and set the clock period
244 drive_sys.cpu_clk_domain = SrcClockDomain(clock = options.cpu_clock,
245 voltage_domain =
246 drive_sys.cpu_voltage_domain)
247
248 drive_sys.cpu = DriveCPUClass(clk_domain=drive_sys.cpu_clk_domain,
249 cpu_id=0)
250 drive_sys.cpu.createThreads()
251 drive_sys.cpu.createInterruptController()
252 drive_sys.cpu.connectAllPorts(drive_sys.membus)
253 if options.fastmem:
254 drive_sys.cpu.fastmem = True
255 if options.kernel is not None:
256 drive_sys.kernel = binary(options.kernel)
257
258 if is_kvm_cpu(DriveCPUClass):
259 drive_sys.vm = KvmVM()
260
261 drive_sys.iobridge = Bridge(delay='50ns',
262 ranges = drive_sys.mem_ranges)
263 drive_sys.iobridge.slave = drive_sys.iobus.master
264 drive_sys.iobridge.master = drive_sys.membus.slave
265
266 # Create the appropriate memory controllers and connect them to the
267 # memory bus
268 drive_sys.mem_ctrls = [DriveMemClass(range = r)
269 for r in drive_sys.mem_ranges]
270 for i in xrange(len(drive_sys.mem_ctrls)):
271 drive_sys.mem_ctrls[i].port = drive_sys.membus.master
272
273 drive_sys.init_param = options.init_param
274
275 return drive_sys
276
277# Add options
278parser = optparse.OptionParser()
279Options.addCommonOptions(parser)
280Options.addFSOptions(parser)
281
282# Add the ruby specific and protocol specific options
283if '--ruby' in sys.argv:
284 Ruby.define_options(parser)
285
286(options, args) = parser.parse_args()
287
288if args:
289 print "Error: script doesn't take any positional arguments"
290 sys.exit(1)
291
292# system under test can be any CPU
293(TestCPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options)
294
295# Match the memories with the CPUs, based on the options for the test system
296TestMemClass = Simulation.setMemClass(options)
297
298if options.benchmark:
299 try:
300 bm = Benchmarks[options.benchmark]
301 except KeyError:
302 print "Error benchmark %s has not been defined." % options.benchmark
303 print "Valid benchmarks are: %s" % DefinedBenchmarks
304 sys.exit(1)
305else:
306 if options.dual:
307 bm = [SysConfig(disk=options.disk_image, mem=options.mem_size),
308 SysConfig(disk=options.disk_image, mem=options.mem_size)]
309 else:
310 bm = [SysConfig(disk=options.disk_image, mem=options.mem_size)]
311
312np = options.num_cpus
313
314test_sys = build_test_system(np)
315if len(bm) == 2:
316 drive_sys = build_drive_system(np)
317 root = makeDualRoot(True, test_sys, drive_sys, options.etherdump)
318elif len(bm) == 1:
319 root = Root(full_system=True, system=test_sys)
320else:
321 print "Error I don't know how to create more than 2 systems."
322 sys.exit(1)
323
324if options.timesync:
325 root.time_sync_enable = True
326
327if options.frame_capture:
328 VncServer.frame_capture = True
329
330Simulation.setWorkCountOptions(test_sys, options)
331Simulation.run(options, root, test_sys, FutureClass)