gem5 startup script: revisited fs.py to get rid of ARM linux images

In former versions, the aforementioned image was 'required' to run
gem5 although it wasn't actually used at all. With the new python
script fail_fs.py, it suffices to start gem5 on a target foo.elf by
simply typing $ ../scripts/run-gem5.sh path/to/target/foo.elf

Change-Id: I7f48460e50d48d55fe22f2381e2ae8aec8510233
This commit is contained in:
Adrian Böckenkamp
2013-08-14 17:33:00 +02:00
committed by Gerrit Code Review
parent c0121b1a9b
commit 5e238cc3f9
2 changed files with 191 additions and 0 deletions

View File

@ -0,0 +1,185 @@
# --------------------------------------------------------------
# This script invokes the gem5 simulator. It is written to be used
# with the Fail* framework. For further information, see
# http://www.m5sim.org/Simulation_Scripts_Explained
# This script is based on $FAIL/simulators/gem5/configs/example/fs.py
#
# Author: Adrian Böckenkamp
#
# --------------------------------------------------------------
# Required Python modules:
import optparse
import sys
import m5 # required by gem5
from m5.objects import * # dito
from m5.util import addToPath, fatal # some helpers
addToPath('../common') # to find the next modules:
from FSConfig import *
import Simulation # for setWorkCountOptions(), run()
import CacheConfig
import Options # for parsing the command line
# --------------------------------------------------------------
# Configuration phase:
parser = optparse.OptionParser() # TODO: functionality useful?
Options.addCommonOptions(parser) # TODO: remove unused options
Options.addFSOptions(parser) # TODO: dito
(options, args) = parser.parse_args()
if args:
print "Error: script doesn't take any positional arguments"
sys.exit(1)
print "[Fail*] Welcome to the FULL SYSTEM simulation script for gem5!"
# Sets up the low-level system parameter:
class FailArmSystem(System):
type = 'ArmSystem'
load_addr_mask = 0xffffffff
# 0x35 Implementor is '5' from "M5"
# 0x0 Variant
# 0xf Architecture from CPUID scheme
# 0xc00 Primary part number ("c" or higher implies ARM v7)
# 0x0 Revision
midr_regval = Param.UInt32(0x350fc000, "MIDR value")
multi_proc = Param.Bool(True, "Multiprocessor system?")
boot_loader = Param.String("", "File that contains the boot loader code if any")
gic_cpu_addr = Param.Addr(0, "Addres of the GIC CPU interface")
flags_addr = Param.Addr(0, "Address of the flags register for MP booting")
# Creates gem5-related (Python) system objects (hierarchy):
def makeFailArmSystem(mem_mode, machine_type):
assert machine_type
self = FailArmSystem()
# generic system
mdesc = SysConfig()
self.readfile = mdesc.script()
self.iobus = NoncoherentBus()
self.membus = MemBus()
self.membus.badaddr_responder.warn_access = "warn"
self.bridge = Bridge(delay='50ns', nack_delay='4ns')
self.bridge.master = self.iobus.slave
self.bridge.slave = self.membus.master
self.mem_mode = mem_mode
if machine_type == "RealView_PBX":
self.realview = RealViewPBX()
elif machine_type == "RealView_EB":
self.realview = RealViewEB()
elif machine_type == "VExpress_ELT":
self.realview = VExpress_ELT()
elif machine_type == "VExpress_EMM":
self.realview = VExpress_EMM()
self.load_addr_mask = 0xffffffff
else:
print "Unknown Machine Type"
sys.exit(1)
# No disk image / IDE controller interface stuff.
# EOT character on UART will end the simulation
self.realview.uart.end_on_eot = True
self.physmem = SimpleMemory(range = AddrRange(Addr(mdesc.mem())),
zero = True)
self.physmem.port = self.membus.master
self.realview.attachOnChipIO(self.membus, self.bridge)
self.realview.attachIO(self.iobus)
self.intrctrl = IntrControl()
self.terminal = Terminal()
self.vncserver = VncServer()
self.system_port = self.membus.slave
return self
# Driver system CPU is always simple... note this is an assignment of
# a class, not an instance.
DriveCPUClass = AtomicSimpleCPU
drive_mem_mode = 'atomic'
# We use the atomic simple CPU model:
class TestCPUClass(AtomicSimpleCPU): pass
# "TestCPUClass" is our CPU class type (sic!), derived from AtomicSimpleCPU
test_mem_mode = 'atomic'
FutureClass = None
TestCPUClass.clock = '2GHz'
DriveCPUClass.clock = '2GHz'
# Extract #CPUs:
np = options.num_cpus
# This script is only designed to be used with ARM targets. However,
# it should be simple to extend it.
if buildEnv['TARGET_ISA'] != "arm":
fatal("Incapable of building %s full system (only for ARM)! You may want to try fs.py instead.", buildEnv['TARGET_ISA'])
# Create the gem5 component hierarchy (see above for the definition).
# In particular, it specifies system-specific parameters (e.g., Multi-
# processor system flag, memory bus (type), an UART, ...):
test_sys = makeFailArmSystem(test_mem_mode, options.machine_type)
# Set the path to the kernel. Essentially, this the path to your
# experiment target (e.g., the abo-simple-arm.elf file). It should
# contain the bootload code as well.
if options.kernel is not None:
print "[Fail*] Using target: " + options.kernel
test_sys.kernel = options.kernel
else:
print "[Fail*] No kernel target given, exiting!"
sys.exit(1)
test_sys.init_param = options.init_param
# Construct the CPUs (np in total) and connect them to the "test system":
test_sys.cpu = [TestCPUClass(cpu_id=i) for i in xrange(np)]
# Create the memory:
mem_size = SysConfig().mem()
# Create the caches:
if options.caches or options.l2cache:
test_sys.iocache = IOCache(addr_ranges=[test_sys.physmem.range])
test_sys.iocache.cpu_side = test_sys.iobus.master
test_sys.iocache.mem_side = test_sys.membus.slave
else:
test_sys.iobridge = Bridge(delay='50ns', nack_delay='4ns',
ranges = [test_sys.physmem.range])
test_sys.iobridge.slave = test_sys.iobus.master
test_sys.iobridge.master = test_sys.membus.slave
# Sanity check
if options.fastmem and (options.caches or options.l2cache):
fatal("You cannot use fastmem in combination with caches!")
for i in xrange(np):
if options.fastmem:
test_sys.cpu[i].fastmem = True
if options.checker:
test_sys.cpu[i].addCheckerCpu()
CacheConfig.config_cache(options, test_sys)
# Setup the root node and connect the hierarchy:
root = Root(full_system=True, system=test_sys)
# TODO: What's this for?
if options.timesync:
root.time_sync_enable = True
# TODO: What's this for?
if options.frame_capture:
VncServer.frame_capture = True
# --------------------------------------------------------------
# Simulation phase:
Simulation.setWorkCountOptions(test_sys, options) # see Simulation.py
# In essence, "run(...)" calls m5.instantiate() and, finally, m5.simulate().
Simulation.run(options, root, test_sys, FutureClass)