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