1 # Copyright (c) 2010-2013, 2016 ARM Limited
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.
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.
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.
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.
48 from m5
.defines
import buildEnv
49 from m5
.objects
import *
50 from m5
.util
import addToPath
, fatal
56 from common
.FSConfig
import *
57 from common
.SysPaths
import *
58 from common
.Benchmarks
import *
59 from common
import Simulation
60 from common
import CacheConfig
61 from common
import MemConfig
62 from common
import CpuConfig
63 from common
.Caches
import *
64 from common
import Options
67 # Check if KVM support has been enabled, we might need to do VM
68 # configuration if that's the case.
69 have_kvm_support
= 'BaseKvmCPU' in globals()
70 def is_kvm_cpu(cpu_class
):
71 return have_kvm_support
and cpu_class
!= None and \
72 issubclass(cpu_class
, BaseKvmCPU
)
74 def cmd_line_template():
75 if options
.command_line
and options
.command_line_file
:
76 print "Error: --command-line and --command-line-file are " \
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()
85 def build_test_system(np
):
86 cmdline
= cmd_line_template()
87 if buildEnv
['TARGET_ISA'] == "alpha":
88 test_sys
= makeLinuxAlphaSystem(test_mem_mode
, bm
[0], options
.ruby
,
90 elif buildEnv
['TARGET_ISA'] == "mips":
91 test_sys
= makeLinuxMipsSystem(test_mem_mode
, bm
[0], cmdline
=cmdline
)
92 elif buildEnv
['TARGET_ISA'] == "sparc":
93 test_sys
= makeSparcSystem(test_mem_mode
, bm
[0], cmdline
=cmdline
)
94 elif buildEnv
['TARGET_ISA'] == "x86":
95 test_sys
= makeLinuxX86System(test_mem_mode
, options
.num_cpus
, bm
[0],
96 options
.ruby
, cmdline
=cmdline
)
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
,
100 bare_metal
=options
.bare_metal
,
102 external_memory
=options
.external_memory_system
,
104 if options
.enable_context_switch_stats_dump
:
105 test_sys
.enable_context_switch_stats_dump
= True
107 fatal("Incapable of building %s full system!", buildEnv
['TARGET_ISA'])
109 # Set the cache line size for the entire system
110 test_sys
.cache_line_size
= options
.cacheline_size
112 # Create a top-level voltage domain
113 test_sys
.voltage_domain
= VoltageDomain(voltage
= options
.sys_voltage
)
115 # Create a source clock for the system and set the clock period
116 test_sys
.clk_domain
= SrcClockDomain(clock
= options
.sys_clock
,
117 voltage_domain
= test_sys
.voltage_domain
)
119 # Create a CPU voltage domain
120 test_sys
.cpu_voltage_domain
= VoltageDomain()
122 # Create a source clock for the CPUs and set the clock period
123 test_sys
.cpu_clk_domain
= SrcClockDomain(clock
= options
.cpu_clock
,
125 test_sys
.cpu_voltage_domain
)
127 if options
.kernel
is not None:
128 test_sys
.kernel
= binary(options
.kernel
)
130 if options
.script
is not None:
131 test_sys
.readfile
= options
.script
134 test_sys
.have_lpae
= True
136 if options
.virtualisation
:
137 test_sys
.have_virtualization
= True
139 test_sys
.init_param
= options
.init_param
141 # For now, assign all the CPUs to the same clock domain
142 test_sys
.cpu
= [TestCPUClass(clk_domain
=test_sys
.cpu_clk_domain
, cpu_id
=i
)
145 if is_kvm_cpu(TestCPUClass
) or is_kvm_cpu(FutureClass
):
146 test_sys
.kvm_vm
= KvmVM()
149 # Check for timing mode because ruby does not support atomic accesses
150 if not (options
.cpu_type
== "detailed" or options
.cpu_type
== "timing"):
151 print >> sys
.stderr
, "Ruby requires TimingSimpleCPU or O3CPU!!"
154 Ruby
.create_system(options
, True, test_sys
, test_sys
.iobus
,
157 # Create a seperate clock domain for Ruby
158 test_sys
.ruby
.clk_domain
= SrcClockDomain(clock
= options
.ruby_clock
,
159 voltage_domain
= test_sys
.voltage_domain
)
161 # Connect the ruby io port to the PIO bus,
162 # assuming that there is just one such port.
163 test_sys
.iobus
.master
= test_sys
.ruby
._io
_port
.slave
165 for (i
, cpu
) in enumerate(test_sys
.cpu
):
167 # Tie the cpu ports to the correct ruby system ports
169 cpu
.clk_domain
= test_sys
.cpu_clk_domain
171 cpu
.createInterruptController()
173 cpu
.icache_port
= test_sys
.ruby
._cpu
_ports
[i
].slave
174 cpu
.dcache_port
= test_sys
.ruby
._cpu
_ports
[i
].slave
176 if buildEnv
['TARGET_ISA'] in ("x86", "arm"):
177 cpu
.itb
.walker
.port
= test_sys
.ruby
._cpu
_ports
[i
].slave
178 cpu
.dtb
.walker
.port
= test_sys
.ruby
._cpu
_ports
[i
].slave
180 if buildEnv
['TARGET_ISA'] in "x86":
181 cpu
.interrupts
[0].pio
= test_sys
.ruby
._cpu
_ports
[i
].master
182 cpu
.interrupts
[0].int_master
= test_sys
.ruby
._cpu
_ports
[i
].slave
183 cpu
.interrupts
[0].int_slave
= test_sys
.ruby
._cpu
_ports
[i
].master
186 if options
.caches
or options
.l2cache
:
187 # By default the IOCache runs at the system clock
188 test_sys
.iocache
= IOCache(addr_ranges
= test_sys
.mem_ranges
)
189 test_sys
.iocache
.cpu_side
= test_sys
.iobus
.master
190 test_sys
.iocache
.mem_side
= test_sys
.membus
.slave
191 elif not options
.external_memory_system
:
192 test_sys
.iobridge
= Bridge(delay
='50ns', ranges
= test_sys
.mem_ranges
)
193 test_sys
.iobridge
.slave
= test_sys
.iobus
.master
194 test_sys
.iobridge
.master
= test_sys
.membus
.slave
198 if TestCPUClass
!= AtomicSimpleCPU
:
199 fatal("Fastmem can only be used with atomic CPU!")
200 if (options
.caches
or options
.l2cache
):
201 fatal("You cannot use fastmem in combination with caches!")
203 if options
.simpoint_profile
:
204 if not options
.fastmem
:
205 # Atomic CPU checked with fastmem option already
206 fatal("SimPoint generation should be done with atomic cpu and fastmem")
208 fatal("SimPoint generation not supported with more than one CPUs")
212 test_sys
.cpu
[i
].fastmem
= True
213 if options
.simpoint_profile
:
214 test_sys
.cpu
[i
].addSimPointProbe(options
.simpoint_interval
)
216 test_sys
.cpu
[i
].addCheckerCpu()
217 test_sys
.cpu
[i
].createThreads()
219 # If elastic tracing is enabled when not restoring from checkpoint and
220 # when not fast forwarding using the atomic cpu, then check that the
221 # TestCPUClass is DerivO3CPU or inherits from DerivO3CPU. If the check
222 # passes then attach the elastic trace probe.
223 # If restoring from checkpoint or fast forwarding, the code that does this for
224 # FutureCPUClass is in the Simulation module. If the check passes then the
225 # elastic trace probe is attached to the switch CPUs.
226 if options
.elastic_trace_en
and options
.checkpoint_restore
== None and \
227 not options
.fast_forward
:
228 CpuConfig
.config_etrace(TestCPUClass
, test_sys
.cpu
, options
)
230 CacheConfig
.config_cache(options
, test_sys
)
232 MemConfig
.config_mem(options
, test_sys
)
236 def build_drive_system(np
):
237 # driver system CPU is always simple, so is the memory
238 # Note this is an assignment of a class, not an instance.
239 DriveCPUClass
= AtomicSimpleCPU
240 drive_mem_mode
= 'atomic'
241 DriveMemClass
= SimpleMemory
243 cmdline
= cmd_line_template()
244 if buildEnv
['TARGET_ISA'] == 'alpha':
245 drive_sys
= makeLinuxAlphaSystem(drive_mem_mode
, bm
[1], cmdline
=cmdline
)
246 elif buildEnv
['TARGET_ISA'] == 'mips':
247 drive_sys
= makeLinuxMipsSystem(drive_mem_mode
, bm
[1], cmdline
=cmdline
)
248 elif buildEnv
['TARGET_ISA'] == 'sparc':
249 drive_sys
= makeSparcSystem(drive_mem_mode
, bm
[1], cmdline
=cmdline
)
250 elif buildEnv
['TARGET_ISA'] == 'x86':
251 drive_sys
= makeLinuxX86System(drive_mem_mode
, np
, bm
[1],
253 elif buildEnv
['TARGET_ISA'] == 'arm':
254 drive_sys
= makeArmSystem(drive_mem_mode
, options
.machine_type
, np
,
255 bm
[1], options
.dtb_filename
, cmdline
=cmdline
)
257 # Create a top-level voltage domain
258 drive_sys
.voltage_domain
= VoltageDomain(voltage
= options
.sys_voltage
)
260 # Create a source clock for the system and set the clock period
261 drive_sys
.clk_domain
= SrcClockDomain(clock
= options
.sys_clock
,
262 voltage_domain
= drive_sys
.voltage_domain
)
264 # Create a CPU voltage domain
265 drive_sys
.cpu_voltage_domain
= VoltageDomain()
267 # Create a source clock for the CPUs and set the clock period
268 drive_sys
.cpu_clk_domain
= SrcClockDomain(clock
= options
.cpu_clock
,
270 drive_sys
.cpu_voltage_domain
)
272 drive_sys
.cpu
= DriveCPUClass(clk_domain
=drive_sys
.cpu_clk_domain
,
274 drive_sys
.cpu
.createThreads()
275 drive_sys
.cpu
.createInterruptController()
276 drive_sys
.cpu
.connectAllPorts(drive_sys
.membus
)
278 drive_sys
.cpu
.fastmem
= True
279 if options
.kernel
is not None:
280 drive_sys
.kernel
= binary(options
.kernel
)
282 if is_kvm_cpu(DriveCPUClass
):
283 drive_sys
.kvm_vm
= KvmVM()
285 drive_sys
.iobridge
= Bridge(delay
='50ns',
286 ranges
= drive_sys
.mem_ranges
)
287 drive_sys
.iobridge
.slave
= drive_sys
.iobus
.master
288 drive_sys
.iobridge
.master
= drive_sys
.membus
.slave
290 # Create the appropriate memory controllers and connect them to the
292 drive_sys
.mem_ctrls
= [DriveMemClass(range = r
)
293 for r
in drive_sys
.mem_ranges
]
294 for i
in xrange(len(drive_sys
.mem_ctrls
)):
295 drive_sys
.mem_ctrls
[i
].port
= drive_sys
.membus
.master
297 drive_sys
.init_param
= options
.init_param
302 parser
= optparse
.OptionParser()
303 Options
.addCommonOptions(parser
)
304 Options
.addFSOptions(parser
)
306 # Add the ruby specific and protocol specific options
307 if '--ruby' in sys
.argv
:
308 Ruby
.define_options(parser
)
310 (options
, args
) = parser
.parse_args()
313 print "Error: script doesn't take any positional arguments"
316 # system under test can be any CPU
317 (TestCPUClass
, test_mem_mode
, FutureClass
) = Simulation
.setCPUClass(options
)
319 # Match the memories with the CPUs, based on the options for the test system
320 TestMemClass
= Simulation
.setMemClass(options
)
322 if options
.benchmark
:
324 bm
= Benchmarks
[options
.benchmark
]
326 print "Error benchmark %s has not been defined." % options
.benchmark
327 print "Valid benchmarks are: %s" % DefinedBenchmarks
331 bm
= [SysConfig(disk
=options
.disk_image
, rootdev
=options
.root_device
,
332 mem
=options
.mem_size
, os_type
=options
.os_type
),
333 SysConfig(disk
=options
.disk_image
, rootdev
=options
.root_device
,
334 mem
=options
.mem_size
, os_type
=options
.os_type
)]
336 bm
= [SysConfig(disk
=options
.disk_image
, rootdev
=options
.root_device
,
337 mem
=options
.mem_size
, os_type
=options
.os_type
)]
339 np
= options
.num_cpus
341 test_sys
= build_test_system(np
)
343 drive_sys
= build_drive_system(np
)
344 root
= makeDualRoot(True, test_sys
, drive_sys
, options
.etherdump
)
345 elif len(bm
) == 1 and options
.dist
:
346 # This system is part of a dist-gem5 simulation
347 root
= makeDistRoot(test_sys
,
350 options
.dist_server_name
,
351 options
.dist_server_port
,
352 options
.dist_sync_repeat
,
353 options
.dist_sync_start
,
354 options
.ethernet_linkspeed
,
355 options
.ethernet_linkdelay
,
358 root
= Root(full_system
=True, system
=test_sys
)
360 print "Error I don't know how to create more than 2 systems."
364 root
.time_sync_enable
= True
366 if options
.frame_capture
:
367 VncServer
.frame_capture
= True
369 Simulation
.setWorkCountOptions(test_sys
, options
)
370 Simulation
.run(options
, root
, test_sys
, FutureClass
)