fs.py revision 10519:7a3ad4b09ce4
16019Shines@cs.fsu.edu# Copyright (c) 2010-2013 ARM Limited 27189Sgblack@eecs.umich.edu# All rights reserved. 37189Sgblack@eecs.umich.edu# 47189Sgblack@eecs.umich.edu# The license below extends only to copyright in the software and shall 57189Sgblack@eecs.umich.edu# not be construed as granting a license to any other intellectual 67189Sgblack@eecs.umich.edu# property including but not limited to intellectual property relating 77189Sgblack@eecs.umich.edu# to a hardware implementation of the functionality of the software 87189Sgblack@eecs.umich.edu# licensed hereunder. You may use the software subject to the license 97189Sgblack@eecs.umich.edu# terms below provided that you ensure that this notice is replicated 107189Sgblack@eecs.umich.edu# unmodified and in its entirety in all distributions of the software, 117189Sgblack@eecs.umich.edu# modified or unmodified, in source code or in binary form. 127189Sgblack@eecs.umich.edu# 137189Sgblack@eecs.umich.edu# Copyright (c) 2012-2014 Mark D. Hill and David A. Wood 146019Shines@cs.fsu.edu# Copyright (c) 2009-2011 Advanced Micro Devices, Inc. 156019Shines@cs.fsu.edu# Copyright (c) 2006-2007 The Regents of The University of Michigan 166019Shines@cs.fsu.edu# All rights reserved. 176019Shines@cs.fsu.edu# 186019Shines@cs.fsu.edu# Redistribution and use in source and binary forms, with or without 196019Shines@cs.fsu.edu# modification, are permitted provided that the following conditions are 206019Shines@cs.fsu.edu# met: redistributions of source code must retain the above copyright 216019Shines@cs.fsu.edu# notice, this list of conditions and the following disclaimer; 226019Shines@cs.fsu.edu# redistributions in binary form must reproduce the above copyright 236019Shines@cs.fsu.edu# notice, this list of conditions and the following disclaimer in the 246019Shines@cs.fsu.edu# documentation and/or other materials provided with the distribution; 256019Shines@cs.fsu.edu# neither the name of the copyright holders nor the names of its 266019Shines@cs.fsu.edu# contributors may be used to endorse or promote products derived from 276019Shines@cs.fsu.edu# this software without specific prior written permission. 286019Shines@cs.fsu.edu# 296019Shines@cs.fsu.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 306019Shines@cs.fsu.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 316019Shines@cs.fsu.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 326019Shines@cs.fsu.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 336019Shines@cs.fsu.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 346019Shines@cs.fsu.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 356019Shines@cs.fsu.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 366019Shines@cs.fsu.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 376019Shines@cs.fsu.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 386019Shines@cs.fsu.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 396019Shines@cs.fsu.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 406019Shines@cs.fsu.edu# 416735Sgblack@eecs.umich.edu# Authors: Ali Saidi 426735Sgblack@eecs.umich.edu# Brad Beckmann 436019Shines@cs.fsu.edu 446019Shines@cs.fsu.eduimport optparse 456019Shines@cs.fsu.eduimport sys 466019Shines@cs.fsu.edu 476019Shines@cs.fsu.eduimport m5 487362Sgblack@eecs.umich.edufrom m5.defines import buildEnv 496735Sgblack@eecs.umich.edufrom m5.objects import * 506735Sgblack@eecs.umich.edufrom m5.util import addToPath, fatal 516019Shines@cs.fsu.edu 526019Shines@cs.fsu.eduaddToPath('../common') 536019Shines@cs.fsu.eduaddToPath('../ruby') 546019Shines@cs.fsu.edu 556019Shines@cs.fsu.eduimport Ruby 566019Shines@cs.fsu.edu 576735Sgblack@eecs.umich.edufrom FSConfig import * 586019Shines@cs.fsu.edufrom SysPaths import * 597362Sgblack@eecs.umich.edufrom Benchmarks import * 606019Shines@cs.fsu.eduimport Simulation 616019Shines@cs.fsu.eduimport CacheConfig 626735Sgblack@eecs.umich.eduimport MemConfig 636735Sgblack@eecs.umich.edufrom Caches import * 646019Shines@cs.fsu.eduimport Options 657362Sgblack@eecs.umich.edu 667362Sgblack@eecs.umich.edu 677362Sgblack@eecs.umich.edu# Check if KVM support has been enabled, we might need to do VM 687362Sgblack@eecs.umich.edu# configuration if that's the case. 697362Sgblack@eecs.umich.eduhave_kvm_support = 'BaseKvmCPU' in globals() 707362Sgblack@eecs.umich.edudef is_kvm_cpu(cpu_class): 717362Sgblack@eecs.umich.edu return have_kvm_support and cpu_class != None and \ 727362Sgblack@eecs.umich.edu issubclass(cpu_class, BaseKvmCPU) 737362Sgblack@eecs.umich.edu 747362Sgblack@eecs.umich.edudef build_test_system(np): 757362Sgblack@eecs.umich.edu if buildEnv['TARGET_ISA'] == "alpha": 767362Sgblack@eecs.umich.edu test_sys = makeLinuxAlphaSystem(test_mem_mode, bm[0], options.ruby) 777362Sgblack@eecs.umich.edu elif buildEnv['TARGET_ISA'] == "mips": 787362Sgblack@eecs.umich.edu test_sys = makeLinuxMipsSystem(test_mem_mode, bm[0]) 797362Sgblack@eecs.umich.edu elif buildEnv['TARGET_ISA'] == "sparc": 807362Sgblack@eecs.umich.edu test_sys = makeSparcSystem(test_mem_mode, bm[0]) 817362Sgblack@eecs.umich.edu elif buildEnv['TARGET_ISA'] == "x86": 827362Sgblack@eecs.umich.edu test_sys = makeLinuxX86System(test_mem_mode, options.num_cpus, bm[0], 837362Sgblack@eecs.umich.edu options.ruby) 847362Sgblack@eecs.umich.edu elif buildEnv['TARGET_ISA'] == "arm": 857362Sgblack@eecs.umich.edu test_sys = makeArmSystem(test_mem_mode, options.machine_type, 867362Sgblack@eecs.umich.edu options.num_cpus, bm[0], options.dtb_filename, 877362Sgblack@eecs.umich.edu bare_metal=options.bare_metal) 887362Sgblack@eecs.umich.edu if options.enable_context_switch_stats_dump: 897362Sgblack@eecs.umich.edu test_sys.enable_context_switch_stats_dump = True 906735Sgblack@eecs.umich.edu else: 916735Sgblack@eecs.umich.edu fatal("Incapable of building %s full system!", buildEnv['TARGET_ISA']) 926735Sgblack@eecs.umich.edu 936735Sgblack@eecs.umich.edu # Set the cache line size for the entire system 946735Sgblack@eecs.umich.edu test_sys.cache_line_size = options.cacheline_size 956735Sgblack@eecs.umich.edu 966735Sgblack@eecs.umich.edu # Create a top-level voltage domain 976735Sgblack@eecs.umich.edu test_sys.voltage_domain = VoltageDomain(voltage = options.sys_voltage) 986735Sgblack@eecs.umich.edu 996735Sgblack@eecs.umich.edu # Create a source clock for the system and set the clock period 1006735Sgblack@eecs.umich.edu test_sys.clk_domain = SrcClockDomain(clock = options.sys_clock, 1016735Sgblack@eecs.umich.edu voltage_domain = test_sys.voltage_domain) 1026019Shines@cs.fsu.edu 1036735Sgblack@eecs.umich.edu # Create a CPU voltage domain 1046019Shines@cs.fsu.edu test_sys.cpu_voltage_domain = VoltageDomain() 1056735Sgblack@eecs.umich.edu 1066735Sgblack@eecs.umich.edu # Create a source clock for the CPUs and set the clock period 1076735Sgblack@eecs.umich.edu test_sys.cpu_clk_domain = SrcClockDomain(clock = options.cpu_clock, 1086735Sgblack@eecs.umich.edu voltage_domain = 1096735Sgblack@eecs.umich.edu test_sys.cpu_voltage_domain) 1106735Sgblack@eecs.umich.edu 1116735Sgblack@eecs.umich.edu if options.kernel is not None: 1126019Shines@cs.fsu.edu test_sys.kernel = binary(options.kernel) 1136019Shines@cs.fsu.edu 1146735Sgblack@eecs.umich.edu if options.script is not None: 1157362Sgblack@eecs.umich.edu test_sys.readfile = options.script 1166019Shines@cs.fsu.edu 1176735Sgblack@eecs.umich.edu if options.lpae: 1186735Sgblack@eecs.umich.edu test_sys.have_lpae = True 1196735Sgblack@eecs.umich.edu 1206019Shines@cs.fsu.edu if options.virtualisation: 1216735Sgblack@eecs.umich.edu test_sys.have_virtualization = True 1226735Sgblack@eecs.umich.edu 1236735Sgblack@eecs.umich.edu test_sys.init_param = options.init_param 1246735Sgblack@eecs.umich.edu 1256735Sgblack@eecs.umich.edu # For now, assign all the CPUs to the same clock domain 1266735Sgblack@eecs.umich.edu test_sys.cpu = [TestCPUClass(clk_domain=test_sys.cpu_clk_domain, cpu_id=i) 1276735Sgblack@eecs.umich.edu for i in xrange(np)] 1286735Sgblack@eecs.umich.edu 1296019Shines@cs.fsu.edu if is_kvm_cpu(TestCPUClass) or is_kvm_cpu(FutureClass): 1306019Shines@cs.fsu.edu test_sys.vm = KvmVM() 1317400SAli.Saidi@ARM.com 1327400SAli.Saidi@ARM.com if options.ruby: 1337400SAli.Saidi@ARM.com # Check for timing mode because ruby does not support atomic accesses 1347400SAli.Saidi@ARM.com if not (options.cpu_type == "detailed" or options.cpu_type == "timing"): 1357400SAli.Saidi@ARM.com print >> sys.stderr, "Ruby requires TimingSimpleCPU or O3CPU!!" 1367400SAli.Saidi@ARM.com sys.exit(1) 1377400SAli.Saidi@ARM.com 1387400SAli.Saidi@ARM.com Ruby.create_system(options, True, test_sys, test_sys.iobus, 1397400SAli.Saidi@ARM.com test_sys._dma_ports) 1407189Sgblack@eecs.umich.edu test_sys.physmem = [SimpleMemory(range = r, null = True) 1417362Sgblack@eecs.umich.edu for r in test_sys.mem_ranges] 1427189Sgblack@eecs.umich.edu 1437189Sgblack@eecs.umich.edu # Create a seperate clock domain for Ruby 1447189Sgblack@eecs.umich.edu test_sys.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock, 1457189Sgblack@eecs.umich.edu voltage_domain = test_sys.voltage_domain) 1467189Sgblack@eecs.umich.edu 1477189Sgblack@eecs.umich.edu for (i, cpu) in enumerate(test_sys.cpu): 1487189Sgblack@eecs.umich.edu # 1497189Sgblack@eecs.umich.edu # Tie the cpu ports to the correct ruby system ports 1507189Sgblack@eecs.umich.edu # 1517189Sgblack@eecs.umich.edu cpu.clk_domain = test_sys.cpu_clk_domain 1527189Sgblack@eecs.umich.edu cpu.createThreads() 1537189Sgblack@eecs.umich.edu cpu.createInterruptController() 1547189Sgblack@eecs.umich.edu 1557189Sgblack@eecs.umich.edu cpu.icache_port = test_sys.ruby._cpu_ports[i].slave 1567189Sgblack@eecs.umich.edu cpu.dcache_port = test_sys.ruby._cpu_ports[i].slave 1577189Sgblack@eecs.umich.edu 1587189Sgblack@eecs.umich.edu if buildEnv['TARGET_ISA'] == "x86": 1597189Sgblack@eecs.umich.edu cpu.itb.walker.port = test_sys.ruby._cpu_ports[i].slave 1607189Sgblack@eecs.umich.edu cpu.dtb.walker.port = test_sys.ruby._cpu_ports[i].slave 1617362Sgblack@eecs.umich.edu 1627197Sgblack@eecs.umich.edu cpu.interrupts.pio = test_sys.ruby._cpu_ports[i].master 1637197Sgblack@eecs.umich.edu cpu.interrupts.int_master = test_sys.ruby._cpu_ports[i].slave 1647197Sgblack@eecs.umich.edu cpu.interrupts.int_slave = test_sys.ruby._cpu_ports[i].master 1657197Sgblack@eecs.umich.edu 1667197Sgblack@eecs.umich.edu # Connect the ruby io port to the PIO bus, 1677197Sgblack@eecs.umich.edu # assuming that there is just one such port. 1687197Sgblack@eecs.umich.edu test_sys.iobus.master = test_sys.ruby._io_port.slave 1697197Sgblack@eecs.umich.edu 1707197Sgblack@eecs.umich.edu else: 1717197Sgblack@eecs.umich.edu if options.caches or options.l2cache: 1727197Sgblack@eecs.umich.edu # By default the IOCache runs at the system clock 1737197Sgblack@eecs.umich.edu test_sys.iocache = IOCache(addr_ranges = test_sys.mem_ranges) 1747362Sgblack@eecs.umich.edu test_sys.iocache.cpu_side = test_sys.iobus.master 1757362Sgblack@eecs.umich.edu test_sys.iocache.mem_side = test_sys.membus.slave 1767362Sgblack@eecs.umich.edu else: 1777362Sgblack@eecs.umich.edu test_sys.iobridge = Bridge(delay='50ns', ranges = test_sys.mem_ranges) 1787362Sgblack@eecs.umich.edu test_sys.iobridge.slave = test_sys.iobus.master 1797362Sgblack@eecs.umich.edu test_sys.iobridge.master = test_sys.membus.slave 1807362Sgblack@eecs.umich.edu 1817362Sgblack@eecs.umich.edu # Sanity check 1827362Sgblack@eecs.umich.edu if options.fastmem: 1837362Sgblack@eecs.umich.edu if TestCPUClass != AtomicSimpleCPU: 1847362Sgblack@eecs.umich.edu fatal("Fastmem can only be used with atomic CPU!") 1857362Sgblack@eecs.umich.edu if (options.caches or options.l2cache): 1867362Sgblack@eecs.umich.edu fatal("You cannot use fastmem in combination with caches!") 1877362Sgblack@eecs.umich.edu 1887362Sgblack@eecs.umich.edu for i in xrange(np): 1897362Sgblack@eecs.umich.edu if options.fastmem: 1907362Sgblack@eecs.umich.edu test_sys.cpu[i].fastmem = True 1917362Sgblack@eecs.umich.edu if options.checker: 1927362Sgblack@eecs.umich.edu test_sys.cpu[i].addCheckerCpu() 1937362Sgblack@eecs.umich.edu test_sys.cpu[i].createThreads() 1947362Sgblack@eecs.umich.edu 1957362Sgblack@eecs.umich.edu CacheConfig.config_cache(options, test_sys) 1967362Sgblack@eecs.umich.edu MemConfig.config_mem(options, test_sys) 1977362Sgblack@eecs.umich.edu 1987362Sgblack@eecs.umich.edu return test_sys 1997362Sgblack@eecs.umich.edu 2007362Sgblack@eecs.umich.edudef build_drive_system(np): 2017362Sgblack@eecs.umich.edu # driver system CPU is always simple, so is the memory 2027362Sgblack@eecs.umich.edu # Note this is an assignment of a class, not an instance. 2037362Sgblack@eecs.umich.edu DriveCPUClass = AtomicSimpleCPU 2047362Sgblack@eecs.umich.edu drive_mem_mode = 'atomic' 2057362Sgblack@eecs.umich.edu DriveMemClass = SimpleMemory 2067362Sgblack@eecs.umich.edu 2077362Sgblack@eecs.umich.edu if buildEnv['TARGET_ISA'] == 'alpha': 2087362Sgblack@eecs.umich.edu drive_sys = makeLinuxAlphaSystem(drive_mem_mode, bm[1]) 2097362Sgblack@eecs.umich.edu elif buildEnv['TARGET_ISA'] == 'mips': 2107362Sgblack@eecs.umich.edu drive_sys = makeLinuxMipsSystem(drive_mem_mode, bm[1]) 2117362Sgblack@eecs.umich.edu elif buildEnv['TARGET_ISA'] == 'sparc': 2127362Sgblack@eecs.umich.edu drive_sys = makeSparcSystem(drive_mem_mode, bm[1]) 2137362Sgblack@eecs.umich.edu elif buildEnv['TARGET_ISA'] == 'x86': 2147362Sgblack@eecs.umich.edu drive_sys = makeLinuxX86System(drive_mem_mode, np, bm[1]) 2157362Sgblack@eecs.umich.edu elif buildEnv['TARGET_ISA'] == 'arm': 2167362Sgblack@eecs.umich.edu drive_sys = makeArmSystem(drive_mem_mode, options.machine_type, bm[1]) 2177362Sgblack@eecs.umich.edu 2186019Shines@cs.fsu.edu # Create a top-level voltage domain 2196019Shines@cs.fsu.edu drive_sys.voltage_domain = VoltageDomain(voltage = options.sys_voltage) 2206019Shines@cs.fsu.edu 2216019Shines@cs.fsu.edu # Create a source clock for the system and set the clock period 2226019Shines@cs.fsu.edu drive_sys.clk_domain = SrcClockDomain(clock = options.sys_clock, 223 voltage_domain = drive_sys.voltage_domain) 224 225 # Create a CPU voltage domain 226 drive_sys.cpu_voltage_domain = VoltageDomain() 227 228 # Create a source clock for the CPUs and set the clock period 229 drive_sys.cpu_clk_domain = SrcClockDomain(clock = options.cpu_clock, 230 voltage_domain = 231 drive_sys.cpu_voltage_domain) 232 233 drive_sys.cpu = DriveCPUClass(clk_domain=drive_sys.cpu_clk_domain, 234 cpu_id=0) 235 drive_sys.cpu.createThreads() 236 drive_sys.cpu.createInterruptController() 237 drive_sys.cpu.connectAllPorts(drive_sys.membus) 238 if options.fastmem: 239 drive_sys.cpu.fastmem = True 240 if options.kernel is not None: 241 drive_sys.kernel = binary(options.kernel) 242 243 if is_kvm_cpu(DriveCPUClass): 244 drive_sys.vm = KvmVM() 245 246 drive_sys.iobridge = Bridge(delay='50ns', 247 ranges = drive_sys.mem_ranges) 248 drive_sys.iobridge.slave = drive_sys.iobus.master 249 drive_sys.iobridge.master = drive_sys.membus.slave 250 251 # Create the appropriate memory controllers and connect them to the 252 # memory bus 253 drive_sys.mem_ctrls = [DriveMemClass(range = r) 254 for r in drive_sys.mem_ranges] 255 for i in xrange(len(drive_sys.mem_ctrls)): 256 drive_sys.mem_ctrls[i].port = drive_sys.membus.master 257 258 drive_sys.init_param = options.init_param 259 260 return drive_sys 261 262# Add options 263parser = optparse.OptionParser() 264Options.addCommonOptions(parser) 265Options.addFSOptions(parser) 266 267# Add the ruby specific and protocol specific options 268if '--ruby' in sys.argv: 269 Ruby.define_options(parser) 270 271(options, args) = parser.parse_args() 272 273if args: 274 print "Error: script doesn't take any positional arguments" 275 sys.exit(1) 276 277# system under test can be any CPU 278(TestCPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options) 279 280# Match the memories with the CPUs, based on the options for the test system 281TestMemClass = Simulation.setMemClass(options) 282 283if options.benchmark: 284 try: 285 bm = Benchmarks[options.benchmark] 286 except KeyError: 287 print "Error benchmark %s has not been defined." % options.benchmark 288 print "Valid benchmarks are: %s" % DefinedBenchmarks 289 sys.exit(1) 290else: 291 if options.dual: 292 bm = [SysConfig(disk=options.disk_image, mem=options.mem_size), 293 SysConfig(disk=options.disk_image, mem=options.mem_size)] 294 else: 295 bm = [SysConfig(disk=options.disk_image, mem=options.mem_size)] 296 297np = options.num_cpus 298 299test_sys = build_test_system(np) 300if len(bm) == 2: 301 drive_sys = build_drive_system(np) 302 root = makeDualRoot(True, test_sys, drive_sys, options.etherdump) 303elif len(bm) == 1: 304 root = Root(full_system=True, system=test_sys) 305else: 306 print "Error I don't know how to create more than 2 systems." 307 sys.exit(1) 308 309if options.timesync: 310 root.time_sync_enable = True 311 312if options.frame_capture: 313 VncServer.frame_capture = True 314 315Simulation.setWorkCountOptions(test_sys, options) 316Simulation.run(options, root, test_sys, FutureClass) 317