main.py revision 12563
14202Sbinkertn@umich.edu# Copyright (c) 2016 ARM Limited
24202Sbinkertn@umich.edu# All rights reserved.
34202Sbinkertn@umich.edu#
44202Sbinkertn@umich.edu# The license below extends only to copyright in the software and shall
54202Sbinkertn@umich.edu# not be construed as granting a license to any other intellectual
64202Sbinkertn@umich.edu# property including but not limited to intellectual property relating
74202Sbinkertn@umich.edu# to a hardware implementation of the functionality of the software
84202Sbinkertn@umich.edu# licensed hereunder.  You may use the software subject to the license
94202Sbinkertn@umich.edu# terms below provided that you ensure that this notice is replicated
104202Sbinkertn@umich.edu# unmodified and in its entirety in all distributions of the software,
114202Sbinkertn@umich.edu# modified or unmodified, in source code or in binary form.
124202Sbinkertn@umich.edu#
134202Sbinkertn@umich.edu# Copyright (c) 2005 The Regents of The University of Michigan
144202Sbinkertn@umich.edu# All rights reserved.
154202Sbinkertn@umich.edu#
164202Sbinkertn@umich.edu# Redistribution and use in source and binary forms, with or without
174202Sbinkertn@umich.edu# modification, are permitted provided that the following conditions are
184202Sbinkertn@umich.edu# met: redistributions of source code must retain the above copyright
194202Sbinkertn@umich.edu# notice, this list of conditions and the following disclaimer;
204202Sbinkertn@umich.edu# redistributions in binary form must reproduce the above copyright
214202Sbinkertn@umich.edu# notice, this list of conditions and the following disclaimer in the
224202Sbinkertn@umich.edu# documentation and/or other materials provided with the distribution;
234202Sbinkertn@umich.edu# neither the name of the copyright holders nor the names of its
244202Sbinkertn@umich.edu# contributors may be used to endorse or promote products derived from
254202Sbinkertn@umich.edu# this software without specific prior written permission.
264202Sbinkertn@umich.edu#
274202Sbinkertn@umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
284202Sbinkertn@umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
294202Sbinkertn@umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
304202Sbinkertn@umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
314202Sbinkertn@umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
324202Sbinkertn@umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3310996Sandreas.sandberg@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3410996Sandreas.sandberg@arm.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
359398Sandreas.hansson@arm.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
369850Sandreas.hansson@arm.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
379259SAli.Saidi@ARM.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
384486Sbinkertn@umich.edu#
3910146Sandreas.hansson@arm.com# Authors: Nathan Binkert
4010478SAndrew.Bardsley@arm.com
4110478SAndrew.Bardsley@arm.comfrom __future__ import print_function
426165Ssanchezd@stanford.edu
439850Sandreas.hansson@arm.comimport code
4410405Sandreas.hansson@arm.comimport datetime
4511184Serfan.azarkhish@unibo.itimport os
4611185Serfan.azarkhish@unibo.itimport socket
4712802Sandreas.sandberg@arm.comimport sys
486168Snate@binkert.org
499850Sandreas.hansson@arm.com__all__ = [ 'options', 'arguments', 'main' ]
509259SAli.Saidi@ARM.com
514202Sbinkertn@umich.eduusage="%prog [gem5 options] script.py [script options]"
5210405Sandreas.hansson@arm.comversion="%prog 2.0"
5310431SOmar.Naji@arm.combrief_copyright=\
5410146Sandreas.hansson@arm.com    "gem5 is copyrighted software; use the --copyright option for details."
5510478SAndrew.Bardsley@arm.com
5610478SAndrew.Bardsley@arm.comdef parse_options():
574202Sbinkertn@umich.edu    import config
588761Sgblack@eecs.umich.edu    from options import OptionParser
5910405Sandreas.hansson@arm.com
604202Sbinkertn@umich.edu    options = OptionParser(usage=usage, version=version,
614202Sbinkertn@umich.edu                           description=brief_copyright)
628914Sandreas.hansson@arm.com    option = options.add_option
6310405Sandreas.hansson@arm.com    group = options.set_group
6410405Sandreas.hansson@arm.com
6510405Sandreas.hansson@arm.com    listener_modes = ( "on", "off", "auto" )
6610405Sandreas.hansson@arm.com
6710614Skanishk.sugand@arm.com    # Help options
684202Sbinkertn@umich.edu    option('-B', "--build-info", action="store_true", default=False,
6910405Sandreas.hansson@arm.com        help="Show build information")
7011184Serfan.azarkhish@unibo.it    option('-C', "--copyright", action="store_true", default=False,
7111185Serfan.azarkhish@unibo.it        help="Show full copyright information")
7212802Sandreas.sandberg@arm.com    option('-R', "--readme", action="store_true", default=False,
736168Snate@binkert.org        help="Show the readme")
749850Sandreas.hansson@arm.com
759850Sandreas.hansson@arm.com    # Options for configuring the base simulator
769850Sandreas.hansson@arm.com    option('-d', "--outdir", metavar="DIR", default="m5out",
778763Sgblack@eecs.umich.edu        help="Set the output directory to DIR [Default: %default]")
787768SAli.Saidi@ARM.com    option('-r', "--redirect-stdout", action="store_true", default=False,
7910131Sandreas.hansson@arm.com        help="Redirect stdout (& stderr, without -e) to file")
8010131Sandreas.hansson@arm.com    option('-e', "--redirect-stderr", action="store_true", default=False,
8110131Sandreas.hansson@arm.com        help="Redirect stderr to file")
8210131Sandreas.hansson@arm.com    option("--stdout-file", metavar="FILE", default="simout",
8310066Sandreas.hansson@arm.com        help="Filename for -r redirection [Default: %default]")
8410612SMarco.Elver@ARM.com    option("--stderr-file", metavar="FILE", default="simerr",
8510612SMarco.Elver@ARM.com        help="Filename for -e redirection [Default: %default]")
8610612SMarco.Elver@ARM.com    option("--listener-mode", metavar="{on,off,auto}",
8710612SMarco.Elver@ARM.com        choices=listener_modes, default="auto",
8810405Sandreas.hansson@arm.com        help="Port (e.g., gdb) listener mode (auto: Enable if running " \
8910405Sandreas.hansson@arm.com        "interactively) [Default: %default]")
9010405Sandreas.hansson@arm.com    option("--listener-loopback-only", action="store_true", default=False,
9110405Sandreas.hansson@arm.com        help="Port listeners will only accept connections over the " \
9210399Sstephan.diestelhorst@arm.com        "loopback device")
9310405Sandreas.hansson@arm.com    option('-i', "--interactive", action="store_true", default=False,
9410405Sandreas.hansson@arm.com        help="Invoke the interactive interpreter after running the script")
959036Sandreas.hansson@arm.com    option("--pdb", action="store_true", default=False,
969164Sandreas.hansson@arm.com        help="Invoke the python debugger before running the script")
978981Sandreas.hansson@arm.com    option('-p', "--path", metavar="PATH[:PATH]", action='append', split=':',
989243Sandreas.hansson@arm.com        help="Prepend PATH to the system path when invoking the script")
9910247Sandreas.hansson@arm.com    option('-q', "--quiet", action="count", default=0,
10010208Sandreas.hansson@arm.com        help="Reduce verbosity")
10110478SAndrew.Bardsley@arm.com    option('-v', "--verbose", action="count", default=0,
1028335Snate@binkert.org        help="Increase verbosity")
1038335Snate@binkert.org
1048335Snate@binkert.org    # Statistics options
1058914Sandreas.hansson@arm.com    group("Statistics Options")
10610614Skanishk.sugand@arm.com    option("--stats-file", metavar="FILE", default="stats.txt",
10710066Sandreas.hansson@arm.com        help="Sets the output file for statistics [Default: %default]")
10811184Serfan.azarkhish@unibo.it
10911185Serfan.azarkhish@unibo.it    # Configuration Options
11010612SMarco.Elver@ARM.com    group("Configuration Options")
11110612SMarco.Elver@ARM.com    option("--dump-config", metavar="FILE", default="config.ini",
11210612SMarco.Elver@ARM.com        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        execfile(options_file, 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
194def main(*args):
195    import m5
196
197    import core
198    import debug
199    import defines
200    import event
201    import info
202    import stats
203    import trace
204
205    from util import inform, fatal, panic, isInteractive
206
207    if len(args) == 0:
208        options, arguments = parse_options()
209    elif len(args) == 2:
210        options, arguments = args
211    else:
212        raise TypeError, "main() takes 0 or 2 arguments (%d given)" % len(args)
213
214    m5.options = options
215
216    def check_tracing():
217        if defines.TRACING_ON:
218            return
219
220        fatal("Tracing is not enabled.  Compile with TRACING_ON")
221
222    # Set the main event queue for the main thread.
223    event.mainq = event.getEventQueue(0)
224    event.setEventQueue(event.mainq)
225
226    if not os.path.isdir(options.outdir):
227        os.makedirs(options.outdir)
228
229    # These filenames are used only if the redirect_std* options are set
230    stdout_file = os.path.join(options.outdir, options.stdout_file)
231    stderr_file = os.path.join(options.outdir, options.stderr_file)
232
233    # Print redirection notices here before doing any redirection
234    if options.redirect_stdout and not options.redirect_stderr:
235        print("Redirecting stdout and stderr to", stdout_file)
236    else:
237        if options.redirect_stdout:
238            print("Redirecting stdout to", stdout_file)
239        if options.redirect_stderr:
240            print("Redirecting stderr to", stderr_file)
241
242    # Now redirect stdout/stderr as desired
243    if options.redirect_stdout:
244        redir_fd = os.open(stdout_file, os. O_WRONLY | os.O_CREAT | os.O_TRUNC)
245        os.dup2(redir_fd, sys.stdout.fileno())
246        if not options.redirect_stderr:
247            os.dup2(redir_fd, sys.stderr.fileno())
248
249    if options.redirect_stderr:
250        redir_fd = os.open(stderr_file, os. O_WRONLY | os.O_CREAT | os.O_TRUNC)
251        os.dup2(redir_fd, sys.stderr.fileno())
252
253    done = False
254
255    if options.build_info:
256        done = True
257        print('Build information:')
258        print()
259        print('compiled %s' % defines.compileDate)
260        print('build options:')
261        keys = defines.buildEnv.keys()
262        keys.sort()
263        for key in keys:
264            val = defines.buildEnv[key]
265            print('    %s = %s' % (key, val))
266        print()
267
268    if options.copyright:
269        done = True
270        print(info.COPYING)
271        print()
272
273    if options.readme:
274        done = True
275        print('Readme:')
276        print()
277        print(info.README)
278        print()
279
280    if options.debug_help:
281        done = True
282        check_tracing()
283        debug.help()
284
285    if options.list_sim_objects:
286        import SimObject
287        done = True
288        print("SimObjects:")
289        objects = SimObject.allClasses.keys()
290        objects.sort()
291        for name in objects:
292            obj = SimObject.allClasses[name]
293            print("    %s" % obj)
294            params = obj._params.keys()
295            params.sort()
296            for pname in params:
297                param = obj._params[pname]
298                default = getattr(param, 'default', '')
299                print("        %s" % pname)
300                if default:
301                    print("            default: %s" % default)
302                print("            desc: %s" % param.desc)
303                print()
304            print()
305
306    if done:
307        sys.exit(0)
308
309    # setting verbose and quiet at the same time doesn't make sense
310    if options.verbose > 0 and options.quiet > 0:
311        options.usage(2)
312
313    verbose = options.verbose - options.quiet
314    if verbose >= 0:
315        print("gem5 Simulator System.  http://gem5.org")
316        print(brief_copyright)
317        print()
318
319        print("gem5 compiled %s" % defines.compileDate)
320
321        print("gem5 started %s" %
322              datetime.datetime.now().strftime("%b %e %Y %X"))
323        print("gem5 executing on %s, pid %d" %
324              (socket.gethostname(), os.getpid()))
325
326        # in Python 3 pipes.quote() is moved to shlex.quote()
327        import pipes
328        print("command line:", " ".join(map(pipes.quote, sys.argv)))
329        print()
330
331    # check to make sure we can find the listed script
332    if not arguments or not os.path.isfile(arguments[0]):
333        if arguments and not os.path.isfile(arguments[0]):
334            print("Script %s not found" % arguments[0])
335
336        options.usage(2)
337
338    # tell C++ about output directory
339    core.setOutputDir(options.outdir)
340
341    # update the system path with elements from the -p option
342    sys.path[0:0] = options.path
343
344    # set stats options
345    stats.addStatVisitor(options.stats_file)
346
347    # Disable listeners unless running interactively or explicitly
348    # enabled
349    if options.listener_mode == "off":
350        m5.disableAllListeners()
351    elif options.listener_mode == "auto":
352        if not isInteractive():
353            inform("Standard input is not a terminal, disabling listeners.")
354            m5.disableAllListeners()
355    elif options.listener_mode == "on":
356        pass
357    else:
358        panic("Unhandled listener mode: %s" % options.listener_mode)
359
360    if options.listener_loopback_only:
361        m5.listenersLoopbackOnly()
362
363    # set debugging options
364    debug.setRemoteGDBPort(options.remote_gdb_port)
365    for when in options.debug_break:
366        debug.schedBreak(int(when))
367
368    if options.debug_flags:
369        check_tracing()
370
371        on_flags = []
372        off_flags = []
373        for flag in options.debug_flags:
374            off = False
375            if flag.startswith('-'):
376                flag = flag[1:]
377                off = True
378
379            if flag not in debug.flags:
380                print("invalid debug flag '%s'" % flag, file=sys.stderr)
381                sys.exit(1)
382
383            if off:
384                debug.flags[flag].disable()
385            else:
386                debug.flags[flag].enable()
387
388    if options.debug_start:
389        check_tracing()
390        e = event.create(trace.enable, event.Event.Debug_Enable_Pri)
391        event.mainq.schedule(e, options.debug_start)
392    else:
393        trace.enable()
394
395    if options.debug_end:
396        check_tracing()
397        e = event.create(trace.disable, event.Event.Debug_Enable_Pri)
398        event.mainq.schedule(e, options.debug_end)
399
400    trace.output(options.debug_file)
401
402    for ignore in options.debug_ignore:
403        check_tracing()
404        trace.ignore(ignore)
405
406    sys.argv = arguments
407    sys.path = [ os.path.dirname(sys.argv[0]) ] + sys.path
408
409    filename = sys.argv[0]
410    filedata = file(filename, 'r').read()
411    filecode = compile(filedata, filename, 'exec')
412    scope = { '__file__' : filename,
413              '__name__' : '__m5_main__' }
414
415    # if pdb was requested, execfile the thing under pdb, otherwise,
416    # just do the execfile normally
417    if options.pdb:
418        import pdb
419        import traceback
420
421        pdb = pdb.Pdb()
422        try:
423            pdb.run(filecode, scope)
424        except SystemExit:
425            print("The program exited via sys.exit(). Exit status: ", end=' ')
426            print(sys.exc_info()[1])
427        except:
428            traceback.print_exc()
429            print("Uncaught exception. Entering post mortem debugging")
430            t = sys.exc_info()[2]
431            while t.tb_next is not None:
432                t = t.tb_next
433                pdb.interaction(t.tb_frame,t)
434    else:
435        exec filecode in scope
436
437    # once the script is done
438    if options.interactive:
439        interact(scope)
440
441if __name__ == '__main__':
442    from pprint import pprint
443
444    options, arguments = parse_options()
445
446    print('opts:')
447    pprint(options, indent=4)
448    print()
449
450    print('args:')
451    pprint(arguments, indent=4)
452