fs_bigLITTLE.py revision 11936
111935Sandreas.sandberg@arm.com# Copyright (c) 2016-2017 ARM Limited 211569Sgabor.dozsa@arm.com# All rights reserved. 311569Sgabor.dozsa@arm.com# 411569Sgabor.dozsa@arm.com# The license below extends only to copyright in the software and shall 511569Sgabor.dozsa@arm.com# not be construed as granting a license to any other intellectual 611569Sgabor.dozsa@arm.com# property including but not limited to intellectual property relating 711569Sgabor.dozsa@arm.com# to a hardware implementation of the functionality of the software 811569Sgabor.dozsa@arm.com# licensed hereunder. You may use the software subject to the license 911569Sgabor.dozsa@arm.com# terms below provided that you ensure that this notice is replicated 1011569Sgabor.dozsa@arm.com# unmodified and in its entirety in all distributions of the software, 1111569Sgabor.dozsa@arm.com# modified or unmodified, in source code or in binary form. 1211569Sgabor.dozsa@arm.com# 1311569Sgabor.dozsa@arm.com# Redistribution and use in source and binary forms, with or without 1411569Sgabor.dozsa@arm.com# modification, are permitted provided that the following conditions are 1511569Sgabor.dozsa@arm.com# met: redistributions of source code must retain the above copyright 1611569Sgabor.dozsa@arm.com# notice, this list of conditions and the following disclaimer; 1711569Sgabor.dozsa@arm.com# redistributions in binary form must reproduce the above copyright 1811569Sgabor.dozsa@arm.com# notice, this list of conditions and the following disclaimer in the 1911569Sgabor.dozsa@arm.com# documentation and/or other materials provided with the distribution; 2011569Sgabor.dozsa@arm.com# neither the name of the copyright holders nor the names of its 2111569Sgabor.dozsa@arm.com# contributors may be used to endorse or promote products derived from 2211569Sgabor.dozsa@arm.com# this software without specific prior written permission. 2311569Sgabor.dozsa@arm.com# 2411569Sgabor.dozsa@arm.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2511569Sgabor.dozsa@arm.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2611569Sgabor.dozsa@arm.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2711569Sgabor.dozsa@arm.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2811569Sgabor.dozsa@arm.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2911569Sgabor.dozsa@arm.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3011569Sgabor.dozsa@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3111569Sgabor.dozsa@arm.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3211569Sgabor.dozsa@arm.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3311569Sgabor.dozsa@arm.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3411569Sgabor.dozsa@arm.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3511569Sgabor.dozsa@arm.com# 3611569Sgabor.dozsa@arm.com# Authors: Gabor Dozsa 3711569Sgabor.dozsa@arm.com# Andreas Sandberg 3811569Sgabor.dozsa@arm.com 3911569Sgabor.dozsa@arm.com# This is an example configuration script for full system simulation of 4011569Sgabor.dozsa@arm.com# a generic ARM bigLITTLE system. 4111569Sgabor.dozsa@arm.com 4211569Sgabor.dozsa@arm.com 4311569Sgabor.dozsa@arm.comimport argparse 4411569Sgabor.dozsa@arm.comimport os 4511569Sgabor.dozsa@arm.comimport sys 4611569Sgabor.dozsa@arm.comimport m5 4711936Sandreas.sandberg@arm.comimport m5.util 4811569Sgabor.dozsa@arm.comfrom m5.objects import * 4911569Sgabor.dozsa@arm.com 5011682Sandreas.hansson@arm.comm5.util.addToPath("../../") 5111682Sandreas.hansson@arm.com 5211682Sandreas.hansson@arm.comfrom common import SysPaths 5311682Sandreas.hansson@arm.comfrom common import CpuConfig 5411569Sgabor.dozsa@arm.com 5511569Sgabor.dozsa@arm.comimport devices 5611936Sandreas.sandberg@arm.comfrom devices import AtomicCluster, KvmCluster 5711569Sgabor.dozsa@arm.com 5811569Sgabor.dozsa@arm.com 5911569Sgabor.dozsa@arm.comdefault_dtb = 'armv8_gem5_v1_big_little_2_2.dtb' 6011569Sgabor.dozsa@arm.comdefault_kernel = 'vmlinux4.3.aarch64' 6111569Sgabor.dozsa@arm.comdefault_disk = 'aarch64-ubuntu-trusty-headless.img' 6211569Sgabor.dozsa@arm.comdefault_rcs = 'bootscript.rcS' 6311569Sgabor.dozsa@arm.com 6411569Sgabor.dozsa@arm.comdefault_mem_size= "2GB" 6511569Sgabor.dozsa@arm.com 6611936Sandreas.sandberg@arm.comdef _to_ticks(value): 6711936Sandreas.sandberg@arm.com """Helper function to convert a latency from string format to Ticks""" 6811936Sandreas.sandberg@arm.com 6911936Sandreas.sandberg@arm.com return m5.ticks.fromSeconds(m5.util.convert.anyToLatency(value)) 7011936Sandreas.sandberg@arm.com 7111936Sandreas.sandberg@arm.comdef _using_pdes(root): 7211936Sandreas.sandberg@arm.com """Determine if the simulator is using multiple parallel event queues""" 7311936Sandreas.sandberg@arm.com 7411936Sandreas.sandberg@arm.com for obj in root.descendants(): 7511936Sandreas.sandberg@arm.com if not m5.proxy.isproxy(obj.eventq_index) and \ 7611936Sandreas.sandberg@arm.com obj.eventq_index != root.eventq_index: 7711936Sandreas.sandberg@arm.com return True 7811936Sandreas.sandberg@arm.com 7911936Sandreas.sandberg@arm.com return False 8011936Sandreas.sandberg@arm.com 8111630Sgabor.dozsa@arm.com 8211630Sgabor.dozsa@arm.comclass BigCluster(devices.CpuCluster): 8311630Sgabor.dozsa@arm.com def __init__(self, system, num_cpus, cpu_clock, 8411630Sgabor.dozsa@arm.com cpu_voltage="1.0V"): 8511630Sgabor.dozsa@arm.com cpu_config = [ CpuConfig.get("arm_detailed"), devices.L1I, devices.L1D, 8611630Sgabor.dozsa@arm.com devices.WalkCache, devices.L2 ] 8711630Sgabor.dozsa@arm.com super(BigCluster, self).__init__(system, num_cpus, cpu_clock, 8811630Sgabor.dozsa@arm.com cpu_voltage, *cpu_config) 8911630Sgabor.dozsa@arm.com 9011630Sgabor.dozsa@arm.comclass LittleCluster(devices.CpuCluster): 9111630Sgabor.dozsa@arm.com def __init__(self, system, num_cpus, cpu_clock, 9211630Sgabor.dozsa@arm.com cpu_voltage="1.0V"): 9311630Sgabor.dozsa@arm.com cpu_config = [ CpuConfig.get("minor"), devices.L1I, devices.L1D, 9411630Sgabor.dozsa@arm.com devices.WalkCache, devices.L2 ] 9511630Sgabor.dozsa@arm.com super(LittleCluster, self).__init__(system, num_cpus, cpu_clock, 9611630Sgabor.dozsa@arm.com cpu_voltage, *cpu_config) 9711630Sgabor.dozsa@arm.com 9811630Sgabor.dozsa@arm.com 9911756Sgabor.dozsa@arm.comdef createSystem(caches, kernel, bootscript, disks=[]): 10011756Sgabor.dozsa@arm.com sys = devices.SimpleSystem(caches, default_mem_size, 10111756Sgabor.dozsa@arm.com kernel=SysPaths.binary(kernel), 10211569Sgabor.dozsa@arm.com readfile=bootscript, 10311569Sgabor.dozsa@arm.com machine_type="DTOnly") 10411569Sgabor.dozsa@arm.com 10511756Sgabor.dozsa@arm.com sys.mem_ctrls = SimpleMemory(range=sys._mem_range) 10611569Sgabor.dozsa@arm.com sys.mem_ctrls.port = sys.membus.master 10711569Sgabor.dozsa@arm.com 10811569Sgabor.dozsa@arm.com sys.connect() 10911569Sgabor.dozsa@arm.com 11011569Sgabor.dozsa@arm.com # Attach disk images 11111569Sgabor.dozsa@arm.com if disks: 11211569Sgabor.dozsa@arm.com def cow_disk(image_file): 11311569Sgabor.dozsa@arm.com image = CowDiskImage() 11411569Sgabor.dozsa@arm.com image.child.image_file = SysPaths.disk(image_file) 11511569Sgabor.dozsa@arm.com return image 11611569Sgabor.dozsa@arm.com 11711569Sgabor.dozsa@arm.com sys.disk_images = [ cow_disk(f) for f in disks ] 11811569Sgabor.dozsa@arm.com sys.pci_vio_block = [ PciVirtIO(vio=VirtIOBlock(image=img)) 11911569Sgabor.dozsa@arm.com for img in sys.disk_images ] 12011569Sgabor.dozsa@arm.com for dev in sys.pci_vio_block: 12111569Sgabor.dozsa@arm.com sys.attach_pci(dev) 12211569Sgabor.dozsa@arm.com 12311569Sgabor.dozsa@arm.com sys.realview.setupBootLoader(sys.membus, sys, SysPaths.binary) 12411569Sgabor.dozsa@arm.com 12511569Sgabor.dozsa@arm.com return sys 12611569Sgabor.dozsa@arm.com 12711936Sandreas.sandberg@arm.comcpu_types = { 12811936Sandreas.sandberg@arm.com "atomic" : (AtomicCluster, AtomicCluster), 12911936Sandreas.sandberg@arm.com "timing" : (BigCluster, LittleCluster), 13011936Sandreas.sandberg@arm.com} 13111936Sandreas.sandberg@arm.com 13211936Sandreas.sandberg@arm.com# Only add the KVM CPU if it has been compiled into gem5 13311936Sandreas.sandberg@arm.comif devices.have_kvm: 13411936Sandreas.sandberg@arm.com cpu_types["kvm"] = (KvmCluster, KvmCluster) 13511936Sandreas.sandberg@arm.com 13611569Sgabor.dozsa@arm.com 13711843Sgabor.dozsa@arm.comdef addOptions(parser): 13811569Sgabor.dozsa@arm.com parser.add_argument("--restore-from", type=str, default=None, 13911569Sgabor.dozsa@arm.com help="Restore from checkpoint") 14011569Sgabor.dozsa@arm.com parser.add_argument("--dtb", type=str, default=default_dtb, 14111569Sgabor.dozsa@arm.com help="DTB file to load") 14211569Sgabor.dozsa@arm.com parser.add_argument("--kernel", type=str, default=default_kernel, 14311569Sgabor.dozsa@arm.com help="Linux kernel") 14411569Sgabor.dozsa@arm.com parser.add_argument("--disk", action="append", type=str, default=[], 14511569Sgabor.dozsa@arm.com help="Disks to instantiate") 14611569Sgabor.dozsa@arm.com parser.add_argument("--bootscript", type=str, default=default_rcs, 14711569Sgabor.dozsa@arm.com help="Linux bootscript") 14811936Sandreas.sandberg@arm.com parser.add_argument("--cpu-type", type=str, choices=cpu_types.keys(), 14911936Sandreas.sandberg@arm.com default="timing", 15011936Sandreas.sandberg@arm.com help="CPU simulation mode. Default: %(default)s") 15111569Sgabor.dozsa@arm.com parser.add_argument("--kernel-init", type=str, default="/sbin/init", 15211569Sgabor.dozsa@arm.com help="Override init") 15311569Sgabor.dozsa@arm.com parser.add_argument("--big-cpus", type=int, default=1, 15411569Sgabor.dozsa@arm.com help="Number of big CPUs to instantiate") 15511569Sgabor.dozsa@arm.com parser.add_argument("--little-cpus", type=int, default=1, 15611569Sgabor.dozsa@arm.com help="Number of little CPUs to instantiate") 15711569Sgabor.dozsa@arm.com parser.add_argument("--caches", action="store_true", default=False, 15811569Sgabor.dozsa@arm.com help="Instantiate caches") 15911569Sgabor.dozsa@arm.com parser.add_argument("--last-cache-level", type=int, default=2, 16011569Sgabor.dozsa@arm.com help="Last level of caches (e.g. 3 for L3)") 16111569Sgabor.dozsa@arm.com parser.add_argument("--big-cpu-clock", type=str, default="2GHz", 16211569Sgabor.dozsa@arm.com help="Big CPU clock frequency") 16311569Sgabor.dozsa@arm.com parser.add_argument("--little-cpu-clock", type=str, default="1GHz", 16411569Sgabor.dozsa@arm.com help="Little CPU clock frequency") 16511936Sandreas.sandberg@arm.com parser.add_argument("--sim-quantum", type=str, default="1ms", 16611936Sandreas.sandberg@arm.com help="Simulation quantum for parallel simulation. " \ 16711936Sandreas.sandberg@arm.com "Default: %(default)s") 16811843Sgabor.dozsa@arm.com return parser 16911569Sgabor.dozsa@arm.com 17011843Sgabor.dozsa@arm.comdef build(options): 17111569Sgabor.dozsa@arm.com m5.ticks.fixGlobalFrequency() 17211569Sgabor.dozsa@arm.com 17311569Sgabor.dozsa@arm.com kernel_cmd = [ 17411569Sgabor.dozsa@arm.com "earlyprintk=pl011,0x1c090000", 17511569Sgabor.dozsa@arm.com "console=ttyAMA0", 17611569Sgabor.dozsa@arm.com "lpj=19988480", 17711569Sgabor.dozsa@arm.com "norandmaps", 17811569Sgabor.dozsa@arm.com "loglevel=8", 17911569Sgabor.dozsa@arm.com "mem=%s" % default_mem_size, 18011569Sgabor.dozsa@arm.com "root=/dev/vda1", 18111569Sgabor.dozsa@arm.com "rw", 18211569Sgabor.dozsa@arm.com "init=%s" % options.kernel_init, 18311569Sgabor.dozsa@arm.com "vmalloc=768MB", 18411569Sgabor.dozsa@arm.com ] 18511569Sgabor.dozsa@arm.com 18611569Sgabor.dozsa@arm.com root = Root(full_system=True) 18711569Sgabor.dozsa@arm.com 18811756Sgabor.dozsa@arm.com disks = [default_disk] if len(options.disk) == 0 else options.disk 18911756Sgabor.dozsa@arm.com system = createSystem(options.caches, 19011756Sgabor.dozsa@arm.com options.kernel, 19111756Sgabor.dozsa@arm.com options.bootscript, 19211756Sgabor.dozsa@arm.com disks=disks) 19311569Sgabor.dozsa@arm.com 19411569Sgabor.dozsa@arm.com root.system = system 19511569Sgabor.dozsa@arm.com system.boot_osflags = " ".join(kernel_cmd) 19611569Sgabor.dozsa@arm.com 19711630Sgabor.dozsa@arm.com if options.big_cpus + options.little_cpus == 0: 19811630Sgabor.dozsa@arm.com m5.util.panic("Empty CPU clusters") 19911630Sgabor.dozsa@arm.com 20011936Sandreas.sandberg@arm.com big_model, little_model = cpu_types[options.cpu_type] 20111936Sandreas.sandberg@arm.com 20211936Sandreas.sandberg@arm.com all_cpus = [] 20311569Sgabor.dozsa@arm.com # big cluster 20411569Sgabor.dozsa@arm.com if options.big_cpus > 0: 20511936Sandreas.sandberg@arm.com system.bigCluster = big_model(system, options.big_cpus, 20611936Sandreas.sandberg@arm.com options.big_cpu_clock) 20711936Sandreas.sandberg@arm.com system.mem_mode = system.bigCluster.memoryMode() 20811936Sandreas.sandberg@arm.com all_cpus += system.bigCluster.cpus 20911936Sandreas.sandberg@arm.com 21011630Sgabor.dozsa@arm.com # little cluster 21111630Sgabor.dozsa@arm.com if options.little_cpus > 0: 21211936Sandreas.sandberg@arm.com system.littleCluster = little_model(system, options.little_cpus, 21311936Sandreas.sandberg@arm.com options.little_cpu_clock) 21411936Sandreas.sandberg@arm.com system.mem_mode = system.littleCluster.memoryMode() 21511936Sandreas.sandberg@arm.com all_cpus += system.littleCluster.cpus 21611569Sgabor.dozsa@arm.com 21711936Sandreas.sandberg@arm.com # Figure out the memory mode 21811936Sandreas.sandberg@arm.com if options.big_cpus > 0 and options.little_cpus > 0 and \ 21911936Sandreas.sandberg@arm.com system.littleCluster.memoryMode() != system.littleCluster.memoryMode(): 22011936Sandreas.sandberg@arm.com m5.util.panic("Memory mode missmatch among CPU clusters") 22111569Sgabor.dozsa@arm.com 22211569Sgabor.dozsa@arm.com 22311630Sgabor.dozsa@arm.com # create caches 22411630Sgabor.dozsa@arm.com system.addCaches(options.caches, options.last_cache_level) 22511630Sgabor.dozsa@arm.com if not options.caches: 22611630Sgabor.dozsa@arm.com if options.big_cpus > 0 and system.bigCluster.requireCaches(): 22711630Sgabor.dozsa@arm.com m5.util.panic("Big CPU model requires caches") 22811630Sgabor.dozsa@arm.com if options.little_cpus > 0 and system.littleCluster.requireCaches(): 22911630Sgabor.dozsa@arm.com m5.util.panic("Little CPU model requires caches") 23011569Sgabor.dozsa@arm.com 23111936Sandreas.sandberg@arm.com # Create a KVM VM and do KVM-specific configuration 23211936Sandreas.sandberg@arm.com if issubclass(big_model, KvmCluster): 23311936Sandreas.sandberg@arm.com _build_kvm(system, all_cpus) 23411936Sandreas.sandberg@arm.com 23511569Sgabor.dozsa@arm.com # Linux device tree 23611569Sgabor.dozsa@arm.com system.dtb_filename = SysPaths.binary(options.dtb) 23711569Sgabor.dozsa@arm.com 23811843Sgabor.dozsa@arm.com return root 23911843Sgabor.dozsa@arm.com 24011936Sandreas.sandberg@arm.comdef _build_kvm(system, cpus): 24111936Sandreas.sandberg@arm.com system.kvm_vm = KvmVM() 24211936Sandreas.sandberg@arm.com 24311936Sandreas.sandberg@arm.com # Assign KVM CPUs to their own event queues / threads. This 24411936Sandreas.sandberg@arm.com # has to be done after creating caches and other child objects 24511936Sandreas.sandberg@arm.com # since these mustn't inherit the CPU event queue. 24611936Sandreas.sandberg@arm.com if len(cpus) > 1: 24711936Sandreas.sandberg@arm.com device_eq = 0 24811936Sandreas.sandberg@arm.com first_cpu_eq = 1 24911936Sandreas.sandberg@arm.com for idx, cpu in enumerate(cpus): 25011936Sandreas.sandberg@arm.com # Child objects usually inherit the parent's event 25111936Sandreas.sandberg@arm.com # queue. Override that and use the same event queue for 25211936Sandreas.sandberg@arm.com # all devices. 25311936Sandreas.sandberg@arm.com for obj in cpu.descendants(): 25411936Sandreas.sandberg@arm.com obj.eventq_index = device_eq 25511936Sandreas.sandberg@arm.com cpu.eventq_index = first_cpu_eq + idx 25611936Sandreas.sandberg@arm.com 25711936Sandreas.sandberg@arm.com 25811843Sgabor.dozsa@arm.com 25911935Sandreas.sandberg@arm.comdef instantiate(options, checkpoint_dir=None): 26011936Sandreas.sandberg@arm.com # Setup the simulation quantum if we are running in PDES-mode 26111936Sandreas.sandberg@arm.com # (e.g., when using KVM) 26211936Sandreas.sandberg@arm.com root = Root.getInstance() 26311936Sandreas.sandberg@arm.com if root and _using_pdes(root): 26411936Sandreas.sandberg@arm.com m5.util.inform("Running in PDES mode with a %s simulation quantum.", 26511936Sandreas.sandberg@arm.com options.sim_quantum) 26611936Sandreas.sandberg@arm.com root.sim_quantum = _to_ticks(options.sim_quantum) 26711936Sandreas.sandberg@arm.com 26811569Sgabor.dozsa@arm.com # Get and load from the chkpt or simpoint checkpoint 26911935Sandreas.sandberg@arm.com if options.restore_from: 27011935Sandreas.sandberg@arm.com if checkpoint_dir and not os.path.isabs(options.restore_from): 27111935Sandreas.sandberg@arm.com cpt = os.path.join(checkpoint_dir, options.restore_from) 27211935Sandreas.sandberg@arm.com else: 27311935Sandreas.sandberg@arm.com cpt = options.restore_from 27411935Sandreas.sandberg@arm.com 27511935Sandreas.sandberg@arm.com m5.util.inform("Restoring from checkpoint %s", cpt) 27611935Sandreas.sandberg@arm.com m5.instantiate(cpt) 27711569Sgabor.dozsa@arm.com else: 27811569Sgabor.dozsa@arm.com m5.instantiate() 27911569Sgabor.dozsa@arm.com 28011843Sgabor.dozsa@arm.com 28111843Sgabor.dozsa@arm.comdef run(checkpoint_dir=m5.options.outdir): 28211569Sgabor.dozsa@arm.com # start simulation (and drop checkpoints when requested) 28311569Sgabor.dozsa@arm.com while True: 28411569Sgabor.dozsa@arm.com event = m5.simulate() 28511569Sgabor.dozsa@arm.com exit_msg = event.getCause() 28611569Sgabor.dozsa@arm.com if exit_msg == "checkpoint": 28711569Sgabor.dozsa@arm.com print "Dropping checkpoint at tick %d" % m5.curTick() 28811843Sgabor.dozsa@arm.com cpt_dir = os.path.join(checkpoint_dir, "cpt.%d" % m5.curTick()) 28911843Sgabor.dozsa@arm.com m5.checkpoint(cpt_dir) 29011569Sgabor.dozsa@arm.com print "Checkpoint done." 29111569Sgabor.dozsa@arm.com else: 29211569Sgabor.dozsa@arm.com print exit_msg, " @ ", m5.curTick() 29311569Sgabor.dozsa@arm.com break 29411569Sgabor.dozsa@arm.com 29511569Sgabor.dozsa@arm.com sys.exit(event.getCode()) 29611569Sgabor.dozsa@arm.com 29711569Sgabor.dozsa@arm.com 29811843Sgabor.dozsa@arm.comdef main(): 29911843Sgabor.dozsa@arm.com parser = argparse.ArgumentParser( 30011843Sgabor.dozsa@arm.com description="Generic ARM big.LITTLE configuration") 30111843Sgabor.dozsa@arm.com addOptions(parser) 30211843Sgabor.dozsa@arm.com options = parser.parse_args() 30311843Sgabor.dozsa@arm.com root = build(options) 30411935Sandreas.sandberg@arm.com instantiate(options) 30511843Sgabor.dozsa@arm.com run() 30611843Sgabor.dozsa@arm.com 30711843Sgabor.dozsa@arm.com 30811569Sgabor.dozsa@arm.comif __name__ == "__m5_main__": 30911569Sgabor.dozsa@arm.com main() 310