main.py revision 11923:d2f0605ac2af
1# Copyright (c) 2016 ARM Limited 2# All rights reserved. 3# 4# The license below extends only to copyright in the software and shall 5# not be construed as granting a license to any other intellectual 6# property including but not limited to intellectual property relating 7# to a hardware implementation of the functionality of the software 8# licensed hereunder. You may use the software subject to the license 9# terms below provided that you ensure that this notice is replicated 10# unmodified and in its entirety in all distributions of the software, 11# modified or unmodified, in source code or in binary form. 12# 13# Copyright (c) 2005 The Regents of The University of Michigan 14# All rights reserved. 15# 16# Redistribution and use in source and binary forms, with or without 17# modification, are permitted provided that the following conditions are 18# met: redistributions of source code must retain the above copyright 19# notice, this list of conditions and the following disclaimer; 20# redistributions in binary form must reproduce the above copyright 21# notice, this list of conditions and the following disclaimer in the 22# documentation and/or other materials provided with the distribution; 23# neither the name of the copyright holders nor the names of its 24# contributors may be used to endorse or promote products derived from 25# this software without specific prior written permission. 26# 27# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 30# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 31# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 32# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 34# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 35# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 37# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38# 39# Authors: Nathan Binkert 40 41import code 42import datetime 43import os 44import socket 45import sys 46 47__all__ = [ 'options', 'arguments', 'main' ] 48 49usage="%prog [gem5 options] script.py [script options]" 50version="%prog 2.0" 51brief_copyright=\ 52 "gem5 is copyrighted software; use the --copyright option for details." 53 54def parse_options(): 55 import config 56 from options import OptionParser 57 58 options = OptionParser(usage=usage, version=version, 59 description=brief_copyright) 60 option = options.add_option 61 group = options.set_group 62 63 listener_modes = ( "on", "off", "auto" ) 64 65 # Help options 66 option('-B', "--build-info", action="store_true", default=False, 67 help="Show build information") 68 option('-C', "--copyright", action="store_true", default=False, 69 help="Show full copyright information") 70 option('-R', "--readme", action="store_true", default=False, 71 help="Show the readme") 72 73 # Options for configuring the base simulator 74 option('-d', "--outdir", metavar="DIR", default="m5out", 75 help="Set the output directory to DIR [Default: %default]") 76 option('-r', "--redirect-stdout", action="store_true", default=False, 77 help="Redirect stdout (& stderr, without -e) to file") 78 option('-e', "--redirect-stderr", action="store_true", default=False, 79 help="Redirect stderr to file") 80 option("--stdout-file", metavar="FILE", default="simout", 81 help="Filename for -r redirection [Default: %default]") 82 option("--stderr-file", metavar="FILE", default="simerr", 83 help="Filename for -e redirection [Default: %default]") 84 option("--listener-mode", metavar="{on,off,auto}", 85 choices=listener_modes, default="auto", 86 help="Port (e.g., gdb) listener mode (auto: Enable if running " \ 87 "interactively) [Default: %default]") 88 option('-i', "--interactive", action="store_true", default=False, 89 help="Invoke the interactive interpreter after running the script") 90 option("--pdb", action="store_true", default=False, 91 help="Invoke the python debugger before running the script") 92 option('-p', "--path", metavar="PATH[:PATH]", action='append', split=':', 93 help="Prepend PATH to the system path when invoking the script") 94 option('-q', "--quiet", action="count", default=0, 95 help="Reduce verbosity") 96 option('-v', "--verbose", action="count", default=0, 97 help="Increase verbosity") 98 99 # Statistics options 100 group("Statistics Options") 101 option("--stats-file", metavar="FILE", default="stats.txt", 102 help="Sets the output file for statistics [Default: %default]") 103 104 # Configuration Options 105 group("Configuration Options") 106 option("--dump-config", metavar="FILE", default="config.ini", 107 help="Dump configuration output file [Default: %default]") 108 option("--json-config", metavar="FILE", default="config.json", 109 help="Create JSON output of the configuration [Default: %default]") 110 option("--dot-config", metavar="FILE", default="config.dot", 111 help="Create DOT & pdf outputs of the configuration [Default: %default]") 112 option("--dot-dvfs-config", metavar="FILE", default=None, 113 help="Create DOT & pdf outputs of the DVFS configuration" + \ 114 " [Default: %default]") 115 116 # Debugging options 117 group("Debugging Options") 118 option("--debug-break", metavar="TICK[,TICK]", action='append', split=',', 119 help="Create breakpoint(s) at TICK(s) " \ 120 "(kills process if no debugger attached)") 121 option("--debug-help", action='store_true', 122 help="Print help on debug flags") 123 option("--debug-flags", metavar="FLAG[,FLAG]", action='append', split=',', 124 help="Sets the flags for debug output (-FLAG disables a flag)") 125 option("--debug-start", metavar="TICK", type='int', 126 help="Start debug output at TICK") 127 option("--debug-end", metavar="TICK", type='int', 128 help="End debug output at TICK") 129 option("--debug-file", metavar="FILE", default="cout", 130 help="Sets the output file for debug [Default: %default]") 131 option("--debug-ignore", metavar="EXPR", action='append', split=':', 132 help="Ignore EXPR sim objects") 133 option("--remote-gdb-port", type='int', default=7000, 134 help="Remote gdb base port (set to 0 to disable listening)") 135 136 # Help options 137 group("Help Options") 138 option("--list-sim-objects", action='store_true', default=False, 139 help="List all built-in SimObjects, their params and default values") 140 141 # load the options.py config file to allow people to set their own 142 # default options 143 options_file = config.get('options.py') 144 if options_file: 145 scope = { 'options' : options } 146 execfile(options_file, scope) 147 148 arguments = options.parse_args() 149 return options,arguments 150 151def interact(scope): 152 banner = "gem5 Interactive Console" 153 154 ipshell = None 155 prompt_in1 = "gem5 \\#> " 156 prompt_out = "gem5 \\#: " 157 158 # Is IPython version 0.10 or earlier available? 159 try: 160 from IPython.Shell import IPShellEmbed 161 ipshell = IPShellEmbed(argv=["-prompt_in1", prompt_in1, 162 "-prompt_out", prompt_out], 163 banner=banner, user_ns=scope) 164 except ImportError: 165 pass 166 167 # Is IPython version 0.11 or later available? 168 if not ipshell: 169 try: 170 import IPython 171 from IPython.config.loader import Config 172 from IPython.terminal.embed import InteractiveShellEmbed 173 174 cfg = Config() 175 cfg.PromptManager.in_template = prompt_in1 176 cfg.PromptManager.out_template = prompt_out 177 ipshell = InteractiveShellEmbed(config=cfg, user_ns=scope, 178 banner1=banner) 179 except ImportError: 180 pass 181 182 if ipshell: 183 ipshell() 184 else: 185 # Use the Python shell in the standard library if IPython 186 # isn't available. 187 code.InteractiveConsole(scope).interact(banner) 188 189def main(*args): 190 import m5 191 192 import core 193 import debug 194 import defines 195 import event 196 import info 197 import stats 198 import trace 199 200 from util import inform, fatal, panic, isInteractive 201 202 if len(args) == 0: 203 options, arguments = parse_options() 204 elif len(args) == 2: 205 options, arguments = args 206 else: 207 raise TypeError, "main() takes 0 or 2 arguments (%d given)" % len(args) 208 209 m5.options = options 210 211 def check_tracing(): 212 if defines.TRACING_ON: 213 return 214 215 fatal("Tracing is not enabled. Compile with TRACING_ON") 216 217 # Set the main event queue for the main thread. 218 event.mainq = event.getEventQueue(0) 219 event.setEventQueue(event.mainq) 220 221 if not os.path.isdir(options.outdir): 222 os.makedirs(options.outdir) 223 224 # These filenames are used only if the redirect_std* options are set 225 stdout_file = os.path.join(options.outdir, options.stdout_file) 226 stderr_file = os.path.join(options.outdir, options.stderr_file) 227 228 # Print redirection notices here before doing any redirection 229 if options.redirect_stdout and not options.redirect_stderr: 230 print "Redirecting stdout and stderr to", stdout_file 231 else: 232 if options.redirect_stdout: 233 print "Redirecting stdout to", stdout_file 234 if options.redirect_stderr: 235 print "Redirecting stderr to", stderr_file 236 237 # Now redirect stdout/stderr as desired 238 if options.redirect_stdout: 239 redir_fd = os.open(stdout_file, os. O_WRONLY | os.O_CREAT | os.O_TRUNC) 240 os.dup2(redir_fd, sys.stdout.fileno()) 241 if not options.redirect_stderr: 242 os.dup2(redir_fd, sys.stderr.fileno()) 243 244 if options.redirect_stderr: 245 redir_fd = os.open(stderr_file, os. O_WRONLY | os.O_CREAT | os.O_TRUNC) 246 os.dup2(redir_fd, sys.stderr.fileno()) 247 248 done = False 249 250 if options.build_info: 251 done = True 252 print 'Build information:' 253 print 254 print 'compiled %s' % defines.compileDate; 255 print 'build options:' 256 keys = defines.buildEnv.keys() 257 keys.sort() 258 for key in keys: 259 val = defines.buildEnv[key] 260 print ' %s = %s' % (key, val) 261 print 262 263 if options.copyright: 264 done = True 265 print info.COPYING 266 print 267 268 if options.readme: 269 done = True 270 print 'Readme:' 271 print 272 print info.README 273 print 274 275 if options.debug_help: 276 done = True 277 check_tracing() 278 debug.help() 279 280 if options.list_sim_objects: 281 import SimObject 282 done = True 283 print "SimObjects:" 284 objects = SimObject.allClasses.keys() 285 objects.sort() 286 for name in objects: 287 obj = SimObject.allClasses[name] 288 print " %s" % obj 289 params = obj._params.keys() 290 params.sort() 291 for pname in params: 292 param = obj._params[pname] 293 default = getattr(param, 'default', '') 294 print " %s" % pname 295 if default: 296 print " default: %s" % default 297 print " desc: %s" % param.desc 298 print 299 print 300 301 if done: 302 sys.exit(0) 303 304 # setting verbose and quiet at the same time doesn't make sense 305 if options.verbose > 0 and options.quiet > 0: 306 options.usage(2) 307 308 verbose = options.verbose - options.quiet 309 if verbose >= 0: 310 print "gem5 Simulator System. http://gem5.org" 311 print brief_copyright 312 print 313 314 print "gem5 compiled %s" % defines.compileDate; 315 316 print "gem5 started %s" % \ 317 datetime.datetime.now().strftime("%b %e %Y %X") 318 print "gem5 executing on %s, pid %d" % \ 319 (socket.gethostname(), os.getpid()) 320 321 # in Python 3 pipes.quote() is moved to shlex.quote() 322 import pipes 323 print "command line:", " ".join(map(pipes.quote, sys.argv)) 324 print 325 326 # check to make sure we can find the listed script 327 if not arguments or not os.path.isfile(arguments[0]): 328 if arguments and not os.path.isfile(arguments[0]): 329 print "Script %s not found" % arguments[0] 330 331 options.usage(2) 332 333 # tell C++ about output directory 334 core.setOutputDir(options.outdir) 335 336 # update the system path with elements from the -p option 337 sys.path[0:0] = options.path 338 339 # set stats options 340 stats.addStatVisitor(options.stats_file) 341 342 # Disable listeners unless running interactively or explicitly 343 # enabled 344 if options.listener_mode == "off": 345 m5.disableAllListeners() 346 elif options.listener_mode == "auto": 347 if not isInteractive(): 348 inform("Standard input is not a terminal, disabling listeners.") 349 m5.disableAllListeners() 350 elif options.listener_mode == "on": 351 pass 352 else: 353 panic("Unhandled listener mode: %s" % options.listener_mode) 354 355 # set debugging options 356 debug.setRemoteGDBPort(options.remote_gdb_port) 357 for when in options.debug_break: 358 debug.schedBreak(int(when)) 359 360 if options.debug_flags: 361 check_tracing() 362 363 on_flags = [] 364 off_flags = [] 365 for flag in options.debug_flags: 366 off = False 367 if flag.startswith('-'): 368 flag = flag[1:] 369 off = True 370 371 if flag not in debug.flags: 372 print >>sys.stderr, "invalid debug flag '%s'" % flag 373 sys.exit(1) 374 375 if off: 376 debug.flags[flag].disable() 377 else: 378 debug.flags[flag].enable() 379 380 if options.debug_start: 381 check_tracing() 382 e = event.create(trace.enable, event.Event.Debug_Enable_Pri) 383 event.mainq.schedule(e, options.debug_start) 384 else: 385 trace.enable() 386 387 if options.debug_end: 388 check_tracing() 389 e = event.create(trace.disable, event.Event.Debug_Enable_Pri) 390 event.mainq.schedule(e, options.debug_end) 391 392 trace.output(options.debug_file) 393 394 for ignore in options.debug_ignore: 395 check_tracing() 396 trace.ignore(ignore) 397 398 sys.argv = arguments 399 sys.path = [ os.path.dirname(sys.argv[0]) ] + sys.path 400 401 filename = sys.argv[0] 402 filedata = file(filename, 'r').read() 403 filecode = compile(filedata, filename, 'exec') 404 scope = { '__file__' : filename, 405 '__name__' : '__m5_main__' } 406 407 # we want readline if we're doing anything interactive 408 if options.interactive or options.pdb: 409 exec "import readline" in scope 410 411 # if pdb was requested, execfile the thing under pdb, otherwise, 412 # just do the execfile normally 413 if options.pdb: 414 import pdb 415 import traceback 416 417 pdb = pdb.Pdb() 418 try: 419 pdb.run(filecode, scope) 420 except SystemExit: 421 print "The program exited via sys.exit(). Exit status: ", 422 print sys.exc_info()[1] 423 except: 424 traceback.print_exc() 425 print "Uncaught exception. Entering post mortem debugging" 426 t = sys.exc_info()[2] 427 while t.tb_next is not None: 428 t = t.tb_next 429 pdb.interaction(t.tb_frame,t) 430 else: 431 exec filecode in scope 432 433 # once the script is done 434 if options.interactive: 435 interact(scope) 436 437if __name__ == '__main__': 438 from pprint import pprint 439 440 options, arguments = parse_options() 441 442 print 'opts:' 443 pprint(options, indent=4) 444 print 445 446 print 'args:' 447 pprint(arguments, indent=4) 448