dc8aab924c9ebf0a94c64f401d5b00c7d7447c96
[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 from util import attrdict, fatal
36 import config
37 from options import OptionParser
38
39 __all__ = [ 'options', 'arguments', 'main' ]
40
41 usage="%prog [m5 options] script.py [script options]"
42 version="%prog 2.0"
43 brief_copyright='''
44 Copyright (c) 2001-2008
45 The Regents of The University of Michigan
46 All Rights Reserved
47 '''
48
49 options = OptionParser(usage=usage, version=version,
50 description=brief_copyright)
51 add_option = options.add_option
52 set_group = options.set_group
53 usage = options.usage
54
55 # Help options
56 add_option('-A', "--authors", action="store_true", default=False,
57 help="Show author information")
58 add_option('-B', "--build-info", action="store_true", default=False,
59 help="Show build information")
60 add_option('-C', "--copyright", action="store_true", default=False,
61 help="Show full copyright information")
62 add_option('-R', "--readme", action="store_true", default=False,
63 help="Show the readme")
64
65 # Options for configuring the base simulator
66 add_option('-d', "--outdir", metavar="DIR", default="m5out",
67 help="Set the output directory to DIR [Default: %default]")
68 add_option('-r', "--redirect-stdout", action="store_true", default=False,
69 help="Redirect stdout (& stderr, without -e) to file")
70 add_option('-e', "--redirect-stderr", action="store_true", default=False,
71 help="Redirect stderr to file")
72 add_option("--stdout-file", metavar="FILE", default="simout",
73 help="Filename for -r redirection [Default: %default]")
74 add_option("--stderr-file", metavar="FILE", default="simerr",
75 help="Filename for -e redirection [Default: %default]")
76 add_option('-i', "--interactive", action="store_true", default=False,
77 help="Invoke the interactive interpreter after running the script")
78 add_option("--pdb", action="store_true", default=False,
79 help="Invoke the python debugger before running the script")
80 add_option('-p', "--path", metavar="PATH[:PATH]", action='append', split=':',
81 help="Prepend PATH to the system path when invoking the script")
82 add_option('-q', "--quiet", action="count", default=0,
83 help="Reduce verbosity")
84 add_option('-v', "--verbose", action="count", default=0,
85 help="Increase verbosity")
86
87 # Statistics options
88 set_group("Statistics Options")
89 add_option("--stats-file", metavar="FILE", default="stats.txt",
90 help="Sets the output file for statistics [Default: %default]")
91
92 # Configuration Options
93 set_group("Configuration Options")
94 add_option("--dump-config", metavar="FILE", default="config.ini",
95 help="Dump configuration output file [Default: %default]")
96
97 # Debugging options
98 set_group("Debugging Options")
99 add_option("--debug-break", metavar="TIME[,TIME]", action='append', split=',',
100 help="Cycle to create a breakpoint")
101 add_option("--remote-gdb-port", type='int', default=7000,
102 help="Remote gdb base port (set to 0 to disable listening)")
103
104 # Tracing options
105 set_group("Trace Options")
106 add_option("--trace-help", action='store_true',
107 help="Print help on trace flags")
108 add_option("--trace-flags", metavar="FLAG[,FLAG]", action='append', split=',',
109 help="Sets the flags for tracing (-FLAG disables a flag)")
110 add_option("--trace-start", metavar="TIME", type='int',
111 help="Start tracing at TIME (must be in ticks)")
112 add_option("--trace-file", metavar="FILE", default="cout",
113 help="Sets the output file for tracing [Default: %default]")
114 add_option("--trace-ignore", metavar="EXPR", action='append', split=':',
115 help="Ignore EXPR sim objects")
116
117 # Help options
118 set_group("Help Options")
119 add_option("--list-sim-objects", action='store_true', default=False,
120 help="List all built-in SimObjects, their parameters and default values")
121
122 # load the options.py config file to allow people to set their own
123 # default options
124 options_file = config.get('options.py')
125 if options_file:
126 scope = { 'options' : options }
127 execfile(options_file, scope)
128
129 arguments = options.parse_args()
130
131 def main():
132 import core
133 import debug
134 import defines
135 import event
136 import info
137 import stats
138 import trace
139
140 def check_tracing():
141 if defines.TRACING_ON:
142 return
143
144 fatal("Tracing is not enabled. Compile with TRACING_ON")
145
146 if not os.path.isdir(options.outdir):
147 os.makedirs(options.outdir)
148
149 # These filenames are used only if the redirect_std* options are set
150 stdout_file = os.path.join(options.outdir, options.stdout_file)
151 stderr_file = os.path.join(options.outdir, options.stderr_file)
152
153 # Print redirection notices here before doing any redirection
154 if options.redirect_stdout and not options.redirect_stderr:
155 print "Redirecting stdout and stderr to", stdout_file
156 else:
157 if options.redirect_stdout:
158 print "Redirecting stdout to", stdout_file
159 if options.redirect_stderr:
160 print "Redirecting stderr to", stderr_file
161
162 # Now redirect stdout/stderr as desired
163 if options.redirect_stdout:
164 redir_fd = os.open(stdout_file, os. O_WRONLY | os.O_CREAT | os.O_TRUNC)
165 os.dup2(redir_fd, sys.stdout.fileno())
166 if not options.redirect_stderr:
167 os.dup2(redir_fd, sys.stderr.fileno())
168
169 if options.redirect_stderr:
170 redir_fd = os.open(stderr_file, os. O_WRONLY | os.O_CREAT | os.O_TRUNC)
171 os.dup2(redir_fd, sys.stderr.fileno())
172
173 done = False
174
175 if options.build_info:
176 done = True
177 print 'Build information:'
178 print
179 print 'compiled %s' % defines.compileDate;
180 print 'build options:'
181 keys = defines.buildEnv.keys()
182 keys.sort()
183 for key in keys:
184 val = defines.buildEnv[key]
185 print ' %s = %s' % (key, val)
186 print
187
188 if options.copyright:
189 done = True
190 print info.LICENSE
191 print
192
193 if options.authors:
194 done = True
195 print 'Author information:'
196 print
197 print info.AUTHORS
198 print
199
200 if options.readme:
201 done = True
202 print 'Readme:'
203 print
204 print info.README
205 print
206
207 if options.trace_help:
208 done = True
209 check_tracing()
210 trace.help()
211
212 if options.list_sim_objects:
213 import SimObject
214 done = True
215 print "SimObjects:"
216 objects = SimObject.allClasses.keys()
217 objects.sort()
218 for name in objects:
219 obj = SimObject.allClasses[name]
220 print " %s" % obj
221 params = obj._params.keys()
222 params.sort()
223 for pname in params:
224 param = obj._params[pname]
225 default = getattr(param, 'default', '')
226 print " %s" % pname
227 if default:
228 print " default: %s" % default
229 print " desc: %s" % param.desc
230 print
231 print
232
233 if done:
234 sys.exit(0)
235
236 # setting verbose and quiet at the same time doesn't make sense
237 if options.verbose > 0 and options.quiet > 0:
238 options.usage(2)
239
240 verbose = options.verbose - options.quiet
241 if options.verbose >= 0:
242 print "M5 Simulator System"
243 print brief_copyright
244 print
245
246 print "M5 compiled %s" % defines.compileDate;
247
248 print "M5 started %s" % datetime.datetime.now().strftime("%b %e %Y %X")
249 print "M5 executing on %s" % socket.gethostname()
250
251 print "command line:",
252 for argv in sys.argv:
253 print argv,
254 print
255
256 # check to make sure we can find the listed script
257 if not arguments or not os.path.isfile(arguments[0]):
258 if arguments and not os.path.isfile(arguments[0]):
259 print "Script %s not found" % arguments[0]
260
261 options.usage(2)
262
263 # tell C++ about output directory
264 core.setOutputDir(options.outdir)
265
266 # update the system path with elements from the -p option
267 sys.path[0:0] = options.path
268
269 # set stats options
270 stats.initText(options.stats_file)
271
272 # set debugging options
273 debug.setRemoteGDBPort(options.remote_gdb_port)
274 for when in options.debug_break:
275 debug.schedBreakCycle(int(when))
276
277 if options.trace_flags:
278 check_tracing()
279
280 on_flags = []
281 off_flags = []
282 for flag in options.trace_flags:
283 off = False
284 if flag.startswith('-'):
285 flag = flag[1:]
286 off = True
287 if flag not in trace.flags.all and flag != "All":
288 print >>sys.stderr, "invalid trace flag '%s'" % flag
289 sys.exit(1)
290
291 if off:
292 off_flags.append(flag)
293 else:
294 on_flags.append(flag)
295
296 for flag in on_flags:
297 trace.set(flag)
298
299 for flag in off_flags:
300 trace.clear(flag)
301
302 if options.trace_start:
303 check_tracing()
304 e = event.create(trace.enable, event.Event.Trace_Enable_Pri)
305 event.mainq.schedule(e, options.trace_start)
306 else:
307 trace.enable()
308
309 trace.output(options.trace_file)
310
311 for ignore in options.trace_ignore:
312 check_tracing()
313 trace.ignore(ignore)
314
315 sys.argv = arguments
316 sys.path = [ os.path.dirname(sys.argv[0]) ] + sys.path
317
318 filename = sys.argv[0]
319 filedata = file(filename, 'r').read()
320 filecode = compile(filedata, filename, 'exec')
321 scope = { '__file__' : filename,
322 '__name__' : '__m5_main__' }
323
324 # we want readline if we're doing anything interactive
325 if options.interactive or options.pdb:
326 exec "import readline" in scope
327
328 # if pdb was requested, execfile the thing under pdb, otherwise,
329 # just do the execfile normally
330 if options.pdb:
331 import pdb
332 import traceback
333
334 pdb = pdb.Pdb()
335 try:
336 pdb.run(filecode, scope)
337 except SystemExit:
338 print "The program exited via sys.exit(). Exit status: ",
339 print sys.exc_info()[1]
340 except:
341 traceback.print_exc()
342 print "Uncaught exception. Entering post mortem debugging"
343 t = sys.exc_info()[2]
344 while t.tb_next is not None:
345 t = t.tb_next
346 pdb.interaction(t.tb_frame,t)
347 else:
348 exec filecode in scope
349
350 # once the script is done
351 if options.interactive:
352 banner = "M5 Interactive Console"
353 try:
354 from IPython.Shell import IPShellEmbed
355 ipshell = IPShellEmbed(banner=banner,user_ns=scope)
356 ipshell()
357 except ImportError:
358 code.InteractiveConsole(scope).interact(banner)
359
360 if __name__ == '__main__':
361 from pprint import pprint
362
363 print 'opts:'
364 pprint(options, indent=4)
365 print
366
367 print 'args:'
368 pprint(arguments, indent=4)