starter_se.py revision 12564
11689SN/A# Copyright (c) 2016-2017 ARM Limited
28948Sandreas.hansson@arm.com# All rights reserved.
38707Sandreas.hansson@arm.com#
48707Sandreas.hansson@arm.com# The license below extends only to copyright in the software and shall
58707Sandreas.hansson@arm.com# not be construed as granting a license to any other intellectual
68707Sandreas.hansson@arm.com# property including but not limited to intellectual property relating
78707Sandreas.hansson@arm.com# to a hardware implementation of the functionality of the software
88707Sandreas.hansson@arm.com# licensed hereunder.  You may use the software subject to the license
98707Sandreas.hansson@arm.com# terms below provided that you ensure that this notice is replicated
108707Sandreas.hansson@arm.com# unmodified and in its entirety in all distributions of the software,
118707Sandreas.hansson@arm.com# modified or unmodified, in source code or in binary form.
128707Sandreas.hansson@arm.com#
138707Sandreas.hansson@arm.com# Redistribution and use in source and binary forms, with or without
142325SN/A# modification, are permitted provided that the following conditions are
157897Shestness@cs.utexas.edu# met: redistributions of source code must retain the above copyright
161689SN/A# notice, this list of conditions and the following disclaimer;
171689SN/A# redistributions in binary form must reproduce the above copyright
181689SN/A# notice, this list of conditions and the following disclaimer in the
191689SN/A# documentation and/or other materials provided with the distribution;
201689SN/A# neither the name of the copyright holders nor the names of its
211689SN/A# contributors may be used to endorse or promote products derived from
221689SN/A# this software without specific prior written permission.
231689SN/A#
241689SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
251689SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
261689SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
271689SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
281689SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
291689SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
301689SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
311689SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
321689SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
331689SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
341689SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
351689SN/A#
361689SN/A#  Authors:  Andreas Sandberg
371689SN/A#            Chuan Zhu
381689SN/A#            Gabor Dozsa
391689SN/A#
402665Ssaidi@eecs.umich.edu
412665Ssaidi@eecs.umich.edu"""This script is the syscall emulation example script from the ARM
422756Sksewell@umich.eduResearch Starter Kit on System Modeling. More information can be found
437897Shestness@cs.utexas.eduat: http://www.arm.com/ResearchEnablement/SystemModeling
441689SN/A"""
451689SN/A
468779Sgblack@eecs.umich.edufrom __future__ import print_function
476658Snate@binkert.org
488887Sgeoffrey.blake@arm.comimport os
498887Sgeoffrey.blake@arm.comimport m5
508229Snate@binkert.orgfrom m5.util import addToPath
518229Snate@binkert.orgfrom m5.objects import *
528229Snate@binkert.orgimport argparse
534762Snate@binkert.orgimport shlex
548779Sgblack@eecs.umich.edu
554762Snate@binkert.orgm5.util.addToPath('../..')
564762Snate@binkert.org
578232Snate@binkert.orgfrom common import MemConfig
589152Satgutier@umich.edufrom common.cores.arm import HPI
598232Snate@binkert.org
608232Snate@binkert.orgimport devices
614762Snate@binkert.org
624762Snate@binkert.org
638793Sgblack@eecs.umich.edu
648779Sgblack@eecs.umich.edu# Pre-defined CPU configurations. Each tuple must be ordered as : (cpu_class,
654762Snate@binkert.org# l1_icache_class, l1_dcache_class, walk_cache_class, l2_Cache_class). Any of
668460SAli.Saidi@ARM.com# the cache class may be 'None' if the particular cache is not present.
674762Snate@binkert.orgcpu_types = {
685702Ssaidi@eecs.umich.edu    "atomic" : ( AtomicSimpleCPU, None, None, None, None),
695702Ssaidi@eecs.umich.edu    "minor" : (MinorCPU,
708232Snate@binkert.org               devices.L1I, devices.L1D,
715702Ssaidi@eecs.umich.edu               devices.WalkCache,
725702Ssaidi@eecs.umich.edu               devices.L2),
738737Skoansin.tan@gmail.com    "hpi" : ( HPI.HPI,
745529Snate@binkert.org              HPI.HPI_ICache, HPI.HPI_DCache,
752669Sktlim@umich.edu              HPI.HPI_WalkCache,
766221Snate@binkert.org              HPI.HPI_L2)
771060SN/A}
785529Snate@binkert.org
795712Shsul@eecs.umich.edu
801060SN/Aclass SimpleSeSystem(System):
811060SN/A    '''
821060SN/A    Example system class for syscall emulation mode
832292SN/A    '''
842733Sktlim@umich.edu
852292SN/A    # Use a fixed cache line size of 64 bytes
862292SN/A    cache_line_size = 64
872292SN/A
882292SN/A    def __init__(self, args, **kwargs):
898707Sandreas.hansson@arm.com        super(SimpleSeSystem, self).__init__(**kwargs)
908707Sandreas.hansson@arm.com
918975Sandreas.hansson@arm.com        # Setup book keeping to be able to use CpuClusters from the
928707Sandreas.hansson@arm.com        # devices module.
938707Sandreas.hansson@arm.com        self._clusters = []
948948Sandreas.hansson@arm.com        self._num_cpus = 0
958948Sandreas.hansson@arm.com
968948Sandreas.hansson@arm.com        # Create a voltage and clock domain for system components
978707Sandreas.hansson@arm.com        self.voltage_domain = VoltageDomain(voltage="3.3V")
988707Sandreas.hansson@arm.com        self.clk_domain = SrcClockDomain(clock="1GHz",
998707Sandreas.hansson@arm.com                                         voltage_domain=self.voltage_domain)
1008707Sandreas.hansson@arm.com
1018707Sandreas.hansson@arm.com        # Create the off-chip memory bus.
1028707Sandreas.hansson@arm.com        self.membus = SystemXBar()
1038707Sandreas.hansson@arm.com
1048707Sandreas.hansson@arm.com        # Wire up the system port that gem5 uses to load the kernel
1058707Sandreas.hansson@arm.com        # and to perform debug accesses.
1068707Sandreas.hansson@arm.com        self.system_port = self.membus.slave
1078707Sandreas.hansson@arm.com
1088707Sandreas.hansson@arm.com
1098707Sandreas.hansson@arm.com        # Add CPUs to the system. A cluster of CPUs typically have
1108975Sandreas.hansson@arm.com        # private L1 caches and a shared L2 cache.
1118707Sandreas.hansson@arm.com        self.cpu_cluster = devices.CpuCluster(self,
1128975Sandreas.hansson@arm.com                                              args.num_cores,
1138707Sandreas.hansson@arm.com                                              args.cpu_freq, "1.2V",
1148707Sandreas.hansson@arm.com                                              *cpu_types[args.cpu])
1158707Sandreas.hansson@arm.com
1168975Sandreas.hansson@arm.com        # Create a cache hierarchy (unless we are simulating a
1178975Sandreas.hansson@arm.com        # functional CPU in atomic memory mode) for the CPU cluster
1188948Sandreas.hansson@arm.com        # and connect it to the shared memory bus.
1198975Sandreas.hansson@arm.com        if self.cpu_cluster.memoryMode() == "timing":
1208948Sandreas.hansson@arm.com            self.cpu_cluster.addL1()
1218948Sandreas.hansson@arm.com            self.cpu_cluster.addL2(self.cpu_cluster.clk_domain)
1228948Sandreas.hansson@arm.com        self.cpu_cluster.connectMemSide(self.membus)
1238707Sandreas.hansson@arm.com
1248707Sandreas.hansson@arm.com        # Tell gem5 about the memory mode used by the CPUs we are
1258707Sandreas.hansson@arm.com        # simulating.
1268707Sandreas.hansson@arm.com        self.mem_mode = self.cpu_cluster.memoryMode()
1278707Sandreas.hansson@arm.com
1288707Sandreas.hansson@arm.com    def numCpuClusters(self):
1291060SN/A        return len(self._clusters)
1301755SN/A
1315606Snate@binkert.org    def addCpuCluster(self, cpu_cluster, num_cpus):
1321060SN/A        assert cpu_cluster not in self._clusters
1331060SN/A        assert num_cpus > 0
1341060SN/A        self._clusters.append(cpu_cluster)
1351060SN/A        self._num_cpus += num_cpus
1361060SN/A
1371755SN/A    def numCpus(self):
1381060SN/A        return self._num_cpus
1391060SN/A
1401060SN/Adef get_processes(cmd):
1411060SN/A    """Interprets commands to run and returns a list of processes"""
1421060SN/A
1431060SN/A    cwd = os.getcwd()
1445336Shines@cs.fsu.edu    multiprocesses = []
1451060SN/A    for idx, c in enumerate(cmd):
1464873Sstever@eecs.umich.edu        argv = shlex.split(c)
1471060SN/A
1481060SN/A        process = Process(pid=100 + idx, cwd=cwd, cmd=argv, executable=argv[0])
1491060SN/A
1502829Sksewell@umich.edu        print("info: %d. command and arguments: %s" % (idx + 1, process.cmd))
1515606Snate@binkert.org        multiprocesses.append(process)
1522829Sksewell@umich.edu
1532829Sksewell@umich.edu    return multiprocesses
1542829Sksewell@umich.edu
1552829Sksewell@umich.edu
1562829Sksewell@umich.edudef create(args):
1572829Sksewell@umich.edu    ''' Create and configure the system object. '''
1582829Sksewell@umich.edu
1592829Sksewell@umich.edu    system = SimpleSeSystem(args)
1602829Sksewell@umich.edu
1612829Sksewell@umich.edu    # Tell components about the expected physical memory ranges. This
1622829Sksewell@umich.edu    # is, for example, used by the MemConfig helper to determine where
1632829Sksewell@umich.edu    # to map DRAMs in the physical address space.
1642829Sksewell@umich.edu    system.mem_ranges = [ AddrRange(start=0, size=args.mem_size) ]
1652829Sksewell@umich.edu
1662829Sksewell@umich.edu    # Configure the off-chip memory system.
1672829Sksewell@umich.edu    MemConfig.config_mem(args, system)
1682829Sksewell@umich.edu
1692829Sksewell@umich.edu    # Parse the command line and get a list of Processes instances
1702829Sksewell@umich.edu    # that we can pass to gem5.
1712829Sksewell@umich.edu    processes = get_processes(args.commands_to_run)
1722829Sksewell@umich.edu    if len(processes) != args.num_cores:
1735336Shines@cs.fsu.edu        print("Error: Cannot map %d command(s) onto %d CPU(s)" %
1742829Sksewell@umich.edu              (len(processes), args.num_cores))
1754873Sstever@eecs.umich.edu        sys.exit(1)
1762829Sksewell@umich.edu
1772829Sksewell@umich.edu    # Assign one workload to each CPU
1782829Sksewell@umich.edu    for cpu, workload in zip(system.cpu_cluster.cpus, processes):
1792875Sksewell@umich.edu        cpu.workload = workload
1805606Snate@binkert.org
1812875Sksewell@umich.edu    return system
1822875Sksewell@umich.edu
1832875Sksewell@umich.edu
1842875Sksewell@umich.edudef main():
1852875Sksewell@umich.edu    parser = argparse.ArgumentParser(epilog=__doc__)
1862875Sksewell@umich.edu
1873859Sbinkertn@umich.edu    parser.add_argument("commands_to_run", metavar="command(s)", nargs='*',
1882875Sksewell@umich.edu                        help="Command(s) to run")
1892875Sksewell@umich.edu    parser.add_argument("--cpu", type=str, choices=cpu_types.keys(),
1902875Sksewell@umich.edu                        default="atomic",
1913859Sbinkertn@umich.edu                        help="CPU model to use")
1922875Sksewell@umich.edu    parser.add_argument("--cpu-freq", type=str, default="4GHz")
1932875Sksewell@umich.edu    parser.add_argument("--num-cores", type=int, default=1,
1942875Sksewell@umich.edu                        help="Number of CPU cores")
1952875Sksewell@umich.edu    parser.add_argument("--mem-type", default="DDR3_1600_8x8",
1962875Sksewell@umich.edu                        choices=MemConfig.mem_names(),
1972875Sksewell@umich.edu                        help = "type of memory to use")
1982875Sksewell@umich.edu    parser.add_argument("--mem-channels", type=int, default=2,
1993221Sktlim@umich.edu                        help = "number of memory channels")
2003221Sktlim@umich.edu    parser.add_argument("--mem-ranks", type=int, default=None,
2012875Sksewell@umich.edu                        help = "number of memory ranks per channel")
2022875Sksewell@umich.edu    parser.add_argument("--mem-size", action="store", type=str,
2032875Sksewell@umich.edu                        default="2GB",
2042875Sksewell@umich.edu                        help="Specify the physical memory size")
2055336Shines@cs.fsu.edu
2062875Sksewell@umich.edu    args = parser.parse_args()
2074873Sstever@eecs.umich.edu
2082875Sksewell@umich.edu    # Create a single root node for gem5's object hierarchy. There can
2092875Sksewell@umich.edu    # only exist one root node in the simulator at any given
2102875Sksewell@umich.edu    # time. Tell gem5 that we want to use syscall emulation mode
2115595Sgblack@eecs.umich.edu    # instead of full system mode.
2122733Sktlim@umich.edu    root = Root(full_system=False)
2133781Sgblack@eecs.umich.edu
2143781Sgblack@eecs.umich.edu    # Populate the root node with a system. A system corresponds to a
2151060SN/A    # single node with shared memory.
2165737Scws3k@cs.virginia.edu    root.system = create(args)
2175737Scws3k@cs.virginia.edu
2185737Scws3k@cs.virginia.edu    # Instantiate the C++ object hierarchy. After this point,
2192292SN/A    # SimObjects can't be instantiated anymore.
2205595Sgblack@eecs.umich.edu    m5.instantiate()
2215595Sgblack@eecs.umich.edu
2225595Sgblack@eecs.umich.edu    # Start the simulator. This gives control to the C++ world and
2235595Sgblack@eecs.umich.edu    # starts the simulator. The returned event tells the simulation
2245595Sgblack@eecs.umich.edu    # script why the simulator exited.
2251060SN/A    event = m5.simulate()
2265595Sgblack@eecs.umich.edu
2274329Sktlim@umich.edu    # Print the reason for the simulation exit. Some exit codes are
2281060SN/A    # requests for service (e.g., checkpoints) from the simulation
2295529Snate@binkert.org    # script. We'll just ignore them here and exit.
2302292SN/A    print(event.getCause(), " @ ", m5.curTick())
2312292SN/A    sys.exit(event.getCode())
2321060SN/A
2335595Sgblack@eecs.umich.edu
2344329Sktlim@umich.eduif __name__ == "__m5_main__":
2352292SN/A    main()
2365529Snate@binkert.org