diff options
74 files changed, 1483 insertions, 214 deletions
diff --git a/configs/common/Caches.py b/configs/common/Caches.py index d86fba246..4692ef537 100644 --- a/configs/common/Caches.py +++ b/configs/common/Caches.py @@ -37,3 +37,10 @@ class L1Cache(BaseCache): tgts_per_mshr = 5 protocol = CoherenceProtocol(protocol='moesi') +class L2Cache(BaseCache): + assoc = 8 + block_size = 64 + latency = 10 + mshrs = 20 + tgts_per_mshr = 12 + diff --git a/configs/common/cpu2000.py b/configs/common/cpu2000.py new file mode 100644 index 000000000..7dc7a7afe --- /dev/null +++ b/configs/common/cpu2000.py @@ -0,0 +1,702 @@ +# Copyright (c) 2006 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Nathan Binkert + +import os +import sys +from os.path import basename, exists, join as joinpath, normpath +from os.path import isdir, isfile, islink + +spec_dist = '/dist/m5/cpu2000' + +def copyfiles(srcdir, dstdir): + from filecmp import cmp as filecmp + from shutil import copyfile + + srcdir = normpath(srcdir) + dstdir = normpath(dstdir) + + if not isdir(dstdir): + os.mkdir(dstdir) + + for root, dirs, files in os.walk(srcdir): + root = normpath(root) + prefix = os.path.commonprefix([root, srcdir]) + + root = root[len(prefix):] + if root.startswith('/'): + root = root[1:] + + for entry in dirs: + newdir = joinpath(dstdir, root, entry) + if not isdir(newdir): + os.mkdir(newdir) + + for entry in files: + dest = normpath(joinpath(dstdir, root, entry)) + src = normpath(joinpath(srcdir, root, entry)) + if not isfile(dest) or not filecmp(src, dest): + copyfile(src, dest) + + # some of the spec benchmarks expect to be run from one directory up. + # just create some symlinks that solve the problem + inlink = joinpath(dstdir, 'input') + outlink = joinpath(dstdir, 'output') + if not exists(inlink): + os.symlink('.', inlink) + if not exists(outlink): + os.symlink('.', outlink) + +class Benchmark(object): + def __init__(self, isa, os, input_set): + if not hasattr(self.__class__, 'name'): + self.name = self.__class__.__name__ + + if not hasattr(self.__class__, 'binary'): + self.binary = self.name + + if not hasattr(self.__class__, 'args'): + self.args = [] + + if not hasattr(self.__class__, 'output'): + self.output = '%s.out' % self.name + + try: + func = getattr(self.__class__, input_set) + except AttributeError: + raise AttributeError, \ + 'The benchmark %s does not have the %s input set' % \ + (self.name, input_set) + + executable = joinpath(spec_dist, 'binaries', isa, os, self.binary) + if not isfile(executable): + raise AttributeError, '%s not found' % executable + self.executable = executable + + # root of tree for input & output data files + data_dir = joinpath(spec_dist, 'data', self.name) + # optional subtree with files shared across input sets + all_dir = joinpath(data_dir, 'all') + # dirs for input & output files for this input set + inputs_dir = joinpath(data_dir, input_set, 'input') + outputs_dir = joinpath(data_dir, input_set, 'output') + + if not isdir(inputs_dir): + raise AttributeError, '%s not found' % inputs_dir + + self.inputs_dir = [ inputs_dir ] + if isdir(all_dir): + self.inputs_dir += [ joinpath(all_dir, 'input') ] + if isdir(outputs_dir): + self.outputs_dir = outputs_dir + + if not hasattr(self.__class__, 'stdin'): + self.stdin = joinpath(inputs_dir, '%s.in' % self.name) + if not isfile(self.stdin): + self.stdin = None + + if not hasattr(self.__class__, 'stdout'): + self.stdout = joinpath(outputs_dir, '%s.out' % self.name) + if not isfile(self.stdout): + self.stdout = None + + func(self, isa, os) + + def makeLiveProcessArgs(self, **kwargs): + # set up default args for LiveProcess object + process_args = {} + process_args['cmd'] = self.name + ' ' + ' '.join(self.args) + process_args['executable'] = self.executable + if self.stdin: + process_args['input'] = self.stdin + if self.stdout: + process_args['output'] = self.stdout + + # explicit keywords override defaults + process_args.update(kwargs) + + return process_args + + def makeLiveProcess(self, **kwargs): + process_args = self.makeLiveProcessArgs(**kwargs) + + # figure out working directory: use m5's outdir unless + # overridden by LiveProcess's cwd param + cwd = process_args.get('cwd') + if not cwd: + from m5.main import options + cwd = options.outdir + process_args['cwd'] = cwd + if not isdir(cwd): + os.makedirs(cwd) + # copy input files to working directory + for d in self.inputs_dir: + copyfiles(d, cwd) + # generate LiveProcess object + from m5.objects import LiveProcess + return LiveProcess(**process_args) + + def __str__(self): + return self.name + +class DefaultBenchmark(Benchmark): + def ref(self, isa, os): pass + def test(self, isa, os): pass + def train(self, isa, os): pass + +class MinneDefaultBenchmark(DefaultBenchmark): + def smred(self, isa, os): pass + def mdred(self, isa, os): pass + def lgred(self, isa, os): pass + +class ammp(MinneDefaultBenchmark): + name = 'ammp' + number = 188 + lang = 'C' + +class applu(MinneDefaultBenchmark): + name = 'applu' + number = 173 + lang = 'F77' + +class apsi(MinneDefaultBenchmark): + name = 'apsi' + number = 301 + lang = 'F77' + +class art(DefaultBenchmark): + name = 'art' + number = 179 + lang = 'C' + + def test(self, isa, os): + self.args = [ '-scanfile', 'c756hel.in', + '-trainfile1', 'a10.img', + '-stride', '2', + '-startx', '134', + '-starty', '220', + '-endx', '139', + '-endy', '225', + '-objects', '1' ] + self.output = 'test.out' + + def train(self, isa, os): + self.args = [ '-scanfile', 'c756hel.in', + '-trainfile1', 'a10.img', + '-stride', '2', + '-startx', '134', + '-starty', '220', + '-endx', '184', + '-endy', '240', + '-objects', '3' ] + self.output = 'train.out' + + def lgred(self, isa, os): + self.args = ['-scanfile', 'c756hel.in', + '-trainfile1', 'a10.img', + '-stride', '5', + '-startx', '134', + '-starty', '220', + '-endx', '184', + '-endy', '240', + '-objects', '1' ] + self.output = 'lgred.out' + + +class art110(art): + def ref(self, isa, os): + self.args = [ '-scanfile', 'c756hel.in', + '-trainfile1', 'a10.img', + '-trainfile2', 'hc.img', + '-stride', '2', + '-startx', '110', + '-starty', '200', + '-endx', '160', + '-endy', '240', + '-objects', '10' ] + self.output = 'ref.1.out' + +class art470(art): + def ref(self, isa, os): + self.args = [ '-scanfile', 'c756hel.in', + '-trainfile1', 'a10.img', + '-trainfile2', 'hc.img', + '-stride', '2', + '-startx', '470', + '-starty', '140', + '-endx', '520', + '-endy', '180', + '-objects', '10' ] + self.output = 'ref.2.out' + +class equake(DefaultBenchmark): + name = 'equake' + number = 183 + lang = 'C' + + def lgred(self, isa, os): pass + +class facerec(MinneDefaultBenchmark): + name = 'facerec' + number = 187 + lang = 'F' + +class fma3d(MinneDefaultBenchmark): + name = 'fma3d' + number = 191 + lang = 'F' + +class galgel(MinneDefaultBenchmark): + name = 'galgel' + number = 178 + lang = 'F' + +class lucas(MinneDefaultBenchmark): + name = 'lucas' + number = 189 + lang = 'F' + +class mesa(Benchmark): + name = 'mesa' + number = 177 + lang = 'C' + stdin = None + + def __set_args(self, frames): + self.args = [ '-frames', frames, '-meshfile', '%s.in' % self.name, + '-ppmfile', '%s.ppm' % self.name ] + + def test(self, isa, os): + self.__set_args('10') + + def train(self, isa, os): + self.__set_args('500') + + def ref(self, isa, os): + self.__set_args('1000') + + def lgred(self, isa, os): + self.__set_args('1') + +class mgrid(MinneDefaultBenchmark): + name = 'mgrid' + number = 172 + lang = 'F77' + +class sixtrack(DefaultBenchmark): + name = 'sixtrack' + number = 200 + lang = 'F77' + + def lgred(self, isa, os): pass + +class swim(MinneDefaultBenchmark): + name = 'swim' + number = 171 + lang = 'F77' + +class wupwise(DefaultBenchmark): + name = 'wupwise' + number = 168 + lang = 'F77' + + def lgred(self, isa, os): pass + +class bzip2(DefaultBenchmark): + name = 'bzip2' + number = 256 + lang = 'C' + + def test(self, isa, os): + self.args = [ 'input.random' ] + + def train(self, isa, os): + self.args = [ 'input.compressed' ] + +class bzip2_source(bzip2): + def ref(self, isa, os): + self.args = [ 'input.source', '58' ] + + def lgred(self, isa, os): + self.args = [ 'input.source', '1' ] + +class bzip2_graphic(bzip2): + def ref(self, isa, os): + self.args = [ 'input.graphic', '58' ] + + def lgred(self, isa, os): + self.args = [ 'input.graphic', '1' ] + +class bzip2_program(bzip2): + def ref(self, isa, os): + self.args = [ 'input.program', '58' ] + + def lgred(self, isa, os): + self.args = [ 'input.program', '1' ] + +class crafty(MinneDefaultBenchmark): + name = 'crafty' + number = 186 + lang = 'C' + +class eon(MinneDefaultBenchmark): + name = 'eon' + number = 252 + lang = 'CXX' + stdin = None + +class eon_kajiya(eon): + args = [ 'chair.control.kajiya', 'chair.camera', 'chair.surfaces', + 'chair.kajiya.ppm', 'ppm', 'pixels_out.kajiya'] + output = 'kajiya_log.out' + + +class eon_cook(eon): + args = [ 'chair.control.cook', 'chair.camera', 'chair.surfaces', + 'chair.cook.ppm', 'ppm', 'pixels_out.cook' ] + output = 'cook_log.out' + +class eon_rushmeier(eon): + args = [ 'chair.control.rushmeier', 'chair.camera', 'chair.surfaces', + 'chair.rushmeier.ppm', 'ppm', 'pixels_out.rushmeier' ] + output = 'rushmeier_log.out' + +class gap(DefaultBenchmark): + name = 'gap' + number = 254 + lang = 'C' + + def __set_args(self, size): + self.args = [ '-l', './', '-q', '-m', size ] + + def test(self, isa, os): + self.__set_args('64M') + + def train(self, isa, os): + self.__set_args('128M') + + def ref(self, isa, os): + self.__set_args('192M') + + def lgred(self, isa, os): + self.__set_args('64M') + + def mdred(self, isa, os): + self.__set_args('64M') + + def smred(self, isa, os): + self.__set_args('64M') + +class gcc(DefaultBenchmark): + name = 'gcc' + number = 176 + lang = 'C' + + def test(self, isa, os): + self.args = [ 'cccp.i', '-o', 'cccp.s' ] + + def train(self, isa, os): + self.args = [ 'cp-decl.i', '-o', 'cp-decl.s' ] + + def smred(self, isa, os): + self.args = [ 'c-iterate.i', '-o', 'c-iterate.s' ] + + def mdred(self, isa, os): + self.args = [ 'rdlanal.i', '-o', 'rdlanal.s' ] + + def lgred(self, isa, os): + self.args = [ 'cp-decl.i', '-o', 'cp-decl.s' ] + +class gcc_166(gcc): + def ref(self, isa, os): + self.args = [ '166.i', '-o', '166.s' ] + +class gcc_200(gcc): + def ref(self, isa, os): + self.args = [ '200.i', '-o', '200.s' ] + +class gcc_expr(gcc): + def ref(self, isa, os): + self.args = [ 'expr.i', '-o', 'expr.s' ] + +class gcc_integrate(gcc): + def ref(self, isa, os): + self.args = [ 'integrate.i', '-o', 'integrate.s' ] + +class gcc_scilab(gcc): + def ref(self, isa, os): + self.args = [ 'scilab.i', '-o', 'scilab.s' ] + +class gzip(DefaultBenchmark): + name = 'gzip' + number = 164 + lang = 'C' + + def test(self, isa, os): + self.args = [ 'input.compressed', '2' ] + + def train(self, isa, os): + self.args = [ 'input.combined', '32' ] + +class gzip_source(gzip): + def ref(self, isa, os): + self.args = [ 'input.source', '1' ] + def smred(self, isa, os): + self.args = [ 'input.source', '1' ] + def mdred(self, isa, os): + self.args = [ 'input.source', '1' ] + def lgred(self, isa, os): + self.args = [ 'input.source', '1' ] + +class gzip_log(gzip): + def ref(self, isa, os): + self.args = [ 'input.log', '60' ] + def smred(self, isa, os): + self.args = [ 'input.log', '1' ] + def mdred(self, isa, os): + self.args = [ 'input.log', '1' ] + def lgred(self, isa, os): + self.args = [ 'input.log', '1' ] + +class gzip_graphic(gzip): + def ref(self, isa, os): + self.args = [ 'input.graphic', '60' ] + def smred(self, isa, os): + self.args = [ 'input.graphic', '1' ] + def mdred(self, isa, os): + self.args = [ 'input.graphic', '1' ] + def lgred(self, isa, os): + self.args = [ 'input.graphic', '1' ] + +class gzip_random(gzip): + def ref(self, isa, os): + self.args = [ 'input.random', '60' ] + def smred(self, isa, os): + self.args = [ 'input.random', '1' ] + def mdred(self, isa, os): + self.args = [ 'input.random', '1' ] + def lgred(self, isa, os): + self.args = [ 'input.random', '1' ] + +class gzip_program(gzip): + def ref(self, isa, os): + self.args = [ 'input.program', '60' ] + def smred(self, isa, os): + self.args = [ 'input.program', '1' ] + def mdred(self, isa, os): + self.args = [ 'input.program', '1' ] + def lgred(self, isa, os): + self.args = [ 'input.program', '1' ] + +class mcf(MinneDefaultBenchmark): + name = 'mcf' + number = 181 + lang = 'C' + +class parser(MinneDefaultBenchmark): + name = 'parser' + number = 197 + lang = 'C' + args = [ '2.1.dict', '-batch' ] + +class perlbmk(DefaultBenchmark): + name = 'perlbmk' + number = 253 + lang = 'C' + + def test(self, isa, os): + self.args = [ '-I.', '-I', 'lib', 'test.pl' ] + self.stdin = 'test.in' + +class perlbmk_diffmail(perlbmk): + def ref(self, isa, os): + self.args = [ '-I', 'lib', 'diffmail.pl', '2', '550', '15', '24', + '23', '100' ] + + def train(self, isa, os): + self.args = [ '-I', 'lib', 'diffmail.pl', '2', '350', '15', '24', + '23', '150' ] + +class perlbmk_scrabbl(perlbmk): + def train(self, isa, os): + self.args = [ '-I.', '-I', 'lib', 'scrabbl.pl' ] + self.stdin = 'scrabbl.in' + +class perlbmk_makerand(perlbmk): + def ref(self, isa, os): + self.args = [ '-I', 'lib', 'makerand.pl' ] + + def lgred(self, isa, os): + self.args = [ '-I.', '-I', 'lib', 'lgred.makerand.pl' ] + + def mdred(self, isa, os): + self.args = [ '-I.', '-I', 'lib', 'mdred.makerand.pl' ] + + def smred(self, isa, os): + self.args = [ '-I.', '-I', 'lib', 'smred.makerand.pl' ] + +class perlbmk_perfect(perlbmk): + def ref(self, isa, os): + self.args = [ '-I', 'lib', 'perfect.pl', 'b', '3', 'm', '4' ] + + def train(self, isa, os): + self.args = [ '-I', 'lib', 'perfect.pl', 'b', '3' ] + +class perlbmk_splitmail1(perlbmk): + def ref(self, isa, os): + self.args = [ '-I', 'lib', 'splitmail.pl', '850', '5', '19', + '18', '1500' ] + +class perlbmk_splitmail2(perlbmk): + def ref(self, isa, os): + self.args = [ '-I', 'lib', 'splitmail.pl', '704', '12', '26', + '16', '836' ] + +class perlbmk_splitmail3(perlbmk): + def ref(self, isa, os): + self.args = [ '-I', 'lib', 'splitmail.pl', '535', '13', '25', + '24', '1091' ] + +class perlbmk_splitmail4(perlbmk): + def ref(self, isa, os): + self.args = [ '-I', 'lib', 'splitmail.pl', '957', '12', '23', + '26', '1014' ] + +class twolf(Benchmark): + name = 'twolf' + number = 300 + lang = 'C' + stdin = None + + def test(self, isa, os): + self.args = [ 'test' ] + + def train(self, isa, os): + self.args = [ 'train' ] + + def ref(self, isa, os): + self.args = [ 'ref' ] + + def smred(self, isa, os): + self.args = [ 'smred' ] + + def mdred(self, isa, os): + self.args = [ 'mdred' ] + + def lgred(self, isa, os): + self.args = [ 'lgred' ] + +class vortex(Benchmark): + name = 'vortex' + number = 255 + lang = 'C' + stdin = None + + def __init__(self, isa, os, input_set): + if isa == 'alpha': + self.endian = 'lendian' + else: + raise AttributeError, "unknown ISA %s" % isa + + super(vortex, self).__init__(isa, os, input_set) + + def test(self, isa, os): + self.args = [ '%s.raw' % self.endian ] + self.output = 'vortex.out' + + def train(self, isa, os): + self.args = [ '%s.raw' % self.endian ] + self.output = 'vortex.out' + + def smred(self, isa, os): + self.args = [ '%s.raw' % self.endian ] + self.output = 'vortex.out' + + def mdred(self, isa, os): + self.args = [ '%s.raw' % self.endian ] + self.output = 'vortex.out' + + def lgred(self, isa, os): + self.args = [ '%s.raw' % self.endian ] + self.output = 'vortex.out' + +class vortex1(vortex): + def ref(self, isa, os): + self.args = [ '%s1.raw' % self.endian ] + self.output = 'vortex1.out' + + +class vortex2(vortex): + def ref(self, isa, os): + self.args = [ '%s2.raw' % self.endian ] + self.output = 'vortex2.out' + +class vortex3(vortex): + def ref(self, isa, os): + self.args = [ '%s3.raw' % self.endian ] + self.output = 'vortex3.out' + +class vpr(MinneDefaultBenchmark): + name = 'vpr' + number = 175 + lang = 'C' + +# not sure about vpr minnespec place.in +class vpr_place(vpr): + args = [ 'net.in', 'arch.in', 'place.out', 'dum.out', '-nodisp', + '-place_only', '-init_t', '5', '-exit_t', '0.005', + '-alpha_t', '0.9412', '-inner_num', '2' ] + output = 'place_log.out' + +class vpr_route(vpr): + args = [ 'net.in', 'arch.in', 'place.in', 'route.out', '-nodisp', + '-route_only', '-route_chan_width', '15', + '-pres_fac_mult', '2', '-acc_fac', '1', + '-first_iter_pres_fac', '4', '-initial_pres_fac', '8' ] + output = 'route_log.out' + +all = [ ammp, applu, apsi, art110, art470, equake, facerec, fma3d, galgel, + lucas, mesa, mgrid, sixtrack, swim, wupwise, bzip2_source, + bzip2_graphic, bzip2_program, crafty, eon_kajiya, eon_cook, + eon_rushmeier, gap, gcc_166, gcc_200, gcc_expr, gcc_integrate, + gcc_scilab, gzip_source, gzip_log, gzip_graphic, gzip_random, + gzip_program, mcf, parser, perlbmk_diffmail, perlbmk_makerand, + perlbmk_perfect, perlbmk_splitmail1, perlbmk_splitmail2, + perlbmk_splitmail3, perlbmk_splitmail4, twolf, vortex1, vortex2, + vortex3, vpr_place, vpr_route ] + +__all__ = [ x.__name__ for x in all ] + +if __name__ == '__main__': + from pprint import pprint + for bench in all: + for input_set in 'ref', 'test', 'train': + print 'class: %s' % bench.__name__ + x = bench('alpha', 'tru64', input_set) + print '%s: %s' % (x, input_set) + pprint(x.makeLiveProcessArgs()) + print diff --git a/configs/example/fs.py b/configs/example/fs.py index a9f1d579a..a70a60b97 100644 --- a/configs/example/fs.py +++ b/configs/example/fs.py @@ -47,6 +47,7 @@ config_root = os.path.dirname(config_path) parser = optparse.OptionParser() # Benchmark options +parser.add_option("--l2cache", action="store_true") parser.add_option("--dual", action="store_true", help="Simulate two systems attached with an ethernet link") parser.add_option("-b", "--benchmark", action="store", type="string", @@ -93,12 +94,23 @@ else: test_sys = makeLinuxAlphaSystem(test_mem_mode, bm[0]) np = options.num_cpus + +if options.l2cache: + test_sys.l2 = L2Cache(size = '2MB') + test_sys.tol2bus = Bus() + test_sys.l2.cpu_side = test_sys.tol2bus.port + test_sys.l2.mem_side = test_sys.membus.port + test_sys.cpu = [TestCPUClass(cpu_id=i) for i in xrange(np)] for i in xrange(np): if options.caches: test_sys.cpu[i].addPrivateSplitL1Caches(L1Cache(size = '32kB'), L1Cache(size = '64kB')) - test_sys.cpu[i].connectMemPorts(test_sys.membus) + + if options.l2cache: + test_sys.cpu[i].connectMemPorts(test_sys.tol2bus) + else: + test_sys.cpu[i].connectMemPorts(test_sys.membus) if len(bm) == 2: drive_sys = makeLinuxAlphaSystem(drive_mem_mode, bm[1]) diff --git a/configs/splash2/cluster.py b/configs/splash2/cluster.py new file mode 100644 index 000000000..799b85e6c --- /dev/null +++ b/configs/splash2/cluster.py @@ -0,0 +1,303 @@ +# Copyright (c) 2006 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Ron Dreslinski + +# Simple test script +# +# "m5 test.py" + +import m5 +from m5.objects import * +import os, optparse, sys +m5.AddToPath('../common') + +# -------------------- +# Define Command Line Options +# ==================== + +parser = optparse.OptionParser() + +parser.add_option("-d", "--detailed", action="store_true") +parser.add_option("-t", "--timing", action="store_true") +parser.add_option("-m", "--maxtick", type="int") +parser.add_option("-c", "--numclusters", + help="Number of clusters", type="int") +parser.add_option("-n", "--numcpus", + help="Number of cpus in total", type="int") +parser.add_option("-f", "--frequency", + default = "1GHz", + help="Frequency of each CPU") +parser.add_option("-p", "--protocol", + default="moesi", + help="The coherence protocol to use for the L1'a (i.e. MOESI, MOSI)") +parser.add_option("--l1size", + default = "32kB") +parser.add_option("--l1latency", + default = 1) +parser.add_option("--l2size", + default = "256kB") +parser.add_option("--l2latency", + default = 10) +parser.add_option("--rootdir", + help="ROot directory of Splash2", + default="/dist/splash2/codes/") +parser.add_option("-b", "--benchmark", + help="Splash 2 benchmark to run") + +(options, args) = parser.parse_args() + +if args: + print "Error: script doesn't take any positional arguments" + sys.exit(1) + +# -------------------- +# Define Splash2 Benchmarks +# ==================== +class Cholesky(LiveProcess): + executable = options.rootdir + '/kernels/cholesky/CHOLESKY' + cmd = 'CHOLESKY -p' + str(options.numcpus) + ' '\ + + options.rootdir + '/kernels/cholesky/inputs/tk23.O' + +class FFT(LiveProcess): + executable = options.rootdir + 'kernels/fft/FFT' + cmd = 'FFT -p' + str(options.numcpus) + ' -m18' + +class LU_contig(LiveProcess): + executable = options.rootdir + 'kernels/lu/contiguous_blocks/LU' + cmd = 'LU -p' + str(options.numcpus) + +class LU_noncontig(LiveProcess): + executable = options.rootdir + 'kernels/lu/non_contiguous_blocks/LU' + cmd = 'LU -p' + str(options.numcpus) + +class Radix(LiveProcess): + executable = options.rootdir + 'kernels/radix/RADIX' + cmd = 'RADIX -n524288 -p' + str(options.numcpus) + +class Barnes(LiveProcess): + executable = options.rootdir + 'apps/barnes/BARNES' + cmd = 'BARNES' + input = options.rootdir + 'apps/barnes/input.p' + str(options.numcpus) + +class FMM(LiveProcess): + executable = options.rootdir + 'apps/fmm/FMM' + cmd = 'FMM' + input = options.rootdir + 'apps/fmm/inputs/input.2048.p' + str(options.numcpus) + +class Ocean_contig(LiveProcess): + executable = options.rootdir + 'apps/ocean/contiguous_partitions/OCEAN' + cmd = 'OCEAN -p' + str(options.numcpus) + +class Ocean_noncontig(LiveProcess): + executable = options.rootdir + 'apps/ocean/non_contiguous_partitions/OCEAN' + cmd = 'OCEAN -p' + str(options.numcpus) + +class Raytrace(LiveProcess): + executable = options.rootdir + 'apps/raytrace/RAYTRACE' + cmd = 'RAYTRACE -p' + str(options.numcpus) + ' ' \ + + options.rootdir + 'apps/raytrace/inputs/teapot.env' + +class Water_nsquared(LiveProcess): + executable = options.rootdir + 'apps/water-nsquared/WATER-NSQUARED' + cmd = 'WATER-NSQUARED' + input = options.rootdir + 'apps/water-nsquared/input.p' + str(options.numcpus) + +class Water_spatial(LiveProcess): + executable = options.rootdir + 'apps/water-spatial/WATER-SPATIAL' + cmd = 'WATER-SPATIAL' + input = options.rootdir + 'apps/water-spatial/input.p' + str(options.numcpus) + + +# -------------------- +# Base L1 Cache Definition +# ==================== + +class L1(BaseCache): + latency = options.l1latency + block_size = 64 + mshrs = 12 + tgts_per_mshr = 8 + protocol = CoherenceProtocol(protocol=options.protocol) + +# ---------------------- +# Base L2 Cache Definition +# ---------------------- + +class L2(BaseCache): + block_size = 64 + latency = options.l2latency + mshrs = 92 + tgts_per_mshr = 16 + write_buffers = 8 + +# ---------------------- +# Define the clusters with their cpus +# ---------------------- +class Cluster: + pass + +cpusPerCluster = options.numcpus/options.numclusters + +busFrequency = Frequency(options.frequency) +busFrequency *= cpusPerCluster + +all_cpus = [] +all_l1s = [] +all_l1buses = [] +if options.timing: + clusters = [ Cluster() for i in xrange(options.numclusters)] + for j in xrange(options.numclusters): + clusters[j].id = j + for cluster in clusters: + cluster.clusterbus = Bus(clock=busFrequency) + all_l1buses += [cluster.clusterbus] + cluster.cpus = [TimingSimpleCPU(cpu_id = i + cluster.id, + clock=options.frequency) + for i in xrange(cpusPerCluster)] + all_cpus += cluster.cpus + cluster.l1 = L1(size=options.l1size, assoc = 4) + all_l1s += [cluster.l1] +elif options.detailed: + clusters = [ Cluster() for i in xrange(options.numclusters)] + for j in xrange(options.numclusters): + clusters[j].id = j + for cluster in clusters: + cluster.clusterbus = Bus(clock=busFrequency) + all_l1buses += [cluster.clusterbus] + cluster.cpus = [DerivO3CPU(cpu_id = i + cluster.id, + clock=options.frequency) + for i in xrange(cpusPerCluster)] + all_cpus += cluster.cpus + cluster.l1 = L1(size=options.l1size, assoc = 4) + all_l1s += [cluster.l1] +else: + clusters = [ Cluster() for i in xrange(options.numclusters)] + for j in xrange(options.numclusters): + clusters[j].id = j + for cluster in clusters: + cluster.clusterbus = Bus(clock=busFrequency) + all_l1buses += [cluster.clusterbus] + cluster.cpus = [AtomicSimpleCPU(cpu_id = i + cluster.id, + clock=options.frequency) + for i in xrange(cpusPerCluster)] + all_cpus += cluster.cpus + cluster.l1 = L1(size=options.l1size, assoc = 4) + all_l1s += [cluster.l1] + +# ---------------------- +# Create a system, and add system wide objects +# ---------------------- +system = System(cpu = all_cpus, l1_ = all_l1s, l1bus_ = all_l1buses, physmem = PhysicalMemory(), + membus = Bus(clock = busFrequency)) + +system.toL2bus = Bus(clock = busFrequency) +system.l2 = L2(size = options.l2size, assoc = 8) + +# ---------------------- +# Connect the L2 cache and memory together +# ---------------------- + +system.physmem.port = system.membus.port +system.l2.cpu_side = system.toL2bus.port +system.l2.mem_side = system.membus.port + +# ---------------------- +# Connect the L2 cache and clusters together +# ---------------------- +for cluster in clusters: + cluster.l1.cpu_side = cluster.clusterbus.port + cluster.l1.mem_side = system.toL2bus.port + for cpu in cluster.cpus: + cpu.icache_port = cluster.clusterbus.port + cpu.dcache_port = cluster.clusterbus.port + cpu.mem = cluster.l1 + +# ---------------------- +# Define the root +# ---------------------- + +root = Root(system = system) + +# -------------------- +# Pick the correct Splash2 Benchmarks +# ==================== +if options.benchmark == 'Cholesky': + root.workload = Cholesky() +elif options.benchmark == 'FFT': + root.workload = FFT() +elif options.benchmark == 'LUContig': + root.workload = LU_contig() +elif options.benchmark == 'LUNoncontig': + root.workload = LU_noncontig() +elif options.benchmark == 'Radix': + root.workload = Radix() +elif options.benchmark == 'Barnes': + root.workload = Barnes() +elif options.benchmark == 'FMM': + root.workload = FMM() +elif options.benchmark == 'OceanContig': + root.workload = Ocean_contig() +elif options.benchmark == 'OceanNoncontig': + root.workload = Ocean_noncontig() +elif options.benchmark == 'Raytrace': + root.workload = Raytrace() +elif options.benchmark == 'WaterNSquared': + root.workload = Water_nsquared() +elif options.benchmark == 'WaterSpatial': + root.workload = Water_spatial() +else: + panic("The --benchmark environment variable was set to something" \ + +" improper.\nUse Cholesky, FFT, LUContig, LUNoncontig, Radix" \ + +", Barnes, FMM, OceanContig,\nOceanNoncontig, Raytrace," \ + +" WaterNSquared, or WaterSpatial\n") + +# -------------------- +# Assign the workload to the cpus +# ==================== + +for cluster in clusters: + for cpu in cluster.cpus: + cpu.workload = root.workload + +# ---------------------- +# Run the simulation +# ---------------------- + +if options.timing or options.detailed: + root.system.mem_mode = 'timing' + +# instantiate configuration +m5.instantiate(root) + +# simulate until program terminates +if options.maxtick: + exit_event = m5.simulate(options.maxtick) +else: + exit_event = m5.simulate(m5.MaxTick) + +print 'Exiting @ tick', m5.curTick(), 'because', exit_event.getCause() + diff --git a/configs/splash2/run.py b/configs/splash2/run.py index 7d56cb830..b162e0cc7 100644 --- a/configs/splash2/run.py +++ b/configs/splash2/run.py @@ -262,7 +262,7 @@ m5.instantiate(root) if options.maxtick: exit_event = m5.simulate(options.maxtick) else: - exit_event = m5.simulate(1000000000000) + exit_event = m5.simulate(m5.MaxTick) print 'Exiting @ tick', m5.curTick(), 'because', exit_event.getCause() diff --git a/src/SConscript b/src/SConscript index 385047f7f..9d54174ab 100644 --- a/src/SConscript +++ b/src/SConscript @@ -129,6 +129,7 @@ base_sources = Split(''' mem/cache/cache_builder.cc + python/swig/debug_wrap.cc python/swig/main_wrap.cc sim/builder.cc diff --git a/src/arch/alpha/interrupts.hh b/src/arch/alpha/interrupts.hh index a86fb2d7b..388ccacde 100644 --- a/src/arch/alpha/interrupts.hh +++ b/src/arch/alpha/interrupts.hh @@ -138,9 +138,8 @@ namespace AlphaISA } if (ipl && ipl > tc->readMiscReg(IPR_IPLR)) { -// assert(!newInfoSet); newIpl = ipl; - newSummary = newSummary; + newSummary = summary; newInfoSet = true; DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", tc->readMiscReg(IPR_IPLR), ipl, summary); diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc index 56342dbc5..f7d946e2e 100644 --- a/src/arch/alpha/linux/process.cc +++ b/src/arch/alpha/linux/process.cc @@ -576,6 +576,7 @@ AlphaLinuxProcess::AlphaLinuxProcess(const std::string &name, int stderr_fd, std::vector<std::string> &argv, std::vector<std::string> &envp, + const std::string &cwd, uint64_t _uid, uint64_t _euid, uint64_t _gid, @@ -583,7 +584,7 @@ AlphaLinuxProcess::AlphaLinuxProcess(const std::string &name, uint64_t _pid, uint64_t _ppid) : AlphaLiveProcess(name, objFile, system, stdin_fd, stdout_fd, - stderr_fd, argv, envp, _uid, _euid, _gid, _egid, _pid, _ppid), + stderr_fd, argv, envp, cwd, _uid, _euid, _gid, _egid, _pid, _ppid), Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)) { //init_regs->intRegFile[0] = 0; diff --git a/src/arch/alpha/linux/process.hh b/src/arch/alpha/linux/process.hh index b23904844..2076f6339 100644 --- a/src/arch/alpha/linux/process.hh +++ b/src/arch/alpha/linux/process.hh @@ -46,6 +46,7 @@ class AlphaLinuxProcess : public AlphaLiveProcess int stdin_fd, int stdout_fd, int stderr_fd, std::vector<std::string> &argv, std::vector<std::string> &envp, + const std::string &cwd, uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid, uint64_t _pid, uint64_t _ppid); diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc index 9e360e80f..85619e493 100644 --- a/src/arch/alpha/process.cc +++ b/src/arch/alpha/process.cc @@ -43,10 +43,11 @@ using namespace std; AlphaLiveProcess::AlphaLiveProcess(const std::string &nm, ObjectFile *objFile, System *_system, int stdin_fd, int stdout_fd, int stderr_fd, std::vector<std::string> &argv, std::vector<std::string> &envp, + const std::string &cwd, uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid, uint64_t _pid, uint64_t _ppid) : LiveProcess(nm, objFile, _system, stdin_fd, stdout_fd, stderr_fd, - argv, envp, _uid, _euid, _gid, _egid, _pid, _ppid) + argv, envp, cwd, _uid, _euid, _gid, _egid, _pid, _ppid) { brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize(); brk_point = roundUp(brk_point, VMPageSize); diff --git a/src/arch/alpha/process.hh b/src/arch/alpha/process.hh index c4aeb1885..8eede502a 100644 --- a/src/arch/alpha/process.hh +++ b/src/arch/alpha/process.hh @@ -47,6 +47,7 @@ class AlphaLiveProcess : public LiveProcess System *_system, int stdin_fd, int stdout_fd, int stderr_fd, std::vector<std::string> &argv, std::vector<std::string> &envp, + const std::string &cwd, uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid, uint64_t _pid, uint64_t _ppid); diff --git a/src/arch/alpha/tru64/process.cc b/src/arch/alpha/tru64/process.cc index 55b8ebf8b..a1f02b16c 100644 --- a/src/arch/alpha/tru64/process.cc +++ b/src/arch/alpha/tru64/process.cc @@ -581,11 +581,12 @@ AlphaTru64Process::AlphaTru64Process(const std::string &name, int stderr_fd, std::vector<std::string> &argv, std::vector<std::string> &envp, + const std::string &cwd, uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid, uint64_t _pid, uint64_t _ppid) : AlphaLiveProcess(name, objFile, system, stdin_fd, stdout_fd, - stderr_fd, argv, envp, _uid, _euid, _gid, _egid, _pid, _ppid), + stderr_fd, argv, envp, cwd, _uid, _euid, _gid, _egid, _pid, _ppid), Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)), Num_Mach_Syscall_Descs(sizeof(machSyscallDescs) / sizeof(SyscallDesc)) { diff --git a/src/arch/alpha/tru64/process.hh b/src/arch/alpha/tru64/process.hh index 23429dad3..f5643c0b9 100644 --- a/src/arch/alpha/tru64/process.hh +++ b/src/arch/alpha/tru64/process.hh @@ -45,6 +45,7 @@ class AlphaTru64Process : public AlphaLiveProcess int stdin_fd, int stdout_fd, int stderr_fd, std::vector<std::string> &argv, std::vector<std::string> &envp, + const std::string &cwd, uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid, uint64_t _pid, uint64_t _ppid); diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index d182cfa30..a847608d8 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -411,6 +411,7 @@ MipsLinuxProcess::MipsLinuxProcess(const std::string &name, int stderr_fd, std::vector<std::string> &argv, std::vector<std::string> &envp, + const std::string &cwd, uint64_t _uid, uint64_t _euid, uint64_t _gid, @@ -418,7 +419,7 @@ MipsLinuxProcess::MipsLinuxProcess(const std::string &name, uint64_t _pid, uint64_t _ppid) : MipsLiveProcess(name, objFile, system, stdin_fd, stdout_fd, stderr_fd, - argv, envp, _uid, _euid, _gid, _egid, _pid, _ppid), + argv, envp, cwd, _uid, _euid, _gid, _egid, _pid, _ppid), Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)) { } diff --git a/src/arch/mips/linux/process.hh b/src/arch/mips/linux/process.hh index 06f86379c..398e1cfc2 100644 --- a/src/arch/mips/linux/process.hh +++ b/src/arch/mips/linux/process.hh @@ -43,6 +43,7 @@ class MipsLinuxProcess : public MipsLiveProcess int stdin_fd, int stdout_fd, int stderr_fd, std::vector<std::string> &argv, std::vector<std::string> &envp, + const std::string &cwd, uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid, uint64_t _pid, uint64_t _ppid); diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc index 4bc91ca24..d1e6e27bf 100644 --- a/src/arch/mips/process.cc +++ b/src/arch/mips/process.cc @@ -44,10 +44,11 @@ using namespace MipsISA; MipsLiveProcess::MipsLiveProcess(const std::string &nm, ObjectFile *objFile, System *_system, int stdin_fd, int stdout_fd, int stderr_fd, std::vector<std::string> &argv, std::vector<std::string> &envp, + const std::string &cwd, uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid, uint64_t _pid, uint64_t _ppid) : LiveProcess(nm, objFile, _system, stdin_fd, stdout_fd, stderr_fd, - argv, envp, _uid, _euid, _gid, _egid, _pid, _ppid) + argv, envp, cwd, _uid, _euid, _gid, _egid, _pid, _ppid) { // Set up stack. On MIPS, stack starts at the top of kuseg // user address space. MIPS stack grows down from here diff --git a/src/arch/mips/process.hh b/src/arch/mips/process.hh index fb004375d..af85e8ee9 100644 --- a/src/arch/mips/process.hh +++ b/src/arch/mips/process.hh @@ -48,6 +48,7 @@ class MipsLiveProcess : public LiveProcess System *_system, int stdin_fd, int stdout_fd, int stderr_fd, std::vector<std::string> &argv, std::vector<std::string> &envp, + const std::string &cwd, uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid, uint64_t _pid, uint64_t _ppid); diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh index 0072f4184..70838d1ce 100644 --- a/src/arch/sparc/interrupts.hh +++ b/src/arch/sparc/interrupts.hh @@ -79,6 +79,11 @@ namespace SparcISA return NoFault; } + void updateIntrInfo(ThreadContext * tc) + { + + } + void serialize(std::ostream &os) { } diff --git a/src/arch/sparc/linux/process.cc b/src/arch/sparc/linux/process.cc index 44c893f2b..565975fe0 100644 --- a/src/arch/sparc/linux/process.cc +++ b/src/arch/sparc/linux/process.cc @@ -391,11 +391,12 @@ SparcLinuxProcess::SparcLinuxProcess(const std::string &name, int stderr_fd, std::vector<std::string> &argv, std::vector<std::string> &envp, + const std::string &cwd, uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid, uint64_t _pid, uint64_t _ppid) : SparcLiveProcess(name, objFile, system, - stdin_fd, stdout_fd, stderr_fd, argv, envp, + stdin_fd, stdout_fd, stderr_fd, argv, envp, cwd, _uid, _euid, _gid, _egid, _pid, _ppid), Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)) { diff --git a/src/arch/sparc/linux/process.hh b/src/arch/sparc/linux/process.hh index c758d5433..e212de973 100644 --- a/src/arch/sparc/linux/process.hh +++ b/src/arch/sparc/linux/process.hh @@ -49,6 +49,7 @@ class SparcLinuxProcess : public SparcLiveProcess int stdin_fd, int stdout_fd, int stderr_fd, std::vector<std::string> &argv, std::vector<std::string> &envp, + const std::string &cwd, uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid, uint64_t _pid, uint64_t _ppid); diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 11a799ccb..3efe4fc08 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -47,10 +47,11 @@ using namespace SparcISA; SparcLiveProcess::SparcLiveProcess(const std::string &nm, ObjectFile *objFile, System *_system, int stdin_fd, int stdout_fd, int stderr_fd, std::vector<std::string> &argv, std::vector<std::string> &envp, + const std::string &cwd, uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid, uint64_t _pid, uint64_t _ppid) : LiveProcess(nm, objFile, _system, stdin_fd, stdout_fd, stderr_fd, - argv, envp, _uid, _euid, _gid, _egid, _pid, _ppid) + argv, envp, cwd, _uid, _euid, _gid, _egid, _pid, _ppid) { // XXX all the below need to be updated for SPARC - Ali diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh index 2320810c7..1cf7ec224 100644 --- a/src/arch/sparc/process.hh +++ b/src/arch/sparc/process.hh @@ -64,6 +64,7 @@ class SparcLiveProcess : public LiveProcess System *_system, int stdin_fd, int stdout_fd, int stderr_fd, std::vector<std::string> &argv, std::vector<std::string> &envp, + const std::string &cwd, uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid, uint64_t _pid, uint64_t _ppid); diff --git a/src/arch/sparc/solaris/process.cc b/src/arch/sparc/solaris/process.cc index ff466c8e6..f9876bf00 100644 --- a/src/arch/sparc/solaris/process.cc +++ b/src/arch/sparc/solaris/process.cc @@ -329,6 +329,7 @@ SparcSolarisProcess::SparcSolarisProcess(const std::string &name, int stderr_fd, std::vector<std::string> &argv, std::vector<std::string> &envp, + const std::string &cwd, uint64_t _uid, uint64_t _euid, uint64_t _gid, @@ -336,7 +337,7 @@ SparcSolarisProcess::SparcSolarisProcess(const std::string &name, uint64_t _pid, uint64_t _ppid) : SparcLiveProcess(name, objFile, system, - stdin_fd, stdout_fd, stderr_fd, argv, envp, + stdin_fd, stdout_fd, stderr_fd, argv, envp, cwd, _uid, _euid, _gid, _egid, _pid, _ppid), Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)) { diff --git a/src/arch/sparc/solaris/process.hh b/src/arch/sparc/solaris/process.hh index 2cf329211..f65a60656 100644 --- a/src/arch/sparc/solaris/process.hh +++ b/src/arch/sparc/solaris/process.hh @@ -48,6 +48,7 @@ class SparcSolarisProcess : public SparcLiveProcess int stdin_fd, int stdout_fd, int stderr_fd, std::vector<std::string> &argv, std::vector<std::string> &envp, + const std::string &cwd, uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid, uint64_t _pid, uint64_t _ppid); diff --git a/src/base/misc.hh b/src/base/misc.hh index 87faf20e6..1c5720ce1 100644 --- a/src/base/misc.hh +++ b/src/base/misc.hh @@ -76,6 +76,19 @@ void __warn(const std::string&, cp::ArgList &, const char*, const char*, int); #define warn(args...) \ __warn__(args, cp::ArgListNull()) +// Only print the warning message the first time it is seen. This +// doesn't check the warning string itself, it just only lets one +// warning come from the statement. So, even if the arguments change +// and that would have resulted in a different warning message, +// subsequent messages would still be supressed. +#define warn_once(args...) do { \ + static bool once = false; \ + if (!once) { \ + __warn__(args, cp::ArgListNull()); \ + once = true; \ + } \ + } while (0) + // // assert() that prints out the current cycle // diff --git a/src/cpu/base.cc b/src/cpu/base.cc index 4c243a2e9..7cbbb0b96 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -97,11 +97,13 @@ CPUProgressEvent::description() #if FULL_SYSTEM BaseCPU::BaseCPU(Params *p) : MemObject(p->name), clock(p->clock), checkInterrupts(true), - params(p), number_of_threads(p->numberOfThreads), system(p->system) + params(p), number_of_threads(p->numberOfThreads), system(p->system), + phase(p->phase) #else BaseCPU::BaseCPU(Params *p) : MemObject(p->name), clock(p->clock), params(p), - number_of_threads(p->numberOfThreads), system(p->system) + number_of_threads(p->numberOfThreads), system(p->system), + phase(p->phase) #endif { // currentTick = curTick; @@ -257,8 +259,9 @@ BaseCPU::regStats() Tick BaseCPU::nextCycle() { - Tick next_tick = curTick + clock - 1; + Tick next_tick = curTick - phase + clock - 1; next_tick -= (next_tick % clock); + next_tick += phase; return next_tick; } @@ -266,11 +269,12 @@ Tick BaseCPU::nextCycle(Tick begin_tick) { Tick next_tick = begin_tick; + next_tick -= (next_tick % clock); + next_tick += phase; while (next_tick < curTick) next_tick += clock; - next_tick -= (next_tick % clock); assert(next_tick >= curTick); return next_tick; } diff --git a/src/cpu/base.hh b/src/cpu/base.hh index 788f77e3a..1d9b6a93b 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -153,6 +153,7 @@ class BaseCPU : public MemObject Tick functionTraceStart; System *system; int cpu_id; + Tick phase; #if FULL_SYSTEM Tick profile; @@ -209,6 +210,8 @@ class BaseCPU : public MemObject System *system; + Tick phase; + #if FULL_SYSTEM /** * Serialize this object to the given output stream. diff --git a/src/cpu/memtest/memtest.cc b/src/cpu/memtest/memtest.cc index 91e073cf0..180f41541 100644 --- a/src/cpu/memtest/memtest.cc +++ b/src/cpu/memtest/memtest.cc @@ -81,8 +81,13 @@ MemTest::CpuPort::recvFunctional(PacketPtr pkt) void MemTest::CpuPort::recvStatusChange(Status status) { - if (status == RangeChange) + if (status == RangeChange) { + if (!snoopRangeSent) { + snoopRangeSent = true; + sendStatusChange(Port::RangeChange); + } return; + } panic("MemTest doesn't expect recvStatusChange callback!"); } @@ -145,6 +150,9 @@ MemTest::MemTest(const string &name, // thread = new SimpleThread(NULL, 0, NULL, 0, mainMem); curTick = 0; + cachePort.snoopRangeSent = false; + funcPort.snoopRangeSent = true; + // Needs to be masked off once we know the block size. traceBlockAddr = _traceAddr; baseAddr1 = 0x100000; diff --git a/src/cpu/memtest/memtest.hh b/src/cpu/memtest/memtest.hh index 2694efd39..7bf34d827 100644 --- a/src/cpu/memtest/memtest.hh +++ b/src/cpu/memtest/memtest.hh @@ -100,6 +100,8 @@ class MemTest : public MemObject : Port(_name, _memtest), memtest(_memtest) { } + bool snoopRangeSent; + protected: virtual bool recvTiming(PacketPtr pkt); @@ -120,6 +122,8 @@ class MemTest : public MemObject CpuPort cachePort; CpuPort funcPort; + bool snoopRangeSent; + class MemTestSenderState : public Packet::SenderState { public: diff --git a/src/cpu/o3/alpha/cpu_builder.cc b/src/cpu/o3/alpha/cpu_builder.cc index 09ccc7f65..5a375a4b8 100644 --- a/src/cpu/o3/alpha/cpu_builder.cc +++ b/src/cpu/o3/alpha/cpu_builder.cc @@ -48,6 +48,7 @@ class DerivO3CPU : public AlphaO3CPU<AlphaSimpleImpl> BEGIN_DECLARE_SIM_OBJECT_PARAMS(DerivO3CPU) Param<int> clock; + Param<int> phase; Param<int> numThreads; Param<int> activity; @@ -158,6 +159,7 @@ END_DECLARE_SIM_OBJECT_PARAMS(DerivO3CPU) BEGIN_INIT_SIM_OBJECT_PARAMS(DerivO3CPU) INIT_PARAM(clock, "clock speed"), + INIT_PARAM_DFLT(phase, "clock phase", 0), INIT_PARAM(numThreads, "number of HW thread contexts"), INIT_PARAM_DFLT(activity, "Initial activity count", 0), diff --git a/src/cpu/o3/alpha/cpu_impl.hh b/src/cpu/o3/alpha/cpu_impl.hh index b2ef78360..98fd0699a 100644 --- a/src/cpu/o3/alpha/cpu_impl.hh +++ b/src/cpu/o3/alpha/cpu_impl.hh @@ -116,24 +116,6 @@ AlphaO3CPU<Impl>::AlphaO3CPU(Params *params) #if FULL_SYSTEM // Setup quiesce event. this->thread[i]->quiesceEvent = new EndQuiesceEvent(tc); - - Port *mem_port; - FunctionalPort *phys_port; - VirtualPort *virt_port; - phys_port = new FunctionalPort(csprintf("%s-%d-funcport", - name(), i)); - mem_port = this->system->physmem->getPort("functional"); - mem_port->setPeer(phys_port); - phys_port->setPeer(mem_port); - - virt_port = new VirtualPort(csprintf("%s-%d-vport", - name(), i)); - mem_port = this->system->physmem->getPort("functional"); - mem_port->setPeer(virt_port); - virt_port->setPeer(mem_port); - - this->thread[i]->setPhysPort(phys_port); - this->thread[i]->setVirtPort(virt_port); #endif // Give the thread the TC. this->thread[i]->tc = tc; diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 580816372..3dc353a9f 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -497,6 +497,8 @@ FullO3CPU<Impl>::init() } #if FULL_SYSTEM + src_tc->init(); + TheISA::initCPU(src_tc, src_tc->readCpuId()); #endif } diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh index cc9a8abf5..04016347a 100644 --- a/src/cpu/o3/fetch.hh +++ b/src/cpu/o3/fetch.hh @@ -83,6 +83,8 @@ class DefaultFetch : Port(_fetch->name() + "-iport"), fetch(_fetch) { } + bool snoopRangeSent; + protected: /** Atomic version of receive. Panics. */ virtual Tick recvAtomic(PacketPtr pkt); diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index 25faa407e..63d22b293 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -70,8 +70,13 @@ template<class Impl> void DefaultFetch<Impl>::IcachePort::recvStatusChange(Status status) { - if (status == RangeChange) + if (status == RangeChange) { + if (!snoopRangeSent) { + snoopRangeSent = true; + sendStatusChange(Port::RangeChange); + } return; + } panic("DefaultFetch doesn't expect recvStatusChange callback!"); } @@ -287,6 +292,8 @@ DefaultFetch<Impl>::setCPU(O3CPU *cpu_ptr) // Name is finally available, so create the port. icachePort = new IcachePort(this); + icachePort->snoopRangeSent = false; + #if USE_CHECKER if (cpu->checker) { cpu->checker->setIcachePort(icachePort); diff --git a/src/cpu/o3/lsq.hh b/src/cpu/o3/lsq.hh index 6b12d75b4..7559a36d5 100644 --- a/src/cpu/o3/lsq.hh +++ b/src/cpu/o3/lsq.hh @@ -298,6 +298,8 @@ class LSQ { : lsq(_lsq) { } + bool snoopRangeSent; + protected: /** Atomic version of receive. Panics. */ virtual Tick recvAtomic(PacketPtr pkt); diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh index 5e7945c1c..6758e51c8 100644 --- a/src/cpu/o3/lsq_impl.hh +++ b/src/cpu/o3/lsq_impl.hh @@ -53,9 +53,13 @@ template <class Impl> void LSQ<Impl>::DcachePort::recvStatusChange(Status status) { - if (status == RangeChange) + if (status == RangeChange) { + if (!snoopRangeSent) { + snoopRangeSent = true; + sendStatusChange(Port::RangeChange); + } return; - + } panic("O3CPU doesn't expect recvStatusChange callback!"); } @@ -97,6 +101,8 @@ LSQ<Impl>::LSQ(Params *params) { DPRINTF(LSQ, "Creating LSQ object.\n"); + dcachePort.snoopRangeSent = false; + //**********************************************/ //************ Handle SMT Parameters ***********/ //**********************************************/ diff --git a/src/cpu/o3/mips/cpu_builder.cc b/src/cpu/o3/mips/cpu_builder.cc index ee9f2b48d..66741aee9 100644 --- a/src/cpu/o3/mips/cpu_builder.cc +++ b/src/cpu/o3/mips/cpu_builder.cc @@ -49,6 +49,7 @@ class DerivO3CPU : public MipsO3CPU<MipsSimpleImpl> BEGIN_DECLARE_SIM_OBJECT_PARAMS(DerivO3CPU) Param<int> clock; +Param<int> phase; Param<int> numThreads; Param<int> activity; @@ -146,6 +147,7 @@ END_DECLARE_SIM_OBJECT_PARAMS(DerivO3CPU) BEGIN_INIT_SIM_OBJECT_PARAMS(DerivO3CPU) INIT_PARAM(clock, "clock speed"), + INIT_PARAM_DFLT(phase, "clock phase", 0), INIT_PARAM(numThreads, "number of HW thread contexts"), INIT_PARAM_DFLT(activity, "Initial activity count", 0), diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh index daee2fc7d..031f36480 100755 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@ -91,6 +91,8 @@ class O3ThreadContext : public ThreadContext virtual VirtualPort *getVirtPort(ThreadContext *src_tc = NULL); void delVirtPort(VirtualPort *vp); + + virtual void init() { thread->init(); } #else virtual TranslatingPort *getMemPort() { return thread->getMemPort(); } diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh index 8d623f5b8..0180756e3 100755 --- a/src/cpu/o3/thread_context_impl.hh +++ b/src/cpu/o3/thread_context_impl.hh @@ -41,12 +41,9 @@ O3ThreadContext<Impl>::getVirtPort(ThreadContext *src_tc) return thread->getVirtPort(); VirtualPort *vp; - Port *mem_port; vp = new VirtualPort("tc-vport", src_tc); - mem_port = cpu->system->physmem->getPort("functional"); - mem_port->setPeer(vp); - vp->setPeer(mem_port); + thread->connectToMemFunc(vp); return vp; } diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 58dc1fe5f..cd335e36d 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -77,6 +77,9 @@ AtomicSimpleCPU::init() for (int i = 0; i < threadContexts.size(); ++i) { ThreadContext *tc = threadContexts[i]; + // initialize the mem pointers + tc->init(); + // initialize CPU, including PC TheISA::initCPU(tc, tc->readCpuId()); } @@ -94,7 +97,7 @@ Tick AtomicSimpleCPU::CpuPort::recvAtomic(PacketPtr pkt) { //Snooping a coherence request, just return - return curTick; + return 0; } void @@ -107,8 +110,13 @@ AtomicSimpleCPU::CpuPort::recvFunctional(PacketPtr pkt) void AtomicSimpleCPU::CpuPort::recvStatusChange(Status status) { - if (status == RangeChange) + if (status == RangeChange) { + if (!snoopRangeSent) { + snoopRangeSent = true; + sendStatusChange(Port::RangeChange); + } return; + } panic("AtomicSimpleCPU doesn't expect recvStatusChange callback!"); } @@ -127,6 +135,9 @@ AtomicSimpleCPU::AtomicSimpleCPU(Params *p) { _status = Idle; + icachePort.snoopRangeSent = false; + dcachePort.snoopRangeSent = false; + ifetch_req = new Request(); ifetch_req->setThreadContext(p->cpu_id, 0); // Add thread ID if we add MT ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast); @@ -512,6 +523,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AtomicSimpleCPU) #endif // FULL_SYSTEM Param<int> clock; + Param<int> phase; Param<bool> defer_registration; Param<int> width; @@ -547,6 +559,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AtomicSimpleCPU) #endif // FULL_SYSTEM INIT_PARAM(clock, "clock speed"), + INIT_PARAM_DFLT(phase, "clock phase", 0), INIT_PARAM(defer_registration, "defer system registration (for sampling)"), INIT_PARAM(width, "cpu width"), INIT_PARAM(function_trace, "Enable function trace"), @@ -567,6 +580,7 @@ CREATE_SIM_OBJECT(AtomicSimpleCPU) params->max_loads_all_threads = max_loads_all_threads; params->progress_interval = progress_interval; params->deferRegistration = defer_registration; + params->phase = phase; params->clock = clock; params->functionTrace = function_trace; params->functionTraceStart = function_trace_start; diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh index 166a18127..0df6fe079 100644 --- a/src/cpu/simple/atomic.hh +++ b/src/cpu/simple/atomic.hh @@ -90,6 +90,8 @@ class AtomicSimpleCPU : public BaseSimpleCPU : Port(_name, _cpu), cpu(_cpu) { } + bool snoopRangeSent; + protected: virtual bool recvTiming(PacketPtr pkt); diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index db2c940c0..aa23a00e8 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -59,6 +59,9 @@ TimingSimpleCPU::init() for (int i = 0; i < threadContexts.size(); ++i) { ThreadContext *tc = threadContexts[i]; + // initialize the mem pointers + tc->init(); + // initialize CPU, including PC TheISA::initCPU(tc, tc->readCpuId()); } @@ -82,8 +85,13 @@ TimingSimpleCPU::CpuPort::recvFunctional(PacketPtr pkt) void TimingSimpleCPU::CpuPort::recvStatusChange(Status status) { - if (status == RangeChange) + if (status == RangeChange) { + if (!snoopRangeSent) { + snoopRangeSent = true; + sendStatusChange(Port::RangeChange); + } return; + } panic("TimingSimpleCPU doesn't expect recvStatusChange callback!"); } @@ -101,6 +109,10 @@ TimingSimpleCPU::TimingSimpleCPU(Params *p) cpu_id(p->cpu_id) { _status = Idle; + + icachePort.snoopRangeSent = false; + dcachePort.snoopRangeSent = false; + ifetch_pkt = dcache_pkt = NULL; drainEvent = NULL; fetchEvent = NULL; @@ -160,7 +172,7 @@ TimingSimpleCPU::resume() fetchEvent = new EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch>(this, false); - fetchEvent->schedule(curTick); + fetchEvent->schedule(nextCycle()); } changeState(SimObject::Running); @@ -232,7 +244,7 @@ TimingSimpleCPU::activateContext(int thread_num, int delay) // kick things off by initiating the fetch of the next instruction fetchEvent = new EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch>(this, false); - fetchEvent->schedule(curTick + cycles(delay)); + fetchEvent->schedule(nextCycle(curTick + cycles(delay))); } @@ -281,6 +293,8 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags) // memory system takes ownership of packet dcache_pkt = NULL; } + } else { + delete req; } // This will need a new way to tell if it has a dcache attached. @@ -366,6 +380,8 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) dcache_pkt = NULL; } } + } else { + delete req; } // This will need a new way to tell if it's hooked up to a cache or not. @@ -448,6 +464,8 @@ TimingSimpleCPU::fetch() ifetch_pkt = NULL; } } else { + delete ifetch_req; + delete ifetch_pkt; // fetch fault: advance directly to next instruction (fault handler) advanceInst(fault); } @@ -481,13 +499,13 @@ TimingSimpleCPU::completeIfetch(PacketPtr pkt) _status = Running; - delete pkt->req; - delete pkt; - numCycles += curTick - previousTick; previousTick = curTick; if (getState() == SimObject::Draining) { + delete pkt->req; + delete pkt; + completeDrain(); return; } @@ -519,6 +537,9 @@ TimingSimpleCPU::completeIfetch(PacketPtr pkt) postExecute(); advanceInst(fault); } + + delete pkt->req; + delete pkt; } void @@ -674,6 +695,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(TimingSimpleCPU) #endif // FULL_SYSTEM Param<int> clock; + Param<int> phase; Param<bool> defer_registration; Param<int> width; @@ -709,6 +731,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(TimingSimpleCPU) #endif // FULL_SYSTEM INIT_PARAM(clock, "clock speed"), + INIT_PARAM_DFLT(phase, "clock phase", 0), INIT_PARAM(defer_registration, "defer system registration (for sampling)"), INIT_PARAM(width, "cpu width"), INIT_PARAM(function_trace, "Enable function trace"), @@ -730,6 +753,7 @@ CREATE_SIM_OBJECT(TimingSimpleCPU) params->progress_interval = progress_interval; params->deferRegistration = defer_registration; params->clock = clock; + params->phase = phase; params->functionTrace = function_trace; params->functionTraceStart = function_trace_start; params->system = system; diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh index 408fa315e..fe5d03666 100644 --- a/src/cpu/simple/timing.hh +++ b/src/cpu/simple/timing.hh @@ -82,6 +82,8 @@ class TimingSimpleCPU : public BaseSimpleCPU : Port(_name, _cpu), cpu(_cpu), lat(_lat) { } + bool snoopRangeSent; + protected: virtual Tick recvAtomic(PacketPtr pkt); @@ -166,8 +168,6 @@ class TimingSimpleCPU : public BaseSimpleCPU PacketPtr ifetch_pkt; PacketPtr dcache_pkt; - - int cpu_id; Tick previousTick; diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc index 1edcbf352..13d0e2e29 100644 --- a/src/cpu/simple_thread.cc +++ b/src/cpu/simple_thread.cc @@ -91,18 +91,6 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys, } else { kernelStats = NULL; } - Port *mem_port; - physPort = new FunctionalPort(csprintf("%s-%d-funcport", - cpu->name(), tid)); - mem_port = system->physmem->getPort("functional"); - mem_port->setPeer(physPort); - physPort->setPeer(mem_port); - - virtPort = new VirtualPort(csprintf("%s-%d-vport", - cpu->name(), tid)); - mem_port = system->physmem->getPort("functional"); - mem_port->setPeer(virtPort); - virtPort->setPeer(mem_port); } #else SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, @@ -309,10 +297,7 @@ SimpleThread::getVirtPort(ThreadContext *src_tc) return virtPort; VirtualPort *vp = new VirtualPort("tc-vport", src_tc); - Port *mem_port = getMemFuncPort(); - - mem_port->setPeer(vp); - vp->setPeer(mem_port); + connectToMemFunc(vp); return vp; } diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh index 1e6a907f8..baeb7a8be 100644 --- a/src/cpu/thread_context.hh +++ b/src/cpu/thread_context.hh @@ -133,6 +133,8 @@ class ThreadContext virtual VirtualPort *getVirtPort(ThreadContext *tc = NULL) = 0; virtual void delVirtPort(VirtualPort *vp) = 0; + + virtual void init() = 0; #else virtual TranslatingPort *getMemPort() = 0; @@ -305,6 +307,8 @@ class ProxyThreadContext : public ThreadContext VirtualPort *getVirtPort(ThreadContext *tc = NULL) { return actualTC->getVirtPort(tc); } void delVirtPort(VirtualPort *vp) { return actualTC->delVirtPort(vp); } + + void init() {actualTC->init(); } #else TranslatingPort *getMemPort() { return actualTC->getMemPort(); } diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc index 8602f8a50..9cac4fd26 100644 --- a/src/cpu/thread_state.cc +++ b/src/cpu/thread_state.cc @@ -39,6 +39,7 @@ #if FULL_SYSTEM #include "arch/kernel_stats.hh" #include "cpu/quiesce_event.hh" +#include "mem/vport.hh" #endif #if FULL_SYSTEM @@ -111,6 +112,28 @@ ThreadState::unserialize(Checkpoint *cp, const std::string §ion) } #if FULL_SYSTEM +void +ThreadState::init() +{ + initPhysPort(); + initVirtPort(); +} + +void +ThreadState::initPhysPort() +{ + physPort = new FunctionalPort(csprintf("%s-%d-funcport", + baseCpu->name(), tid)); + connectToMemFunc(physPort); +} + +void +ThreadState::initVirtPort() +{ + virtPort = new VirtualPort(csprintf("%s-%d-vport", + baseCpu->name(), tid)); + connectToMemFunc(virtPort); +} void ThreadState::profileClear() @@ -138,17 +161,14 @@ ThreadState::getMemPort() baseCpu->name(), tid), process->pTable, false); - Port *func_port = getMemFuncPort(); - - func_port->setPeer(port); - port->setPeer(func_port); + connectToMemFunc(port); return port; } #endif -Port * -ThreadState::getMemFuncPort() +void +ThreadState::connectToMemFunc(Port *port) { Port *dcache_port, *func_mem_port; @@ -161,5 +181,6 @@ ThreadState::getMemFuncPort() func_mem_port = mem_object->getPort("functional"); assert(func_mem_port != NULL); - return func_mem_port; + func_mem_port->setPeer(port); + port->setPeer(func_mem_port); } diff --git a/src/cpu/thread_state.hh b/src/cpu/thread_state.hh index 0a0af8b71..1844be8b7 100644 --- a/src/cpu/thread_state.hh +++ b/src/cpu/thread_state.hh @@ -91,6 +91,12 @@ struct ThreadState { Tick readLastSuspend() { return lastSuspend; } #if FULL_SYSTEM + void init(); + + void initPhysPort(); + + void initVirtPort(); + void dumpFuncProfile(); EndQuiesceEvent *getQuiesceEvent() { return quiesceEvent; } @@ -141,12 +147,11 @@ struct ThreadState { /** Sets the status of this thread. */ void setStatus(Status new_status) { _status = new_status; } - protected: - /** Gets a functional port from the memory object that's connected - * to the CPU. */ - Port *getMemFuncPort(); - public: + /** Connects port to the functional port of the memory object + * below the CPU. */ + void connectToMemFunc(Port *port); + /** Number of instructions committed. */ Counter numInst; /** Stat for number instructions committed. */ diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc index 38dcfd2e8..b787f79ca 100644 --- a/src/mem/bridge.cc +++ b/src/mem/bridge.cc @@ -91,10 +91,16 @@ Bridge::init() bool Bridge::BridgePort::recvTiming(PacketPtr pkt) { - DPRINTF(BusBridge, "recvTiming: src %d dest %d addr 0x%x\n", - pkt->getSrc(), pkt->getDest(), pkt->getAddr()); + if (pkt->flags & SNOOP_COMMIT) { + DPRINTF(BusBridge, "recvTiming: src %d dest %d addr 0x%x\n", + pkt->getSrc(), pkt->getDest(), pkt->getAddr()); - return otherPort->queueForSendTiming(pkt); + return otherPort->queueForSendTiming(pkt); + } + else { + // Else it's just a snoop, properly return if we are blocking + return !queueFull(); + } } diff --git a/src/mem/bus.cc b/src/mem/bus.cc index 8ea67a0e4..6b5b63f50 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -160,11 +160,12 @@ Bus::recvTiming(PacketPtr pkt) short dest = pkt->getDest(); if (dest == Packet::Broadcast) { - if (timingSnoop(pkt)) { + port = findPort(pkt->getAddr(), pkt->getSrc()); + if (timingSnoop(pkt, port ? port : interfaces[pkt->getSrc()])) { bool success; pkt->flags |= SNOOP_COMMIT; - success = timingSnoop(pkt); + success = timingSnoop(pkt, port ? port : interfaces[pkt->getSrc()]); assert(success); if (pkt->flags & SATISFIED) { @@ -177,7 +178,6 @@ Bus::recvTiming(PacketPtr pkt) occupyBus(pkt); return true; } - port = findPort(pkt->getAddr(), pkt->getSrc()); } else { //Snoop didn't succeed DPRINTF(Bus, "Adding a retry to RETRY list %i\n", pktPort); @@ -192,22 +192,28 @@ Bus::recvTiming(PacketPtr pkt) occupyBus(pkt); - if (port->sendTiming(pkt)) { - // Packet was successfully sent. Return true. - // Also take care of retries - if (inRetry) { - DPRINTF(Bus, "Remove retry from list %i\n", retryList.front()); - retryList.front()->onRetryList(false); - retryList.pop_front(); - inRetry = false; + if (port) { + if (port->sendTiming(pkt)) { + // Packet was successfully sent. Return true. + // Also take care of retries + if (inRetry) { + DPRINTF(Bus, "Remove retry from list %i\n", retryList.front()); + retryList.front()->onRetryList(false); + retryList.pop_front(); + inRetry = false; + } + return true; } + + // Packet not successfully sent. Leave or put it on the retry list. + DPRINTF(Bus, "Adding a retry to RETRY list %i\n", pktPort); + addToRetryList(pktPort); + return false; + } + else { + //Forwarding up from responder, just return true; return true; } - - // Packet not successfully sent. Leave or put it on the retry list. - DPRINTF(Bus, "Adding a retry to RETRY list %i\n", pktPort); - addToRetryList(pktPort); - return false; } void @@ -290,7 +296,10 @@ Bus::findPort(Addr addr, int id) // we shouldn't be sending this back to where it came from - assert(dest_id != id); + // only on a functional access and then we should terminate + // the cyclical call. + if (dest_id == id) + return 0; return interfaces[dest_id]; } @@ -307,7 +316,18 @@ Bus::findSnoopPorts(Addr addr, int id) if (portSnoopList[i].range == addr && portSnoopList[i].portId != id) { //Careful to not overlap ranges //or snoop will be called more than once on the port - ports.push_back(portSnoopList[i].portId); + + //@todo Fix this hack because ranges are overlapping + //need to make sure we dont't create overlapping ranges + bool hack_overlap = false; + int size = ports.size(); + for (int j=0; j < size; j++) { + if (ports[j] == portSnoopList[i].portId) + hack_overlap = true; + } + + if (!hack_overlap) + ports.push_back(portSnoopList[i].portId); // DPRINTF(Bus, " found snoop addr %#llx on device%d\n", addr, // portSnoopList[i].portId); } @@ -317,17 +337,19 @@ Bus::findSnoopPorts(Addr addr, int id) } Tick -Bus::atomicSnoop(PacketPtr pkt) +Bus::atomicSnoop(PacketPtr pkt, Port *responder) { std::vector<int> ports = findSnoopPorts(pkt->getAddr(), pkt->getSrc()); Tick response_time = 0; while (!ports.empty()) { - Tick response = interfaces[ports.back()]->sendAtomic(pkt); - if (response) { - assert(!response_time); //Multiple responders - response_time = response; + if (interfaces[ports.back()] != responder) { + Tick response = interfaces[ports.back()]->sendAtomic(pkt); + if (response) { + assert(!response_time); //Multiple responders + response_time = response; + } } ports.pop_back(); } @@ -335,26 +357,31 @@ Bus::atomicSnoop(PacketPtr pkt) } void -Bus::functionalSnoop(PacketPtr pkt) +Bus::functionalSnoop(PacketPtr pkt, Port *responder) { std::vector<int> ports = findSnoopPorts(pkt->getAddr(), pkt->getSrc()); + //The packet may be changed by another bus on snoops, restore the id after each + int id = pkt->getSrc(); while (!ports.empty() && pkt->result != Packet::Success) { - interfaces[ports.back()]->sendFunctional(pkt); + if (interfaces[ports.back()] != responder) + interfaces[ports.back()]->sendFunctional(pkt); ports.pop_back(); + pkt->setSrc(id); } } bool -Bus::timingSnoop(PacketPtr pkt) +Bus::timingSnoop(PacketPtr pkt, Port* responder) { std::vector<int> ports = findSnoopPorts(pkt->getAddr(), pkt->getSrc()); bool success = true; while (!ports.empty() && success) { - success = interfaces[ports.back()]->sendTiming(pkt); + if (interfaces[ports.back()] != responder) //Don't call if responder also, once will do + success = interfaces[ports.back()]->sendTiming(pkt); ports.pop_back(); } @@ -370,15 +397,21 @@ Bus::recvAtomic(PacketPtr pkt) DPRINTF(Bus, "recvAtomic: packet src %d dest %d addr 0x%x cmd %s\n", pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString()); assert(pkt->getDest() == Packet::Broadcast); + pkt->flags |= SNOOP_COMMIT; // Assume one bus cycle in order to get through. This may have // some clock skew issues yet again... pkt->finishTime = curTick + clock; - Tick snoopTime = atomicSnoop(pkt); + + Port *port = findPort(pkt->getAddr(), pkt->getSrc()); + Tick snoopTime = atomicSnoop(pkt, port ? port : interfaces[pkt->getSrc()]); + if (snoopTime) return snoopTime; //Snoop satisfies it + else if (port) + return port->sendAtomic(pkt); else - return findPort(pkt->getAddr(), pkt->getSrc())->sendAtomic(pkt); + return 0; } /** Function called by the port when the bus is receiving a Functional @@ -389,11 +422,15 @@ Bus::recvFunctional(PacketPtr pkt) DPRINTF(Bus, "recvFunctional: packet src %d dest %d addr 0x%x cmd %s\n", pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString()); assert(pkt->getDest() == Packet::Broadcast); - functionalSnoop(pkt); + pkt->flags |= SNOOP_COMMIT; + + Port* port = findPort(pkt->getAddr(), pkt->getSrc()); + functionalSnoop(pkt, port ? port : interfaces[pkt->getSrc()]); // If the snooping found what we were looking for, we're done. - if (pkt->result != Packet::Success) - findPort(pkt->getAddr(), pkt->getSrc())->sendFunctional(pkt); + if (pkt->result != Packet::Success && port) { + port->sendFunctional(pkt); + } } /** Function called by the port when the bus is receiving a status change.*/ @@ -451,6 +488,7 @@ Bus::recvStatusChange(Port::Status status, int id) dm.portId = id; dm.range = *iter; + //@todo, make sure we don't overlap ranges DPRINTF(BusAddrRanges, "Adding snoop range %#llx - %#llx for id %d\n", dm.range.start, dm.range.end, id); portSnoopList.push_back(dm); @@ -493,7 +531,7 @@ Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id) for (dflt_iter = defaultRange.begin(); dflt_iter != defaultRange.end(); dflt_iter++) { resp.push_back(*dflt_iter); - DPRINTF(BusAddrRanges, " -- %#llx : %#llx\n",dflt_iter->start, + DPRINTF(BusAddrRanges, " -- Dflt: %#llx : %#llx\n",dflt_iter->start, dflt_iter->end); } for (portIter = portList.begin(); portIter != portList.end(); portIter++) { @@ -519,6 +557,18 @@ Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id) portIter->range.start, portIter->range.end); } } + + for (portIter = portSnoopList.begin(); + portIter != portSnoopList.end(); portIter++) + { + if (portIter->portId != id) { + snoop.push_back(portIter->range); + DPRINTF(BusAddrRanges, " -- Snoop: %#llx : %#llx\n", + portIter->range.start, portIter->range.end); + //@todo We need to properly insert snoop ranges + //not overlapping the ranges (multiple) + } + } } unsigned int diff --git a/src/mem/bus.hh b/src/mem/bus.hh index ff1d2545d..c472b6143 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -109,16 +109,16 @@ class Bus : public MemObject std::vector<int> findSnoopPorts(Addr addr, int id); /** Snoop all relevant ports atomicly. */ - Tick atomicSnoop(PacketPtr pkt); + Tick atomicSnoop(PacketPtr pkt, Port* responder); /** Snoop all relevant ports functionally. */ - void functionalSnoop(PacketPtr pkt); + void functionalSnoop(PacketPtr pkt, Port *responder); /** Call snoop on caches, be sure to set SNOOP_COMMIT bit if you want * the snoop to happen * @return True if succeds. */ - bool timingSnoop(PacketPtr pkt); + bool timingSnoop(PacketPtr pkt, Port *responder); /** Process address range request. * @param resp addresses that we can respond to diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc index c16cb6945..3af61375d 100644 --- a/src/mem/cache/base_cache.cc +++ b/src/mem/cache/base_cache.cc @@ -160,11 +160,14 @@ BaseCache::CachePort::recvRetry() PacketPtr pkt; assert(waitingOnRetry); if (!drainList.empty()) { - DPRINTF(CachePort, "%s attempting to send a retry for response\n", name()); + DPRINTF(CachePort, "%s attempting to send a retry for response (%i waiting)\n" + , name(), drainList.size()); //We have some responses to drain first - if (sendTiming(drainList.front())) { - DPRINTF(CachePort, "%s sucessful in sending a retry for response\n", name()); - drainList.pop_front(); + pkt = drainList.front(); + drainList.pop_front(); + if (sendTiming(pkt)) { + DPRINTF(CachePort, "%s sucessful in sending a retry for" + "response (%i still waiting)\n", name(), drainList.size()); if (!drainList.empty() || !isCpuSide && cache->doMasterRequest() || isCpuSide && cache->doSlaveRequest()) { @@ -175,6 +178,9 @@ BaseCache::CachePort::recvRetry() } waitingOnRetry = false; } + else { + drainList.push_front(pkt); + } // Check if we're done draining once this list is empty if (drainList.empty()) cache->checkDrain(); diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh index 584c2d5df..ef4955432 100644 --- a/src/mem/cache/base_cache.hh +++ b/src/mem/cache/base_cache.hh @@ -144,8 +144,6 @@ class BaseCache : public MemObject protected: CachePort *memSidePort; - bool snoopRangesSent; - public: virtual Port *getPort(const std::string &if_name, int idx = -1); @@ -171,10 +169,6 @@ class BaseCache : public MemObject if (status == Port::RangeChange){ if (!isCpuSide) { cpuSidePort->sendStatusChange(Port::RangeChange); - if (!snoopRangesSent) { - snoopRangesSent = true; - memSidePort->sendStatusChange(Port::RangeChange); - } } else { memSidePort->sendStatusChange(Port::RangeChange); @@ -358,7 +352,6 @@ class BaseCache : public MemObject //Start ports at null if more than one is created we should panic cpuSidePort = NULL; memSidePort = NULL; - snoopRangesSent = false; } ~BaseCache() diff --git a/src/mem/cache/miss/miss_queue.cc b/src/mem/cache/miss/miss_queue.cc index fe467a8ea..3c4586272 100644 --- a/src/mem/cache/miss/miss_queue.cc +++ b/src/mem/cache/miss/miss_queue.cc @@ -612,6 +612,8 @@ MissQueue::handleResponse(PacketPtr &pkt, Tick time) if (mshr->hasTargets()) { // Didn't satisfy all the targets, need to resend Packet::Command cmd = mshr->getTarget()->cmd; + mshr->pkt->setDest(Packet::Broadcast); + mshr->pkt->result = Packet::Unknown; mq.markPending(mshr, cmd); mshr->order = order++; cache->setMasterRequest(Request_MSHR, time); diff --git a/src/mem/packet.hh b/src/mem/packet.hh index 2bc51bf12..19251941f 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -301,7 +301,7 @@ class Packet /** Destructor. */ ~Packet() - { deleteData(); } + { if (staticData || dynamicData) deleteData(); } /** Reinitialize packet address and size from the associated * Request object, and reset other fields that may have been diff --git a/src/python/SConscript b/src/python/SConscript index 5c351c32a..be6248bab 100644 --- a/src/python/SConscript +++ b/src/python/SConscript @@ -98,11 +98,17 @@ pyzip_files.append('m5/defines.py') pyzip_files.append('m5/info.py') pyzip_files.append(join(env['ROOT'], 'util/pbs/jobfile.py')) +env.Command(['swig/debug_wrap.cc', 'm5/internal/debug.py'], + 'swig/debug.i', + '$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} ' + '-o ${TARGETS[0]} $SOURCES') + env.Command(['swig/main_wrap.cc', 'm5/internal/main.py'], 'swig/main.i', '$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} ' '-o ${TARGETS[0]} $SOURCES') +pyzip_dep_files.append('m5/internal/debug.py') pyzip_dep_files.append('m5/internal/main.py') # Action function to build the zip archive. Uses the PyZipFile module diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 1e224c0cf..114c668a6 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -275,7 +275,8 @@ def main(): objects.Statistics.text_file = options.stats_file # set debugging options - objects.Debug.break_cycles = options.debug_break + for when in options.debug_break: + internal.debug.schedBreakCycle(int(when)) # set tracing options objects.Trace.flags = options.trace_flags diff --git a/src/python/m5/objects/BaseCPU.py b/src/python/m5/objects/BaseCPU.py index 2f702a4bf..8037c90af 100644 --- a/src/python/m5/objects/BaseCPU.py +++ b/src/python/m5/objects/BaseCPU.py @@ -47,6 +47,7 @@ class BaseCPU(SimObject): "defer registration with system (for sampling)") clock = Param.Clock(Parent.clock, "clock speed") + phase = Param.Latency("0ns", "clock phase") _mem_ports = [] diff --git a/src/python/m5/objects/Process.py b/src/python/m5/objects/Process.py index 771ad4101..79268e6f4 100644 --- a/src/python/m5/objects/Process.py +++ b/src/python/m5/objects/Process.py @@ -12,6 +12,7 @@ class LiveProcess(Process): executable = Param.String('', "executable (overrides cmd[0] if set)") cmd = VectorParam.String("command line (executable plus arguments)") env = VectorParam.String('', "environment settings") + cwd = Param.String('', "current working directory") input = Param.String('cin', "filename for stdin") uid = Param.Int(100, 'user id') euid = Param.Int(100, 'effective user id') diff --git a/src/python/m5/objects/Root.py b/src/python/m5/objects/Root.py index 8e8d87f6d..b6123f192 100644 --- a/src/python/m5/objects/Root.py +++ b/src/python/m5/objects/Root.py @@ -5,7 +5,6 @@ from Serialize import Statreset from Statistics import Statistics from Trace import Trace from ExeTrace import ExecutionTrace -from Debug import Debug class Root(SimObject): type = 'Root' @@ -22,4 +21,3 @@ class Root(SimObject): trace = Trace() exetrace = ExecutionTrace() serialize = Serialize() - debug = Debug() diff --git a/src/python/swig/debug.i b/src/python/swig/debug.i new file mode 100644 index 000000000..8da2974ca --- /dev/null +++ b/src/python/swig/debug.i @@ -0,0 +1,19 @@ +%module debug + +%{ +// include these files when compiling debug_wrap.cc +#include "sim/host.hh" +%} + +%include "stdint.i" +%include "sim/host.hh" + +%inline %{ +extern void schedBreakCycle(Tick when); +%} + +%wrapper %{ +// fix up module name to reflect the fact that it's inside the m5 package +#undef SWIG_name +#define SWIG_name "m5.internal._debug" +%} diff --git a/src/sim/debug.cc b/src/sim/debug.cc index be9566836..84ab1074d 100644 --- a/src/sim/debug.cc +++ b/src/sim/debug.cc @@ -94,45 +94,17 @@ DebugBreakEvent::description() } // -// Parameter context for global debug options -// -class DebugContext : public ParamContext -{ - public: - DebugContext(const string &_iniSection) - : ParamContext(_iniSection) {} - void checkParams(); -}; - -DebugContext debugParams("debug"); - -VectorParam<Tick> break_cycles(&debugParams, "break_cycles", - "cycle(s) to create breakpoint events"); - -void -DebugContext::checkParams() -{ - if (break_cycles.isValid()) { - vector<Tick> &cycles = break_cycles; - - vector<Tick>::iterator i = cycles.begin(); - vector<Tick>::iterator end = cycles.end(); - - for (; i < end; ++i) - new DebugBreakEvent(&mainEventQueue, *i); - } -} - -// // handy function to schedule DebugBreakEvent on main event queue // (callable from debugger) // -void sched_break_cycle(Tick when) +void +schedBreakCycle(Tick when) { new DebugBreakEvent(&mainEventQueue, when); } -void eventq_dump() +void +eventqDump() { mainEventQueue.dump(); } diff --git a/src/sim/main.cc b/src/sim/main.cc index 6037283a4..17209ac20 100644 --- a/src/sim/main.cc +++ b/src/sim/main.cc @@ -119,6 +119,7 @@ abortHandler(int sigtype) extern "C" { void init_main(); +void init_debug(); } int @@ -157,8 +158,9 @@ main(int argc, char **argv) Py_Initialize(); PySys_SetArgv(argc, argv); - // initialize SWIG 'm5.internal.main' module + // initialize SWIG modules init_main(); + init_debug(); PyRun_SimpleString("import m5.main"); PyRun_SimpleString("m5.main.main()"); diff --git a/src/sim/process.cc b/src/sim/process.cc index f3e289d41..b43fa7d00 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -314,11 +314,12 @@ LiveProcess::LiveProcess(const string &nm, ObjectFile *_objFile, System *_system, int stdin_fd, int stdout_fd, int stderr_fd, vector<string> &_argv, vector<string> &_envp, + const string &_cwd, uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid, uint64_t _pid, uint64_t _ppid) : Process(nm, _system, stdin_fd, stdout_fd, stderr_fd), - objFile(_objFile), argv(_argv), envp(_envp) + objFile(_objFile), argv(_argv), envp(_envp), cwd(_cwd) { __uid = _uid; __euid = _euid; @@ -427,6 +428,7 @@ LiveProcess::create(const std::string &nm, System *system, int stdin_fd, int stdout_fd, int stderr_fd, std::string executable, std::vector<std::string> &argv, std::vector<std::string> &envp, + const std::string &cwd, uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid, uint64_t _pid, uint64_t _ppid) @@ -445,14 +447,14 @@ LiveProcess::create(const std::string &nm, System *system, int stdin_fd, case ObjectFile::Tru64: process = new AlphaTru64Process(nm, objFile, system, stdin_fd, stdout_fd, stderr_fd, - argv, envp, + argv, envp, cwd, _uid, _euid, _gid, _egid, _pid, _ppid); break; case ObjectFile::Linux: process = new AlphaLinuxProcess(nm, objFile, system, stdin_fd, stdout_fd, stderr_fd, - argv, envp, + argv, envp, cwd, _uid, _euid, _gid, _egid, _pid, _ppid); break; @@ -466,7 +468,7 @@ LiveProcess::create(const std::string &nm, System *system, int stdin_fd, case ObjectFile::Linux: process = new SparcLinuxProcess(nm, objFile, system, stdin_fd, stdout_fd, stderr_fd, - argv, envp, + argv, envp, cwd, _uid, _euid, _gid, _egid, _pid, _ppid); break; @@ -474,7 +476,7 @@ LiveProcess::create(const std::string &nm, System *system, int stdin_fd, case ObjectFile::Solaris: process = new SparcSolarisProcess(nm, objFile, system, stdin_fd, stdout_fd, stderr_fd, - argv, envp, + argv, envp, cwd, _uid, _euid, _gid, _egid, _pid, _ppid); break; default: @@ -487,7 +489,7 @@ LiveProcess::create(const std::string &nm, System *system, int stdin_fd, case ObjectFile::Linux: process = new MipsLinuxProcess(nm, objFile, system, stdin_fd, stdout_fd, stderr_fd, - argv, envp, + argv, envp, cwd, _uid, _euid, _gid, _egid, _pid, _ppid); break; @@ -512,6 +514,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(LiveProcess) Param<string> input; Param<string> output; VectorParam<string> env; + Param<string> cwd; SimObjectParam<System *> system; Param<uint64_t> uid; Param<uint64_t> euid; @@ -530,6 +533,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(LiveProcess) INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"), INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"), INIT_PARAM(env, "environment settings"), + INIT_PARAM(cwd, "current working directory"), INIT_PARAM(system, "system"), INIT_PARAM(uid, "user id"), INIT_PARAM(euid, "effective user id"), @@ -566,7 +570,7 @@ CREATE_SIM_OBJECT(LiveProcess) return LiveProcess::create(getInstanceName(), system, stdin_fd, stdout_fd, stderr_fd, (string)executable == "" ? cmd[0] : executable, - cmd, env, + cmd, env, cwd, uid, euid, gid, egid, pid, ppid); } diff --git a/src/sim/process.hh b/src/sim/process.hh index 5c37f725e..616c02c00 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -177,11 +177,13 @@ class LiveProcess : public Process ObjectFile *objFile; std::vector<std::string> argv; std::vector<std::string> envp; + std::string cwd; LiveProcess(const std::string &nm, ObjectFile *objFile, System *_system, int stdin_fd, int stdout_fd, int stderr_fd, std::vector<std::string> &argv, std::vector<std::string> &envp, + const std::string &cwd, uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid, uint64_t _pid, uint64_t _ppid); @@ -207,6 +209,20 @@ class LiveProcess : public Process inline uint64_t pid() {return __pid;} inline uint64_t ppid() {return __ppid;} + std::string + fullPath(const std::string &filename) + { + if (filename[0] == '/' || cwd.empty()) + return filename; + + std::string full = cwd; + + if (cwd[cwd.size() - 1] != '/') + full += '/'; + + return full + filename; + } + virtual void syscall(int64_t callnum, ThreadContext *tc); virtual SyscallDesc* getDesc(int callnum) = 0; @@ -220,6 +236,7 @@ class LiveProcess : public Process std::string executable, std::vector<std::string> &argv, std::vector<std::string> &envp, + const std::string &cwd, uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid, uint64_t _pid, uint64_t _ppid); diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index 9028d590b..ab44c0a35 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -214,6 +214,9 @@ unlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) return (TheISA::IntReg)-EFAULT; + // Adjust path for current working directory + path = p->fullPath(path); + int result = unlink(path.c_str()); return (result == -1) ? -errno : result; } @@ -231,6 +234,10 @@ renameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) if (!tc->getMemPort()->tryReadString(new_name, tc->getSyscallArg(1))) return -EFAULT; + // Adjust path for current working directory + old_name = p->fullPath(old_name); + new_name = p->fullPath(new_name); + int64_t result = rename(old_name.c_str(), new_name.c_str()); return (result == -1) ? -errno : result; } @@ -245,6 +252,9 @@ truncateFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) off_t length = tc->getSyscallArg(1); + // Adjust path for current working directory + path = p->fullPath(path); + int result = truncate(path.c_str(), length); return (result == -1) ? -errno : result; } @@ -277,6 +287,9 @@ chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) uint32_t group = tc->getSyscallArg(2); gid_t hostGroup = group; + // Adjust path for current working directory + path = p->fullPath(path); + int result = chown(path.c_str(), hostOwner, hostGroup); return (result == -1) ? -errno : result; } diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index e79712a19..27356c9f1 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -500,6 +500,9 @@ openFunc(SyscallDesc *desc, int callnum, LiveProcess *process, hostFlags |= O_BINARY; #endif + // Adjust path for current working directory + path = process->fullPath(path); + DPRINTF(SyscallVerbose, "opening file %s\n", path.c_str()); // open the file @@ -526,6 +529,9 @@ chmodFunc(SyscallDesc *desc, int callnum, LiveProcess *process, // XXX translate mode flags via OS::something??? hostMode = mode; + // Adjust path for current working directory + path = process->fullPath(path); + // do the chmod int result = chmod(path.c_str(), hostMode); if (result < 0) @@ -573,6 +579,9 @@ statFunc(SyscallDesc *desc, int callnum, LiveProcess *process, if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) return -EFAULT; + // Adjust path for current working directory + path = process->fullPath(path); + struct stat hostBuf; int result = stat(path.c_str(), &hostBuf); @@ -626,6 +635,9 @@ lstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process, if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) return -EFAULT; + // Adjust path for current working directory + path = process->fullPath(path); + struct stat hostBuf; int result = lstat(path.c_str(), &hostBuf); @@ -648,6 +660,9 @@ lstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process, if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) return -EFAULT; + // Adjust path for current working directory + path = process->fullPath(path); + #if NO_STAT64 struct stat hostBuf; int result = lstat(path.c_str(), &hostBuf); @@ -701,6 +716,9 @@ statfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process, if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) return -EFAULT; + // Adjust path for current working directory + path = process->fullPath(path); + struct statfs hostBuf; int result = statfs(path.c_str(), &hostBuf); @@ -896,6 +914,10 @@ utimesFunc(SyscallDesc *desc, int callnum, LiveProcess *process, hostTimeval[i].tv_sec = gtoh((*tp)[i].tv_sec); hostTimeval[i].tv_usec = gtoh((*tp)[i].tv_usec); } + + // Adjust path for current working directory + path = process->fullPath(path); + int result = utimes(path.c_str(), hostTimeval); if (result < 0) @@ -912,17 +934,8 @@ getrusageFunc(SyscallDesc *desc, int callnum, LiveProcess *process, int who = tc->getSyscallArg(0); // THREAD, SELF, or CHILDREN TypedBufferArg<typename OS::rusage> rup(tc->getSyscallArg(1)); - if (who != OS::TGT_RUSAGE_SELF) { - // don't really handle THREAD or CHILDREN, but just warn and - // plow ahead - warn("getrusage() only supports RUSAGE_SELF. Parameter %d ignored.", - who); - } - - getElapsedTime(rup->ru_utime.tv_sec, rup->ru_utime.tv_usec); - rup->ru_utime.tv_sec = htog(rup->ru_utime.tv_sec); - rup->ru_utime.tv_usec = htog(rup->ru_utime.tv_usec); - + rup->ru_utime.tv_sec = 0; + rup->ru_utime.tv_usec = 0; rup->ru_stime.tv_sec = 0; rup->ru_stime.tv_usec = 0; rup->ru_maxrss = 0; @@ -940,6 +953,24 @@ getrusageFunc(SyscallDesc *desc, int callnum, LiveProcess *process, rup->ru_nvcsw = 0; rup->ru_nivcsw = 0; + switch (who) { + case OS::TGT_RUSAGE_SELF: + getElapsedTime(rup->ru_utime.tv_sec, rup->ru_utime.tv_usec); + rup->ru_utime.tv_sec = htog(rup->ru_utime.tv_sec); + rup->ru_utime.tv_usec = htog(rup->ru_utime.tv_usec); + break; + + case OS::TGT_RUSAGE_CHILDREN: + // do nothing. We have no child processes, so they take no time. + break; + + default: + // don't really handle THREAD or CHILDREN, but just warn and + // plow ahead + warn("getrusage() only supports RUSAGE_SELF. Parameter %d ignored.", + who); + } + rup.copyOut(tc->getMemPort()); return 0; diff --git a/tests/long/00.gzip/test.py b/tests/long/00.gzip/test.py index 5c33376bd..06ccb656b 100644 --- a/tests/long/00.gzip/test.py +++ b/tests/long/00.gzip/test.py @@ -26,6 +26,8 @@ # # Authors: Korey Sewell -process = LiveProcess(executable = binpath('gzip')) -process.cmd = 'gzip ' + inputpath('gzip', 'smred.log') + ' 1' -root.system.cpu.workload = process +m5.AddToPath('../configs/common') +from cpu2000 import gzip_log + +workload = gzip_log('alpha', 'tru64', 'smred') +root.system.cpu.workload = workload.makeLiveProcess() diff --git a/tests/long/10.mcf/test.py b/tests/long/10.mcf/test.py index 36d077c96..f545aad3d 100644 --- a/tests/long/10.mcf/test.py +++ b/tests/long/10.mcf/test.py @@ -26,6 +26,8 @@ # # Authors: Korey Sewell -process = LiveProcess(executable = binpath('mcf')) -process.cmd = 'mcf' + inputpath('mcf', 'lgred.in') -root.system.cpu.workload = process +m5.AddToPath('../configs/common') +from cpu2000 import mcf + +workload = mcf('alpha', 'tru64', 'lgred') +root.system.cpu.workload = workload.makeLiveProcess() diff --git a/tests/long/20.parser/test.py b/tests/long/20.parser/test.py index 760908722..8703ae634 100644 --- a/tests/long/20.parser/test.py +++ b/tests/long/20.parser/test.py @@ -26,7 +26,8 @@ # # Authors: Korey Sewell -process = LiveProcess(executable = binpath('parser')) -process.cmd = 'parser 2.1.dict -batch' -process.input = inputpath('parser', 'lgred.in') -root.system.cpu.workload = process +m5.AddToPath('../configs/common') +from cpu2000 import parser + +workload = parser('alpha', 'tru64', 'lgred') +root.system.cpu.workload = workload.makeLiveProcess() diff --git a/tests/long/30.eon/test.py b/tests/long/30.eon/test.py index d6bf3bb76..828b6390c 100644 --- a/tests/long/30.eon/test.py +++ b/tests/long/30.eon/test.py @@ -26,10 +26,8 @@ # # Authors: Korey Sewell -process = LiveProcess(executable = binpath('eon')) -process.cmd = 'eon' + inputpath('eon', 'chair.control.cook') + \ - inputpath('eon', 'chair.camera') + \ - inputpath('eon', 'chair.surfaces') + \ - inputpath('eon', 'chair.cook.ppm') + 'ppm' \ - + 'pixels_out.cook' -root.system.cpu.workload = process +m5.AddToPath('../configs/common') +from cpu2000 import eon_cook + +workload = eon_cook('alpha', 'tru64', 'mdred') +root.system.cpu.workload = workload.makeLiveProcess() diff --git a/tests/long/40.perlbmk/test.py b/tests/long/40.perlbmk/test.py index 81c36bab3..2f9dd0ff0 100644 --- a/tests/long/40.perlbmk/test.py +++ b/tests/long/40.perlbmk/test.py @@ -26,6 +26,8 @@ # # Authors: Korey Sewell -process = LiveProcess(executable = binpath('perlbmk')) -process.cmd = 'perlbmk -I./lib' + inputpath('perlbmk', 'lgred.makerand.pl') -root.system.cpu.workload = process +m5.AddToPath('../configs/common') +from cpu2000 import perlbmk_makerand + +workload = perlbmk_makerand('alpha', 'tru64', 'lgred') +root.system.cpu.workload = workload.makeLiveProcess() diff --git a/tests/long/50.vortex/test.py b/tests/long/50.vortex/test.py index f6d1e03df..bd57ef6e6 100644 --- a/tests/long/50.vortex/test.py +++ b/tests/long/50.vortex/test.py @@ -26,6 +26,8 @@ # # Authors: Korey Sewell -process = LiveProcess(executable = binpath('vortex')) -process.cmd = 'vortex' + inputpath('smred.raw') -root.system.cpu.workload = process +m5.AddToPath('../configs/common') +from cpu2000 import vortex + +workload = vortex('alpha', 'tru64', 'smred') +root.system.cpu.workload = workload.makeLiveProcess() diff --git a/tests/long/60.bzip2/test.py b/tests/long/60.bzip2/test.py index e96d64656..362ca524e 100644 --- a/tests/long/60.bzip2/test.py +++ b/tests/long/60.bzip2/test.py @@ -26,6 +26,8 @@ # # Authors: Korey Sewell -process = LiveProcess(executable = binpath('bzip2')) -process.cmd = cmd = 'bzip2' + inputpath('bzip2', 'lgred.source') -root.system.cpu.workload = process +m5.AddToPath('../configs/common') +from cpu2000 import bzip2_source + +workload = bzip2_source('alpha', 'tru64', 'lgred') +root.system.cpu.workload = workload.makeLiveProcess() diff --git a/tests/long/70.twolf/test.py b/tests/long/70.twolf/test.py index be7a04f97..c105a17e2 100644 --- a/tests/long/70.twolf/test.py +++ b/tests/long/70.twolf/test.py @@ -26,6 +26,8 @@ # # Authors: Korey Sewell -process = LiveProcess(executable = binpath('twolf')) -process.cmd = 'twolf' + inputpath('twolf', 'smred/smred') -root.system.cpu.workload = process +m5.AddToPath('../configs/common') +from cpu2000 import twolf + +workload = twolf('alpha', 'tru64', 'smred') +root.system.cpu.workload = workload.makeLiveProcess() |