__init__.py revision 2860:843426871cbc
16019Shines@cs.fsu.edu# Copyright (c) 2005 The Regents of The University of Michigan
210338SCurtis.Dunham@arm.com# All rights reserved.
37093Sgblack@eecs.umich.edu#
47093Sgblack@eecs.umich.edu# Redistribution and use in source and binary forms, with or without
57093Sgblack@eecs.umich.edu# modification, are permitted provided that the following conditions are
67093Sgblack@eecs.umich.edu# met: redistributions of source code must retain the above copyright
77093Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer;
87093Sgblack@eecs.umich.edu# redistributions in binary form must reproduce the above copyright
97093Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the
107093Sgblack@eecs.umich.edu# documentation and/or other materials provided with the distribution;
117093Sgblack@eecs.umich.edu# neither the name of the copyright holders nor the names of its
127093Sgblack@eecs.umich.edu# contributors may be used to endorse or promote products derived from
137093Sgblack@eecs.umich.edu# this software without specific prior written permission.
146019Shines@cs.fsu.edu#
156019Shines@cs.fsu.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
166019Shines@cs.fsu.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
176019Shines@cs.fsu.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
186019Shines@cs.fsu.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
196019Shines@cs.fsu.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
206019Shines@cs.fsu.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
216019Shines@cs.fsu.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
226019Shines@cs.fsu.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
236019Shines@cs.fsu.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
246019Shines@cs.fsu.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
256019Shines@cs.fsu.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
266019Shines@cs.fsu.edu#
276019Shines@cs.fsu.edu# Authors: Nathan Binkert
286019Shines@cs.fsu.edu#          Steve Reinhardt
296019Shines@cs.fsu.edu
306019Shines@cs.fsu.eduimport sys, os, time, atexit, optparse
316019Shines@cs.fsu.edu
326019Shines@cs.fsu.edu# import the SWIG-wrapped main C++ functions
336019Shines@cs.fsu.eduimport cc_main
346019Shines@cs.fsu.edu# import a few SWIG-wrapped items (those that are likely to be used
356019Shines@cs.fsu.edu# directly by user scripts) completely into this module for
366019Shines@cs.fsu.edu# convenience
376019Shines@cs.fsu.edufrom cc_main import simulate, SimLoopExitEvent, setCheckpointDir
386019Shines@cs.fsu.edu
396019Shines@cs.fsu.edu# import the m5 compile options
406019Shines@cs.fsu.eduimport defines
416735Sgblack@eecs.umich.edu
426735Sgblack@eecs.umich.edu# define this here so we can use it right away if necessary
4310037SARM gem5 Developersdef panic(string):
4410037SARM gem5 Developers    print >>sys.stderr, 'panic:', string
456019Shines@cs.fsu.edu    sys.exit(1)
466019Shines@cs.fsu.edu
476019Shines@cs.fsu.edu# Prepend given directory to system module search path.  We may not
4810037SARM gem5 Developers# need this anymore if we can structure our config library more like a
4910037SARM gem5 Developers# Python package.
5010037SARM gem5 Developersdef AddToPath(path):
5110037SARM gem5 Developers    # if it's a relative path and we know what directory the current
528229Snate@binkert.org    # python script is in, make the path relative to that directory.
538229Snate@binkert.org    if not os.path.isabs(path) and sys.path[0]:
546019Shines@cs.fsu.edu        path = os.path.join(sys.path[0], path)
558232Snate@binkert.org    path = os.path.realpath(path)
568782Sgblack@eecs.umich.edu    # sys.path[0] should always refer to the current script's directory,
576019Shines@cs.fsu.edu    # so place the new dir right after that.
586019Shines@cs.fsu.edu    sys.path.insert(1, path)
596019Shines@cs.fsu.edu
606019Shines@cs.fsu.edu
6110037SARM gem5 Developers# The m5 module's pointer to the parsed options object
6210037SARM gem5 Developersoptions = None
6310037SARM gem5 Developers
6410037SARM gem5 Developers
6510037SARM gem5 Developers# User should call this function after calling parse_args() to pass
6610037SARM gem5 Developers# parsed standard option values back into the m5 module for
6710037SARM gem5 Developers# processing.
6810037SARM gem5 Developersdef setStandardOptions(_options):
6910037SARM gem5 Developers    # Set module global var
7010037SARM gem5 Developers    global options
7110037SARM gem5 Developers    options = _options
7210037SARM gem5 Developers    # tell C++ about output directory
7310037SARM gem5 Developers    cc_main.setOutputDir(options.outdir)
7410037SARM gem5 Developers
7510037SARM gem5 Developers# Callback to set trace flags.  Not necessarily the best way to do
7610037SARM gem5 Developers# things in the long run (particularly if we change how these global
7710037SARM gem5 Developers# options are handled).
7810037SARM gem5 Developersdef setTraceFlags(option, opt_str, value, parser):
7910037SARM gem5 Developers    objects.Trace.flags = value
8010037SARM gem5 Developers
8110037SARM gem5 Developersdef setTraceStart(option, opt_str, value, parser):
8210037SARM gem5 Developers    objects.Trace.start = value
8310037SARM gem5 Developers
8410037SARM gem5 Developersdef setTraceFile(option, opt_str, value, parser):
8510037SARM gem5 Developers    objects.Trace.file = value
8610037SARM gem5 Developers
8710037SARM gem5 Developersdef noPCSymbol(option, opt_str, value, parser):
8810037SARM gem5 Developers    objects.ExecutionTrace.pc_symbol = False
8910037SARM gem5 Developers
9010037SARM gem5 Developersdef noPrintCycle(option, opt_str, value, parser):
9110037SARM gem5 Developers    objects.ExecutionTrace.print_cycle = False
9210037SARM gem5 Developers
9310037SARM gem5 Developersdef noPrintOpclass(option, opt_str, value, parser):
9410037SARM gem5 Developers    objects.ExecutionTrace.print_opclass = False
9510037SARM gem5 Developers
9610037SARM gem5 Developersdef noPrintThread(option, opt_str, value, parser):
9710037SARM gem5 Developers    objects.ExecutionTrace.print_thread = False
9810037SARM gem5 Developers
9910037SARM gem5 Developersdef noPrintEA(option, opt_str, value, parser):
10010037SARM gem5 Developers    objects.ExecutionTrace.print_effaddr = False
1016019Shines@cs.fsu.edu
10210037SARM gem5 Developersdef noPrintData(option, opt_str, value, parser):
10310037SARM gem5 Developers    objects.ExecutionTrace.print_data = False
10410037SARM gem5 Developers
1056019Shines@cs.fsu.edudef printFetchseq(option, opt_str, value, parser):
10610037SARM gem5 Developers    objects.ExecutionTrace.print_fetchseq = True
10710037SARM gem5 Developers
10810037SARM gem5 Developersdef printCpseq(option, opt_str, value, parser):
10910037SARM gem5 Developers    objects.ExecutionTrace.print_cpseq = True
11010037SARM gem5 Developers
11110037SARM gem5 Developersdef dumpOnExit(option, opt_str, value, parser):
11210037SARM gem5 Developers    objects.Trace.dump_on_exit = True
11310037SARM gem5 Developers
11410037SARM gem5 Developersdef debugBreak(option, opt_str, value, parser):
11510037SARM gem5 Developers    objects.Debug.break_cycles = value
11610037SARM gem5 Developers
11710037SARM gem5 Developersdef statsTextFile(option, opt_str, value, parser):
11810037SARM gem5 Developers    objects.Statistics.text_file = value
11910037SARM gem5 Developers
12010037SARM gem5 Developers# Standard optparse options.  Need to be explicitly included by the
12110037SARM gem5 Developers# user script when it calls optparse.OptionParser().
12210037SARM gem5 DevelopersstandardOptions = [
12310037SARM gem5 Developers    optparse.make_option("--outdir", type="string", default="."),
12410037SARM gem5 Developers    optparse.make_option("--traceflags", type="string", action="callback",
12510037SARM gem5 Developers                         callback=setTraceFlags),
12610037SARM gem5 Developers    optparse.make_option("--tracestart", type="int", action="callback",
12710037SARM gem5 Developers                         callback=setTraceStart),
12810037SARM gem5 Developers    optparse.make_option("--tracefile", type="string", action="callback",
12910037SARM gem5 Developers                         callback=setTraceFile),
13010037SARM gem5 Developers    optparse.make_option("--nopcsymbol",
13110037SARM gem5 Developers                         action="callback", callback=noPCSymbol,
13210037SARM gem5 Developers                         help="Disable PC symbols in trace output"),
13310037SARM gem5 Developers    optparse.make_option("--noprintcycle",
13410037SARM gem5 Developers                         action="callback", callback=noPrintCycle,
13510037SARM gem5 Developers                         help="Don't print cycle numbers in trace output"),
13610037SARM gem5 Developers    optparse.make_option("--noprintopclass",
13710037SARM gem5 Developers                         action="callback", callback=noPrintOpclass,
13810037SARM gem5 Developers                         help="Don't print op class type in trace output"),
13910037SARM gem5 Developers    optparse.make_option("--noprintthread",
14010037SARM gem5 Developers                         action="callback", callback=noPrintThread,
14110037SARM gem5 Developers                         help="Don't print thread number in trace output"),
14210037SARM gem5 Developers    optparse.make_option("--noprinteffaddr",
14310037SARM gem5 Developers                         action="callback", callback=noPrintEA,
14410037SARM gem5 Developers                         help="Don't print effective address in trace output"),
14510037SARM gem5 Developers    optparse.make_option("--noprintdata",
1466019Shines@cs.fsu.edu                         action="callback", callback=noPrintData,
14710037SARM gem5 Developers                         help="Don't print result data in trace output"),
14810037SARM gem5 Developers    optparse.make_option("--printfetchseq",
14910037SARM gem5 Developers                         action="callback", callback=printFetchseq,
1506019Shines@cs.fsu.edu                         help="Print fetch sequence numbers in trace output"),
15110037SARM gem5 Developers    optparse.make_option("--printcpseq",
15210037SARM gem5 Developers                         action="callback", callback=printCpseq,
15310037SARM gem5 Developers                         help="Print correct path sequence numbers in trace output"),
15410037SARM gem5 Developers    optparse.make_option("--dumponexit",
15510037SARM gem5 Developers                         action="callback", callback=dumpOnExit,
15610037SARM gem5 Developers                         help="Dump trace buffer on exit"),
15710037SARM gem5 Developers    optparse.make_option("--debugbreak", type="int", metavar="CYCLE",
15810037SARM gem5 Developers                         action="callback", callback=debugBreak,
15910037SARM gem5 Developers                         help="Cycle to create a breakpoint"),
16010037SARM gem5 Developers    optparse.make_option("--statsfile", type="string", action="callback",
16110037SARM gem5 Developers                         callback=statsTextFile, metavar="FILE",
16210037SARM gem5 Developers                         help="Sets the output file for the statistics")
16310037SARM gem5 Developers    ]
16410037SARM gem5 Developers
16510037SARM gem5 Developers# make a SmartDict out of the build options for our local use
16610037SARM gem5 Developersimport smartdict
16710037SARM gem5 Developersbuild_env = smartdict.SmartDict()
16810037SARM gem5 Developersbuild_env.update(defines.m5_build_env)
16910037SARM gem5 Developers
17010037SARM gem5 Developers# make a SmartDict out of the OS environment too
17110037SARM gem5 Developersenv = smartdict.SmartDict()
17210037SARM gem5 Developersenv.update(os.environ)
17310037SARM gem5 Developers
17410037SARM gem5 Developers
17510037SARM gem5 Developers# Function to provide to C++ so it can look up instances based on paths
17610037SARM gem5 Developersdef resolveSimObject(name):
17710037SARM gem5 Developers    obj = config.instanceDict[name]
17810037SARM gem5 Developers    return obj.getCCObject()
17910037SARM gem5 Developers
18010037SARM gem5 Developers# The final hook to generate .ini files.  Called from the user script
18110037SARM gem5 Developers# once the config is built.
18210037SARM gem5 Developersdef instantiate(root):
18310037SARM gem5 Developers    config.ticks_per_sec = float(root.clock.frequency)
18410037SARM gem5 Developers    # ugly temporary hack to get output to config.ini
18510037SARM gem5 Developers    sys.stdout = file(os.path.join(options.outdir, 'config.ini'), 'w')
18610037SARM gem5 Developers    root.print_ini()
18710037SARM gem5 Developers    sys.stdout.close() # close config.ini
18810037SARM gem5 Developers    sys.stdout = sys.__stdout__ # restore to original
18910037SARM gem5 Developers    cc_main.loadIniFile(resolveSimObject)  # load config.ini into C++
19010037SARM gem5 Developers    root.createCCObject()
19110037SARM gem5 Developers    root.connectPorts()
1926019Shines@cs.fsu.edu    cc_main.finalInit()
19310037SARM gem5 Developers    noDot = True # temporary until we fix dot
19410037SARM gem5 Developers    if not noDot:
19510037SARM gem5 Developers       dot = pydot.Dot()
1966019Shines@cs.fsu.edu       instance.outputDot(dot)
19710037SARM gem5 Developers       dot.orientation = "portrait"
19810037SARM gem5 Developers       dot.size = "8.5,11"
19910037SARM gem5 Developers       dot.ranksep="equally"
20010037SARM gem5 Developers       dot.rank="samerank"
20110037SARM gem5 Developers       dot.write("config.dot")
20210037SARM gem5 Developers       dot.write_ps("config.ps")
20310037SARM gem5 Developers
20410037SARM gem5 Developers# Export curTick to user script.
20510037SARM gem5 Developersdef curTick():
20610037SARM gem5 Developers    return cc_main.cvar.curTick
20710037SARM gem5 Developers
20810037SARM gem5 Developers# register our C++ exit callback function with Python
20910037SARM gem5 Developersatexit.register(cc_main.doExitCleanup)
21010037SARM gem5 Developers
21110037SARM gem5 Developers# This import allows user scripts to reference 'm5.objects.Foo' after
21210037SARM gem5 Developers# just doing an 'import m5' (without an 'import m5.objects').  May not
21310037SARM gem5 Developers# matter since most scripts will probably 'from m5.objects import *'.
21410037SARM gem5 Developersimport objects
21510037SARM gem5 Developers
21610037SARM gem5 Developers# This loops until all objects have been fully drained.
21710037SARM gem5 Developersdef doDrain(root):
21810037SARM gem5 Developers    all_drained = drain(root)
21910037SARM gem5 Developers    while (not all_drained):
22010037SARM gem5 Developers        all_drained = drain(root)
22110037SARM gem5 Developers
22210037SARM gem5 Developers# Tries to drain all objects.  Draining might not be completed unless
22310037SARM gem5 Developers# all objects return that they are drained on the first call.  This is
22410037SARM gem5 Developers# because as objects drain they may cause other objects to no longer
22510037SARM gem5 Developers# be drained.
22610037SARM gem5 Developersdef drain(root):
22710037SARM gem5 Developers    all_drained = False
22810037SARM gem5 Developers    drain_event = cc_main.createCountedDrain()
22910037SARM gem5 Developers    unready_objects = root.startDrain(drain_event, True)
23010037SARM gem5 Developers    # If we've got some objects that can't drain immediately, then simulate
23110037SARM gem5 Developers    if unready_objects > 0:
23210037SARM gem5 Developers        drain_event.setCount(unready_objects)
23310037SARM gem5 Developers        simulate()
23410037SARM gem5 Developers    else:
23510037SARM gem5 Developers        all_drained = True
23610037SARM gem5 Developers    cc_main.cleanupCountedDrain(drain_event)
23710037SARM gem5 Developers    return all_drained
23810037SARM gem5 Developers
23910037SARM gem5 Developersdef resume(root):
24010037SARM gem5 Developers    root.resume()
24110037SARM gem5 Developers
24210037SARM gem5 Developersdef checkpoint(root):
24310037SARM gem5 Developers    if not isinstance(root, objects.Root):
24410037SARM gem5 Developers        raise TypeError, "Object is not a root object. Checkpoint must be called on a root object."
24510037SARM gem5 Developers    doDrain(root)
24610037SARM gem5 Developers    print "Writing checkpoint"
24710037SARM gem5 Developers    cc_main.serializeAll()
24810037SARM gem5 Developers    resume(root)
24910037SARM gem5 Developers
25010037SARM gem5 Developersdef restoreCheckpoint(root):
25110037SARM gem5 Developers    print "Restoring from checkpoint"
25210037SARM gem5 Developers    cc_main.unserializeAll()
25310037SARM gem5 Developers
25410037SARM gem5 Developersdef changeToAtomic(system):
25510037SARM gem5 Developers    if not isinstance(system, objects.Root) and not isinstance(system, System):
25610037SARM gem5 Developers        raise TypeError, "Object is not a root or system object.  Checkpoint must be "
25710037SARM gem5 Developers        "called on a root object."
25810037SARM gem5 Developers    doDrain(system)
25910037SARM gem5 Developers    print "Changing memory mode to atomic"
26010037SARM gem5 Developers    system.changeTiming(cc_main.SimObject.Atomic)
26110037SARM gem5 Developers    resume(system)
26210037SARM gem5 Developers
26310037SARM gem5 Developersdef changeToTiming(system):
26410037SARM gem5 Developers    if not isinstance(system, objects.Root) and not isinstance(system, System):
26510037SARM gem5 Developers        raise TypeError, "Object is not a root or system object.  Checkpoint must be "
26610037SARM gem5 Developers        "called on a root object."
26710037SARM gem5 Developers    doDrain(system)
26810037SARM gem5 Developers    print "Changing memory mode to timing"
26910037SARM gem5 Developers    system.changeTiming(cc_main.SimObject.Timing)
27010037SARM gem5 Developers    resume(system)
27110037SARM gem5 Developers
27210037SARM gem5 Developersdef switchCpus(cpuList):
27310037SARM gem5 Developers    if not isinstance(cpuList, list):
27410037SARM gem5 Developers        raise RuntimeError, "Must pass a list to this function"
27510037SARM gem5 Developers    for i in cpuList:
27610037SARM gem5 Developers        if not isinstance(i, tuple):
27710037SARM gem5 Developers            raise RuntimeError, "List must have tuples of (oldCPU,newCPU)"
27810037SARM gem5 Developers
27910037SARM gem5 Developers    [old_cpus, new_cpus] = zip(*cpuList)
28010037SARM gem5 Developers
28110037SARM gem5 Developers    for cpu in old_cpus:
28210037SARM gem5 Developers        if not isinstance(cpu, objects.BaseCPU):
28310037SARM gem5 Developers            raise TypeError, "%s is not of type BaseCPU", cpu
28410037SARM gem5 Developers    for cpu in new_cpus:
28510037SARM gem5 Developers        if not isinstance(cpu, objects.BaseCPU):
28610037SARM gem5 Developers            raise TypeError, "%s is not of type BaseCPU", cpu
28710037SARM gem5 Developers
28810037SARM gem5 Developers    # Drain all of the individual CPUs
28910037SARM gem5 Developers    drain_event = cc_main.createCountedDrain()
29010037SARM gem5 Developers    unready_cpus = 0
29110037SARM gem5 Developers    for old_cpu in old_cpus:
29210037SARM gem5 Developers        unready_cpus += old_cpu.startDrain(drain_event, False)
29310037SARM gem5 Developers    # If we've got some objects that can't drain immediately, then simulate
29410037SARM gem5 Developers    if unready_cpus > 0:
2956019Shines@cs.fsu.edu        drain_event.setCount(unready_cpus)
29610037SARM gem5 Developers        simulate()
2977362Sgblack@eecs.umich.edu    cc_main.cleanupCountedDrain(drain_event)
2986735Sgblack@eecs.umich.edu    # Now all of the CPUs are ready to be switched out
29910037SARM gem5 Developers    for old_cpu in old_cpus:
3006019Shines@cs.fsu.edu        old_cpu._ccObject.switchOut()
30110037SARM gem5 Developers    index = 0
30210037SARM gem5 Developers    print "Switching CPUs"
3037400SAli.Saidi@ARM.com    for new_cpu in new_cpus:
3046735Sgblack@eecs.umich.edu        new_cpu.takeOverFrom(old_cpus[index])
3056735Sgblack@eecs.umich.edu        new_cpu._ccObject.resume()
30610037SARM gem5 Developers        index += 1
3076735Sgblack@eecs.umich.edu