summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2009-04-06 10:19:36 -0700
committerGabe Black <gblack@eecs.umich.edu>2009-04-06 10:19:36 -0700
commitd080581db1f9ee4e1e6d07d2b01c13c67908a391 (patch)
treecc484b289fa5a30c4631f9faa1d8b456bffeebfc /util
parent7a7c4c5fca83a8d47c7e71c9c080a882ebe204a9 (diff)
parent639cb0a42d953ee32bc7e96b0cdfa96cd40e9fc1 (diff)
downloadgem5-d080581db1f9ee4e1e6d07d2b01c13c67908a391.tar.xz
Merge ARM into the head. ARM will compile but may not actually work.
Diffstat (limited to 'util')
-rw-r--r--util/batch/jobfile.py539
-rw-r--r--util/m5/Makefile.x86 (renamed from util/stats/orderdict.py)63
-rw-r--r--util/m5/m5.c317
-rw-r--r--util/m5/m5op.h26
-rw-r--r--util/m5/m5op_alpha.S180
-rw-r--r--util/m5/m5op_x86.S66
-rw-r--r--util/m5/m5ops.h68
-rw-r--r--util/mkblankimage.sh219
-rw-r--r--util/pbs/jobfile.py539
-rw-r--r--util/style.py79
-rw-r--r--util/term/term.c65
-rwxr-xr-xutil/tracediff71
12 files changed, 779 insertions, 1453 deletions
diff --git a/util/batch/jobfile.py b/util/batch/jobfile.py
deleted file mode 100644
index b78d7f3e1..000000000
--- a/util/batch/jobfile.py
+++ /dev/null
@@ -1,539 +0,0 @@
-# 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: Kevin Lim
-
-import sys
-
-class ternary(object):
- def __new__(cls, *args):
- if len(args) > 1:
- raise TypeError, \
- '%s() takes at most 1 argument (%d given)' % \
- (cls.__name__, len(args))
-
- if args:
- if not isinstance(args[0], (bool, ternary)):
- raise TypeError, \
- '%s() argument must be True, False, or Any' % \
- cls.__name__
- return args[0]
- return super(ternary, cls).__new__(cls)
-
- def __bool__(self):
- return True
-
- def __neg__(self):
- return self
-
- def __eq__(self, other):
- return True
-
- def __ne__(self, other):
- return False
-
- def __str__(self):
- return 'Any'
-
- def __repr__(self):
- return 'Any'
-
-Any = ternary()
-
-class Flags(dict):
- def __init__(self, *args, **kwargs):
- super(Flags, self).__init__()
- self.update(*args, **kwargs)
-
- def __getattr__(self, attr):
- return self[attr]
-
- def __setattr__(self, attr, value):
- self[attr] = value
-
- def __setitem__(self, item, value):
- return super(Flags, self).__setitem__(item, ternary(value))
-
- def __getitem__(self, item):
- if item not in self:
- return False
- return super(Flags, self).__getitem__(item)
-
- def update(self, *args, **kwargs):
- for arg in args:
- if isinstance(arg, Flags):
- super(Flags, self).update(arg)
- elif isinstance(arg, dict):
- for key,val in kwargs.iteritems():
- self[key] = val
- else:
- raise AttributeError, \
- 'flags not of type %s or %s, but %s' % \
- (Flags, dict, type(arg))
-
- for key,val in kwargs.iteritems():
- self[key] = val
-
- def match(self, *args, **kwargs):
- match = Flags(*args, **kwargs)
-
- for key,value in match.iteritems():
- if self[key] != value:
- return False
-
- return True
-
-def crossproduct(items):
- if not isinstance(items, (list, tuple)):
- raise AttributeError, 'crossproduct works only on sequences'
-
- if not items:
- yield None
- return
-
- current = items[0]
- remainder = items[1:]
-
- if not hasattr(current, '__iter__'):
- current = [ current ]
-
- for item in current:
- for rem in crossproduct(remainder):
- data = [ item ]
- if rem:
- data += rem
- yield data
-
-def flatten(items):
- if not isinstance(items, (list, tuple)):
- yield items
- return
-
- for item in items:
- for flat in flatten(item):
- yield flat
-
-class Data(object):
- def __init__(self, name, desc, **kwargs):
- self.name = name
- self.desc = desc
- self.system = None
- self.flags = Flags()
- self.env = {}
- for k,v in kwargs.iteritems():
- setattr(self, k, v)
-
- def update(self, obj):
- if not isinstance(obj, Data):
- raise AttributeError, "can only update from Data object"
-
- self.env.update(obj.env)
- self.flags.update(obj.flags)
- if obj.system:
- if self.system and self.system != obj.system:
- raise AttributeError, \
- "conflicting values for system: '%s'/'%s'" % \
- (self.system, obj.system)
- self.system = obj.system
-
- def printinfo(self):
- if self.name:
- print 'name: %s' % self.name
- if self.desc:
- print 'desc: %s' % self.desc
- if self.system:
- print 'system: %s' % self.system
-
- def printverbose(self):
- print 'flags:'
- keys = self.flags.keys()
- keys.sort()
- for key in keys:
- print ' %s = %s' % (key, self.flags[key])
- print 'env:'
- keys = self.env.keys()
- keys.sort()
- for key in keys:
- print ' %s = %s' % (key, self.env[key])
- print
-
- def __str__(self):
- return self.name
-
-class Job(Data):
- def __init__(self, options):
- super(Job, self).__init__('', '')
- self.setoptions(options)
-
- self.checkpoint = False
- opts = []
- for opt in options:
- cpt = opt.group.checkpoint
- if not cpt:
- self.checkpoint = True
- continue
- if isinstance(cpt, Option):
- opt = cpt.clone(suboptions=False)
- else:
- opt = opt.clone(suboptions=False)
-
- opts.append(opt)
-
- if not opts:
- self.checkpoint = False
-
- if self.checkpoint:
- self.checkpoint = Job(opts)
-
- def clone(self):
- return Job(self.options)
-
- def __getattribute__(self, attr):
- if attr == 'name':
- names = [ ]
- for opt in self.options:
- if opt.name:
- names.append(opt.name)
- return ':'.join(names)
-
- if attr == 'desc':
- descs = [ ]
- for opt in self.options:
- if opt.desc:
- descs.append(opt.desc)
- return ', '.join(descs)
-
- return super(Job, self).__getattribute__(attr)
-
- def setoptions(self, options):
- config = options[0].config
- for opt in options:
- if opt.config != config:
- raise AttributeError, \
- "All options are not from the same Configuration"
-
- self.config = config
- self.groups = [ opt.group for opt in options ]
- self.options = options
-
- self.update(self.config)
- for group in self.groups:
- self.update(group)
-
- for option in self.options:
- self.update(option)
- if option._suboption:
- self.update(option._suboption)
-
- def printinfo(self):
- super(Job, self).printinfo()
- if self.checkpoint:
- print 'checkpoint: %s' % self.checkpoint.name
- print 'config: %s' % self.config.name
- print 'groups: %s' % [ g.name for g in self.groups ]
- print 'options: %s' % [ o.name for o in self.options ]
- super(Job, self).printverbose()
-
-class SubOption(Data):
- def __init__(self, name, desc, **kwargs):
- super(SubOption, self).__init__(name, desc, **kwargs)
- self.number = None
-
-class Option(Data):
- def __init__(self, name, desc, **kwargs):
- super(Option, self).__init__(name, desc, **kwargs)
- self._suboptions = []
- self._suboption = None
- self.number = None
-
- def __getattribute__(self, attr):
- if attr == 'name':
- name = self.__dict__[attr]
- if self._suboption is not None:
- name = '%s:%s' % (name, self._suboption.name)
- return name
-
- if attr == 'desc':
- desc = [ self.__dict__[attr] ]
- if self._suboption is not None and self._suboption.desc:
- desc.append(self._suboption.desc)
- return ', '.join(desc)
-
-
- return super(Option, self).__getattribute__(attr)
-
- def suboption(self, name, desc, **kwargs):
- subo = SubOption(name, desc, **kwargs)
- subo.config = self.config
- subo.group = self.group
- subo.option = self
- subo.number = len(self._suboptions)
- self._suboptions.append(subo)
- return subo
-
- def clone(self, suboptions=True):
- option = Option(self.__dict__['name'], self.__dict__['desc'])
- option.update(self)
- option.group = self.group
- option.config = self.config
- option.number = self.number
- if suboptions:
- option._suboptions.extend(self._suboptions)
- option._suboption = self._suboption
- return option
-
- def subopts(self):
- if not self._suboptions:
- return [ self ]
-
- subopts = []
- for subo in self._suboptions:
- option = self.clone()
- option._suboption = subo
- subopts.append(option)
-
- return subopts
-
- def printinfo(self):
- super(Option, self).printinfo()
- print 'config: %s' % self.config.name
- super(Option, self).printverbose()
-
-class Group(Data):
- def __init__(self, name, desc, **kwargs):
- super(Group, self).__init__(name, desc, **kwargs)
- self._options = []
- self.checkpoint = False
- self.number = None
-
- def option(self, name, desc, **kwargs):
- opt = Option(name, desc, **kwargs)
- opt.config = self.config
- opt.group = self
- opt.number = len(self._options)
- self._options.append(opt)
- return opt
-
- def options(self):
- return self._options
-
- def subopts(self):
- subopts = []
- for opt in self._options:
- for subo in opt.subopts():
- subopts.append(subo)
- return subopts
-
- def printinfo(self):
- super(Group, self).printinfo()
- print 'config: %s' % self.config.name
- print 'options: %s' % [ o.name for o in self._options ]
- super(Group, self).printverbose()
-
-class Configuration(Data):
- def __init__(self, name, desc, **kwargs):
- super(Configuration, self).__init__(name, desc, **kwargs)
- self._groups = []
- self._posfilters = []
- self._negfilters = []
-
- def group(self, name, desc, **kwargs):
- grp = Group(name, desc, **kwargs)
- grp.config = self
- grp.number = len(self._groups)
- self._groups.append(grp)
- return grp
-
- def groups(self, flags=Flags(), sign=True):
- if not flags:
- return self._groups
-
- return [ grp for grp in self._groups if sign ^ grp.flags.match(flags) ]
-
- def checkchildren(self, kids):
- for kid in kids:
- if kid.config != self:
- raise AttributeError, "child from the wrong configuration"
-
- def sortgroups(self, groups):
- groups = [ (grp.number, grp) for grp in groups ]
- groups.sort()
- return [ grp[1] for grp in groups ]
-
- def options(self, groups = None, checkpoint = False):
- if groups is None:
- groups = self._groups
- self.checkchildren(groups)
- groups = self.sortgroups(groups)
- if checkpoint:
- groups = [ grp for grp in groups if grp.checkpoint ]
- optgroups = [ g.options() for g in groups ]
- else:
- optgroups = [ g.subopts() for g in groups ]
- for options in crossproduct(optgroups):
- for opt in options:
- cpt = opt.group.checkpoint
- if not isinstance(cpt, bool) and cpt != opt:
- if checkpoint:
- break
- else:
- yield options
- else:
- if checkpoint:
- yield options
-
- def addfilter(self, filt, pos=True):
- import re
- filt = re.compile(filt)
- if pos:
- self._posfilters.append(filt)
- else:
- self._negfilters.append(filt)
-
- def jobfilter(self, job):
- for filt in self._negfilters:
- if filt.match(job.name):
- return False
-
- if not self._posfilters:
- return True
-
- for filt in self._posfilters:
- if filt.match(job.name):
- return True
-
- return False
-
- def checkpoints(self, groups = None):
- for options in self.options(groups, True):
- job = Job(options)
- if self.jobfilter(job):
- yield job
-
- def jobs(self, groups = None):
- for options in self.options(groups, False):
- job = Job(options)
- if self.jobfilter(job):
- yield job
-
- def alljobs(self, groups = None):
- for options in self.options(groups, True):
- yield Job(options)
- for options in self.options(groups, False):
- yield Job(options)
-
- def find(self, jobname):
- for job in self.alljobs():
- if job.name == jobname:
- return job
- else:
- raise AttributeError, "job '%s' not found" % jobname
-
- def job(self, options):
- self.checkchildren(options)
- options = [ (opt.group.number, opt) for opt in options ]
- options.sort()
- options = [ opt[1] for opt in options ]
- job = Job(options)
- return job
-
- def printinfo(self):
- super(Configuration, self).printinfo()
- print 'groups: %s' % [ g.name for g in self._grouips ]
- super(Configuration, self).printverbose()
-
-def JobFile(jobfile):
- from os.path import expanduser, isfile, join as joinpath
- filename = expanduser(jobfile)
-
- # Can't find filename in the current path, search sys.path
- if not isfile(filename):
- for path in sys.path:
- testname = joinpath(path, filename)
- if isfile(testname):
- filename = testname
- break
- else:
- raise AttributeError, \
- "Could not find file '%s'" % jobfile
-
- data = {}
- execfile(filename, data)
- if 'conf' not in data:
- raise ImportError, 'cannot import name conf from %s' % jobfile
- conf = data['conf']
- import jobfile
- if not isinstance(conf, Configuration):
- raise AttributeError, \
- 'conf in jobfile: %s (%s) is not type %s' % \
- (jobfile, type(conf), Configuration)
- return conf
-
-if __name__ == '__main__':
- from jobfile import *
- import sys
-
- usage = 'Usage: %s [-b] [-c] [-v] <jobfile>' % sys.argv[0]
-
- try:
- import getopt
- opts, args = getopt.getopt(sys.argv[1:], '-bcv')
- except getopt.GetoptError:
- sys.exit(usage)
-
- if len(args) != 1:
- raise AttributeError, usage
-
- both = False
- checkpoint = False
- verbose = False
- for opt,arg in opts:
- if opt == '-b':
- both = True
- checkpoint = True
- if opt == '-c':
- checkpoint = True
- if opt == '-v':
- verbose = True
-
- jobfile = args[0]
- conf = JobFile(jobfile)
-
- if both:
- gen = conf.alljobs()
- elif checkpoint:
- gen = conf.checkpoints()
- else:
- gen = conf.jobs()
-
- for job in gen:
- if not verbose:
- cpt = ''
- if job.checkpoint:
- cpt = job.checkpoint.name
- print job.name, cpt
- else:
- job.printinfo()
diff --git a/util/stats/orderdict.py b/util/m5/Makefile.x86
index 3f755d299..e2d5d3722 100644
--- a/util/stats/orderdict.py
+++ b/util/m5/Makefile.x86
@@ -1,4 +1,4 @@
-# Copyright (c) 2005 The Regents of The University of Michigan
+# Copyright (c) 2005-2006 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -25,56 +25,25 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Nathan Binkert
+# Ali Saidi
-__all__ = [ 'orderdict' ]
+CC=gcc
+AS=as
+LD=ld
-class orderdict(dict):
- def __init__(self, d = {}):
- self._keys = d.keys()
- super(orderdict, self).__init__(d)
+CFLAGS=-O2
+OBJS=m5.o m5op_x86.o
- def __setitem__(self, key, item):
- super(orderdict, self).__setitem__(key, item)
- if not hasattr(self, '_keys'):
- self._keys = [key,]
- if key not in self._keys:
- self._keys.append(key)
+all: m5
- def __delitem__(self, key):
- super(orderdict, self).__delitem__(key)
- self._keys.remove(key)
+%.o: %.S
+ $(CC) $(CFLAGS) -o $@ -c $<
- def clear(self):
- super(orderdict, self).clear()
- self._keys = []
+%.o: %.c
+ $(CC) $(CFLAGS) -o $@ -c $<
- def items(self):
- for i in self._keys:
- yield i, self[i]
+m5: $(OBJS)
+ $(CC) -o $@ $(OBJS)
- def keys(self):
- return self._keys
-
- def popitem(self):
- if len(self._keys) == 0:
- raise KeyError('dictionary is empty')
- else:
- key = self._keys[-1]
- val = self[key]
- del self[key]
- return key, val
-
- def setdefault(self, key, failobj = None):
- super(orderdict, self).setdefault(key, failobj)
- if key not in self._keys:
- self._keys.append(key)
-
- def update(self, d):
- for key in d.keys():
- if not self.has_key(key):
- self._keys.append(key)
- super(orderdict, self).update(d)
-
- def values(self):
- for i in self._keys:
- yield self[i]
+clean:
+ rm -f *.o m5
diff --git a/util/m5/m5.c b/util/m5/m5.c
index b103796a8..7747fc0bc 100644
--- a/util/m5/m5.c
+++ b/util/m5/m5.c
@@ -28,7 +28,14 @@
* Authors: Nathan Binkert
*/
+#ifdef linux
+#define _GNU_SOURCE
+#include <sched.h>
+#endif
+
#include <inttypes.h>
+#include <err.h>
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -37,154 +44,220 @@
#include "m5op.h"
char *progname;
+char *command = "unspecified";
+void usage();
void
-usage()
+parse_int_args(int argc, char *argv[], uint64_t ints[], int len)
{
- printf("usage: m5 initparam\n"
- " m5 sw99param\n"
- " m5 exit [delay]\n"
- " m5 resetstats [delay [period]]\n"
- " m5 dumpstats [delay [period]]\n"
- " m5 dumpresetstats [delay [period]]\n"
- " m5 checkpoint [delay [period]]\n"
- " m5 readfile\n"
- "\n"
- "All times in nanoseconds!\n");
- exit(1);
-}
+ if (argc > len)
+ usage();
-#define COMPARE(X) (strcmp(X, command) == 0)
+ int i;
+ for (i = 0; i < len; ++i)
+ ints[i] = (i < argc) ? strtoul(argv[i], NULL, 0) : 0;
+}
int
-main(int argc, char *argv[])
+read_file(int dest_fid)
{
- char *command;
- uint64_t param;
- uint64_t arg1 = 0;
- uint64_t arg2 = 0;
+ char buf[256*1024];
+ int offset = 0;
+ int len;
- progname = argv[0];
- if (argc < 2)
+ while ((len = m5_readfile(buf, sizeof(buf), offset)) > 0) {
+ write(dest_fid, buf, len);
+ offset += len;
+ }
+}
+
+void
+do_exit(int argc, char *argv[])
+{
+ if (argc > 1)
usage();
- command = argv[1];
+ m5_exit((argc > 0) ? strtoul(argv[0], NULL, 0) : 0);
+}
- if (COMPARE("initparam")) {
- if (argc != 2)
- usage();
+void
+do_reset_stats(int argc, char *argv[])
+{
+ uint64_t ints[2];
+ parse_int_args(argc, argv, ints, 2);
+ m5_reset_stats(ints[0], ints[1]);
+}
- printf("%ld", m5_initparam());
- return 0;
- }
+void
+do_dump_stats(int argc, char *argv[])
+{
+ uint64_t ints[2];
+ parse_int_args(argc, argv, ints, 2);
+ m5_dump_stats(ints[0], ints[1]);
+}
- if (COMPARE("sw99param")) {
- if (argc != 2)
- usage();
+void
+do_dump_reset_stats(int argc, char *argv[])
+{
+ uint64_t ints[2];
+ parse_int_args(argc, argv, ints, 2);
+ m5_dumpreset_stats(ints[0], ints[1]);
+}
- param = m5_initparam();
- // run-time, rampup-time, rampdown-time, warmup-time, connections
- printf("%d %d %d %d %d", (param >> 48) & 0xfff,
- (param >> 36) & 0xfff, (param >> 24) & 0xfff,
- (param >> 12) & 0xfff, (param >> 0) & 0xfff);
+void
+do_read_file(int argc, char *argv[])
+{
+ if (argc > 0)
+ usage();
- return 0;
- }
+ read_file(STDOUT_FILENO);
+}
- if (COMPARE("exit")) {
- switch (argc) {
- case 3:
- arg1 = strtoul(argv[2], NULL, 0);
- case 2:
- m5_exit(arg1);
- return 0;
-
- default:
- usage();
- }
- }
+void
+do_exec_file(int argc, char *argv[])
+{
+ if (argc > 0)
+ usage();
- if (COMPARE("resetstats")) {
- switch (argc) {
- case 4:
- arg2 = strtoul(argv[3], NULL, 0);
- case 3:
- arg1 = strtoul(argv[2], NULL, 0);
- case 2:
- m5_reset_stats(arg1, arg2);
- return 0;
-
- default:
- usage();
- }
- }
+ const char *destname = "/tmp/execfile";
- if (COMPARE("dumpstats")) {
- switch (argc) {
- case 4:
- arg2 = strtoul(argv[3], NULL, 0);
- case 3:
- arg1 = strtoul(argv[2], NULL, 0);
- case 2:
- m5_dump_stats(arg1, arg2);
- return 0;
-
- default:
- usage();
- }
+ int fid = open(destname, O_WRONLY, 0777);
+ int len = read_file(fid);
+ close(fid);
+ if (len > 0) {
+ execl(destname, "execfile", NULL);
+ err(1, "execl failed!");
}
+}
- if (COMPARE("dumpresetstats")) {
- switch (argc) {
- case 4:
- arg2 = strtoul(argv[3], NULL, 0);
- case 3:
- arg1 = strtoul(argv[2], NULL, 0);
- case 2:
- m5_dumpreset_stats(arg1, arg2);
- return 0;
-
- default:
- usage();
- }
- }
+void
+do_checkpoint(int argc, char *argv[])
+{
+ uint64_t ints[2];
+ parse_int_args(argc, argv, ints, 2);
+ m5_checkpoint(ints[0], ints[1]);
+}
+
+void
+do_load_symbol(int argc, char *argv[])
+{
+ if (argc != 2)
+ usage();
- if (COMPARE("readfile")) {
- char buf[256*1024];
- int offset = 0;
- int len;
+ uint64_t addr = strtoul(argv[0], NULL, 0);
+ char *symbol = argv[1];
+ m5_loadsymbol(addr, symbol);
+}
- if (argc != 2)
- usage();
+void
+do_initparam(int argc, char *argv[])
+{
+ if (argc != 0)
+ usage();
- while ((len = m5_readfile(buf, sizeof(buf), offset)) > 0) {
- write(STDOUT_FILENO, buf, len);
- offset += len;
- }
+
+ printf("%ld", m5_initparam());
+}
- return 0;
- }
+void
+do_sw99param(int argc, char *argv[])
+{
+ if (argc != 0)
+ usage();
+
+ uint64_t param = m5_initparam();
+
+ // run-time, rampup-time, rampdown-time, warmup-time, connections
+ printf("%d %d %d %d %d", (param >> 48) & 0xfff,
+ (param >> 36) & 0xfff, (param >> 24) & 0xfff,
+ (param >> 12) & 0xfff, (param >> 0) & 0xfff);
+}
+
+#ifdef linux
+void
+do_pin(int argc, char *argv[])
+{
+ if (argc < 2)
+ usage();
+
+ cpu_set_t mask;
+ CPU_ZERO(&mask);
+
+ const char *sep = ",";
+ char *target = strtok(argv[0], sep);
+ while (target) {
+ CPU_SET(atoi(target), &mask);
+ target = strtok(NULL, sep);
+ }
+
+ if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) < 0)
+ err(1, "setaffinity");
+
+ execvp(argv[1], &argv[1]);
+ err(1, "execvp failed!");
+}
+#endif
+
+struct MainFunc
+{
+ char *name;
+ void (*func)(int argc, char *argv[]);
+ char *usage;
+};
- if (COMPARE("checkpoint")) {
- switch (argc) {
- case 4:
- arg2 = strtoul(argv[3], NULL, 0);
- case 3:
- arg1 = strtoul(argv[2], NULL, 0);
- case 2:
- m5_checkpoint(arg1, arg2);
- return 0;
-
- default:
- usage();
- }
-
- return 0;
+struct MainFunc mainfuncs[] = {
+ { "exit", do_exit, "[delay]" },
+ { "resetstats", do_reset_stats, "[delay [period]]" },
+ { "dumpstats", do_dump_stats, "[delay [period]]" },
+ { "dumpresetstats", do_dump_reset_stats, "[delay [period]]" },
+ { "readfile", do_read_file, "[filename]" },
+ { "execfile", do_exec_file, "<filename>" },
+ { "checkpoint", do_checkpoint, "[delay [period]]" },
+ { "loadsymbol", do_load_symbol, "<address> <symbol>" },
+ { "initparam", do_initparam, "" },
+ { "sw99param", do_sw99param, "" },
+#ifdef linux
+ { "pin", do_pin, "<cpu> <program> [args ...]" }
+#endif
+};
+int numfuncs = sizeof(mainfuncs) / sizeof(mainfuncs[0]);
+
+void
+usage()
+{
+ int i;
+
+ for (i = 0; i < numfuncs; ++i) {
+ char *header = i ? "" : "usage:";
+ fprintf(stderr, "%-6s %s %s %s\n",
+ header, progname, mainfuncs[i].name, mainfuncs[i].usage);
}
+ fprintf(stderr, "\n");
+ fprintf(stderr, "All times in nanoseconds!\n");
+
+ exit(1);
+}
- if (COMPARE("loadsymbol")) {
- m5_loadsymbol(arg1);
- return 0;
+int
+main(int argc, char *argv[])
+{
+ progname = argv[0];
+ if (argc < 2)
+ usage(1);
+
+ command = argv[1];
+
+ argv += 2;
+ argc -= 2;
+
+ int i;
+ for (i = 0; i < numfuncs; ++i) {
+ if (strcmp(command, mainfuncs[i].name) != 0)
+ continue;
+
+ mainfuncs[i].func(argc, argv);
+ exit(0);
}
- usage();
+
+ usage(1);
}
diff --git a/util/m5/m5op.h b/util/m5/m5op.h
index f4e6bb0f1..b8f13da35 100644
--- a/util/m5/m5op.h
+++ b/util/m5/m5op.h
@@ -39,6 +39,8 @@ void quiesce(void);
void quiesceNs(uint64_t ns);
void quiesceCycle(uint64_t cycles);
uint64_t quiesceTime(void);
+uint64_t rpns();
+void wakeCPU(uint64_t cpuid);
void m5_exit(uint64_t ns_delay);
uint64_t m5_initparam(void);
@@ -51,7 +53,27 @@ void m5_debugbreak(void);
void m5_switchcpu(void);
void m5_addsymbol(uint64_t addr, char *symbol);
void m5_panic(void);
-void m5_anbegin(uint64_t s);
-void m5_anwait(uint64_t s, uint64_t w);
+
+// These operations are for critical path annotation
+void m5a_bsm(char *sm, const void *id, int flags);
+void m5a_esm(char *sm);
+void m5a_begin(int flags, char *st);
+void m5a_end(void);
+void m5a_q(const void *id, char *q, int count);
+void m5a_dq(const void *id, char *q, int count);
+void m5a_wf(const void *id, char *q, char *sm, int count);
+void m5a_we(const void *id, char *q, char *sm, int count);
+void m5a_ws(const void *id, char *q, char *sm);
+void m5a_sq(const void *id, char *q, int count, int flags);
+void m5a_aq(const void *id, char *q, int count);
+void m5a_pq(const void *id, char *q, int count);
+void m5a_l(char *lsm, const void *id, char *sm);
+void m5a_identify(uint64_t id);
+uint64_t m5a_getid(void);
+
+#define M5_AN_FL_NONE 0x0
+#define M5_AN_FL_BAD 0x2
+#define M5_AN_FL_LINK 0x10
+#define M5_AN_FL_RESET 0x20
#endif // __M5OP_H__
diff --git a/util/m5/m5op_alpha.S b/util/m5/m5op_alpha.S
index c5d0e65f8..9e8c49338 100644
--- a/util/m5/m5op_alpha.S
+++ b/util/m5/m5op_alpha.S
@@ -48,11 +48,19 @@ func:
#define END(func) \
.end func
-#define ARM(reg) INST(m5_op, reg, 0, arm_func)
+#define SIMPLE_OP(_f, _o) \
+ LEAF(_f) \
+ _o; \
+ RET; \
+ END(_f)
+
+#define ARM(reg) INST(m5_op, reg, 0, arm_func)
#define QUIESCE INST(m5_op, 0, 0, quiesce_func)
#define QUIESCENS(r1) INST(m5_op, r1, 0, quiescens_func)
#define QUIESCECYC(r1) INST(m5_op, r1, 0, quiescecycle_func)
#define QUIESCETIME INST(m5_op, 0, 0, quiescetime_func)
+#define RPNS INST(m5_op, 0, 0, rpns_func)
+#define WAKE_CPU(r1) INST(m5_op, r1, 0, wakecpu_func)
#define M5EXIT(reg) INST(m5_op, reg, 0, exit_func)
#define INITPARAM(reg) INST(m5_op, reg, 0, initparam_func)
#define LOADSYMBOL(reg) INST(m5_op, reg, 0, loadsymbol_func)
@@ -65,125 +73,61 @@ func:
#define SWITCHCPU INST(m5_op, 0, 0, switchcpu_func)
#define ADDSYMBOL(r1,r2) INST(m5_op, r1, r2, addsymbol_func)
#define PANIC INST(m5_op, 0, 0, panic_func)
-#define AN_BEGIN(r1) INST(m5_op, r1, 0, anbegin_func)
-#define AN_WAIT(r1,r2) INST(m5_op, r1, r2, anwait_func)
-
- .set noreorder
-
- .align 4
-LEAF(arm)
- ARM(16)
- RET
-END(arm)
-
- .align 4
-LEAF(quiesce)
- QUIESCE
- RET
-END(quiesce)
-
- .align 4
-LEAF(quiesceNs)
- QUIESCENS(16)
- RET
-END(quiesceNs)
-
- .align 4
-LEAF(quiesceCycle)
- QUIESCECYC(16)
- RET
-END(quiesceCycle)
-
- .align 4
-LEAF(quiesceTime)
- QUIESCETIME
- RET
-END(quiesceTime)
-
- .align 4
-LEAF(m5_exit)
- M5EXIT(16)
- RET
-END(m5_exit)
-
- .align 4
-LEAF(m5_initparam)
- INITPARAM(0)
- RET
-END(m5_initparam)
-
- .align 4
-LEAF(m5_loadsymbol)
- LOADSYMBOL(0)
- RET
-END(m5_loadsymbol)
- .align 4
-LEAF(m5_reset_stats)
- RESET_STATS(16, 17)
- RET
-END(m5_reset_stats)
+#define AN_BSM INST(m5_op, an_bsm, 0, annotate_func)
+#define AN_ESM INST(m5_op, an_esm, 0, annotate_func)
+#define AN_BEGIN INST(m5_op, an_begin, 0, annotate_func)
+#define AN_END INST(m5_op, an_end, 0, annotate_func)
+#define AN_Q INST(m5_op, an_q, 0, annotate_func)
+#define AN_RQ INST(m5_op, an_rq, 0, annotate_func)
+#define AN_DQ INST(m5_op, an_dq, 0, annotate_func)
+#define AN_WF INST(m5_op, an_wf, 0, annotate_func)
+#define AN_WE INST(m5_op, an_we, 0, annotate_func)
+#define AN_WS INST(m5_op, an_ws, 0, annotate_func)
+#define AN_SQ INST(m5_op, an_sq, 0, annotate_func)
+#define AN_AQ INST(m5_op, an_aq, 0, annotate_func)
+#define AN_PQ INST(m5_op, an_pq, 0, annotate_func)
+#define AN_L INST(m5_op, an_l, 0, annotate_func)
+#define AN_IDENTIFY INST(m5_op, an_identify, 0, annotate_func)
+#define AN_GETID INST(m5_op, an_getid, 0, annotate_func)
- .align 4
-LEAF(m5_dump_stats)
- DUMP_STATS(16, 17)
- RET
-END(m5_dump_stats)
- .align 4
-LEAF(m5_dumpreset_stats)
- DUMPRST_STATS(16, 17)
- RET
-END(m5_dumpreset_stats)
-
- .align 4
-LEAF(m5_checkpoint)
- CHECKPOINT(16, 17)
- RET
-END(m5_checkpoint)
-
- .align 4
-LEAF(m5_readfile)
- READFILE
- RET
-END(m5_readfile)
-
- .align 4
-LEAF(m5_debugbreak)
- DEBUGBREAK
- RET
-END(m5_debugbreak)
-
- .align 4
-LEAF(m5_switchcpu)
- SWITCHCPU
- RET
-END(m5_switchcpu)
-
- .align 4
-LEAF(m5_addsymbol)
- ADDSYMBOL(16, 17)
- RET
-END(m5_addsymbol)
-
- .align 4
-LEAF(m5_panic)
- PANIC
- RET
-END(m5_panic)
-
-
- .align 4
-LEAF(m5_anbegin)
- AN_BEGIN(16)
- RET
-END(m5_anbegin)
-
-
- .align 4
-LEAF(m5_anwait)
- AN_WAIT(16,17)
- RET
-END(m5_anwait)
+ .set noreorder
+SIMPLE_OP(arm, ARM(16))
+SIMPLE_OP(quiesce, QUIESCE)
+SIMPLE_OP(quiesceNs, QUIESCENS(16))
+SIMPLE_OP(quiesceCycle, QUIESCECYC(16))
+SIMPLE_OP(quiesceTime, QUIESCETIME)
+SIMPLE_OP(rpns, RPNS)
+SIMPLE_OP(wakeCPU, WAKE_CPU(16))
+SIMPLE_OP(m5_exit, M5EXIT(16))
+SIMPLE_OP(m5_initparam, INITPARAM(0))
+SIMPLE_OP(m5_loadsymbol, LOADSYMBOL(0))
+SIMPLE_OP(m5_reset_stats, RESET_STATS(16, 17))
+SIMPLE_OP(m5_dump_stats, DUMP_STATS(16, 17))
+SIMPLE_OP(m5_dumpreset_stats, DUMPRST_STATS(16, 17))
+SIMPLE_OP(m5_checkpoint, CHECKPOINT(16, 17))
+SIMPLE_OP(m5_readfile, READFILE)
+SIMPLE_OP(m5_debugbreak, DEBUGBREAK)
+SIMPLE_OP(m5_switchcpu, SWITCHCPU)
+SIMPLE_OP(m5_addsymbol, ADDSYMBOL(16, 17))
+SIMPLE_OP(m5_panic, PANIC)
+
+SIMPLE_OP(m5a_bsm, AN_BSM)
+SIMPLE_OP(m5a_esm, AN_ESM)
+SIMPLE_OP(m5a_begin, AN_BEGIN)
+SIMPLE_OP(m5a_end, AN_END)
+SIMPLE_OP(m5a_q, AN_Q)
+SIMPLE_OP(m5a_rq, AN_RQ)
+SIMPLE_OP(m5a_dq, AN_DQ)
+SIMPLE_OP(m5a_wf, AN_WF)
+SIMPLE_OP(m5a_we, AN_WE)
+SIMPLE_OP(m5a_ws, AN_WS)
+SIMPLE_OP(m5a_sq, AN_SQ)
+SIMPLE_OP(m5a_aq, AN_AQ)
+SIMPLE_OP(m5a_pq, AN_PQ)
+SIMPLE_OP(m5a_l, AN_L)
+SIMPLE_OP(m5a_identify, AN_IDENTIFY)
+SIMPLE_OP(m5a_getid, AN_GETID)
diff --git a/util/m5/m5op_x86.S b/util/m5/m5op_x86.S
new file mode 100644
index 000000000..e85051d98
--- /dev/null
+++ b/util/m5/m5op_x86.S
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2003-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: Gabe Black
+ * Nathan Binkert
+ * Ali Saidi
+ */
+
+#include "m5ops.h"
+
+#define TWO_BYTE_OP(name, number) \
+ .globl name; \
+ .func name; \
+name: \
+ .byte 0x0F, 0x04; \
+ .word number; \
+ ret; \
+ .endfunc;
+
+TWO_BYTE_OP(arm, arm_func)
+TWO_BYTE_OP(quiesce, quiesce_func)
+TWO_BYTE_OP(quiesceNs, quiescens_func)
+TWO_BYTE_OP(quiesceCycle, quiescecycle_func)
+TWO_BYTE_OP(quiesceTime, quiescetime_func)
+TWO_BYTE_OP(rpns, rpns_func)
+TWO_BYTE_OP(m5_exit, exit_func)
+TWO_BYTE_OP(m5_initparam, initparam_func)
+TWO_BYTE_OP(m5_loadsymbol, loadsymbol_func)
+TWO_BYTE_OP(m5_reset_stats, resetstats_func)
+TWO_BYTE_OP(m5_dump_stats, dumpstats_func)
+TWO_BYTE_OP(m5_dumpreset_stats, dumprststats_func)
+TWO_BYTE_OP(m5_checkpoint, ckpt_func)
+TWO_BYTE_OP(m5_readfile, readfile_func)
+TWO_BYTE_OP(m5_debugbreak, debugbreak_func)
+TWO_BYTE_OP(m5_switchcpu, switchcpu_func)
+TWO_BYTE_OP(m5_addsymbol, addsymbol_func)
+TWO_BYTE_OP(m5_panic, panic_func)
+TWO_BYTE_OP(m5_reserved1_func, reserved1_func)
+TWO_BYTE_OP(m5_reserved2_func, reserved2_func)
+TWO_BYTE_OP(m5_reserved3_func, reserved3_func)
+TWO_BYTE_OP(m5_reserved4_func, reserved4_func)
+TWO_BYTE_OP(m5_reserved5_func, reserved5_func)
diff --git a/util/m5/m5ops.h b/util/m5/m5ops.h
index ce0b39b29..7f26fd4d8 100644
--- a/util/m5/m5ops.h
+++ b/util/m5/m5ops.h
@@ -29,26 +29,50 @@
* Ali Saidi
*/
-#define arm_func 0x00
-#define quiesce_func 0x01
-#define quiescens_func 0x02
-#define quiescecycle_func 0x03
-#define quiescetime_func 0x04
-#define ivlb 0x10 // obsolete
-#define ivle 0x11 // obsolete
-#define exit_old_func 0x20 // deprecated!
-#define exit_func 0x21
-#define initparam_func 0x30
-#define loadsymbol_func 0x31
-#define resetstats_func 0x40
-#define dumpstats_func 0x41
-#define dumprststats_func 0x42
-#define ckpt_func 0x43
-#define readfile_func 0x50
-#define debugbreak_func 0x51
-#define switchcpu_func 0x52
-#define addsymbol_func 0x53
-#define panic_func 0x54
-#define anbegin_func 0x55
-#define anwait_func 0x56
+#define arm_func 0x00
+#define quiesce_func 0x01
+#define quiescens_func 0x02
+#define quiescecycle_func 0x03
+#define quiescetime_func 0x04
+#define rpns_func 0x07
+#define wakecpu_func 0x09
+#define deprecated1_func 0x10 // obsolete ivlb
+#define deprecated2_func 0x11 // obsolete ivle
+#define deprecated3_func 0x20 // deprecated exit function
+#define exit_func 0x21
+#define initparam_func 0x30
+#define loadsymbol_func 0x31
+#define resetstats_func 0x40
+#define dumpstats_func 0x41
+#define dumprststats_func 0x42
+#define ckpt_func 0x43
+#define readfile_func 0x50
+#define debugbreak_func 0x51
+#define switchcpu_func 0x52
+#define addsymbol_func 0x53
+#define panic_func 0x54
+
+#define reserved2_func 0x56 // Reserved for user
+#define reserved3_func 0x57 // Reserved for user
+#define reserved4_func 0x58 // Reserved for user
+#define reserved5_func 0x59 // Reserved for user
+
+// These operations are for critical path annotation
+#define annotate_func 0x55
+#define an_bsm 0x1
+#define an_esm 0x2
+#define an_begin 0x3
+#define an_end 0x4
+#define an_q 0x6
+#define an_dq 0x7
+#define an_wf 0x8
+#define an_we 0x9
+#define an_rq 0xA
+#define an_ws 0xB
+#define an_sq 0xC
+#define an_aq 0xD
+#define an_pq 0xE
+#define an_l 0xF
+#define an_identify 0x10
+#define an_getid 0x11
diff --git a/util/mkblankimage.sh b/util/mkblankimage.sh
new file mode 100644
index 000000000..43a3cca29
--- /dev/null
+++ b/util/mkblankimage.sh
@@ -0,0 +1,219 @@
+#!/bin/sh
+#
+# makeblankimage.sh
+# Make a blank M5 disk image
+#
+
+while getopts "m" OPT
+do
+ case "$OPT" in
+ m) MOUNT_IT=1
+ esac
+done
+
+DEBUG=0
+
+if [ $DEBUG -ne 0 ]; then
+ set -x -e
+ OUTPUT=""
+else
+ OUTPUT="> /dev/null 2>&1"
+fi
+
+abort() {
+ echo $@
+ exec /bin/false
+}
+
+find_prog() {
+ PROG_PATH=`which $1`
+ if [ $? -ne 0 ]; then
+ abort "Unable to find program $1, check your PATH variable"
+ fi
+ echo $PROG_PATH
+}
+
+run_priv() {
+ if [ "$HAVE_SUDO" = "y" ]; then
+ eval $SUDO $@ $OUTPUT
+ else
+ eval $@ $OUTPUT
+ fi
+
+ if [ $? -ne 0 ]; then
+ abort "Failed to run $@ as root"
+ fi
+}
+
+usage() {
+ abort "Usage: $0 [root-path to copy] [extra ownership commands ...]"
+}
+
+# Setup PATH to look in the sbins
+export PATH=$PATH:/sbin:/usr/sbin
+
+# Get all of the programs needed, or exit
+DD=`find_prog dd`
+SFDISK=`find_prog sfdisk`
+LOSETUP=`find_prog losetup`
+SUDO=`find_prog sudo`
+MKE2FS=`find_prog mke2fs`
+MKDIR=`find_prog mkdir`
+MOUNT=`find_prog mount`
+UMOUNT=`find_prog umount`
+WHOAMI=`find_prog whoami`
+CP=`find_prog cp`
+CHOWN=`find_prog chown`
+
+# Prompt for the root password, if needed
+CUR_USER=`$WHOAMI`
+
+if [ $# -ge 1 ]; then
+ if [ ! $MOUNT_IT ]; then
+ ROOT_PATH=$1
+
+ if [ ! -d $ROOT_PATH ]; then
+ usage
+ fi
+ else
+ ROOT_PATH=""
+ fi
+else
+ ROOT_PATH=""
+fi
+
+if [ ! "$CUR_USER" = "root" ]; then
+ echo -n "Do you have sudo access? [y/n] "
+ read HAVE_SUDO
+
+ if [ ! "$HAVE_SUDO" = "y" ]; then
+ abort "You must have sudo access or run this script as root"
+ fi
+fi
+
+echo -n "How large do you want this disk image (in MB): "
+read USER_SIZE_MB
+
+# size in bytes = SIZE_MB * 1024 * 1024
+# size in blocks = SIZE_BYTE / 512
+let BLK_SIZE=$USER_SIZE_MB*1024*2
+
+let MAX_LBA=16383*16*63
+
+if [ $BLK_SIZE -ge $MAX_LBA ]; then
+ CYLS=16383
+ HEADS=16
+ SECTORS=63
+else
+ # Set Sectors
+ if [ $BLK_SIZE -ge 63 ]; then
+ SECTORS=63
+ else
+ SECTORS=$BLK_SIZE
+ fi
+
+ # Set Heads
+ let HEAD_SIZE=$BLK_SIZE/$SECTORS
+
+ if [ $HEAD_SIZE -ge 16 ]; then
+ HEADS=16
+ else
+ HEADS=$BLK_SIZE
+ fi
+
+ # Set Cylinders
+ let SEC_HEAD=$SECTORS*$HEADS
+ let CYLS=$BLK_SIZE/$SEC_HEAD
+fi
+
+# Recalculate number of sectors
+let BLK_SIZE=$CYLS*$HEADS*$SECTORS
+
+# Get the name of the file and directory to build in
+echo -n "What directory would you like to build the image in? "
+read IMAGE_DIR
+
+if [ ! -d $IMAGE_DIR ]; then
+ abort "The directory $IMAGE_DIR does not exist"
+fi
+
+echo -n "What would you like to name the image? "
+read IMAGE_NAME
+
+IMAGE_FILE=$IMAGE_DIR/$IMAGE_NAME
+
+# DD the blank image
+echo
+echo "dd'ing the blank image (this make take a while)..."
+eval $DD if=/dev/zero of=$IMAGE_FILE bs=512 count=$BLK_SIZE $OUTPUT
+if [ $? -ne 0 ]; then
+ abort "Unable to create the blank image $IMAGE_NAME in $IMAGE_DIR"
+fi
+
+# losetup the image with no offset to do the fdisk
+echo
+echo "Binding the image and partitioning..."
+run_priv $LOSETUP /dev/loop0 $IMAGE_FILE
+if [ $? -ne 0 ]; then
+ abort "losetup to /dev/loop0 failed, make sure nothing is setup on loop0 (check by typing 'mount') "
+fi
+
+# fdisk the image
+run_priv $SFDISK --no-reread -D -C $CYLS -H $HEADS -S $SECTORS /dev/loop0 <<EOF
+0,
+;
+;
+;
+EOF
+
+# Un-losetup the image
+run_priv $LOSETUP -d /dev/loop0
+
+# Mount the image with an offset and make the filesystem
+echo
+echo "Remounting image and formatting..."
+let BASE_OFFSET=63*512
+
+run_priv $LOSETUP -o $BASE_OFFSET /dev/loop0 $IMAGE_FILE
+
+run_priv $MKE2FS /dev/loop0
+
+# If a root path was specified then copy the root path into the image
+if [ ! -z "$ROOT_PATH" ]; then
+ echo "Copying root from $ROOT_PATH to image file"
+
+ run_priv $MKDIR -p /tmp/mnt
+
+ run_priv $MOUNT /dev/loop0 /tmp/mnt
+
+ run_priv $CP -a $ROOT_PATH/* /tmp/mnt
+
+ run_priv $CHOWN -R root.root /tmp/mnt
+
+ # run extra permissions while disk is mounted
+ TOPDIR=`pwd`
+ cd /tmp/mnt
+ i=2
+ while [ $i -le $# ]; do
+ run_priv ${!i}
+ let i=i+1
+ done
+ cd $TOPDIR
+
+ run_priv $UMOUNT /tmp/mnt
+fi
+
+run_priv $LOSETUP -d /dev/loop0
+
+
+if [ $MOUNT_IT -eq 1 ]; then
+ run_priv mount -o loop,offset=$BASE_OFFSET $IMAGE_FILE /tmp/mnt
+else
+ echo
+ echo "Disk image creation complete."
+ echo "To mount the image, run the following commands:"
+ echo "# $MOUNT -o loop,offset=$BASE_OFFSET $IMAGE_FILE /mount/point"
+ echo
+ echo "And to unmount the image, run:"
+ echo "# $UMOUNT /mount/point"
+fi;
diff --git a/util/pbs/jobfile.py b/util/pbs/jobfile.py
deleted file mode 100644
index fd19b3bf5..000000000
--- a/util/pbs/jobfile.py
+++ /dev/null
@@ -1,539 +0,0 @@
-# Copyright (c) 2005-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 sys
-
-class ternary(object):
- def __new__(cls, *args):
- if len(args) > 1:
- raise TypeError, \
- '%s() takes at most 1 argument (%d given)' % \
- (cls.__name__, len(args))
-
- if args:
- if not isinstance(args[0], (bool, ternary)):
- raise TypeError, \
- '%s() argument must be True, False, or Any' % \
- cls.__name__
- return args[0]
- return super(ternary, cls).__new__(cls)
-
- def __bool__(self):
- return True
-
- def __neg__(self):
- return self
-
- def __eq__(self, other):
- return True
-
- def __ne__(self, other):
- return False
-
- def __str__(self):
- return 'Any'
-
- def __repr__(self):
- return 'Any'
-
-Any = ternary()
-
-class Flags(dict):
- def __init__(self, *args, **kwargs):
- super(Flags, self).__init__()
- self.update(*args, **kwargs)
-
- def __getattr__(self, attr):
- return self[attr]
-
- def __setattr__(self, attr, value):
- self[attr] = value
-
- def __setitem__(self, item, value):
- return super(Flags, self).__setitem__(item, ternary(value))
-
- def __getitem__(self, item):
- if item not in self:
- return False
- return super(Flags, self).__getitem__(item)
-
- def update(self, *args, **kwargs):
- for arg in args:
- if isinstance(arg, Flags):
- super(Flags, self).update(arg)
- elif isinstance(arg, dict):
- for key,val in kwargs.iteritems():
- self[key] = val
- else:
- raise AttributeError, \
- 'flags not of type %s or %s, but %s' % \
- (Flags, dict, type(arg))
-
- for key,val in kwargs.iteritems():
- self[key] = val
-
- def match(self, *args, **kwargs):
- match = Flags(*args, **kwargs)
-
- for key,value in match.iteritems():
- if self[key] != value:
- return False
-
- return True
-
-def crossproduct(items):
- if not isinstance(items, (list, tuple)):
- raise AttributeError, 'crossproduct works only on sequences'
-
- if not items:
- yield None
- return
-
- current = items[0]
- remainder = items[1:]
-
- if not hasattr(current, '__iter__'):
- current = [ current ]
-
- for item in current:
- for rem in crossproduct(remainder):
- data = [ item ]
- if rem:
- data += rem
- yield data
-
-def flatten(items):
- if not isinstance(items, (list, tuple)):
- yield items
- return
-
- for item in items:
- for flat in flatten(item):
- yield flat
-
-class Data(object):
- def __init__(self, name, desc, **kwargs):
- self.name = name
- self.desc = desc
- self.system = None
- self.flags = Flags()
- self.env = {}
- for k,v in kwargs.iteritems():
- setattr(self, k, v)
-
- def update(self, obj):
- if not isinstance(obj, Data):
- raise AttributeError, "can only update from Data object"
-
- self.env.update(obj.env)
- self.flags.update(obj.flags)
- if obj.system:
- if self.system and self.system != obj.system:
- raise AttributeError, \
- "conflicting values for system: '%s'/'%s'" % \
- (self.system, obj.system)
- self.system = obj.system
-
- def printinfo(self):
- if self.name:
- print 'name: %s' % self.name
- if self.desc:
- print 'desc: %s' % self.desc
- if self.system:
- print 'system: %s' % self.system
-
- def printverbose(self):
- print 'flags:'
- keys = self.flags.keys()
- keys.sort()
- for key in keys:
- print ' %s = %s' % (key, self.flags[key])
- print 'env:'
- keys = self.env.keys()
- keys.sort()
- for key in keys:
- print ' %s = %s' % (key, self.env[key])
- print
-
- def __str__(self):
- return self.name
-
-class Job(Data):
- def __init__(self, options):
- super(Job, self).__init__('', '')
- self.setoptions(options)
-
- self.checkpoint = False
- opts = []
- for opt in options:
- cpt = opt.group.checkpoint
- if not cpt:
- self.checkpoint = True
- continue
- if isinstance(cpt, Option):
- opt = cpt.clone(suboptions=False)
- else:
- opt = opt.clone(suboptions=False)
-
- opts.append(opt)
-
- if not opts:
- self.checkpoint = False
-
- if self.checkpoint:
- self.checkpoint = Job(opts)
-
- def clone(self):
- return Job(self.options)
-
- def __getattribute__(self, attr):
- if attr == 'name':
- names = [ ]
- for opt in self.options:
- if opt.name:
- names.append(opt.name)
- return ':'.join(names)
-
- if attr == 'desc':
- descs = [ ]
- for opt in self.options:
- if opt.desc:
- descs.append(opt.desc)
- return ', '.join(descs)
-
- return super(Job, self).__getattribute__(attr)
-
- def setoptions(self, options):
- config = options[0].config
- for opt in options:
- if opt.config != config:
- raise AttributeError, \
- "All options are not from the same Configuration"
-
- self.config = config
- self.groups = [ opt.group for opt in options ]
- self.options = options
-
- self.update(self.config)
- for group in self.groups:
- self.update(group)
-
- for option in self.options:
- self.update(option)
- if option._suboption:
- self.update(option._suboption)
-
- def printinfo(self):
- super(Job, self).printinfo()
- if self.checkpoint:
- print 'checkpoint: %s' % self.checkpoint.name
- print 'config: %s' % self.config.name
- print 'groups: %s' % [ g.name for g in self.groups ]
- print 'options: %s' % [ o.name for o in self.options ]
- super(Job, self).printverbose()
-
-class SubOption(Data):
- def __init__(self, name, desc, **kwargs):
- super(SubOption, self).__init__(name, desc, **kwargs)
- self.number = None
-
-class Option(Data):
- def __init__(self, name, desc, **kwargs):
- super(Option, self).__init__(name, desc, **kwargs)
- self._suboptions = []
- self._suboption = None
- self.number = None
-
- def __getattribute__(self, attr):
- if attr == 'name':
- name = self.__dict__[attr]
- if self._suboption is not None:
- name = '%s:%s' % (name, self._suboption.name)
- return name
-
- if attr == 'desc':
- desc = [ self.__dict__[attr] ]
- if self._suboption is not None and self._suboption.desc:
- desc.append(self._suboption.desc)
- return ', '.join(desc)
-
-
- return super(Option, self).__getattribute__(attr)
-
- def suboption(self, name, desc, **kwargs):
- subo = SubOption(name, desc, **kwargs)
- subo.config = self.config
- subo.group = self.group
- subo.option = self
- subo.number = len(self._suboptions)
- self._suboptions.append(subo)
- return subo
-
- def clone(self, suboptions=True):
- option = Option(self.__dict__['name'], self.__dict__['desc'])
- option.update(self)
- option.group = self.group
- option.config = self.config
- option.number = self.number
- if suboptions:
- option._suboptions.extend(self._suboptions)
- option._suboption = self._suboption
- return option
-
- def subopts(self):
- if not self._suboptions:
- return [ self ]
-
- subopts = []
- for subo in self._suboptions:
- option = self.clone()
- option._suboption = subo
- subopts.append(option)
-
- return subopts
-
- def printinfo(self):
- super(Option, self).printinfo()
- print 'config: %s' % self.config.name
- super(Option, self).printverbose()
-
-class Group(Data):
- def __init__(self, name, desc, **kwargs):
- super(Group, self).__init__(name, desc, **kwargs)
- self._options = []
- self.checkpoint = False
- self.number = None
-
- def option(self, name, desc, **kwargs):
- opt = Option(name, desc, **kwargs)
- opt.config = self.config
- opt.group = self
- opt.number = len(self._options)
- self._options.append(opt)
- return opt
-
- def options(self):
- return self._options
-
- def subopts(self):
- subopts = []
- for opt in self._options:
- for subo in opt.subopts():
- subopts.append(subo)
- return subopts
-
- def printinfo(self):
- super(Group, self).printinfo()
- print 'config: %s' % self.config.name
- print 'options: %s' % [ o.name for o in self._options ]
- super(Group, self).printverbose()
-
-class Configuration(Data):
- def __init__(self, name, desc, **kwargs):
- super(Configuration, self).__init__(name, desc, **kwargs)
- self._groups = []
- self._posfilters = []
- self._negfilters = []
-
- def group(self, name, desc, **kwargs):
- grp = Group(name, desc, **kwargs)
- grp.config = self
- grp.number = len(self._groups)
- self._groups.append(grp)
- return grp
-
- def groups(self, flags=Flags(), sign=True):
- if not flags:
- return self._groups
-
- return [ grp for grp in self._groups if sign ^ grp.flags.match(flags) ]
-
- def checkchildren(self, kids):
- for kid in kids:
- if kid.config != self:
- raise AttributeError, "child from the wrong configuration"
-
- def sortgroups(self, groups):
- groups = [ (grp.number, grp) for grp in groups ]
- groups.sort()
- return [ grp[1] for grp in groups ]
-
- def options(self, groups = None, checkpoint = False):
- if groups is None:
- groups = self._groups
- self.checkchildren(groups)
- groups = self.sortgroups(groups)
- if checkpoint:
- groups = [ grp for grp in groups if grp.checkpoint ]
- optgroups = [ g.options() for g in groups ]
- else:
- optgroups = [ g.subopts() for g in groups ]
- for options in crossproduct(optgroups):
- for opt in options:
- cpt = opt.group.checkpoint
- if not isinstance(cpt, bool) and cpt != opt:
- if checkpoint:
- break
- else:
- yield options
- else:
- if checkpoint:
- yield options
-
- def addfilter(self, filt, pos=True):
- import re
- filt = re.compile(filt)
- if pos:
- self._posfilters.append(filt)
- else:
- self._negfilters.append(filt)
-
- def jobfilter(self, job):
- for filt in self._negfilters:
- if filt.match(job.name):
- return False
-
- if not self._posfilters:
- return True
-
- for filt in self._posfilters:
- if filt.match(job.name):
- return True
-
- return False
-
- def checkpoints(self, groups = None):
- for options in self.options(groups, True):
- job = Job(options)
- if self.jobfilter(job):
- yield job
-
- def jobs(self, groups = None):
- for options in self.options(groups, False):
- job = Job(options)
- if self.jobfilter(job):
- yield job
-
- def alljobs(self, groups = None):
- for options in self.options(groups, True):
- yield Job(options)
- for options in self.options(groups, False):
- yield Job(options)
-
- def find(self, jobname):
- for job in self.alljobs():
- if job.name == jobname:
- return job
- else:
- raise AttributeError, "job '%s' not found" % jobname
-
- def job(self, options):
- self.checkchildren(options)
- options = [ (opt.group.number, opt) for opt in options ]
- options.sort()
- options = [ opt[1] for opt in options ]
- job = Job(options)
- return job
-
- def printinfo(self):
- super(Configuration, self).printinfo()
- print 'groups: %s' % [ g.name for g in self._grouips ]
- super(Configuration, self).printverbose()
-
-def JobFile(jobfile):
- from os.path import expanduser, isfile, join as joinpath
- filename = expanduser(jobfile)
-
- # Can't find filename in the current path, search sys.path
- if not isfile(filename):
- for path in sys.path:
- testname = joinpath(path, filename)
- if isfile(testname):
- filename = testname
- break
- else:
- raise AttributeError, \
- "Could not find file '%s'" % jobfile
-
- data = {}
- execfile(filename, data)
- if 'conf' not in data:
- raise ImportError, 'cannot import name conf from %s' % jobfile
- conf = data['conf']
- import jobfile
- if not isinstance(conf, Configuration):
- raise AttributeError, \
- 'conf in jobfile: %s (%s) is not type %s' % \
- (jobfile, type(conf), Configuration)
- return conf
-
-if __name__ == '__main__':
- from jobfile import *
- import sys
-
- usage = 'Usage: %s [-b] [-c] [-v] <jobfile>' % sys.argv[0]
-
- try:
- import getopt
- opts, args = getopt.getopt(sys.argv[1:], '-bcv')
- except getopt.GetoptError:
- sys.exit(usage)
-
- if len(args) != 1:
- raise AttributeError, usage
-
- both = False
- checkpoint = False
- verbose = False
- for opt,arg in opts:
- if opt == '-b':
- both = True
- checkpoint = True
- if opt == '-c':
- checkpoint = True
- if opt == '-v':
- verbose = True
-
- jobfile = args[0]
- conf = JobFile(jobfile)
-
- if both:
- gen = conf.alljobs()
- elif checkpoint:
- gen = conf.checkpoints()
- else:
- gen = conf.jobs()
-
- for job in gen:
- if not verbose:
- cpt = ''
- if job.checkpoint:
- cpt = job.checkpoint.name
- print job.name, cpt
- else:
- job.printinfo()
diff --git a/util/style.py b/util/style.py
index a6a2377ae..fa9a30b54 100644
--- a/util/style.py
+++ b/util/style.py
@@ -1,5 +1,6 @@
#! /usr/bin/env python
-# Copyright (c) 2007 The Regents of The University of Michigan
+# Copyright (c) 2006 The Regents of The University of Michigan
+# Copyright (c) 2007 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -260,35 +261,42 @@ def modified_lines(old_data, new_data, max_lines):
break
return modified
-def check_whitespace(ui, repo, hooktype, node, parent1, parent2):
- from mercurial import mdiff
+def do_check_whitespace(ui, repo, *files, **args):
+ """check files for proper m5 style guidelines"""
+ from mercurial import mdiff, util
- if hooktype != 'pretxncommit':
- raise AttributeError, \
- "This hook is only meant for pretxncommit, not %s" % hooktype
+ if files:
+ files = frozenset(files)
+
+ def skip(name):
+ return files and name in files
- tabsize = 8
- verbose = ui.configbool('style', 'verbose', False)
def prompt(name, fixonly=None):
- result = ui.prompt("(a)bort, (i)gnore, or (f)ix?", "^[aif]$", "a")
+ if args.get('auto', False):
+ result = 'f'
+ else:
+ result = ui.prompt("(a)bort, (i)gnore, or (f)ix?", "^[aif]$", "a")
if result == 'a':
return True
elif result == 'i':
pass
elif result == 'f':
- fixwhite(repo.wjoin(name), tabsize, fixonly)
+ fixwhite(repo.wjoin(name), args['tabsize'], fixonly)
else:
- raise RepoError, "Invalid response: '%s'" % result
+ raise util.Abort(_("Invalid response: '%s'") % result)
return False
modified, added, removed, deleted, unknown, ignore, clean = repo.status()
for fname in added:
+ if skip(fname):
+ continue
+
ok = True
for line,num in checkwhite(repo.wjoin(fname)):
ui.write("invalid whitespace in %s:%d\n" % (fname, num))
- if verbose:
+ if ui.verbose:
ui.write(">>%s<<\n" % line[-1])
ok = False
@@ -296,21 +304,31 @@ def check_whitespace(ui, repo, hooktype, node, parent1, parent2):
if prompt(fname):
return True
- wctx = repo.workingctx()
+ try:
+ wctx = repo.workingctx()
+ except:
+ from mercurial import context
+ wctx = context.workingctx(repo)
+
for fname in modified:
+ if skip(fname):
+ continue
+
if not whitespace_file(fname):
continue
fctx = wctx.filectx(fname)
pctx = fctx.parents()
- assert len(pctx) in (1, 2)
file_data = fctx.data()
lines = mdiff.splitnewlines(file_data)
- mod_lines = modified_lines(pctx[0].data(), file_data, len(lines))
- if len(pctx) == 2:
- m2 = modified_lines(pctx[1].data(), file_data, len(lines))
- mod_lines = mod_lines & m2 # only the lines that are new in both
+ if len(pctx) in (1, 2):
+ mod_lines = modified_lines(pctx[0].data(), file_data, len(lines))
+ if len(pctx) == 2:
+ m2 = modified_lines(pctx[1].data(), file_data, len(lines))
+ mod_lines = mod_lines & m2 # only the lines that are new in both
+ else:
+ mod_lines = xrange(0, len(lines))
fixonly = set()
for i,line in enumerate(lines):
@@ -321,7 +339,7 @@ def check_whitespace(ui, repo, hooktype, node, parent1, parent2):
continue
ui.write("invalid whitespace: %s:%d\n" % (fname, i+1))
- if verbose:
+ if ui.verbose:
ui.write(">>%s<<\n" % line[:-1])
fixonly.add(i)
@@ -329,6 +347,14 @@ def check_whitespace(ui, repo, hooktype, node, parent1, parent2):
if prompt(fname, fixonly):
return True
+def check_whitespace(ui, repo, hooktype, node, parent1, parent2):
+ if hooktype != 'pretxncommit':
+ raise AttributeError, \
+ "This hook is only meant for pretxncommit, not %s" % hooktype
+
+ args = { 'tabsize' : 8 }
+ do_check_whitespace(ui, repo, **args)
+
def check_format(ui, repo, hooktype, node, parent1, parent2):
if hooktype != 'pretxncommit':
raise AttributeError, \
@@ -350,10 +376,23 @@ def check_format(ui, repo, hooktype, node, parent1, parent2):
elif result.startswith('a'):
return True
else:
- raise RepoError, "Invalid response: '%s'" % result
+ raise util.Abort(_("Invalid response: '%s'") % result)
return False
+try:
+ from mercurial.i18n import _
+except ImportError:
+ def _(arg):
+ return arg
+
+cmdtable = {
+ '^m5style' :
+ ( do_check_whitespace,
+ [ ('a', 'auto', False, _("automatically fix whitespace")),
+ ('t', 'tabsize', 8, _("Number of spaces TAB indents")) ],
+ _('hg m5check [-t <tabsize>] [FILE]...')),
+}
if __name__ == '__main__':
import getopt
diff --git a/util/term/term.c b/util/term/term.c
index 597966159..54924c0e1 100644
--- a/util/term/term.c
+++ b/util/term/term.c
@@ -46,16 +46,16 @@
#include <unistd.h>
#include <fcntl.h>
-ssize_t atomicio(ssize_t (*)(), int, void *, size_t);
-void readwrite(int);
-int remote_connect(char *, char *, struct addrinfo);
+ssize_t atomicio(ssize_t (*)(), int, void *, size_t);
+void readwrite(int);
+int remote_connect(char *, char *, struct addrinfo);
-struct termios saved_ios;
-void raw_term();
-void restore_term();
+struct termios saved_ios;
+void raw_term();
+void restore_term();
-char progname[256];
-void usage(int);
+char progname[256];
+void usage(int);
int
main(int argc, char *argv[])
@@ -139,54 +139,63 @@ remote_connect(char *host, char *port, struct addrinfo hints)
/*
* readwrite()
- * Loop that polls on the network file descriptor and stdin.
+ * Loop that selects on the network file descriptor and stdin.
+ * Changed from poll() by Ali Saidi to make work on Mac OS X >= 10.4
*/
void
readwrite(int nfd)
{
- struct pollfd pfd[2];
+ fd_set read_fds;
char buf[BUFSIZ];
- int wfd = fileno(stdin), n, ret;
+ int wfd = fileno(stdin), n, ret, max_fd;
int lfd = fileno(stdout);
int escape = 0;
+ struct timeval timeout;
- /* Setup Network FD */
- pfd[0].fd = nfd;
- pfd[0].events = POLLIN;
+ if (nfd == -1)
+ return;
- /* Setup STDIN FD */
- pfd[1].fd = wfd;
- pfd[1].events = POLLIN;
+ max_fd = nfd + 1;
- while (pfd[0].fd != -1) {
- if ((n = poll(pfd, 2, -1)) < 0) {
+ while (1) {
+ FD_ZERO(&read_fds);
+ FD_SET(wfd, &read_fds);
+ FD_SET(nfd, &read_fds);
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ n = select(max_fd, &read_fds, NULL, NULL, &timeout);
+ if (n < 0) {
close(nfd);
- err(1, "Polling Error");
+ perror("Select Error:");
}
- if (n == 0)
+ if (n == 0) {
+ if (read(nfd, buf, 0) < 0)
+ return;
+ continue;
+ }
+
+ if (read(nfd, buf, 0) < 0)
return;
- if (pfd[0].revents & POLLIN) {
+ if (FD_ISSET(nfd, &read_fds)) {
if ((n = read(nfd, buf, sizeof(buf))) < 0)
return;
else if (n == 0) {
shutdown(nfd, SHUT_RD);
- pfd[0].fd = -1;
- pfd[0].events = 0;
+ return;
} else {
if ((ret = atomicio(write, lfd, buf, n)) != n)
return;
}
}
- if (pfd[1].revents & POLLIN) {
+ if (FD_ISSET(wfd, &read_fds)) {
if ((n = read(wfd, buf, sizeof(buf))) < 0)
return;
else if (n == 0) {
shutdown(nfd, SHUT_WR);
- pfd[1].fd = -1;
- pfd[1].events = 0;
} else {
if (escape) {
char buf2[] = "~";
@@ -208,7 +217,7 @@ readwrite(int nfd)
return;
}
}
- }
+ } // while
}
void
diff --git a/util/tracediff b/util/tracediff
index 3633fdb48..5349c303d 100755
--- a/util/tracediff
+++ b/util/tracediff
@@ -28,7 +28,9 @@
# Authors: Steve Reinhardt
# Script to simplify using rundiff on trace outputs from two
-# invocations of m5.
+# invocations of m5. Takes a common m5 command line with embedded
+# alternatives and executes the two alternative commands in separate
+# subdirectories with output piped to rundiff.
#
# ******Note that you need to enable some trace flags in the args in order
# to do anything useful!******
@@ -40,6 +42,10 @@
# of the '|' is appended to the respective command lines. Note that
# you'll have to quote the arg or escape the '|' with a backslash
# so that the shell doesn't think you're doing a pipe.
+# - Arguments with '#' characters are split at those characters,
+# processed for alternatives ('|'s) as independent terms, then
+# pasted back into a single argument (without the '#'s). (Sort of
+# inspired by the C preprocessor '##' token pasting operator.)
#
# In other words, the arguments should look like the command line you
# want to run, with "|" used to list the alternatives for the parts
@@ -47,34 +53,67 @@
#
# For example:
#
-# % tracediff m5.opt --opt1 "--opt2|--opt3" --opt4
+# % tracediff m5.opt --opt1 '--opt2|--opt3' --opt4
# would compare these two runs:
# m5.opt --opt1 --opt2 --opt4
# m5.opt --opt1 --opt3 --opt4
#
-# If you want to compare two different simulator binaries, put a '|'
-# in the first script argument ("path1/m5.opt|path2/m5.opt"). If you
-# want to add arguments to one run only, just put a '|' in with text
-# only on one side ("--onlyOn1|"). You can do this with multiple
-# arguments together too ("|-a -b -c" adds three args to the second
+# % tracediff 'path1|path2#/m5.opt' --opt1 --opt2
+# would compare these two runs:
+# path1/m5.opt --opt1 --opt2
+# path2/m5.opt --opt1 --opt2
+#
+# If you want to add arguments to one run only, just put a '|' in with
+# text only on one side ('--onlyOn1|'). You can do this with multiple
+# arguments together too ('|-a -b -c' adds three args to the second
# run only).
#
+# The '-n' argument to tracediff allows you to preview the two
+# generated command lines without running them.
+#
use FindBin;
-if (@ARGV < 2) {
- die "Usage: tracediff \"sim1|sim2\" [common-arg \"arg1|arg2\" ...]\n";
+$dryrun = 0;
+
+if (@ARGV >= 1 && $ARGV[0] eq '-n') {
+ $dryrun = 1;
+ shift @ARGV;
+}
+
+if (@ARGV < 1) {
+ die "Usage: tracediff [-n] \"sim1|sim2\" [common-arg \"arg1|arg2\" ...]\n";
}
foreach $arg (@ARGV) {
- @pair = split('\|', $arg, -1); # -1 enables null trailing fields
- if ($#pair > 0) {
- push @cmd1, $pair[0];
- push @cmd2, $pair[1];
- } else {
- push @cmd1, $arg;
- push @cmd2, $arg;
+ $a1 = $a2 = '';
+ @subargs = split('#', $arg);
+ foreach $subarg (@subargs) {
+ if ($subarg eq '') {
+ next;
+ }
+ @pair = split('\|', $subarg, -1); # -1 enables null trailing fields
+ if (@pair == 1) {
+ $a1 .= $subarg;
+ $a2 .= $subarg;
+ } elsif (@pair == 2) {
+ $a1 .= $pair[0];
+ $a2 .= $pair[1];
+ } else {
+ print 'Parse error: too many |s in ', $arg, "\n";
+ exit(1);
+ }
}
+
+ push @cmd1, $a1;
+ push @cmd2, $a2;
+}
+
+
+if ($dryrun) {
+ print "CMD1: ", join(' ', @cmd1), "\n";
+ print "CMD2: ", join(' ', @cmd2), "\n";
+ exit(0);
}
# First two args are the two simulator binaries to compare