main.py revision 8291:a6363c870af6
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-start", metavar="TIME", type='int', 110 help="Start tracing at TIME (must be in ticks)") 111 option("--trace-file", metavar="FILE", default="cout", 112 help="Sets the output file for tracing [Default: %default]") 113 option("--trace-ignore", metavar="EXPR", action='append', split=':', 114 help="Ignore EXPR sim objects") 115 116 # Help options 117 group("Help Options") 118 option("--list-sim-objects", action='store_true', default=False, 119 help="List all built-in SimObjects, their params and default values") 120 121 # load the options.py config file to allow people to set their own 122 # default options 123 options_file = config.get('options.py') 124 if options_file: 125 scope = { 'options' : options } 126 execfile(options_file, scope) 127 128 arguments = options.parse_args() 129 130 return options,arguments 131 132def interact(scope): 133 banner = "M5 Interactive Console" 134 sys.argv = [] 135 try: 136 from IPython.Shell import IPShellEmbed 137 ipshell = IPShellEmbed(banner=banner,user_ns=scope) 138 ipshell() 139 except ImportError: 140 code.InteractiveConsole(scope).interact(banner) 141 142def main(*args): 143 import m5 144 145 import core 146 import debug 147 import defines 148 import event 149 import info 150 import stats 151 import trace 152 153 from util import fatal 154 155 if len(args) == 0: 156 options, arguments = parse_options() 157 elif len(args) == 2: 158 options, arguments = args 159 else: 160 raise TypeError, "main() takes 0 or 2 arguments (%d given)" % len(args) 161 162 m5.options = options 163 164 def check_tracing(): 165 if defines.TRACING_ON: 166 return 167 168 fatal("Tracing is not enabled. Compile with TRACING_ON") 169 170 if not os.path.isdir(options.outdir): 171 os.makedirs(options.outdir) 172 173 # These filenames are used only if the redirect_std* options are set 174 stdout_file = os.path.join(options.outdir, options.stdout_file) 175 stderr_file = os.path.join(options.outdir, options.stderr_file) 176 177 # Print redirection notices here before doing any redirection 178 if options.redirect_stdout and not options.redirect_stderr: 179 print "Redirecting stdout and stderr to", stdout_file 180 else: 181 if options.redirect_stdout: 182 print "Redirecting stdout to", stdout_file 183 if options.redirect_stderr: 184 print "Redirecting stderr to", stderr_file 185 186 # Now redirect stdout/stderr as desired 187 if options.redirect_stdout: 188 redir_fd = os.open(stdout_file, os. O_WRONLY | os.O_CREAT | os.O_TRUNC) 189 os.dup2(redir_fd, sys.stdout.fileno()) 190 if not options.redirect_stderr: 191 os.dup2(redir_fd, sys.stderr.fileno()) 192 193 if options.redirect_stderr: 194 redir_fd = os.open(stderr_file, os. O_WRONLY | os.O_CREAT | os.O_TRUNC) 195 os.dup2(redir_fd, sys.stderr.fileno()) 196 197 done = False 198 199 if options.build_info: 200 done = True 201 print 'Build information:' 202 print 203 print 'compiled %s' % defines.compileDate; 204 print 'build options:' 205 keys = defines.buildEnv.keys() 206 keys.sort() 207 for key in keys: 208 val = defines.buildEnv[key] 209 print ' %s = %s' % (key, val) 210 print 211 212 if options.copyright: 213 done = True 214 print info.LICENSE 215 print 216 217 if options.authors: 218 done = True 219 print 'Author information:' 220 print 221 print info.AUTHORS 222 print 223 224 if options.readme: 225 done = True 226 print 'Readme:' 227 print 228 print info.README 229 print 230 231 if options.debug_help: 232 done = True 233 check_tracing() 234 debug.help() 235 236 if options.list_sim_objects: 237 import SimObject 238 done = True 239 print "SimObjects:" 240 objects = SimObject.allClasses.keys() 241 objects.sort() 242 for name in objects: 243 obj = SimObject.allClasses[name] 244 print " %s" % obj 245 params = obj._params.keys() 246 params.sort() 247 for pname in params: 248 param = obj._params[pname] 249 default = getattr(param, 'default', '') 250 print " %s" % pname 251 if default: 252 print " default: %s" % default 253 print " desc: %s" % param.desc 254 print 255 print 256 257 if done: 258 sys.exit(0) 259 260 # setting verbose and quiet at the same time doesn't make sense 261 if options.verbose > 0 and options.quiet > 0: 262 options.usage(2) 263 264 verbose = options.verbose - options.quiet 265 if options.verbose >= 0: 266 print "M5 Simulator System" 267 print brief_copyright 268 print 269 270 print "M5 compiled %s" % defines.compileDate; 271 272 print "M5 started %s" % datetime.datetime.now().strftime("%b %e %Y %X") 273 print "M5 executing on %s" % socket.gethostname() 274 275 print "command line:", 276 for argv in sys.argv: 277 print argv, 278 print 279 280 # check to make sure we can find the listed script 281 if not arguments or not os.path.isfile(arguments[0]): 282 if arguments and not os.path.isfile(arguments[0]): 283 print "Script %s not found" % arguments[0] 284 285 options.usage(2) 286 287 # tell C++ about output directory 288 core.setOutputDir(options.outdir) 289 290 # update the system path with elements from the -p option 291 sys.path[0:0] = options.path 292 293 # set stats options 294 stats.initText(options.stats_file) 295 296 # set debugging options 297 debug.setRemoteGDBPort(options.remote_gdb_port) 298 for when in options.debug_break: 299 debug.schedBreakCycle(int(when)) 300 301 if options.debug_flags: 302 check_tracing() 303 304 on_flags = [] 305 off_flags = [] 306 for flag in options.debug_flags: 307 off = False 308 if flag.startswith('-'): 309 flag = flag[1:] 310 off = True 311 312 if flag not in debug.flags: 313 print >>sys.stderr, "invalid debug flag '%s'" % flag 314 sys.exit(1) 315 316 if off: 317 debug.flags[flag].disable() 318 else: 319 debug.flags[flag].enable() 320 321 if options.trace_start: 322 check_tracing() 323 e = event.create(trace.enable, event.Event.Trace_Enable_Pri) 324 event.mainq.schedule(e, options.trace_start) 325 else: 326 trace.enable() 327 328 trace.output(options.trace_file) 329 330 for ignore in options.trace_ignore: 331 check_tracing() 332 trace.ignore(ignore) 333 334 sys.argv = arguments 335 sys.path = [ os.path.dirname(sys.argv[0]) ] + sys.path 336 337 filename = sys.argv[0] 338 filedata = file(filename, 'r').read() 339 filecode = compile(filedata, filename, 'exec') 340 scope = { '__file__' : filename, 341 '__name__' : '__m5_main__' } 342 343 # we want readline if we're doing anything interactive 344 if options.interactive or options.pdb: 345 exec "import readline" in scope 346 347 # if pdb was requested, execfile the thing under pdb, otherwise, 348 # just do the execfile normally 349 if options.pdb: 350 import pdb 351 import traceback 352 353 pdb = pdb.Pdb() 354 try: 355 pdb.run(filecode, scope) 356 except SystemExit: 357 print "The program exited via sys.exit(). Exit status: ", 358 print sys.exc_info()[1] 359 except: 360 traceback.print_exc() 361 print "Uncaught exception. Entering post mortem debugging" 362 t = sys.exc_info()[2] 363 while t.tb_next is not None: 364 t = t.tb_next 365 pdb.interaction(t.tb_frame,t) 366 else: 367 exec filecode in scope 368 369 # once the script is done 370 if options.interactive: 371 interact(scope) 372 373if __name__ == '__main__': 374 from pprint import pprint 375 376 options, arguments = parse_options() 377 378 print 'opts:' 379 pprint(options, indent=4) 380 print 381 382 print 'args:' 383 pprint(arguments, indent=4) 384