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