1# Simple M5 script for use with Barrelfish.  This creates a very
2# basic machine with a set of CPUs connected directly to the
3# simulated memory.
4#
5# (See configs/example/* in the M5 distribution for examples of
6# fuller scripts -- caches, etc.).
7
8# Determine script pathname
9import inspect, os
10import optparse
11import os
12import sys
13import m5
14
15from m5.defines import buildEnv
16from m5.objects import *
17from m5.util import fatal
18
19#from O3_ARM_v7a import *
20import CacheConfig
21from Caches import *
22
23# Try to determine Barrelfish source directory
24# We assume that this script remains in tools/arm_gem5
25bfsrcdir='%s/../..' % os.path.dirname(inspect.getfile(inspect.currentframe()))
26print "Barrelfish source-directory is assume to be %s" % bfsrcdir
27
28class MemBus(SystemXBar):
29    badaddr_responder = BadAddr()
30    default = Self.badaddr_responder.pio
31
32#######################################################################
33#
34# Utility functions
35def setCPUClass(options):
36
37    atomic = False
38    if options.cpu_type == "timing":
39        class TmpClass(TimingSimpleCPU): pass
40    elif options.cpu_type == "detailed" or options.cpu_type == "arm_detailed":
41        if not options.caches and not options.ruby:
42            print "O3 CPU must be used with caches"
43            sys.exit(1)
44        if options.cpu_type == "arm_detailed":
45            class TmpClass(O3_ARM_v7a_3): pass
46        else:
47            class TmpClass(DerivO3CPU): pass
48    elif options.cpu_type == "inorder":
49        if not options.caches:
50            print "InOrder CPU must be used with caches"
51            sys.exit(1)
52        class TmpClass(InOrderCPU): pass
53    else:
54        class TmpClass(AtomicSimpleCPU): pass
55        atomic = True
56
57    CPUClass = None
58    test_mem_mode = 'atomic'
59
60    if not atomic:
61            test_mem_mode = 'timing'
62
63    return (TmpClass, test_mem_mode, CPUClass)
64
65#######################################################################
66#
67# Check that we are running on a full-system arm simulator
68
69if not buildEnv['TARGET_ISA'] == "arm":
70    fatal("Expected TARGET_ISA == arm");
71
72#######################################################################
73#
74# Set up basic configuration options
75
76parser = optparse.OptionParser()
77parser.add_option("--kernel", action="store", type="string")
78parser.add_option("--ramdisk", action="store", type="string")
79parser.add_option("-n", "--num_cpus", type="int", default=1)
80parser.add_option("--cpu-type", type="choice", default="atomic",
81                  choices = ["atomic", "arm_detailed"],
82                  help = "type of cpu to run with")
83parser.add_option("--caches", action="store_true")
84parser.add_option("--l2cache", action="store_true")
85parser.add_option("--l1d_size", type="string", default="64kB")
86parser.add_option("--l1i_size", type="string", default="32kB")
87parser.add_option("--l2_size", type="string", default="2MB")
88parser.add_option("--l3_size", type="string", default="16MB")
89parser.add_option("--l1d_assoc", type="int", default=2)
90parser.add_option("--l1i_assoc", type="int", default=2)
91parser.add_option("--l2_assoc", type="int", default=8)
92parser.add_option("--l3_assoc", type="int", default=16)
93parser.add_option("--cacheline_size", type="int", default=64)
94parser.add_option("--loglevel", type="int", default=4)
95parser.add_option("--clock", action="store", type="string", default='1GHz')
96#parser.add_option("--memchecker", action="store_true")
97#parser.add_option("-d", "--detailed", action="store_true")
98parser.add_option("--spec-input", default="ref", type="choice",
99                      choices=["ref", "test", "train", "smred", "mdred",
100                               "lgred"],
101                      help="Input set size for SPEC CPU2000 benchmarks.")
102parser.add_option("--arm-iset", default="arm", type="choice",
103                      choices=["arm", "thumb", "aarch64"],
104                      help="ARM instruction set.")
105(options, args) = parser.parse_args()
106
107#######################################################################
108#
109# Create simulated machine.
110
111
112(CPUClass, mem_mode, FutureClass) = setCPUClass(options)
113
114system = ArmSystem()
115#system = LinuxArmSystem()
116#kernel to boot
117system.kernel = options.kernel
118
119#memory system
120system.iobus = IOXBar()
121#system.iobus = NoncoherentXBar()
122#system.iobus.forward_latency = 0
123#system.iobus.frontend_latency = 0
124#system.iobus.response_latency = 0
125system.membus = MemBus()
126system.membus.badaddr_responder.warn_access = "warn"
127
128system.bridge = Bridge(delay='50ns')
129system.bridge.master = system.iobus.slave
130system.bridge.slave = system.membus.master
131
132system.physmem = SimpleMemory(range = AddrRange('256MB'),conf_table_reported = True)
133
134system.mem_mode = mem_mode
135#load ramdisk at specific location (256MB = @0x10000000)
136#system.ramdisk = SimpleMemory(range = AddrRange(Addr('256MB'), size = '256MB'), file=options.ramdisk)
137#system.ramdisk.port = system.membus.master
138
139#CPU(s)
140#CPUClass.clock = "1GHz"
141system.cpu = [CPUClass(cpu_id=i) for i in xrange(options.num_cpus)]
142
143#machine type
144system.realview = VExpress_EMM()
145
146#setup bootloader
147system.realview.nvmem = SimpleMemory(range = AddrRange(Addr('2GB'), size = '64MB'), null = True)
148system.realview.nvmem.port = system.membus.master
149# System boot loader is now given relative to source directory
150system.boot_loader = ('%s/tools/aarch64_gem5/boot_emm.aarch64' % bfsrcdir)
151system.highest_el_is_64 = True
152#system.boot_loader_mem = system.realview.nvmem
153#system.realview.setupBootLoader(system.membus, system, '../tools/arm_gem5/boot.arm')
154system.gic_cpu_addr = system.realview.gic.cpu_addr
155system.flags_addr = system.realview.realview_io.pio_addr + 0x30
156
157boot_flags = 'rw loglevel=%s' % (options.loglevel)
158system.boot_osflags = boot_flags
159
160system.realview.attachOnChipIO(system.membus, system.bridge)
161system.realview.attachIO(system.iobus)
162system.intrctrl = IntrControl()
163system.terminal = Terminal()
164system.vncserver = VncServer()
165
166system.physmem.port = system.membus.master
167
168
169system.system_port = system.membus.slave
170
171#Caches
172if options.caches or options.l2cache:
173    system.iocache = IOCache(addr_ranges=[system.physmem.range])
174    system.iocache.cpu_side = system.iobus.master
175    system.iocache.mem_side = system.membus.slave
176else:
177    system.iobridge = Bridge(delay='50ns',
178                               ranges = [system.physmem.range])
179    system.iobridge.slave = system.iobus.master
180    system.iobridge.master = system.membus.slave
181
182CacheConfig.config_cache(options, system)
183
184#######################################################################
185#
186# Start simulation
187
188root = Root(full_system=True, system=system)
189m5.instantiate()
190
191print '..... STARTING SIMULATION'
192
193exit_event = m5.simulate()
194exit_cause = exit_event.getCause()
195
196print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_cause)
197