__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