Deleted Added
sdiff udiff text old ( 13709:dd6b7ac5801f ) new ( 13714:35636064b7a1 )
full compact
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
41from __future__ import print_function
42
43import code
44import datetime
45import os
46import socket
47import sys
48
49__all__ = [ 'options', 'arguments', 'main' ]
50
51usage="%prog [gem5 options] script.py [script options]"
52version="%prog 2.0"
53brief_copyright=\
54 "gem5 is copyrighted software; use the --copyright option for details."
55
56def parse_options():
57 import config
58 from options import OptionParser
59
60 options = OptionParser(usage=usage, version=version,
61 description=brief_copyright)
62 option = options.add_option
63 group = options.set_group
64
65 listener_modes = ( "on", "off", "auto" )
66
67 # Help options
68 option('-B', "--build-info", action="store_true", default=False,
69 help="Show build information")
70 option('-C', "--copyright", action="store_true", default=False,
71 help="Show full copyright information")
72 option('-R', "--readme", action="store_true", default=False,
73 help="Show the readme")
74
75 # Options for configuring the base simulator
76 option('-d', "--outdir", metavar="DIR", default="m5out",
77 help="Set the output directory to DIR [Default: %default]")
78 option('-r', "--redirect-stdout", action="store_true", default=False,
79 help="Redirect stdout (& stderr, without -e) to file")
80 option('-e', "--redirect-stderr", action="store_true", default=False,
81 help="Redirect stderr to file")
82 option("--stdout-file", metavar="FILE", default="simout",
83 help="Filename for -r redirection [Default: %default]")
84 option("--stderr-file", metavar="FILE", default="simerr",
85 help="Filename for -e redirection [Default: %default]")
86 option("--listener-mode", metavar="{on,off,auto}",
87 choices=listener_modes, default="auto",
88 help="Port (e.g., gdb) listener mode (auto: Enable if running " \
89 "interactively) [Default: %default]")
90 option("--listener-loopback-only", action="store_true", default=False,
91 help="Port listeners will only accept connections over the " \
92 "loopback device")
93 option('-i', "--interactive", action="store_true", default=False,
94 help="Invoke the interactive interpreter after running the script")
95 option("--pdb", action="store_true", default=False,
96 help="Invoke the python debugger before running the script")
97 option('-p', "--path", metavar="PATH[:PATH]", action='append', split=':',
98 help="Prepend PATH to the system path when invoking the script")
99 option('-q', "--quiet", action="count", default=0,
100 help="Reduce verbosity")
101 option('-v', "--verbose", action="count", default=0,
102 help="Increase verbosity")
103
104 # Statistics options
105 group("Statistics Options")
106 option("--stats-file", metavar="FILE", default="stats.txt",
107 help="Sets the output file for statistics [Default: %default]")
108
109 # Configuration Options
110 group("Configuration Options")
111 option("--dump-config", metavar="FILE", default="config.ini",
112 help="Dump configuration output file [Default: %default]")
113 option("--json-config", metavar="FILE", default="config.json",
114 help="Create JSON output of the configuration [Default: %default]")
115 option("--dot-config", metavar="FILE", default="config.dot",
116 help="Create DOT & pdf outputs of the configuration [Default: %default]")
117 option("--dot-dvfs-config", metavar="FILE", default=None,
118 help="Create DOT & pdf outputs of the DVFS configuration" + \
119 " [Default: %default]")
120
121 # Debugging options
122 group("Debugging Options")
123 option("--debug-break", metavar="TICK[,TICK]", action='append', split=',',
124 help="Create breakpoint(s) at TICK(s) " \
125 "(kills process if no debugger attached)")
126 option("--debug-help", action='store_true',
127 help="Print help on debug flags")
128 option("--debug-flags", metavar="FLAG[,FLAG]", action='append', split=',',
129 help="Sets the flags for debug output (-FLAG disables a flag)")
130 option("--debug-start", metavar="TICK", type='int',
131 help="Start debug output at TICK")
132 option("--debug-end", metavar="TICK", type='int',
133 help="End debug output at TICK")
134 option("--debug-file", metavar="FILE", default="cout",
135 help="Sets the output file for debug [Default: %default]")
136 option("--debug-ignore", metavar="EXPR", action='append', split=':',
137 help="Ignore EXPR sim objects")
138 option("--remote-gdb-port", type='int', default=7000,
139 help="Remote gdb base port (set to 0 to disable listening)")
140
141 # Help options
142 group("Help Options")
143 option("--list-sim-objects", action='store_true', default=False,
144 help="List all built-in SimObjects, their params and default values")
145
146 # load the options.py config file to allow people to set their own
147 # default options
148 options_file = config.get('options.py')
149 if options_file:
150 scope = { 'options' : options }
151 exec(compile(open(options_file).read(), options_file, 'exec'), scope)
152
153 arguments = options.parse_args()
154 return options,arguments
155
156def interact(scope):
157 banner = "gem5 Interactive Console"
158
159 ipshell = None
160 prompt_in1 = "gem5 \\#> "
161 prompt_out = "gem5 \\#: "
162
163 # Is IPython version 0.10 or earlier available?
164 try:
165 from IPython.Shell import IPShellEmbed
166 ipshell = IPShellEmbed(argv=["-prompt_in1", prompt_in1,
167 "-prompt_out", prompt_out],
168 banner=banner, user_ns=scope)
169 except ImportError:
170 pass
171
172 # Is IPython version 0.11 or later available?
173 if not ipshell:
174 try:
175 import IPython
176 from IPython.config.loader import Config
177 from IPython.terminal.embed import InteractiveShellEmbed
178
179 cfg = Config()
180 cfg.PromptManager.in_template = prompt_in1
181 cfg.PromptManager.out_template = prompt_out
182 ipshell = InteractiveShellEmbed(config=cfg, user_ns=scope,
183 banner1=banner)
184 except ImportError:
185 pass
186
187 if ipshell:
188 ipshell()
189 else:
190 # Use the Python shell in the standard library if IPython
191 # isn't available.
192 code.InteractiveConsole(scope).interact(banner)
193
194
195def _check_tracing():
196 import defines
197
198 if defines.TRACING_ON:
199 return
200
201 fatal("Tracing is not enabled. Compile with TRACING_ON")
202
203def main(*args):
204 import m5
205
206 import core
207 import debug
208 import defines
209 import event
210 import info
211 import stats
212 import trace
213
214 from util import inform, fatal, panic, isInteractive
215
216 if len(args) == 0:
217 options, arguments = parse_options()
218 elif len(args) == 2:
219 options, arguments = args
220 else:
221 raise TypeError("main() takes 0 or 2 arguments (%d given)" % len(args))
222
223 m5.options = options
224
225 # Set the main event queue for the main thread.
226 event.mainq = event.getEventQueue(0)
227 event.setEventQueue(event.mainq)
228
229 if not os.path.isdir(options.outdir):
230 os.makedirs(options.outdir)
231
232 # These filenames are used only if the redirect_std* options are set
233 stdout_file = os.path.join(options.outdir, options.stdout_file)
234 stderr_file = os.path.join(options.outdir, options.stderr_file)
235
236 # Print redirection notices here before doing any redirection
237 if options.redirect_stdout and not options.redirect_stderr:
238 print("Redirecting stdout and stderr to", stdout_file)
239 else:
240 if options.redirect_stdout:
241 print("Redirecting stdout to", stdout_file)
242 if options.redirect_stderr:
243 print("Redirecting stderr to", stderr_file)
244
245 # Now redirect stdout/stderr as desired
246 if options.redirect_stdout:
247 redir_fd = os.open(stdout_file, os. O_WRONLY | os.O_CREAT | os.O_TRUNC)
248 os.dup2(redir_fd, sys.stdout.fileno())
249 if not options.redirect_stderr:
250 os.dup2(redir_fd, sys.stderr.fileno())
251
252 if options.redirect_stderr:
253 redir_fd = os.open(stderr_file, os. O_WRONLY | os.O_CREAT | os.O_TRUNC)
254 os.dup2(redir_fd, sys.stderr.fileno())
255
256 done = False
257
258 if options.build_info:
259 done = True
260 print('Build information:')
261 print()
262 print('compiled %s' % defines.compileDate)
263 print('build options:')
264 keys = list(defines.buildEnv.keys())
265 keys.sort()
266 for key in keys:
267 val = defines.buildEnv[key]
268 print(' %s = %s' % (key, val))
269 print()
270
271 if options.copyright:
272 done = True
273 print(info.COPYING)
274 print()
275
276 if options.readme:
277 done = True
278 print('Readme:')
279 print()
280 print(info.README)
281 print()
282
283 if options.debug_help:
284 done = True
285 _check_tracing()
286 debug.help()
287
288 if options.list_sim_objects:
289 import SimObject
290 done = True
291 print("SimObjects:")
292 objects = list(SimObject.allClasses.keys())
293 objects.sort()
294 for name in objects:
295 obj = SimObject.allClasses[name]
296 print(" %s" % obj)
297 params = list(obj._params.keys())
298 params.sort()
299 for pname in params:
300 param = obj._params[pname]
301 default = getattr(param, 'default', '')
302 print(" %s" % pname)
303 if default:
304 print(" default: %s" % default)
305 print(" desc: %s" % param.desc)
306 print()
307 print()
308
309 if done:
310 sys.exit(0)
311
312 # setting verbose and quiet at the same time doesn't make sense
313 if options.verbose > 0 and options.quiet > 0:
314 options.usage(2)
315
316 verbose = options.verbose - options.quiet
317 if verbose >= 0:
318 print("gem5 Simulator System. http://gem5.org")
319 print(brief_copyright)
320 print()
321
322 print("gem5 compiled %s" % defines.compileDate)
323
324 print("gem5 started %s" %
325 datetime.datetime.now().strftime("%b %e %Y %X"))
326 print("gem5 executing on %s, pid %d" %
327 (socket.gethostname(), os.getpid()))
328
329 # in Python 3 pipes.quote() is moved to shlex.quote()
330 import pipes
331 print("command line:", " ".join(map(pipes.quote, sys.argv)))
332 print()
333
334 # check to make sure we can find the listed script
335 if not arguments or not os.path.isfile(arguments[0]):
336 if arguments and not os.path.isfile(arguments[0]):
337 print("Script %s not found" % arguments[0])
338
339 options.usage(2)
340
341 # tell C++ about output directory
342 core.setOutputDir(options.outdir)
343
344 # update the system path with elements from the -p option
345 sys.path[0:0] = options.path
346
347 # set stats options
348 stats.addStatVisitor(options.stats_file)
349
350 # Disable listeners unless running interactively or explicitly
351 # enabled
352 if options.listener_mode == "off":
353 m5.disableAllListeners()
354 elif options.listener_mode == "auto":
355 if not isInteractive():
356 inform("Standard input is not a terminal, disabling listeners.")
357 m5.disableAllListeners()
358 elif options.listener_mode == "on":
359 pass
360 else:
361 panic("Unhandled listener mode: %s" % options.listener_mode)
362
363 if options.listener_loopback_only:
364 m5.listenersLoopbackOnly()
365
366 # set debugging options
367 debug.setRemoteGDBPort(options.remote_gdb_port)
368 for when in options.debug_break:
369 debug.schedBreak(int(when))
370
371 if options.debug_flags:
372 _check_tracing()
373
374 on_flags = []
375 off_flags = []
376 for flag in options.debug_flags:
377 off = False
378 if flag.startswith('-'):
379 flag = flag[1:]
380 off = True
381
382 if flag not in debug.flags:
383 print("invalid debug flag '%s'" % flag, file=sys.stderr)
384 sys.exit(1)
385
386 if off:
387 debug.flags[flag].disable()
388 else:
389 debug.flags[flag].enable()
390
391 if options.debug_start:
392 _check_tracing()
393 e = event.create(trace.enable, event.Event.Debug_Enable_Pri)
394 event.mainq.schedule(e, options.debug_start)
395 else:
396 trace.enable()
397
398 if options.debug_end:
399 _check_tracing()
400 e = event.create(trace.disable, event.Event.Debug_Enable_Pri)
401 event.mainq.schedule(e, options.debug_end)
402
403 trace.output(options.debug_file)
404
405 for ignore in options.debug_ignore:
406 _check_tracing()
407 trace.ignore(ignore)
408
409 sys.argv = arguments
410 sys.path = [ os.path.dirname(sys.argv[0]) ] + sys.path
411
412 filename = sys.argv[0]
413 filedata = open(filename, 'r').read()
414 filecode = compile(filedata, filename, 'exec')
415 scope = { '__file__' : filename,
416 '__name__' : '__m5_main__' }
417
418 # if pdb was requested, execfile the thing under pdb, otherwise,
419 # just do the execfile normally
420 if options.pdb:
421 import pdb
422 import traceback
423
424 pdb = pdb.Pdb()
425 try:
426 pdb.run(filecode, scope)
427 except SystemExit:
428 print("The program exited via sys.exit(). Exit status: ", end=' ')
429 print(sys.exc_info()[1])
430 except:
431 traceback.print_exc()
432 print("Uncaught exception. Entering post mortem debugging")
433 t = sys.exc_info()[2]
434 while t.tb_next is not None:
435 t = t.tb_next
436 pdb.interaction(t.tb_frame,t)
437 else:
438 exec(filecode, scope)
439
440 # once the script is done
441 if options.interactive:
442 interact(scope)
443
444if __name__ == '__main__':
445 from pprint import pprint
446
447 options, arguments = parse_options()
448
449 print('opts:')
450 pprint(options, indent=4)
451 print()
452
453 print('args:')
454 pprint(arguments, indent=4)